From 734c493dc1e416ee188ad121033b7856e8259816 Mon Sep 17 00:00:00 2001 From: Udo Walter Date: Thu, 18 Jan 2018 17:54:13 +0100 Subject: [statistics] added permissions to view client logs; removed unused query arguments from Paginate::exec (caused an error if query arguments that are actually used in the query are passed to Paginate::exec) --- inc/paginate.inc.php | 2 -- 1 file changed, 2 deletions(-) (limited to 'inc') diff --git a/inc/paginate.inc.php b/inc/paginate.inc.php index cdb4adf1..b212e252 100644 --- a/inc/paginate.inc.php +++ b/inc/paginate.inc.php @@ -65,8 +65,6 @@ class Paginate $countQuery = preg_replace('/ORDER\s+BY\s.*?(\sASC|\sDESC|$)/is', '', $this->query); $countQuery = preg_replace('/SELECT\s.*?\sFROM\s/is', 'SELECT Count(*) AS rowcount FROM ', $countQuery); $countRes = Database::queryFirst($countQuery, $args); - $args['limit_start'] = $this->currentPage; - $args['limit_count'] = $this->perPage; $query = $this->query . ' LIMIT ' . ($this->currentPage * $this->perPage) . ', ' . $this->perPage; $retval = Database::simpleQuery($query, $args); $this->totalRows = (int)$countRes['rowcount']; -- cgit v1.2.3-55-g7522 From c23b6957d841d273cf8b0838481ea461a88a8eb4 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 8 Feb 2018 15:17:30 +0100 Subject: [inc/User] Add locationid 0 to allowed locations in fallback mode --- inc/user.inc.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'inc') diff --git a/inc/user.inc.php b/inc/user.inc.php index 81091e1b..b5a364ee 100644 --- a/inc/user.inc.php +++ b/inc/user.inc.php @@ -47,8 +47,11 @@ class User $permission = $module ? $module->getIdentifier().".".$permission : $permission; return PermissionUtil::getAllowedLocations(self::$user['userid'], $permission); } - if (self::$user['permissions'] & Permission::get('superadmin')) - return array_keys(Location::getLocationsAssoc()); + if (self::$user['permissions'] & Permission::get('superadmin')) { + $a = array_keys(Location::getLocationsAssoc()); + $a[] = 0; + return $a; + } return array(); } -- cgit v1.2.3-55-g7522 From cfa60bc6dc68699efb74342ead37865c074bc66a Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 9 Feb 2018 16:13:17 +0100 Subject: Permissions: Introduce helper functions for common tasks assertPermission ensures the user has a given permission and halts execution otherwise. addGlobalTags is a helper to fill an array for the rendering process with tags associated with (missing) permissions. --- inc/permission.inc.php | 20 ++++++++++++++++++++ inc/user.inc.php | 29 +++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-) (limited to 'inc') diff --git a/inc/permission.inc.php b/inc/permission.inc.php index d04e3c3b..defa9f4d 100644 --- a/inc/permission.inc.php +++ b/inc/permission.inc.php @@ -15,5 +15,25 @@ class Permission return self::$permissions[$permission]; } + + public static function addGlobalTags(&$array, $locationid, $disabled) + { + if (!Module::isAvailable('permissionmanager')) + return; + foreach ($disabled as $perm) { + if (User::hasPermission($perm, $locationid)) + continue; + if (strpos($perm, '.') === false) { + $array[$perm]['disabled'] = 'disabled'; + continue; + } + $temp =& $array; + foreach (explode('.', $perm) as $sub) { + $temp =& $temp[$sub]; + } + $temp['disabled'] = 'disabled'; + } + } + } diff --git a/inc/user.inc.php b/inc/user.inc.php index b5a364ee..eee4f883 100644 --- a/inc/user.inc.php +++ b/inc/user.inc.php @@ -31,8 +31,12 @@ class User if (!self::isLoggedIn()) return false; if (Module::isAvailable("permissionmanager")) { - $module = Page::getModule(); - $permission = $module ? $module->getIdentifier().".".$permission : $permission; + if ($permission{0} === '.') { + $permission = substr($permission, 1); + } else { + $module = Page::getModule(); + $permission = $module ? $module->getIdentifier() . "." . $permission : $permission; + } return PermissionUtil::userHasPermission(self::$user['userid'], $permission, $locationid); } if (self::$user['permissions'] & Permission::get('superadmin')) @@ -40,8 +44,29 @@ class User return (self::$user['permissions'] & Permission::get($permission)) != 0; } + /** + * Confirm current user has the given permission, stop execution and show error message + * otherwise. + * @param string $permission Permission to check for + * @param null|int $locationid location this permission has to apply to, NULL if any location is sufficient + * @param null|string $redirect page to redirect to if permission is not given, NULL defaults to main page + */ + public static function assertPermission($permission, $locationid = NULL, $redirect = NULL) + { + if (User::hasPermission($permission, $locationid)) + return; + Message::addError('main.no-permission'); + if (is_null($redirect)) { + Util::redirect('?do=main'); + } else { + Util::redirect($redirect); + } + } + public static function getAllowedLocations($permission) { + if (!self::isLoggedIn()) + return []; if (Module::isAvailable("permissionmanager")) { $module = Page::getModule(); $permission = $module ? $module->getIdentifier().".".$permission : $permission; -- cgit v1.2.3-55-g7522 From c3a4746d44a3909e1281bbb575987888ae80ac7b Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 14 Feb 2018 13:19:58 +0100 Subject: [inc/Permission] Add parameter to helper; fix for querying foreign module --- inc/permission.inc.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'inc') diff --git a/inc/permission.inc.php b/inc/permission.inc.php index defa9f4d..cd41e986 100644 --- a/inc/permission.inc.php +++ b/inc/permission.inc.php @@ -16,23 +16,32 @@ class Permission } - public static function addGlobalTags(&$array, $locationid, $disabled) + // TODO: Doc/Refactor + public static function addGlobalTags(&$array, $locationid, $disabled, $noneAvailDisabled = null) { if (!Module::isAvailable('permissionmanager')) return; + $one = false; foreach ($disabled as $perm) { - if (User::hasPermission($perm, $locationid)) + if (User::hasPermission($perm, $locationid)) { + $one = true; continue; + } if (strpos($perm, '.') === false) { $array[$perm]['disabled'] = 'disabled'; continue; } $temp =& $array; foreach (explode('.', $perm) as $sub) { + if (empty($sub)) + continue; $temp =& $temp[$sub]; } $temp['disabled'] = 'disabled'; } + if (!$one && !is_null($noneAvailDisabled)) { + $array[$noneAvailDisabled]['disabled'] = true; + } } } -- cgit v1.2.3-55-g7522 From fadc375c510693a87a2e1acb090605bbeed52fe4 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 14 Feb 2018 14:15:05 +0100 Subject: Global: Only show "Warning" badge at the top if user can view event log, also hide warnings on the main page from modules the user has no access to --- inc/dashboard.inc.php | 2 +- inc/permission.inc.php | 9 ++++++++- modules-available/main/page.inc.php | 5 ++++- 3 files changed, 13 insertions(+), 3 deletions(-) (limited to 'inc') diff --git a/inc/dashboard.inc.php b/inc/dashboard.inc.php index 3db42efb..59d81c2d 100644 --- a/inc/dashboard.inc.php +++ b/inc/dashboard.inc.php @@ -68,7 +68,7 @@ class Dashboard 'url' => urlencode($_SERVER['REQUEST_URI']), 'langs' => Dictionary::getLanguages(true), 'user' => User::getName(), - 'warning' => User::getName() !== false && User::getLastSeenEvent() < Property::getLastWarningId(), + 'warning' => User::getName() !== false && User::hasPermission('.eventlog.*') && User::getLastSeenEvent() < Property::getLastWarningId(), 'needsSetup' => User::getName() !== false && Property::getNeedsSetup() )); } diff --git a/inc/permission.inc.php b/inc/permission.inc.php index cd41e986..d6977e32 100644 --- a/inc/permission.inc.php +++ b/inc/permission.inc.php @@ -19,7 +19,7 @@ class Permission // TODO: Doc/Refactor public static function addGlobalTags(&$array, $locationid, $disabled, $noneAvailDisabled = null) { - if (!Module::isAvailable('permissionmanager')) + if (Module::get('permissionmanager') === false) return; $one = false; foreach ($disabled as $perm) { @@ -44,5 +44,12 @@ class Permission } } + public static function moduleHasPermissions($moduleId) + { + if (Module::get('permissionmanager') === false) + return true; + return file_exists('modules/' . $moduleId . '/permissions/permissions.json'); + } + } diff --git a/modules-available/main/page.inc.php b/modules-available/main/page.inc.php index 70296a59..baea8350 100644 --- a/modules-available/main/page.inc.php +++ b/modules-available/main/page.inc.php @@ -26,7 +26,10 @@ class Page_Main extends Page // Warnings $needSetup = false; foreach (Hook::load('main-warning') as $hook) { - include $hook->file; + if (Permission::moduleHasPermissions($hook->moduleId) + && User::hasPermission('.' . $hook->moduleId . '.*')) { + include $hook->file; + } } // Update warning state -- cgit v1.2.3-55-g7522 From 735ac097f1ab25f68687f0af77cab60832a012b2 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 14 Feb 2018 15:31:53 +0100 Subject: [inc/Permission] Add readonly string --- inc/permission.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'inc') diff --git a/inc/permission.inc.php b/inc/permission.inc.php index d6977e32..e61c7423 100644 --- a/inc/permission.inc.php +++ b/inc/permission.inc.php @@ -28,7 +28,7 @@ class Permission continue; } if (strpos($perm, '.') === false) { - $array[$perm]['disabled'] = 'disabled'; + $array[$perm] = ['disabled' => 'disabled', 'readonly' => 'readonly']; continue; } $temp =& $array; @@ -37,7 +37,7 @@ class Permission continue; $temp =& $temp[$sub]; } - $temp['disabled'] = 'disabled'; + $temp = ['disabled' => 'disabled', 'readonly' => 'readonly']; } if (!$one && !is_null($noneAvailDisabled)) { $array[$noneAvailDisabled]['disabled'] = true; -- cgit v1.2.3-55-g7522 From 092b99fb7964ba15d7f20119ef7bd51ca1f2675f Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 15 Feb 2018 13:23:57 +0100 Subject: [inc/User] getAllowedLocations(): Support cross-module checking --- inc/user.inc.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'inc') diff --git a/inc/user.inc.php b/inc/user.inc.php index eee4f883..79facffc 100644 --- a/inc/user.inc.php +++ b/inc/user.inc.php @@ -68,8 +68,12 @@ class User if (!self::isLoggedIn()) return []; if (Module::isAvailable("permissionmanager")) { - $module = Page::getModule(); - $permission = $module ? $module->getIdentifier().".".$permission : $permission; + if ($permission{0} === '.') { + $permission = substr($permission, 1); + } else { + $module = Page::getModule(); + $permission = $module ? $module->getIdentifier() . "." . $permission : $permission; + } return PermissionUtil::getAllowedLocations(self::$user['userid'], $permission); } if (self::$user['permissions'] & Permission::get('superadmin')) { -- cgit v1.2.3-55-g7522 From 276675039e3a596bbf88ff95203e5c1a30723204 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 16 Feb 2018 13:10:16 +0100 Subject: [inc/User] assertPermission(): Don't redirect if it's an ajax call --- inc/user.inc.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'inc') diff --git a/inc/user.inc.php b/inc/user.inc.php index 79facffc..2ba1bad2 100644 --- a/inc/user.inc.php +++ b/inc/user.inc.php @@ -56,6 +56,10 @@ class User if (User::hasPermission($permission, $locationid)) return; Message::addError('main.no-permission'); + if (AJAX) { + Message::renderList(); + exit; + } if (is_null($redirect)) { Util::redirect('?do=main'); } else { -- cgit v1.2.3-55-g7522 From 7afe5a3ffee64ff5c1ee7692a2ac4c83d46d6a78 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 19 Feb 2018 13:36:35 +0100 Subject: [permissionmanager] Implement permissions: Permissinmanager is now protected by permissions. In order to prevent complete lockout, the user with userid == 1 will always be able to edit and assign permissions. (TODO: Communicate this somehow) --- inc/permission.inc.php | 2 +- .../inc/getpermissiondata.inc.php | 22 +++++++- .../permissionmanager/inc/permissionutil.inc.php | 34 ++++++++----- .../permissionmanager/lang/de/permissions.json | 7 +++ .../permissionmanager/lang/de/template-tags.json | 6 ++- .../permissionmanager/lang/en/permissions.json | 7 +++ .../permissionmanager/lang/en/template-tags.json | 6 ++- modules-available/permissionmanager/page.inc.php | 59 +++++++++++++++------- .../permissionmanager/permissions/permissions.json | 17 +++++++ modules-available/permissionmanager/style.css | 4 ++ .../permissionmanager/templates/header-menu.html | 6 +-- .../permissionmanager/templates/roleeditor.html | 5 +- .../permissionmanager/templates/rolestable.html | 25 ++++++--- .../permissionmanager/templates/treenode.html | 2 +- .../permissionmanager/templates/treepanel.html | 2 +- .../roomplanner/permissions/permissions.json | 10 ++++ 16 files changed, 164 insertions(+), 50 deletions(-) create mode 100644 modules-available/permissionmanager/lang/de/permissions.json create mode 100644 modules-available/permissionmanager/lang/en/permissions.json create mode 100644 modules-available/permissionmanager/permissions/permissions.json create mode 100644 modules-available/roomplanner/permissions/permissions.json (limited to 'inc') diff --git a/inc/permission.inc.php b/inc/permission.inc.php index e61c7423..aaef6ba6 100644 --- a/inc/permission.inc.php +++ b/inc/permission.inc.php @@ -33,7 +33,7 @@ class Permission } $temp =& $array; foreach (explode('.', $perm) as $sub) { - if (empty($sub)) + if (empty($sub) || $sub === '*') continue; $temp =& $temp[$sub]; } diff --git a/modules-available/permissionmanager/inc/getpermissiondata.inc.php b/modules-available/permissionmanager/inc/getpermissiondata.inc.php index dd100d42..496c8224 100644 --- a/modules-available/permissionmanager/inc/getpermissiondata.inc.php +++ b/modules-available/permissionmanager/inc/getpermissiondata.inc.php @@ -3,6 +3,9 @@ class GetPermissionData { + const WITH_USER_COUNT = 1; + const WITH_LOCATION_COUNT = 2; + /** * Get data for all users. * @@ -64,11 +67,26 @@ class GetPermissionData /** * Get all roles. * + * @param int $flags Bitmask specifying additional data to fetch (WITH_* constants of this class) * @return array array roles (each with roleid and rolename) */ - public static function getRoles() + public static function getRoles($flags = 0) { - return Database::queryAll("SELECT roleid, rolename FROM role ORDER BY rolename ASC"); + $cols = $joins = ''; + if ($flags & self::WITH_USER_COUNT) { + $cols .= ', Count(DISTINCT rxu.userid) AS users'; + $joins .= ' LEFT JOIN user_x_role rxu ON (r.roleid = rxu.roleid)'; + } + if ($flags & self::WITH_LOCATION_COUNT) { + $cols .= ', Count(DISTINCT rxl.locationid) AS locations'; + $joins .= ' LEFT JOIN role_x_location rxl ON (r.roleid = rxl.roleid)'; + } + if (!empty($joins)) { + $joins .= ' GROUP BY r.roleid'; + } + return Database::queryAll("SELECT r.roleid, r.rolename $cols FROM role r + $joins + ORDER BY rolename ASC"); } /** diff --git a/modules-available/permissionmanager/inc/permissionutil.inc.php b/modules-available/permissionmanager/inc/permissionutil.inc.php index b4d54055..bc42c5a0 100644 --- a/modules-available/permissionmanager/inc/permissionutil.inc.php +++ b/modules-available/permissionmanager/inc/permissionutil.inc.php @@ -53,6 +53,9 @@ class PermissionUtil $permissionid = strtolower($permissionid); self::validatePermission($permissionid); $parts = explode('.', $permissionid); + // Special case: To prevent lockout, userid === 1 always has permissionmanager.* + if ($parts[0] === 'permissionmanager' && User::getId() === 1) + return true; // Limit query to first part of permissionid, which is always the module id $prefix = $parts[0] . '.%'; if (is_null($locationid)) { @@ -103,21 +106,26 @@ class PermissionUtil $permissionid = strtolower($permissionid); self::validatePermission($permissionid); $parts = explode('.', $permissionid); - // Limit query to first part of permissionid, which is always the module id - $prefix = $parts[0] . '.%'; - $res = Database::simpleQuery("SELECT permissionid, locationid FROM role_x_permission - INNER JOIN user_x_role USING (roleid) - INNER JOIN role_x_location USING (roleid) - WHERE user_x_role.userid = :userid AND (permissionid LIKE :prefix OR permissionid LIKE '*')", - compact('userid', 'prefix')); + // Special case: To prevent lockout, userid === 1 always has permissionmanager.* + if ($parts[0] === 'permissionmanager' && User::getId() === 1) { + $allowedLocations = [true]; + } else { + // Limit query to first part of permissionid, which is always the module id + $prefix = $parts[0] . '.%'; + $res = Database::simpleQuery("SELECT permissionid, locationid FROM role_x_permission + INNER JOIN user_x_role USING (roleid) + INNER JOIN role_x_location USING (roleid) + WHERE user_x_role.userid = :userid AND (permissionid LIKE :prefix OR permissionid LIKE '*')", + compact('userid', 'prefix')); - // Gather locationid from relevant rows - self::makeComparisonVariants($parts, $compare, $wildcard, $wclen); - $allowedLocations = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - if (in_array($row['permissionid'], $compare, true) + // Gather locationid from relevant rows + self::makeComparisonVariants($parts, $compare, $wildcard, $wclen); + $allowedLocations = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if (in_array($row['permissionid'], $compare, true) || ($wildcard !== false && strncmp($row['permissionid'], $wildcard, $wclen) === 0)) { - $allowedLocations[(int)$row['locationid']] = true; + $allowedLocations[(int)$row['locationid']] = true; + } } } $locations = Location::getTree(); diff --git a/modules-available/permissionmanager/lang/de/permissions.json b/modules-available/permissionmanager/lang/de/permissions.json new file mode 100644 index 00000000..444c1e8c --- /dev/null +++ b/modules-available/permissionmanager/lang/de/permissions.json @@ -0,0 +1,7 @@ +{ + "locations.view": "Orte mit zugewiesenen Rollen sehen.", + "roles.edit": "Rollen bearbeiten.", + "roles.view": "Rollen sehen.", + "users.edit-roles": "Benutzern Rollen zuweisen oder entziehen.", + "users.view": "Benutzer mit zugewiesenen Rolen sehen." +} \ No newline at end of file diff --git a/modules-available/permissionmanager/lang/de/template-tags.json b/modules-available/permissionmanager/lang/de/template-tags.json index 2ec25b37..52073dee 100644 --- a/modules-available/permissionmanager/lang/de/template-tags.json +++ b/modules-available/permissionmanager/lang/de/template-tags.json @@ -1,18 +1,20 @@ { "lang_addRole": "Rollen erteilen", "lang_addRoleHeading": "Neue Rolle hinzuf\u00fcgen", - "lang_deleteCheck": "Sind Sie sich sicher, dass Sie diese Rolle l\u00f6schen wollen?", "lang_editRoleHeading": "Rolle bearbeiten", "lang_locationAwareDesc": "Berechtigungen mit diesem Symbol k\u00f6nnen auf bestimmte R\u00e4ume\/Orte beschr\u00e4nkt werden. Alle anderen Berechtigungen sind unabh\u00e4ngig von den f\u00fcr diese Rolle ausgew\u00e4hlten Orten.", "lang_locations": "R\u00e4ume", "lang_moduleName": "Rechtemanager", "lang_name": "Name", "lang_newRole": "Rolle anlegen", + "lang_numAssignedUsers": "Benutzer mit dieser Rolle", "lang_permissions": "Rechte", "lang_removeRole": "Rollen entziehen", + "lang_roleDeleteConfirm": "Sind Sie sich sicher, dass Sie diese Rolle l\u00f6schen m\u00f6chten? Benutzer, denen diese Rolle zugewiesen ist, werden die entsprechenden Berechtigungen verlieren.", "lang_roles": "Rollen", "lang_searchPlaceholder": "Nach Rollen suchen...", "lang_selected": "ausgew\u00e4hlte", "lang_selectizePlaceholder": "Nach Rollen filtern...", - "lang_users": "Nutzer" + "lang_users": "Nutzer", + "lang_view": "Anzeigen" } \ No newline at end of file diff --git a/modules-available/permissionmanager/lang/en/permissions.json b/modules-available/permissionmanager/lang/en/permissions.json new file mode 100644 index 00000000..9f7263db --- /dev/null +++ b/modules-available/permissionmanager/lang/en/permissions.json @@ -0,0 +1,7 @@ +{ + "locations.view": "See locations with assigned roles.", + "roles.edit": "Edit roles.", + "roles.view": "Show roles.", + "users.edit-roles": "Assign or remove roles from users.", + "users.view": "See users with assigned roles." +} \ No newline at end of file diff --git a/modules-available/permissionmanager/lang/en/template-tags.json b/modules-available/permissionmanager/lang/en/template-tags.json index cef23422..b7a1d77a 100644 --- a/modules-available/permissionmanager/lang/en/template-tags.json +++ b/modules-available/permissionmanager/lang/en/template-tags.json @@ -1,18 +1,20 @@ { "lang_addRole": "Grant Roles", "lang_addRoleHeading": "Add new role", - "lang_deleteCheck": "Are you sure you want to delete this role?", "lang_editRoleHeading": "Edit role", "lang_locationAwareDesc": "Permissions with this symbol can be restricted to certain locations. All other permissions are independent of the locations selected for this role.", "lang_locations": "Locations", "lang_moduleName": "Permission Manager", "lang_name": "Name", "lang_newRole": "New Role", + "lang_numAssignedUsers": "Users with this role", "lang_permissions": "Permissions", "lang_removeRole": "Revoke Roles", + "lang_roleDeleteConfirm": "Are you sure you want to delete this role? Users currently assigned to this role will lose the according permissions.", "lang_roles": "Roles", "lang_searchPlaceholder": "Search for roles...", "lang_selected": "selected", "lang_selectizePlaceholder": "Filter for roles...", - "lang_users": "Users" + "lang_users": "Users", + "lang_view": "View" } \ No newline at end of file diff --git a/modules-available/permissionmanager/page.inc.php b/modules-available/permissionmanager/page.inc.php index 1c2d56bf..a78f935f 100644 --- a/modules-available/permissionmanager/page.inc.php +++ b/modules-available/permissionmanager/page.inc.php @@ -17,17 +17,21 @@ class Page_PermissionManager extends Page $action = Request::any('action', 'show', 'string'); if ($action === 'addRoleToUser') { + User::assertPermission('users.edit-roles'); $users = Request::post('users', ''); $roles = Request::post('roles', ''); PermissionDbUpdate::addRoleToUser($users, $roles); } elseif ($action === 'removeRoleFromUser') { + User::assertPermission('users.edit-roles'); $users = Request::post('users', ''); $roles = Request::post('roles', ''); PermissionDbUpdate::removeRoleFromUser($users, $roles); } elseif ($action === 'deleteRole') { + User::assertPermission('roles.edit'); $id = Request::post('deleteId', false, 'string'); PermissionDbUpdate::deleteRole($id); } elseif ($action === 'saveRole') { + User::assertPermission('roles.edit'); $roleID = Request::post("roleid", false); $rolename = Request::post("rolename"); $locations = self::processLocations(Request::post("locations")); @@ -44,33 +48,51 @@ class Page_PermissionManager extends Page */ protected function doRender() { - $show = Request::get("show", "roles"); + $show = Request::get("show", false, 'string'); + + if ($show === false) { + foreach (['roles', 'users', 'locations'] as $show) { + if (User::hasPermission($show . '.*')) + break; + } + } // switch between tables, but always show menu to switch tables // get menu button colors - $buttonColors = array(); + $data = array(); if ($show === "roleEditor") { - $buttonColors['groupClass'] = 'slx-fade'; - $buttonColors['rolesButtonClass'] = 'active'; + $data['groupClass'] = 'btn-group-muted'; + $data['rolesButtonClass'] = 'active'; } else { - $buttonColors[$show . 'ButtonClass'] = 'active'; + $data[$show . 'ButtonClass'] = 'active'; } + Permission::addGlobalTags($data['perms'], null, ['roles.*', 'users.*', 'locations.*']); - Render::addtemplate('header-menu', $buttonColors); + Render::addtemplate('header-menu', $data); if ($show === "roles") { - $data = array("roles" => GetPermissionData::getRoles()); + User::assertPermission('roles.*'); + $data = array("roles" => GetPermissionData::getRoles(GetPermissionData::WITH_USER_COUNT)); + Permission::addGlobalTags($data['perms'], null, ['roles.edit']); Render::addTemplate('rolestable', $data); } elseif ($show === "users") { - $data = array("user" => GetPermissionData::getUserData(), "allroles" => GetPermissionData::getRoles()); + User::assertPermission('users.*'); + $data = array("user" => GetPermissionData::getUserData()); + if (User::hasPermission('users.edit-roles')) { + $data['allroles'] = GetPermissionData::getRoles(); + } + Permission::addGlobalTags($data['perms'], null, ['users.edit-roles']); Render::addTemplate('role-filter-selectize', $data); Render::addTemplate('userstable', $data); } elseif ($show === "locations") { + User::assertPermission('locations.*'); $data = array("location" => GetPermissionData::getLocationData(), "allroles" => GetPermissionData::getRoles()); Render::addTemplate('role-filter-selectize', $data); Render::addTemplate('locationstable', $data); } elseif ($show === "roleEditor") { + User::assertPermission('roles.*'); $data = array("cancelShow" => Request::get("cancel", "roles")); + Permission::addGlobalTags($data['perms'], null, ['roles.edit']); $selectedPermissions = array(); $selectedLocations = array(); @@ -83,8 +105,10 @@ class Page_PermissionManager extends Page $selectedLocations = $roleData["locations"]; } - $data["permissionHTML"] = self::generatePermissionHTML(PermissionUtil::getPermissions(), $selectedPermissions); - $data["locationHTML"] = self::generateLocationHTML(Location::getTree(), $selectedLocations); + $data["permissionHTML"] = self::generatePermissionHTML(PermissionUtil::getPermissions(), $selectedPermissions, + false, '', ['perms' => $data['perms']]); + $data["locationHTML"] = self::generateLocationHTML(Location::getTree(), $selectedLocations, + false, '', ['perms' => $data['perms']]); Render::addTemplate('roleeditor', $data); } @@ -99,7 +123,7 @@ class Page_PermissionManager extends Page * @param string $permString the prefix permission string with which all permissions in the permission tree should start * @return string generated html code */ - private static function generatePermissionHTML($permissions, $selectedPermissions = array(), $selectAll = false, $permString = "") + private static function generatePermissionHTML($permissions, $selectedPermissions = array(), $selectAll = false, $permString = "", $tags = []) { $res = ""; $toplevel = $permString == ""; @@ -132,12 +156,12 @@ class Page_PermissionManager extends Page "toplevel" => $toplevel, "checkboxname" => "permissions", "selected" => $selected, - "HTML" => $leaf ? "" : self::generatePermissionHTML($v, $selectedPermissions, $selected, $nextPermString), + "HTML" => $leaf ? "" : self::generatePermissionHTML($v, $selectedPermissions, $selected, $nextPermString, $tags), ); if ($leaf) { $data += $v; } - $res .= Render::parse("treenode", $data); + $res .= Render::parse("treenode", $data + $tags); } if ($toplevel) { $res = Render::parse("treepanel", @@ -145,7 +169,7 @@ class Page_PermissionManager extends Page "name" => Dictionary::translateFile("template-tags", "lang_permissions"), "checkboxname" => "permissions", "selected" => $selectAll, - "HTML" => $res)); + "HTML" => $res) + $tags); } return $res; } @@ -159,7 +183,7 @@ class Page_PermissionManager extends Page * @param array $toplevel true if the location tree are the children of the root location, false if not * @return string generated html code */ - private static function generateLocationHTML($locations, $selectedLocations = array(), $selectAll = false, $toplevel = true) + private static function generateLocationHTML($locations, $selectedLocations = array(), $selectAll = false, $toplevel = true, $tags = []) { $res = ""; if ($toplevel && in_array(0, $selectedLocations)) { @@ -174,7 +198,8 @@ class Page_PermissionManager extends Page "checkboxname" => "locations", "selected" => $selected, "HTML" => array_key_exists("children", $location) ? - self::generateLocationHTML($location["children"], $selectedLocations, $selected, false) : "")); + self::generateLocationHTML($location["children"], $selectedLocations, $selected, false, $tags) : "") + + $tags); } if ($toplevel) { $res = Render::parse("treepanel", @@ -182,7 +207,7 @@ class Page_PermissionManager extends Page "name" => Dictionary::translateFile("template-tags", "lang_locations"), "checkboxname" => "locations", "selected" => $selectAll, - "HTML" => $res)); + "HTML" => $res) + $tags); } return $res; } diff --git a/modules-available/permissionmanager/permissions/permissions.json b/modules-available/permissionmanager/permissions/permissions.json new file mode 100644 index 00000000..3981a2c3 --- /dev/null +++ b/modules-available/permissionmanager/permissions/permissions.json @@ -0,0 +1,17 @@ +{ + "roles.view": { + "location-aware": false + }, + "roles.edit": { + "location-aware": false + }, + "users.view": { + "location-aware": false + }, + "users.edit-roles": { + "location-aware": false + }, + "locations.view": { + "location-aware": false + } +} \ No newline at end of file diff --git a/modules-available/permissionmanager/style.css b/modules-available/permissionmanager/style.css index 8285fdd2..6169b26f 100644 --- a/modules-available/permissionmanager/style.css +++ b/modules-available/permissionmanager/style.css @@ -55,3 +55,7 @@ td > .label { column-count: 3; } } + +.btn-group-muted > button { + color: #aaa; +} \ No newline at end of file diff --git a/modules-available/permissionmanager/templates/header-menu.html b/modules-available/permissionmanager/templates/header-menu.html index ce31d237..91bfa3af 100644 --- a/modules-available/permissionmanager/templates/header-menu.html +++ b/modules-available/permissionmanager/templates/header-menu.html @@ -4,17 +4,17 @@
- - - diff --git a/modules-available/permissionmanager/templates/roleeditor.html b/modules-available/permissionmanager/templates/roleeditor.html index d50f2145..8524427b 100644 --- a/modules-available/permissionmanager/templates/roleeditor.html +++ b/modules-available/permissionmanager/templates/roleeditor.html @@ -22,7 +22,10 @@
{{lang_cancel}} - +
@@ -56,12 +66,13 @@
- {{lang_newRole}} + {{lang_newRole}}
'; foreach ($modules as $module) { - $files = $module->getScripts($module !== $pageModule); + $files = $module->getScripts(); foreach ($files as $file) { echo ''; } diff --git a/index.php b/index.php index 4816ef42..1ecd2109 100644 --- a/index.php +++ b/index.php @@ -79,7 +79,7 @@ abstract class Page if (self::$module === false) { Util::traceError('Invalid Module: ' . $name); } - self::$module->activate(); + self::$module->activate(null, null); self::$instance = self::$module->newPage(); } diff --git a/modules-available/adduser/config.json b/modules-available/adduser/config.json index 706412d0..110f8b67 100644 --- a/modules-available/adduser/config.json +++ b/modules-available/adduser/config.json @@ -1,3 +1,3 @@ { - "category":"main.content" -} + "category": "main.content" +} \ No newline at end of file diff --git a/modules-available/backup/config.json b/modules-available/backup/config.json index 706412d0..110f8b67 100644 --- a/modules-available/backup/config.json +++ b/modules-available/backup/config.json @@ -1,3 +1,3 @@ { - "category":"main.content" -} + "category": "main.content" +} \ No newline at end of file diff --git a/modules-available/baseconfig/config.json b/modules-available/baseconfig/config.json index e4d906e1..357a117e 100644 --- a/modules-available/baseconfig/config.json +++ b/modules-available/baseconfig/config.json @@ -1,4 +1,7 @@ { "category": "main.settings-client", - "dependencies" : ["js_selectize", "bootstrap_multiselect"] -} + "dependencies": [ + "js_selectize", + "bootstrap_multiselect" + ] +} \ No newline at end of file diff --git a/modules-available/baseconfig_bwidm/config.json b/modules-available/baseconfig_bwidm/config.json index af67a188..7e6cf06a 100644 --- a/modules-available/baseconfig_bwidm/config.json +++ b/modules-available/baseconfig_bwidm/config.json @@ -1,3 +1,5 @@ { - "dependencies": ["baseconfig"] -} + "dependencies": [ + "baseconfig" + ] +} \ No newline at end of file diff --git a/modules-available/baseconfig_bwlp/config.json b/modules-available/baseconfig_bwlp/config.json index af67a188..7e6cf06a 100644 --- a/modules-available/baseconfig_bwlp/config.json +++ b/modules-available/baseconfig_bwlp/config.json @@ -1,3 +1,5 @@ { - "dependencies": ["baseconfig"] -} + "dependencies": [ + "baseconfig" + ] +} \ No newline at end of file diff --git a/modules-available/baseconfig_partitions_cdn/config.json b/modules-available/baseconfig_partitions_cdn/config.json index a355eef3..fd4c6f4b 100644 --- a/modules-available/baseconfig_partitions_cdn/config.json +++ b/modules-available/baseconfig_partitions_cdn/config.json @@ -1,4 +1,6 @@ { - "category": "main.settings-client", - "dependencies": [ "baseconfig" ] -} + "category": "main.settings-client", + "dependencies": [ + "baseconfig" + ] +} \ No newline at end of file diff --git a/modules-available/bootstrap_datepicker/config.json b/modules-available/bootstrap_datepicker/config.json index 5a0c7960..69bb0aa9 100644 --- a/modules-available/bootstrap_datepicker/config.json +++ b/modules-available/bootstrap_datepicker/config.json @@ -1,9 +1,10 @@ { - "dependencies" : [], - "css": { - "style.css": true - }, - "scripts": { - "clientscript.js": true - } -} + "dependencies": [], + "css": [ + "style.css" + ], + "scripts": [ + "clientscript.js" + ], + "client-plugin": true +} \ No newline at end of file diff --git a/modules-available/bootstrap_dialog/config.json b/modules-available/bootstrap_dialog/config.json index 5a0c7960..69bb0aa9 100644 --- a/modules-available/bootstrap_dialog/config.json +++ b/modules-available/bootstrap_dialog/config.json @@ -1,9 +1,10 @@ { - "dependencies" : [], - "css": { - "style.css": true - }, - "scripts": { - "clientscript.js": true - } -} + "dependencies": [], + "css": [ + "style.css" + ], + "scripts": [ + "clientscript.js" + ], + "client-plugin": true +} \ No newline at end of file diff --git a/modules-available/bootstrap_multiselect/config.json b/modules-available/bootstrap_multiselect/config.json index 5a0c7960..69bb0aa9 100644 --- a/modules-available/bootstrap_multiselect/config.json +++ b/modules-available/bootstrap_multiselect/config.json @@ -1,9 +1,10 @@ { - "dependencies" : [], - "css": { - "style.css": true - }, - "scripts": { - "clientscript.js": true - } -} + "dependencies": [], + "css": [ + "style.css" + ], + "scripts": [ + "clientscript.js" + ], + "client-plugin": true +} \ No newline at end of file diff --git a/modules-available/bootstrap_switch/config.json b/modules-available/bootstrap_switch/config.json index de4d37b4..3cf0d162 100644 --- a/modules-available/bootstrap_switch/config.json +++ b/modules-available/bootstrap_switch/config.json @@ -1,8 +1,9 @@ { - "css": { - "style.css": true - }, - "scripts": { - "clientscript.js": true - } + "css": [ + "style.css" + ], + "scripts": [ + "clientscript.js" + ], + "client-plugin": true } \ No newline at end of file diff --git a/modules-available/bootstrap_timepicker/config.json b/modules-available/bootstrap_timepicker/config.json index 5a0c7960..69bb0aa9 100644 --- a/modules-available/bootstrap_timepicker/config.json +++ b/modules-available/bootstrap_timepicker/config.json @@ -1,9 +1,10 @@ { - "dependencies" : [], - "css": { - "style.css": true - }, - "scripts": { - "clientscript.js": true - } -} + "dependencies": [], + "css": [ + "style.css" + ], + "scripts": [ + "clientscript.js" + ], + "client-plugin": true +} \ No newline at end of file diff --git a/modules-available/citymanagement/config.json b/modules-available/citymanagement/config.json index e87cbf7d..b356dfc6 100644 --- a/modules-available/citymanagement/config.json +++ b/modules-available/citymanagement/config.json @@ -1,4 +1,4 @@ { - "category":"citymanagement.cities", - "permission":"0" -} + "category": "citymanagement.cities", + "permission": "0" +} \ No newline at end of file diff --git a/modules-available/dnbd3/config.json b/modules-available/dnbd3/config.json index f84a4170..9670ded9 100644 --- a/modules-available/dnbd3/config.json +++ b/modules-available/dnbd3/config.json @@ -1,4 +1,7 @@ { - "category":"main.settings-server", - "dependencies":["locations","runmode"] -} + "category": "main.settings-server", + "dependencies": [ + "locations", + "runmode" + ] +} \ No newline at end of file diff --git a/modules-available/dozmod/config.json b/modules-available/dozmod/config.json index 706412d0..110f8b67 100644 --- a/modules-available/dozmod/config.json +++ b/modules-available/dozmod/config.json @@ -1,3 +1,3 @@ { - "category":"main.content" -} + "category": "main.content" +} \ No newline at end of file diff --git a/modules-available/eventlog/config.json b/modules-available/eventlog/config.json index 6778348d..aa23adb5 100644 --- a/modules-available/eventlog/config.json +++ b/modules-available/eventlog/config.json @@ -1,3 +1,3 @@ { - "category":"main.status" -} + "category": "main.status" +} \ No newline at end of file diff --git a/modules-available/exams/config.json b/modules-available/exams/config.json index 0780ebef..a99d1c1a 100644 --- a/modules-available/exams/config.json +++ b/modules-available/exams/config.json @@ -1,5 +1,12 @@ { - "category":"main.content", - "dependencies": [ "locations", "js_vis", "js_stupidtable", "bootstrap_datepicker", "bootstrap_timepicker", "bootstrap_multiselect"], + "category": "main.content", + "dependencies": [ + "locations", + "js_vis", + "js_stupidtable", + "bootstrap_datepicker", + "bootstrap_timepicker", + "bootstrap_multiselect" + ], "permission": "0" -} +} \ No newline at end of file diff --git a/modules-available/imgmanagement/config.json b/modules-available/imgmanagement/config.json index 6454d96f..2fbb822f 100644 --- a/modules-available/imgmanagement/config.json +++ b/modules-available/imgmanagement/config.json @@ -1,4 +1,4 @@ { - "category":"main.content", - "permission":"1" -} + "category": "main.content", + "permission": "1" +} \ No newline at end of file diff --git a/modules-available/internetaccess/config.json b/modules-available/internetaccess/config.json index 706412d0..110f8b67 100644 --- a/modules-available/internetaccess/config.json +++ b/modules-available/internetaccess/config.json @@ -1,3 +1,3 @@ { - "category":"main.content" -} + "category": "main.content" +} \ No newline at end of file diff --git a/modules-available/js_chart/config.json b/modules-available/js_chart/config.json index de4d37b4..3cf0d162 100644 --- a/modules-available/js_chart/config.json +++ b/modules-available/js_chart/config.json @@ -1,8 +1,9 @@ { - "css": { - "style.css": true - }, - "scripts": { - "clientscript.js": true - } + "css": [ + "style.css" + ], + "scripts": [ + "clientscript.js" + ], + "client-plugin": true } \ No newline at end of file diff --git a/modules-available/js_circles/config.json b/modules-available/js_circles/config.json index de4d37b4..3cf0d162 100644 --- a/modules-available/js_circles/config.json +++ b/modules-available/js_circles/config.json @@ -1,8 +1,9 @@ { - "css": { - "style.css": true - }, - "scripts": { - "clientscript.js": true - } + "css": [ + "style.css" + ], + "scripts": [ + "clientscript.js" + ], + "client-plugin": true } \ No newline at end of file diff --git a/modules-available/js_jqueryui/config.json b/modules-available/js_jqueryui/config.json index 5a0c7960..69bb0aa9 100644 --- a/modules-available/js_jqueryui/config.json +++ b/modules-available/js_jqueryui/config.json @@ -1,9 +1,10 @@ { - "dependencies" : [], - "css": { - "style.css": true - }, - "scripts": { - "clientscript.js": true - } -} + "dependencies": [], + "css": [ + "style.css" + ], + "scripts": [ + "clientscript.js" + ], + "client-plugin": true +} \ No newline at end of file diff --git a/modules-available/js_moment/config.json b/modules-available/js_moment/config.json index 5a0c7960..69bb0aa9 100644 --- a/modules-available/js_moment/config.json +++ b/modules-available/js_moment/config.json @@ -1,9 +1,10 @@ { - "dependencies" : [], - "css": { - "style.css": true - }, - "scripts": { - "clientscript.js": true - } -} + "dependencies": [], + "css": [ + "style.css" + ], + "scripts": [ + "clientscript.js" + ], + "client-plugin": true +} \ No newline at end of file diff --git a/modules-available/js_selectize/config.json b/modules-available/js_selectize/config.json index 5a0c7960..69bb0aa9 100644 --- a/modules-available/js_selectize/config.json +++ b/modules-available/js_selectize/config.json @@ -1,9 +1,10 @@ { - "dependencies" : [], - "css": { - "style.css": true - }, - "scripts": { - "clientscript.js": true - } -} + "dependencies": [], + "css": [ + "style.css" + ], + "scripts": [ + "clientscript.js" + ], + "client-plugin": true +} \ No newline at end of file diff --git a/modules-available/js_stupidtable/config.json b/modules-available/js_stupidtable/config.json index cf932d7e..3cf0d162 100644 --- a/modules-available/js_stupidtable/config.json +++ b/modules-available/js_stupidtable/config.json @@ -1,8 +1,9 @@ { - "css": { - "style.css": true - }, - "scripts": { - "clientscript.js": true - } + "css": [ + "style.css" + ], + "scripts": [ + "clientscript.js" + ], + "client-plugin": true } \ No newline at end of file diff --git a/modules-available/js_vis/config.json b/modules-available/js_vis/config.json index 3b027d31..4c870a22 100644 --- a/modules-available/js_vis/config.json +++ b/modules-available/js_vis/config.json @@ -1,9 +1,12 @@ { - "dependencies" : ["js_moment"], - "css": { - "style.css": true - }, - "scripts": { - "clientscript.js": true - } -} + "dependencies": [ + "js_moment" + ], + "css": [ + "style.css" + ], + "scripts": [ + "clientscript.js" + ], + "client-plugin": true +} \ No newline at end of file diff --git a/modules-available/locationinfo/config.json b/modules-available/locationinfo/config.json index 87825809..837acfcf 100644 --- a/modules-available/locationinfo/config.json +++ b/modules-available/locationinfo/config.json @@ -1,4 +1,9 @@ { - "category":"main.beta", - "dependencies": ["js_jqueryui", "bootstrap_timepicker", "locations", "bootstrap_switch"] -} + "category": "main.beta", + "dependencies": [ + "js_jqueryui", + "bootstrap_timepicker", + "locations", + "bootstrap_switch" + ] +} \ No newline at end of file diff --git a/modules-available/locations/config.json b/modules-available/locations/config.json index 706412d0..110f8b67 100644 --- a/modules-available/locations/config.json +++ b/modules-available/locations/config.json @@ -1,3 +1,3 @@ { - "category":"main.content" -} + "category": "main.content" +} \ No newline at end of file diff --git a/modules-available/main/config.json b/modules-available/main/config.json index 2c63c085..0637a088 100644 --- a/modules-available/main/config.json +++ b/modules-available/main/config.json @@ -1,2 +1 @@ -{ -} +[] \ No newline at end of file diff --git a/modules-available/minilinux/config.json b/modules-available/minilinux/config.json index 28d71577..6c7b7146 100644 --- a/modules-available/minilinux/config.json +++ b/modules-available/minilinux/config.json @@ -1,3 +1,3 @@ { - "category":"main.settings-client" -} + "category": "main.settings-client" +} \ No newline at end of file diff --git a/modules-available/news/config.json b/modules-available/news/config.json index e076ea5c..23cd1443 100644 --- a/modules-available/news/config.json +++ b/modules-available/news/config.json @@ -1,4 +1,6 @@ { - "category":"main.content", - "dependencies": [ "js_stupidtable" ] -} + "category": "main.content", + "dependencies": [ + "js_stupidtable" + ] +} \ No newline at end of file diff --git a/modules-available/permissionmanager/config.json b/modules-available/permissionmanager/config.json index d2071984..25b61de3 100644 --- a/modules-available/permissionmanager/config.json +++ b/modules-available/permissionmanager/config.json @@ -1,4 +1,8 @@ { - "category":"main.content", - "dependencies": [ "locations", "js_stupidtable", "js_selectize" ] -} + "category": "main.content", + "dependencies": [ + "locations", + "js_stupidtable", + "js_selectize" + ] +} \ No newline at end of file diff --git a/modules-available/rebootcontrol/config.json b/modules-available/rebootcontrol/config.json index d8ab5868..43d2c28f 100644 --- a/modules-available/rebootcontrol/config.json +++ b/modules-available/rebootcontrol/config.json @@ -1,4 +1,7 @@ { - "category":"main.beta", - "dependencies": [ "locations", "js_stupidtable" ] -} + "category": "main.beta", + "dependencies": [ + "locations", + "js_stupidtable" + ] +} \ No newline at end of file diff --git a/modules-available/roomplanner/config.json b/modules-available/roomplanner/config.json index 537714c3..62f38773 100644 --- a/modules-available/roomplanner/config.json +++ b/modules-available/roomplanner/config.json @@ -1,3 +1,10 @@ { - "dependencies": ["js_jqueryui", "js_selectize", "bootstrap_dialog", "statistics", "locations", "runmode"] -} + "dependencies": [ + "js_jqueryui", + "js_selectize", + "bootstrap_dialog", + "statistics", + "locations", + "runmode" + ] +} \ No newline at end of file diff --git a/modules-available/runmode/config.json b/modules-available/runmode/config.json index e3c07d48..84e044ce 100644 --- a/modules-available/runmode/config.json +++ b/modules-available/runmode/config.json @@ -1,4 +1,7 @@ { - "dependencies": [ "statistics", "js_selectize" ], - "permission":"0" -} + "dependencies": [ + "statistics", + "js_selectize" + ], + "permission": "0" +} \ No newline at end of file diff --git a/modules-available/serversetup-bwlp/config.json b/modules-available/serversetup-bwlp/config.json index 7205d70a..36268c6a 100644 --- a/modules-available/serversetup-bwlp/config.json +++ b/modules-available/serversetup-bwlp/config.json @@ -1,3 +1,3 @@ { - "category":"main.settings-server" -} + "category": "main.settings-server" +} \ No newline at end of file diff --git a/modules-available/session/config.json b/modules-available/session/config.json index 2c63c085..0637a088 100644 --- a/modules-available/session/config.json +++ b/modules-available/session/config.json @@ -1,2 +1 @@ -{ -} +[] \ No newline at end of file diff --git a/modules-available/statistics/config.json b/modules-available/statistics/config.json index 333f881a..412dc3cb 100644 --- a/modules-available/statistics/config.json +++ b/modules-available/statistics/config.json @@ -1,5 +1,9 @@ { - "category":"main.status", - "dependencies": [ "js_chart", "js_selectize", "bootstrap_datepicker"], - "permission":"0" -} + "category": "main.status", + "dependencies": [ + "js_chart", + "js_selectize", + "bootstrap_datepicker" + ], + "permission": "0" +} \ No newline at end of file diff --git a/modules-available/statistics_reporting/config.json b/modules-available/statistics_reporting/config.json index 78ca35ba..c439efa8 100644 --- a/modules-available/statistics_reporting/config.json +++ b/modules-available/statistics_reporting/config.json @@ -1,4 +1,9 @@ { "category": "main.status", - "dependencies": [ "statistics", "locations", "js_stupidtable", "js_jqueryui" ] -} + "dependencies": [ + "statistics", + "locations", + "js_stupidtable", + "js_jqueryui" + ] +} \ No newline at end of file diff --git a/modules-available/summernote/config.json b/modules-available/summernote/config.json index 5a0c7960..69bb0aa9 100644 --- a/modules-available/summernote/config.json +++ b/modules-available/summernote/config.json @@ -1,9 +1,10 @@ { - "dependencies" : [], - "css": { - "style.css": true - }, - "scripts": { - "clientscript.js": true - } -} + "dependencies": [], + "css": [ + "style.css" + ], + "scripts": [ + "clientscript.js" + ], + "client-plugin": true +} \ No newline at end of file diff --git a/modules-available/support/config.json b/modules-available/support/config.json index 706412d0..110f8b67 100644 --- a/modules-available/support/config.json +++ b/modules-available/support/config.json @@ -1,3 +1,3 @@ { - "category":"main.content" -} + "category": "main.content" +} \ No newline at end of file diff --git a/modules-available/sysconfig/config.json b/modules-available/sysconfig/config.json index 28d71577..6c7b7146 100644 --- a/modules-available/sysconfig/config.json +++ b/modules-available/sysconfig/config.json @@ -1,3 +1,3 @@ { - "category":"main.settings-client" -} + "category": "main.settings-client" +} \ No newline at end of file diff --git a/modules-available/sysconfignew/config.json b/modules-available/sysconfignew/config.json index 28d71577..6c7b7146 100644 --- a/modules-available/sysconfignew/config.json +++ b/modules-available/sysconfignew/config.json @@ -1,3 +1,3 @@ { - "category":"main.settings-client" -} + "category": "main.settings-client" +} \ No newline at end of file diff --git a/modules-available/syslog/config.json b/modules-available/syslog/config.json index 2b718a8e..691bd4df 100644 --- a/modules-available/syslog/config.json +++ b/modules-available/syslog/config.json @@ -1,4 +1,6 @@ { - "category":"main.status", - "dependencies":["js_selectize"] -} + "category": "main.status", + "dependencies": [ + "js_selectize" + ] +} \ No newline at end of file diff --git a/modules-available/systemstatus/config.json b/modules-available/systemstatus/config.json index 3c2efce7..cf774d1b 100644 --- a/modules-available/systemstatus/config.json +++ b/modules-available/systemstatus/config.json @@ -1,4 +1,6 @@ { - "category":"main.status", - "dependencies": [ "js_circles" ] -} + "category": "main.status", + "dependencies": [ + "js_circles" + ] +} \ No newline at end of file diff --git a/modules-available/translation/config.json b/modules-available/translation/config.json index 706412d0..110f8b67 100644 --- a/modules-available/translation/config.json +++ b/modules-available/translation/config.json @@ -1,3 +1,3 @@ { - "category":"main.content" -} + "category": "main.content" +} \ No newline at end of file diff --git a/modules-available/usermanagement/config.json b/modules-available/usermanagement/config.json index 9c66d6bf..428315ba 100644 --- a/modules-available/usermanagement/config.json +++ b/modules-available/usermanagement/config.json @@ -1,4 +1,4 @@ { - "category":"main.users", - "permission":"0" -} + "category": "main.users", + "permission": "0" +} \ No newline at end of file diff --git a/modules-available/vmstore/config.json b/modules-available/vmstore/config.json index 7205d70a..36268c6a 100644 --- a/modules-available/vmstore/config.json +++ b/modules-available/vmstore/config.json @@ -1,3 +1,3 @@ { - "category":"main.settings-server" -} + "category": "main.settings-server" +} \ No newline at end of file diff --git a/modules-available/webinterface/config.json b/modules-available/webinterface/config.json index 7205d70a..36268c6a 100644 --- a/modules-available/webinterface/config.json +++ b/modules-available/webinterface/config.json @@ -1,3 +1,3 @@ { - "category":"main.settings-server" -} + "category": "main.settings-server" +} \ No newline at end of file -- cgit v1.2.3-55-g7522 From b364fcb761be1cbed909422252d32ff842af81be Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 16 Apr 2018 15:10:55 +0200 Subject: [inc/User] Activate module locations before access --- inc/user.inc.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'inc') diff --git a/inc/user.inc.php b/inc/user.inc.php index f12cc39f..2571c61c 100644 --- a/inc/user.inc.php +++ b/inc/user.inc.php @@ -90,8 +90,12 @@ class User return PermissionUtil::getAllowedLocations(self::$user['userid'], $permission); } if (self::$user['permissions'] & Permission::get('superadmin')) { - $a = array_keys(Location::getLocationsAssoc()); - $a[] = 0; + if (Module::isAvailable('locations')) { + $a = array_keys(Location::getLocationsAssoc()); + $a[] = 0; + } else { + $a = [0]; + } return $a; } return array(); -- cgit v1.2.3-55-g7522 From 2d7366b7b01d69b4b94e4324471019bd806d89dc Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 20 Apr 2018 12:52:58 +0200 Subject: [inc/Taskmanagercallback] Fix function call --- inc/taskmanagercallback.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'inc') diff --git a/inc/taskmanagercallback.inc.php b/inc/taskmanagercallback.inc.php index 55e01ba2..8e253962 100644 --- a/inc/taskmanagercallback.inc.php +++ b/inc/taskmanagercallback.inc.php @@ -136,7 +136,7 @@ class TaskmanagerCallback $mod = Module::get('sysconfig'); if ($mod === false) return; - $mod->activate(); + $mod->activate(1, false); if (Taskmanager::isFailed($task)) { ConfigModule::generateFailed($task, $args); } else { @@ -155,7 +155,7 @@ class TaskmanagerCallback $mod = Module::get('sysconfig'); if ($mod === false) return; - $mod->activate(); + $mod->activate(1, false); if (Taskmanager::isFailed($task)) { ConfigTgz::generateFailed($task, $args); } else { -- cgit v1.2.3-55-g7522 From d863b362f2531c85b24b391e363380aebc917b6e Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 25 Apr 2018 16:47:06 +0200 Subject: [inc/Taskmanager] isTask() Only query if taskId is given --- inc/taskmanager.inc.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'inc') diff --git a/inc/taskmanager.inc.php b/inc/taskmanager.inc.php index ed64c613..945e759d 100644 --- a/inc/taskmanager.inc.php +++ b/inc/taskmanager.inc.php @@ -83,13 +83,17 @@ class Taskmanager * Checks whether the given task id corresponds to a known task in the taskmanager. * Returns true iff the taskmanager is reachable and the status of the task * is different from NO_SUCH_TASK. + * If you pass an array it is assumed that it was already queried and is evaluated + * directly. * - * @param string $taskid a task id + * @param string|array $taskid a task id or a task array returned by ::status or ::submit * @return boolean true if taskid exists in taskmanager */ - public static function isTask($taskid) + public static function isTask($task) { - $task = self::status($taskid); + if (is_string($task)) { + $task = self::status($task); + } return isset($task['statusCode']) && $task['statusCode'] !== NO_SUCH_TASK; } -- cgit v1.2.3-55-g7522 From 30c3af19036593d702618290f6a60732617c5297 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 25 Apr 2018 17:00:11 +0200 Subject: [rebootcontrol] Fix NO_SUCH_INSTANCE handling --- inc/taskmanager.inc.php | 9 ++++++--- modules-available/rebootcontrol/inc/rebootcontrol.inc.php | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'inc') diff --git a/inc/taskmanager.inc.php b/inc/taskmanager.inc.php index 945e759d..54821e59 100644 --- a/inc/taskmanager.inc.php +++ b/inc/taskmanager.inc.php @@ -82,7 +82,7 @@ class Taskmanager /** * Checks whether the given task id corresponds to a known task in the taskmanager. * Returns true iff the taskmanager is reachable and the status of the task - * is different from NO_SUCH_TASK. + * is different from NO_SUCH_INSTANCE/_TASK. * If you pass an array it is assumed that it was already queried and is evaluated * directly. * @@ -91,10 +91,13 @@ class Taskmanager */ public static function isTask($task) { + if ($task === false) + return false; if (is_string($task)) { $task = self::status($task); } - return isset($task['statusCode']) && $task['statusCode'] !== NO_SUCH_TASK; + return isset($task['statusCode']) && $task['statusCode'] !== NO_SUCH_INSTANCE + && $task['statusCode'] !== NO_SUCH_TASK; } /** @@ -242,6 +245,6 @@ class Taskmanager } -foreach (array('TASK_FINISHED', 'TASK_ERROR', 'TASK_WAITING', 'NO_SUCH_TASK', 'TASK_PROCESSING') as $i) { +foreach (array('TASK_FINISHED', 'TASK_ERROR', 'TASK_WAITING', 'NO_SUCH_TASK', 'NO_SUCH_INSTANCE', 'TASK_PROCESSING') as $i) { define($i, $i); } diff --git a/modules-available/rebootcontrol/inc/rebootcontrol.inc.php b/modules-available/rebootcontrol/inc/rebootcontrol.inc.php index 1024b036..ec4b84ed 100644 --- a/modules-available/rebootcontrol/inc/rebootcontrol.inc.php +++ b/modules-available/rebootcontrol/inc/rebootcontrol.inc.php @@ -66,7 +66,7 @@ class RebootControl continue; $id = $p[1]; $task = Taskmanager::status($id); - if ($task === false) { + if (!Taskmanager::isTask($task)) { Property::removeFromList(RebootControl::KEY_TASKLIST, $entry); continue; } -- cgit v1.2.3-55-g7522 From 1f18997b2d72a5aea772f0f9d6ddb61718fbd380 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 27 Apr 2018 14:00:57 +0200 Subject: Don't try to load non-existent style.css/clientscript.js --- inc/module.inc.php | 4 ++-- modules-available/js_chart/config.json | 3 --- modules-available/js_circles/config.json | 3 --- modules-available/js_moment/config.json | 3 --- modules-available/js_stupidtable/config.json | 3 --- 5 files changed, 2 insertions(+), 14 deletions(-) (limited to 'inc') diff --git a/inc/module.inc.php b/inc/module.inc.php index fa2c4b98..6d160787 100644 --- a/inc/module.inc.php +++ b/inc/module.inc.php @@ -283,7 +283,7 @@ class Module public function getScripts() { if ($this->directActivation && $this->clientPlugin) { - if (!in_array('clientscript.js', $this->scripts)) { + if (!in_array('clientscript.js', $this->scripts) && file_exists($this->getDir() . '/clientscript.js')) { $this->scripts[] = 'clientscript.js'; } return $this->scripts; @@ -294,7 +294,7 @@ class Module public function getCss() { if ($this->directActivation && $this->clientPlugin) { - if (!in_array('style.css', $this->css)) { + if (!in_array('style.css', $this->css) && file_exists($this->getDir() . '/style.css')) { $this->css[] = 'style.css'; } return $this->css; diff --git a/modules-available/js_chart/config.json b/modules-available/js_chart/config.json index 3cf0d162..5adc886f 100644 --- a/modules-available/js_chart/config.json +++ b/modules-available/js_chart/config.json @@ -1,7 +1,4 @@ { - "css": [ - "style.css" - ], "scripts": [ "clientscript.js" ], diff --git a/modules-available/js_circles/config.json b/modules-available/js_circles/config.json index 3cf0d162..5adc886f 100644 --- a/modules-available/js_circles/config.json +++ b/modules-available/js_circles/config.json @@ -1,7 +1,4 @@ { - "css": [ - "style.css" - ], "scripts": [ "clientscript.js" ], diff --git a/modules-available/js_moment/config.json b/modules-available/js_moment/config.json index 69bb0aa9..96c02bce 100644 --- a/modules-available/js_moment/config.json +++ b/modules-available/js_moment/config.json @@ -1,8 +1,5 @@ { "dependencies": [], - "css": [ - "style.css" - ], "scripts": [ "clientscript.js" ], diff --git a/modules-available/js_stupidtable/config.json b/modules-available/js_stupidtable/config.json index 3cf0d162..5adc886f 100644 --- a/modules-available/js_stupidtable/config.json +++ b/modules-available/js_stupidtable/config.json @@ -1,7 +1,4 @@ { - "css": [ - "style.css" - ], "scripts": [ "clientscript.js" ], -- cgit v1.2.3-55-g7522 From 9b24161637553f3889d9a81344e6eec59dc6aa00 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 7 May 2018 17:34:35 +0200 Subject: [serversetup-bwlp] Add log output to ipxe building task --- inc/event.inc.php | 3 +-- inc/trigger.inc.php | 1 + .../serversetup-bwlp/lang/de/template-tags.json | 4 +++- .../serversetup-bwlp/lang/en/template-tags.json | 4 +++- modules-available/serversetup-bwlp/page.inc.php | 20 ++++++++++-------- .../serversetup-bwlp/templates/ipxe_update.html | 24 ++++++++++++++++++---- 6 files changed, 40 insertions(+), 16 deletions(-) (limited to 'inc') diff --git a/inc/event.inc.php b/inc/event.inc.php index fe59b2b9..b1ee3663 100644 --- a/inc/event.inc.php +++ b/inc/event.inc.php @@ -98,8 +98,7 @@ class Event public static function serverIpChanged() { error_log('Server ip changed'); - global $tidIpxe; - $tidIpxe = Trigger::ipxe(); + Trigger::ipxe(); if (Module::isAvailable('sysconfig')) { // TODO: Modularize events ConfigModule::serverIpChanged(); } diff --git a/inc/trigger.inc.php b/inc/trigger.inc.php index b49cafb0..93f57236 100644 --- a/inc/trigger.inc.php +++ b/inc/trigger.inc.php @@ -25,6 +25,7 @@ class Trigger $task = Taskmanager::submit('CompileIPxe', $data); if (!isset($task['id'])) return false; + Property::set('ipxe-task-id', $task['id'], 15); return $task['id']; } diff --git a/modules-available/serversetup-bwlp/lang/de/template-tags.json b/modules-available/serversetup-bwlp/lang/de/template-tags.json index f80febb0..74ab494b 100644 --- a/modules-available/serversetup-bwlp/lang/de/template-tags.json +++ b/modules-available/serversetup-bwlp/lang/de/template-tags.json @@ -21,9 +21,11 @@ "lang_menuCustomHint3": "und w\u00e4hlen Sie als Standard-Bootverhalten ebenfalls custom.", "lang_menuDisplayTime": "Anzeigedauer des Men\u00fcs", "lang_menuGeneration": "Erzeugen des Bootmen\u00fcs", - "lang_moduleHeading": "iPXE / Boot Menu", + "lang_moduleHeading": "iPXE \/ Boot Menu", + "lang_pxeBuilt": "PXE-Binary gebaut", "lang_seconds": "Sekunden", "lang_set": "Setzen", + "lang_usbBuilt": "USB-Image gebaut", "lang_usbImage": "USB-Image", "lang_usbImgHelp": "Mit dem USB-Image k\u00f6nnen Sie einen bootbaren USB-Stick erstellen, \u00fcber den sich bwLehrpool an Rechnern starten l\u00e4sst, die keinen Netzwerkboot unterst\u00fctzen, bzw. f\u00fcr die keine entsprechende DHCP-Konfiguration vorhanden ist. Dies erfordert dann lediglich, dass in der BIOS-Konfiguration des Rechners USB-Boot zugelassen ist. Der Stick dient dabei lediglich als Einstiegspunkt; es ist nach wie vor ein bwLehrpool-Satellitenserver f\u00fcr den eigentlichen Bootvorgang von N\u00f6ten.", "lang_usbImgHelpLinux": "Nutzen Sie dd, um das Image auf einen USB-Stick zu schreiben. Das Image enth\u00e4lt bereits eine Partitionstabelle, achten Sie daher darauf, dass Sie das Image z.B. nach \/dev\/sdx schreiben, und nicht nach \/dev\/sdx1", diff --git a/modules-available/serversetup-bwlp/lang/en/template-tags.json b/modules-available/serversetup-bwlp/lang/en/template-tags.json index 1948718b..7f519022 100644 --- a/modules-available/serversetup-bwlp/lang/en/template-tags.json +++ b/modules-available/serversetup-bwlp/lang/en/template-tags.json @@ -21,9 +21,11 @@ "lang_menuCustomHint3": "and select as the default boot behavior custom as well.", "lang_menuDisplayTime": "Menu Display Time", "lang_menuGeneration": "Generating boot menu...", - "lang_moduleHeading": "iPXE / Boot Menu", + "lang_moduleHeading": "iPXE \/ Boot Menu", + "lang_pxeBuilt": "Built PXE binary", "lang_seconds": "Seconds", "lang_set": "Set", + "lang_usbBuilt": "Built USB image", "lang_usbImage": "USB image", "lang_usbImgHelp": "The USB image can be used to create a bootable USB stick, which enables you to boot bwLehrpool without changing your DHCP settings or enabling network boot in the clients. The only requirement is that you enable USB boot in the client's BIOS. The USB stick is only used for bootstrapping, the actual bwLehrpool system is still loaded via network from your local bwLehrpool server.", "lang_usbImgHelpLinux": "On Linux you can simply use dd to write the image to a usb stick. The image already contains a partition table, so make sure you write the image to the device itself and not to an already existing partition (e.g. to \/dev\/sdx not \/dev\/sdx1)", diff --git a/modules-available/serversetup-bwlp/page.inc.php b/modules-available/serversetup-bwlp/page.inc.php index 78096d7b..52b3afe4 100644 --- a/modules-available/serversetup-bwlp/page.inc.php +++ b/modules-available/serversetup-bwlp/page.inc.php @@ -54,9 +54,15 @@ class Page_ServerSetup extends Page protected function doRender() { Render::addTemplate("heading"); - $taskid = Request::any('taskid'); - if ($taskid !== false && Taskmanager::isTask($taskid)) { - Render::addTemplate('ipxe_update', array('taskid' => $taskid)); + $task = Property::get('ipxe-task-id'); + if ($task !== false) { + $task = Taskmanager::status($task); + if (!Taskmanager::isTask($task) || Taskmanager::isFinished($task)) { + $task = false; + } + } + if ($task !== false) { + Render::addTemplate('ipxe_update', array('taskid' => $task['id'])); } Permission::addGlobalTags($perms, null, ['edit.menu', 'edit.address', 'download']); @@ -137,9 +143,7 @@ class Page_ServerSetup extends Page } if ($valid) { Property::setServerIp($newAddress); - global $tidIpxe; - if (isset($tidIpxe) && $tidIpxe !== false) - Util::redirect('?do=ServerSetup&taskid=' . $tidIpxe); + Util::redirect('?do=ServerSetup'); } else { Message::addError('invalid-ip', $newAddress); } @@ -163,8 +167,8 @@ class Page_ServerSetup extends Page else $this->currentMenu['masterpassword'] = Crypto::hash6($this->currentMenu['masterpasswordclear']); Property::setBootMenu($this->currentMenu); - $id = Trigger::ipxe(); - Util::redirect('?do=ServerSetup&taskid=' . $id); + Trigger::ipxe(); + Util::redirect('?do=ServerSetup'); } private function handleGetImage() diff --git a/modules-available/serversetup-bwlp/templates/ipxe_update.html b/modules-available/serversetup-bwlp/templates/ipxe_update.html index 9c598667..e7ba5ffa 100644 --- a/modules-available/serversetup-bwlp/templates/ipxe_update.html +++ b/modules-available/serversetup-bwlp/templates/ipxe_update.html @@ -1,20 +1,36 @@
{{lang_menuGeneration}}
-
{{lang_menuGeneration}}
-
-- cgit v1.2.3-55-g7522 From 5e786faa6c577abfd48976a6839f61d08b0a6e5e Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 24 May 2018 15:35:46 +0200 Subject: Introduce proper constants for taskmanager status --- inc/property.inc.php | 2 +- inc/taskmanager.inc.php | 27 ++++++++++++---------- .../sysconfig/addmodule_custommodule.inc.php | 4 ++-- .../sysconfig/inc/configmodule.inc.php | 2 +- modules-available/sysconfig/inc/configtgz.inc.php | 2 +- modules-available/sysconfig/page.inc.php | 6 ++--- 6 files changed, 23 insertions(+), 20 deletions(-) (limited to 'inc') diff --git a/inc/property.inc.php b/inc/property.inc.php index 56adb823..b69be1f8 100644 --- a/inc/property.inc.php +++ b/inc/property.inc.php @@ -168,7 +168,7 @@ class Property if (!Taskmanager::isFinished($task)) { $task = Taskmanager::waitComplete($task['id'], 5000); } - if ($task['statusCode'] !== TASK_FINISHED || !isset($task['data']['content'])) { + if ($task['statusCode'] !== Taskmanager::TASK_FINISHED || !isset($task['data']['content'])) { return isset($task['data']['error']) ? $task['data']['error'] : 'Timeout'; } $data = json_decode($task['data']['content'], true); diff --git a/inc/taskmanager.inc.php b/inc/taskmanager.inc.php index 54821e59..dab950ed 100644 --- a/inc/taskmanager.inc.php +++ b/inc/taskmanager.inc.php @@ -6,6 +6,13 @@ class Taskmanager { + const NO_SUCH_TASK = 'NO_SUCH_TASK'; + const TASK_FINISHED = 'TASK_FINISHED'; + const TASK_ERROR = 'TASK_ERROR'; + const TASK_WAITING = 'TASK_WAITING'; + const NO_SUCH_INSTANCE = 'NO_SUCH_INSTANCE'; + const TASK_PROCESSING = 'TASK_PROCESSING'; + /** * UDP socket used for communication with the task manager * @var resource @@ -49,7 +56,7 @@ class Taskmanager if ($async) return true; $reply = self::readReply($seq); - if ($reply === false || !is_array($reply) || !isset($reply['id']) || (isset($reply['statusCode']) && $reply['statusCode'] === NO_SUCH_TASK)) { + if ($reply === false || !is_array($reply) || !isset($reply['id']) || (isset($reply['statusCode']) && $reply['statusCode'] === Taskmanager::NO_SUCH_TASK)) { self::addErrorMessage($reply); return false; } @@ -82,7 +89,7 @@ class Taskmanager /** * Checks whether the given task id corresponds to a known task in the taskmanager. * Returns true iff the taskmanager is reachable and the status of the task - * is different from NO_SUCH_INSTANCE/_TASK. + * is different from Taskmanager::NO_SUCH_INSTANCE/_TASK. * If you pass an array it is assumed that it was already queried and is evaluated * directly. * @@ -96,8 +103,8 @@ class Taskmanager if (is_string($task)) { $task = self::status($task); } - return isset($task['statusCode']) && $task['statusCode'] !== NO_SUCH_INSTANCE - && $task['statusCode'] !== NO_SUCH_TASK; + return isset($task['statusCode']) && $task['statusCode'] !== Taskmanager::NO_SUCH_INSTANCE + && $task['statusCode'] !== Taskmanager::NO_SUCH_TASK; } /** @@ -110,7 +117,7 @@ class Taskmanager public static function waitComplete($task, $timeout = 2500) { if (is_array($task) && isset($task['id'])) { - if ($task['statusCode'] !== TASK_PROCESSING && $task['statusCode'] !== TASK_WAITING) { + if ($task['statusCode'] !== Taskmanager::TASK_PROCESSING && $task['statusCode'] !== Taskmanager::TASK_WAITING) { self::release($task['id']); return $task; } @@ -124,7 +131,7 @@ class Taskmanager $status = self::status($task); if (!isset($status['statusCode'])) break; - if ($status['statusCode'] !== TASK_PROCESSING && $status['statusCode'] !== TASK_WAITING) { + if ($status['statusCode'] !== Taskmanager::TASK_PROCESSING && $status['statusCode'] !== Taskmanager::TASK_WAITING) { $done = true; break; } @@ -147,7 +154,7 @@ class Taskmanager { if (!is_array($task) || !isset($task['statusCode']) || !isset($task['id'])) return true; - if ($task['statusCode'] !== TASK_WAITING && $task['statusCode'] !== TASK_PROCESSING && $task['statusCode'] !== TASK_FINISHED) + if ($task['statusCode'] !== Taskmanager::TASK_WAITING && $task['statusCode'] !== Taskmanager::TASK_PROCESSING && $task['statusCode'] !== Taskmanager::TASK_FINISHED) return true; return false; } @@ -163,7 +170,7 @@ class Taskmanager { if (!is_array($task) || !isset($task['statusCode']) || !isset($task['id'])) return false; - if ($task['statusCode'] !== TASK_WAITING && $task['statusCode'] !== TASK_PROCESSING) + if ($task['statusCode'] !== Taskmanager::TASK_WAITING && $task['statusCode'] !== Taskmanager::TASK_PROCESSING) return true; return false; } @@ -244,7 +251,3 @@ class Taskmanager } } - -foreach (array('TASK_FINISHED', 'TASK_ERROR', 'TASK_WAITING', 'NO_SUCH_TASK', 'NO_SUCH_INSTANCE', 'TASK_PROCESSING') as $i) { - define($i, $i); -} diff --git a/modules-available/sysconfig/addmodule_custommodule.inc.php b/modules-available/sysconfig/addmodule_custommodule.inc.php index 8c24a071..c234f765 100644 --- a/modules-available/sysconfig/addmodule_custommodule.inc.php +++ b/modules-available/sysconfig/addmodule_custommodule.inc.php @@ -62,7 +62,7 @@ class CustomModule_ProcessUpload extends AddModule_Base unlink($tempfile); $this->tmError(); } - if ($status['statusCode'] != TASK_FINISHED) { + if ($status['statusCode'] != Taskmanager::TASK_FINISHED) { unlink($tempfile); $this->taskError($status); } @@ -128,7 +128,7 @@ class CustomModule_CompressModule extends AddModule_Base if (!isset($status['statusCode'])) { $this->tmError(); } - if ($status['statusCode'] != TASK_FINISHED) { + if ($status['statusCode'] != Taskmanager::TASK_FINISHED) { $this->taskError($status); } // Seems ok, create entry diff --git a/modules-available/sysconfig/inc/configmodule.inc.php b/modules-available/sysconfig/inc/configmodule.inc.php index 2cee37a9..b6db9c4f 100644 --- a/modules-available/sysconfig/inc/configmodule.inc.php +++ b/modules-available/sysconfig/inc/configmodule.inc.php @@ -354,7 +354,7 @@ abstract class ConfigModule // Wait for generation if requested if ($timeoutMs > 0 && isset($ret['id']) && !Taskmanager::isFinished($ret)) $ret = Taskmanager::waitComplete($ret, $timeoutMs); - if ($ret === true || (isset($ret['statusCode']) && $ret['statusCode'] === TASK_FINISHED)) { + if ($ret === true || (isset($ret['statusCode']) && $ret['statusCode'] === Taskmanager::TASK_FINISHED)) { // Already Finished if (file_exists($this->moduleArchive) && !file_exists($tmpTgz)) $tmpTgz = false; // If generateInternal succeeded and there's no tmpTgz, it means the file didn't have to be updated diff --git a/modules-available/sysconfig/inc/configtgz.inc.php b/modules-available/sysconfig/inc/configtgz.inc.php index 5b459a2e..7b042cdb 100644 --- a/modules-available/sysconfig/inc/configtgz.inc.php +++ b/modules-available/sysconfig/inc/configtgz.inc.php @@ -112,7 +112,7 @@ class ConfigTgz // Wait for completion if ($timeoutMs > 0 && !Taskmanager::isFailed($task) && !Taskmanager::isFinished($task)) $task = Taskmanager::waitComplete($task, $timeoutMs); - if ($task === true || (isset($task['statusCode']) && $task['statusCode'] === TASK_FINISHED)) { + if ($task === true || (isset($task['statusCode']) && $task['statusCode'] === Taskmanager::TASK_FINISHED)) { // Success! $this->markUpdated(); return true; diff --git a/modules-available/sysconfig/page.inc.php b/modules-available/sysconfig/page.inc.php index 8d1799af..515d432c 100644 --- a/modules-available/sysconfig/page.inc.php +++ b/modules-available/sysconfig/page.inc.php @@ -425,12 +425,12 @@ class Page_SysConfig extends Page $task = Taskmanager::submit('DeleteFile', array( 'file' => $row['filepath'] )); - if (isset($task['statusCode']) && $task['statusCode'] === TASK_WAITING) { + if (isset($task['statusCode']) && $task['statusCode'] === Taskmanager::TASK_WAITING) { $task = Taskmanager::waitComplete($task['id']); } - if (!isset($task['statusCode']) || $task['statusCode'] === TASK_ERROR) { + if (!isset($task['statusCode']) || $task['statusCode'] === Taskmanager::TASK_ERROR) { Message::addWarning('main.task-error', $task['data']['error']); - } elseif ($task['statusCode'] === TASK_FINISHED) { + } elseif ($task['statusCode'] === Taskmanager::TASK_FINISHED) { Message::addSuccess('module-deleted', $row['title']); } Database::exec("DELETE FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid)); -- cgit v1.2.3-55-g7522 From db0b9f1c1c8c2b20a405edeefc5240a6c0bfb1f5 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 12 Jun 2018 17:13:06 +0200 Subject: [inc/Dashboard] getter for currently defined sub menus --- inc/dashboard.inc.php | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'inc') diff --git a/inc/dashboard.inc.php b/inc/dashboard.inc.php index 59d81c2d..d576a8f1 100644 --- a/inc/dashboard.inc.php +++ b/inc/dashboard.inc.php @@ -103,5 +103,10 @@ class Dashboard { self::$subMenu[] = array('url' => $url, 'name' => $name); } + + public static function getSubmenus() + { + return self::$subMenu; + } } \ No newline at end of file -- cgit v1.2.3-55-g7522 From 6c7a5ff06159c6908a47f11adbe30e2349a5fd75 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 12 Jun 2018 17:13:37 +0200 Subject: [inc/Database] Method to return single-column queries as array --- inc/database.inc.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'inc') diff --git a/inc/database.inc.php b/inc/database.inc.php index d5992795..3b2414b5 100644 --- a/inc/database.inc.php +++ b/inc/database.inc.php @@ -76,6 +76,19 @@ class Database return $res->fetchAll(PDO::FETCH_ASSOC); } + /** + * Fetch the first column of the query as a plain list-of-values array. + * + * @return array|bool List of values representing first column of query + */ + public static function queryColumnArray($query, $args = array(), $ignoreError = null) + { + $res = self::simpleQuery($query, $args, $ignoreError); + if ($res === false) + return false; + return $res->fetchAll(PDO::FETCH_COLUMN, 0); + } + /** * Execute the given query and return the number of rows affected. * Mostly useful for UPDATEs or INSERTs -- cgit v1.2.3-55-g7522 From cd092274b88599449902f480f35291768be6e99e Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 7 Aug 2018 16:54:01 +0200 Subject: [inc/User] Fix access to Page if class is not loaded --- inc/user.inc.php | 11 ++++- lang/pt/flag.png | Bin 1115 -> 0 bytes lang/pt/name.txt | 1 - modules-available/exams/lang/de/template-tags.json | 2 +- modules-available/exams/lang/en/template-tags.json | 2 +- .../coursebackend/coursebackend_hisinone.inc.php | 48 +++++++++++++-------- .../locationinfo/lang/de/template-tags.json | 2 +- .../locationinfo/lang/en/template-tags.json | 2 +- 8 files changed, 43 insertions(+), 25 deletions(-) delete mode 100644 lang/pt/flag.png delete mode 100644 lang/pt/name.txt (limited to 'inc') diff --git a/inc/user.inc.php b/inc/user.inc.php index 2571c61c..20e8cd3d 100644 --- a/inc/user.inc.php +++ b/inc/user.inc.php @@ -34,8 +34,15 @@ class User if ($permission{0} === '.') { $permission = substr($permission, 1); } else { - $module = Page::getModule(); - $permission = $module ? $module->getIdentifier() . "." . $permission : $permission; + if (class_exists('Page')) { + $module = Page::getModule(); + if ($module !== false) { + $module = $module->getIdentifier(); + } + } else { + $module = strtolower(Request::any('do')); + } + $permission = $module ? $module . "." . $permission : $permission; } return PermissionUtil::userHasPermission(self::$user['userid'], $permission, $locationid); } diff --git a/lang/pt/flag.png b/lang/pt/flag.png deleted file mode 100644 index 78c57dea..00000000 Binary files a/lang/pt/flag.png and /dev/null differ diff --git a/lang/pt/name.txt b/lang/pt/name.txt deleted file mode 100644 index 811b10b4..00000000 --- a/lang/pt/name.txt +++ /dev/null @@ -1 +0,0 @@ -Português \ No newline at end of file diff --git a/modules-available/exams/lang/de/template-tags.json b/modules-available/exams/lang/de/template-tags.json index 8bf37143..1dd51374 100644 --- a/modules-available/exams/lang/de/template-tags.json +++ b/modules-available/exams/lang/de/template-tags.json @@ -29,7 +29,7 @@ "lang_headingMain": "bwLehrpool Pr\u00fcfungsmodus", "lang_id": "ID", "lang_lectureName": "Veranstaltungsname", - "lang_lectureOutOfRange": "Achtung: Start- bzw. Endzeitpunkt der Veranstaltung liegen au\u00dferhalb des oben angegebenen Zeitraums", + "lang_lectureOutOfRange": "Achtung: Der oben angegebene Zeitraum ist k\u00fcrzer als die Dauer der Veranstaltung", "lang_location": "Raum\/Ort", "lang_locationInfo": "W\u00e4hlen Sie hier die R\u00e4ume und Orte aus, die w\u00e4hrend des unten ausgew\u00e4hlten Zeitraums in den Pr\u00fcfungsmodus versetzt werden. Wenn sie hier keine Auswahl treffen, werden alle R\u00e4ume in den Pr\u00fcfungsmodus versetzt.", "lang_locations": "R\u00e4ume\/Orte", diff --git a/modules-available/exams/lang/en/template-tags.json b/modules-available/exams/lang/en/template-tags.json index af87bb01..23266154 100644 --- a/modules-available/exams/lang/en/template-tags.json +++ b/modules-available/exams/lang/en/template-tags.json @@ -29,7 +29,7 @@ "lang_headingMain": "bwLehrpool Exam Mode", "lang_id": "ID", "lang_lectureName": "Lecture name", - "lang_lectureOutOfRange": "Hint: Start or end date of given lecture lies outside of exam period given above", + "lang_lectureOutOfRange": "Hint: The exam period given above is shorter than the duration of the given lecture", "lang_location": "Room\/Location", "lang_locationInfo": "Select the rooms and locations you want to enable the exam mode in. Selecting nothing at all means that all clients will boot into exam mode during the given time period.", "lang_locations": "Rooms\/Locations", diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php index 558f5cd0..3b26e625 100644 --- a/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php +++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php @@ -274,8 +274,7 @@ class CourseBackend_HisInOne extends CourseBackend foreach ($eventDetails as $event) { foreach (array('/hisdefaulttext', '/hisshorttext', - '/hisshortcomment', - '/hisplanelements/hisplanelement/hisdefaulttext') as $path) { + '/hisshortcomment') as $path) { $name = $this->getArrayPath($event, $path); if (!empty($name) && !empty($name[0])) break; @@ -284,25 +283,38 @@ class CourseBackend_HisInOne extends CourseBackend if ($name === false) { $name = ['???']; } - $unitPlannedDates = $this->getArrayPath($event, - '/hisplanelements/hisplanelement/hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate'); - if ($unitPlannedDates === false) { - $this->error = 'Cannot find ./hisplanelements/hisplanelement/hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate'; - error_log('Cannot find ./hisplanelements/hisplanelement/hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate'); + $planElements = $this->getArrayPath($event, '/hisplanelements/hisplanelement'); + if ($planElements === false) { + $this->error = 'Cannot find ./hisplanelements/hisplanelement'; + error_log('Cannot find ./hisplanelements/hisplanelement'); error_log(print_r($event, true)); continue; } - foreach ($unitPlannedDates as $plannedDate) { - $eventRoomId = $this->getArrayPath($plannedDate, '/hisroomId')[0]; - $eventDate = $this->getArrayPath($plannedDate, '/hisexecutiondate')[0]; - if (in_array($eventRoomId, $requestedRoomIds) && in_array($eventDate, $currentWeek)) { - $startTime = $this->getArrayPath($plannedDate, '/hisstarttime')[0]; - $endTime = $this->getArrayPath($plannedDate, '/hisendtime')[0]; - $tTables[$eventRoomId][] = array( - 'title' => $name[0], - 'start' => $eventDate . "T" . $startTime, - 'end' => $eventDate . "T" . $endTime - ); + foreach ($planElements as $planElement) { + $unitPlannedDates = $this->getArrayPath($planElement, + '/hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate'); + if ($unitPlannedDates === false) { + $this->error = 'Cannot find ./hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate'; + error_log('Cannot find ./hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate'); + error_log(print_r($planElement, true)); + continue; + } + $localName = $this->getArrayPath($planElement, '/hisdefaulttext'); + if ($localName === false || empty($localName[0])) { + $localName = $name; + } + foreach ($unitPlannedDates as $plannedDate) { + $eventRoomId = $this->getArrayPath($plannedDate, '/hisroomId')[0]; + $eventDate = $this->getArrayPath($plannedDate, '/hisexecutiondate')[0]; + if (in_array($eventRoomId, $requestedRoomIds) && in_array($eventDate, $currentWeek)) { + $startTime = $this->getArrayPath($plannedDate, '/hisstarttime')[0]; + $endTime = $this->getArrayPath($plannedDate, '/hisendtime')[0]; + $tTables[$eventRoomId][] = array( + 'title' => $localName[0], + 'start' => $eventDate . "T" . $startTime, + 'end' => $eventDate . "T" . $endTime + ); + } } } } diff --git a/modules-available/locationinfo/lang/de/template-tags.json b/modules-available/locationinfo/lang/de/template-tags.json index bcdf7148..b51c420b 100644 --- a/modules-available/locationinfo/lang/de/template-tags.json +++ b/modules-available/locationinfo/lang/de/template-tags.json @@ -76,7 +76,7 @@ "lang_remoteSchedule": "Abruf Belegungsplan", "lang_room": "Raum", "lang_roomId": "Raum ID", - "lang_roomIdTooltip": "Die Raum ID, die der Server ben\u00f6tigt, um Kalenderdaten abzurufen", + "lang_roomIdTooltip": "Die Raum ID, die der Server ben\u00f6tigt, um Kalenderdaten abzurufen (bei Exchange die Postfachadresse)", "lang_roomupdateTooltip": "Zeit nach der die PCs aktualisiert werden (in Sekunden)", "lang_rotation": "Rotation", "lang_rotation0": "0\u00b0", diff --git a/modules-available/locationinfo/lang/en/template-tags.json b/modules-available/locationinfo/lang/en/template-tags.json index 558ddff0..f041dc0a 100644 --- a/modules-available/locationinfo/lang/en/template-tags.json +++ b/modules-available/locationinfo/lang/en/template-tags.json @@ -76,7 +76,7 @@ "lang_remoteSchedule": "Time table retrieval", "lang_room": "Room", "lang_roomId": "Room ID", - "lang_roomIdTooltip": "The ID of the room the server needs, for querying the calendar data", + "lang_roomIdTooltip": "The ID of the room the server needs, for querying the calendar data (when using exchange the room mailbox)", "lang_roomupdateTooltip": "Time the PCs in the room gets updated (in seconds)", "lang_rotation": "Rotation", "lang_rotation0": "0\u00b0", -- cgit v1.2.3-55-g7522 From bfe34ff61df650b02610767af673644144f015eb Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 2 Jan 2019 15:26:04 +0100 Subject: [inc/Util] Improve prettyTime year cutoff logic Closes #3518 --- inc/util.inc.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'inc') diff --git a/inc/util.inc.php b/inc/util.inc.php index 9f6f63db..1a5cbefe 100644 --- a/inc/util.inc.php +++ b/inc/util.inc.php @@ -495,7 +495,7 @@ SADFACE; settype($ts, 'int'); if ($ts === 0) return '???'; - static $TODAY = false, $ETODAY = false, $YESTERDAY = false, $YEAR = false; + static $TODAY = false, $ETODAY = false, $YESTERDAY = false, $YEARCUTOFF = false; if (!$ETODAY) $ETODAY = strtotime('today 23:59:59'); if ($ts > $ETODAY) // TODO: Do we need strings for future too? return date('d.m.Y H:i', $ts); @@ -505,8 +505,8 @@ SADFACE; if (!$YESTERDAY) $YESTERDAY = strtotime('yesterday 0:00'); if ($ts >= $YESTERDAY) return Dictionary::translate('lang_yesterday') . ' ' . date('H:i', $ts); - if (!$YEAR) $YEAR = strtotime('this year 1/1'); - if ($ts >= $YEAR) + if (!$YEARCUTOFF) $YEARCUTOFF = min(strtotime('-3 month'), strtotime('this year 1/1')); + if ($ts >= $YEARCUTOFF) return date('d.m. H:i', $ts); return date('d.m.Y', $ts); } -- cgit v1.2.3-55-g7522 From 07b7dcd4d08be00541dcbd4a92a02f267a0b162c Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 17 Jan 2019 14:41:44 +0100 Subject: [serversetup-bwlp] Make ipxe trigger a hook for modularity --- inc/trigger.inc.php | 24 +++++++++++++++------- .../serversetup-bwlp/hooks/ipxe-update.inc.php | 10 +++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 modules-available/serversetup-bwlp/hooks/ipxe-update.inc.php (limited to 'inc') diff --git a/inc/trigger.inc.php b/inc/trigger.inc.php index 93f57236..8a130aca 100644 --- a/inc/trigger.inc.php +++ b/inc/trigger.inc.php @@ -20,13 +20,23 @@ class Trigger */ public static function ipxe() { - $data = Property::getBootMenu(); - $data['ipaddress'] = Property::getServerIp(); - $task = Taskmanager::submit('CompileIPxe', $data); - if (!isset($task['id'])) - return false; - Property::set('ipxe-task-id', $task['id'], 15); - return $task['id']; + $hooks = Hook::load('ipxe-update'); + $taskId = false; + foreach ($hooks as $hook) { + $ret = (function($taskId) use ($hook) { + $ret = include_once($hook->file); + if (is_string($ret)) + return $ret; + return isset($taskId) ? $taskId : false; + })($taskId); + if (is_string($ret)) { + $taskId = $ret; + } elseif (is_array($ret) && isset($ret['id'])) { + $taskId = $ret['id']; + } + } + Property::set('ipxe-task-id', $taskId, 15); + return $taskId; } /** diff --git a/modules-available/serversetup-bwlp/hooks/ipxe-update.inc.php b/modules-available/serversetup-bwlp/hooks/ipxe-update.inc.php new file mode 100644 index 00000000..166e80a8 --- /dev/null +++ b/modules-available/serversetup-bwlp/hooks/ipxe-update.inc.php @@ -0,0 +1,10 @@ + Property::getServerIp() +]; +$task = Taskmanager::submit('CompileIPxeNew', $data); +if (!isset($task['id'])) +return false; +Property::set('ipxe-task-id', $task['id'], 15); +return $task['id']; \ No newline at end of file -- cgit v1.2.3-55-g7522 From efdd92e2dec0c35f3b3c29cb69c6afe418287f1c Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 18 Jan 2019 16:36:50 +0100 Subject: [inc/Trigger] PHP 5.6 compat --- inc/trigger.inc.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'inc') diff --git a/inc/trigger.inc.php b/inc/trigger.inc.php index 8a130aca..e89a9a17 100644 --- a/inc/trigger.inc.php +++ b/inc/trigger.inc.php @@ -23,12 +23,13 @@ class Trigger $hooks = Hook::load('ipxe-update'); $taskId = false; foreach ($hooks as $hook) { - $ret = (function($taskId) use ($hook) { + $ret = function($taskId) use ($hook) { $ret = include_once($hook->file); if (is_string($ret)) return $ret; return isset($taskId) ? $taskId : false; - })($taskId); + }; + $ret = $ret($taskId); if (is_string($ret)) { $taskId = $ret; } elseif (is_array($ret) && isset($ret['id'])) { -- cgit v1.2.3-55-g7522 From 0a040966751e4a45fc9b9ac6cbaaea100b38ce53 Mon Sep 17 00:00:00 2001 From: Christian Hofmaier Date: Tue, 22 Jan 2019 16:12:28 +0100 Subject: [inc/Render] new optional argument to change rendered language --- inc/render.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'inc') diff --git a/inc/render.inc.php b/inc/render.inc.php index 4b1d3643..4da0567e 100644 --- a/inc/render.inc.php +++ b/inc/render.inc.php @@ -213,7 +213,7 @@ class Render * @param string $module name of module to load template from; defaults to currently active module * @return string Rendered template */ - public static function parse($template, $params = false, $module = false) + public static function parse($template, $params = false, $module = false, $lang = false) { if ($module === false && class_exists('Page')) { $module = Page::getModule()->getIdentifier(); @@ -228,7 +228,7 @@ class Render } // Now find all language tags in this array if (preg_match_all('/{{\s*(lang_.+?)\s*}}/', $html, $out) > 0) { - $dictionary = Dictionary::getArray($module, 'template-tags'); + $dictionary = Dictionary::getArray($module, 'template-tags', $lang); $fallback = false; foreach ($out[1] as $tag) { if ($fallback === false && empty($dictionary[$tag])) { -- cgit v1.2.3-55-g7522 From 54a0a4c9b920bce1dc4e93d2cf05ebbea6502be0 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 28 Jan 2019 13:48:03 +0100 Subject: [inc/Util] readableFileSize: support input in KB/MB/... --- inc/util.inc.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'inc') diff --git a/inc/util.inc.php b/inc/util.inc.php index 1a5cbefe..e459cc46 100644 --- a/inc/util.inc.php +++ b/inc/util.inc.php @@ -234,9 +234,10 @@ SADFACE; * * @param float|int $bytes numeric value of the filesize to make readable * @param int $decimals number of decimals to show, -1 for automatic + * @param int $shift how many units to skip, i.e. if you pass in KiB or MiB * @return string human readable string representing the given file size */ - public static function readableFileSize($bytes, $decimals = -1) + public static function readableFileSize($bytes, $decimals = -1, $shift = 0) { $bytes = round($bytes); static $sz = array('Byte', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'); @@ -249,7 +250,7 @@ SADFACE; $decimals = 2 - floor(strlen((int)$bytes) - 1); } } - return sprintf("%.{$decimals}f", $bytes) . "\xe2\x80\x89" . $sz[$factor]; + return sprintf("%.{$decimals}f", $bytes) . "\xe2\x80\x89" . $sz[$factor + $shift]; } public static function sanitizeFilename($name) -- cgit v1.2.3-55-g7522 From 120956761383f8365e95e669a11b344af4764c74 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 30 Jan 2019 13:39:41 +0100 Subject: [inc/Dictionary] Teh evil unvalidated redirects must die! --- inc/dictionary.inc.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'inc') diff --git a/inc/dictionary.inc.php b/inc/dictionary.inc.php index fcbfdfb8..935d1f4e 100644 --- a/inc/dictionary.inc.php +++ b/inc/dictionary.inc.php @@ -30,10 +30,15 @@ class Dictionary if ($lang !== false && in_array($lang, self::$languages)) { setcookie('lang', $lang, time() + 60 * 60 * 24 * 30 * 12); $url = Request::get('url'); - if ($url === false && isset($_SERVER['HTTP_REFERER'])) + if ($url === false && isset($_SERVER['HTTP_REFERER'])) { $url = $_SERVER['HTTP_REFERER']; - if ($url === false) - $url = '?do=Main'; + } + $parts = parse_url($url); + if ($url === false || $parts === false || empty($parts['query'])) { + $url = '?do=main'; + } else { + $url = '?' . $parts['query']; + } Util::redirect($url); } -- cgit v1.2.3-55-g7522 From 2d64b9d8f57f28456eb27c4aed2dde26201b6770 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 12 Feb 2019 14:35:49 +0100 Subject: [serversetup-bwlp] Auto-import of old PXELinux config on bootup Also minor improvements to UI and structuring --- inc/event.inc.php | 11 +++ .../serversetup-bwlp/hooks/bootup.inc.php | 11 +++ .../serversetup-bwlp/inc/bootentry.inc.php | 3 +- .../serversetup-bwlp/inc/ipxe.inc.php | 79 ++++++++++++++++++---- .../serversetup-bwlp/inc/pxelinux.inc.php | 40 +++++++++++ .../serversetup-bwlp/lang/de/messages.json | 12 ++-- .../serversetup-bwlp/lang/de/module.json | 4 +- .../serversetup-bwlp/lang/de/template-tags.json | 23 ++++--- modules-available/serversetup-bwlp/page.inc.php | 39 +++++++---- .../serversetup-bwlp/templates/bootentry-list.html | 12 +++- .../templates/ipxe-new-boot-entry.html | 9 ++- .../serversetup-bwlp/templates/menu-edit.html | 2 +- .../serversetup-bwlp/templates/menu-list.html | 13 +++- 13 files changed, 211 insertions(+), 47 deletions(-) create mode 100644 modules-available/serversetup-bwlp/hooks/bootup.inc.php (limited to 'inc') diff --git a/inc/event.inc.php b/inc/event.inc.php index b1ee3663..4e68ab6d 100644 --- a/inc/event.inc.php +++ b/inc/event.inc.php @@ -24,6 +24,17 @@ class Event Property::clearList('cron.key.status'); Property::clearList('cron.key.blocked'); + // Hooks + foreach (Hook::load('bootup') as $hook) { + // Isolate for local vars + $fun = function() use ($hook) { + include_once($hook->file); + }; + $fun(); + } + + // TODO: Modularize (hooks) + // Tasks: fire away $mountStatus = false; $mountId = Trigger::mount(); diff --git a/modules-available/serversetup-bwlp/hooks/bootup.inc.php b/modules-available/serversetup-bwlp/hooks/bootup.inc.php new file mode 100644 index 00000000..50ac04ae --- /dev/null +++ b/modules-available/serversetup-bwlp/hooks/bootup.inc.php @@ -0,0 +1,11 @@ + 0) { + EventLog::info('Imported old PXELinux menu, with ' . $num . ' additional IP-range based menus.'); + } else { + EventLog::info('Imported old PXELinux menu.'); + } +} diff --git a/modules-available/serversetup-bwlp/inc/bootentry.inc.php b/modules-available/serversetup-bwlp/inc/bootentry.inc.php index 010b660c..69adffd3 100644 --- a/modules-available/serversetup-bwlp/inc/bootentry.inc.php +++ b/modules-available/serversetup-bwlp/inc/bootentry.inc.php @@ -95,7 +95,7 @@ class StandardBootEntry extends BootEntry protected $replace; protected $autoUnload; protected $resetConsole; - protected $arch; // true == available, false == not available + protected $arch; // Constants below const BIOS = 'PCBIOS'; // Only valid for legacy BIOS boot const EFI = 'EFI'; // Only valid for EFI boot @@ -105,6 +105,7 @@ class StandardBootEntry extends BootEntry public function __construct($data = false) { if ($data instanceof PxeSection) { + // Gets arrayfied below $this->executable = $data->kernel; $this->initRd = $data->initrd; $this->commandLine = ' ' . str_replace('vga=current', '', $data->append) . ' '; diff --git a/modules-available/serversetup-bwlp/inc/ipxe.inc.php b/modules-available/serversetup-bwlp/inc/ipxe.inc.php index d5bbb4b2..d34839f0 100644 --- a/modules-available/serversetup-bwlp/inc/ipxe.inc.php +++ b/modules-available/serversetup-bwlp/inc/ipxe.inc.php @@ -3,8 +3,16 @@ class IPxe { + /** + * Import all IP-Range based pxe menus from the given directory. + * + * @param string $configPath The pxelinux.cfg path where to look for menu files in hexadecimal IP format. + * @return Number of menus imported + */ public static function importPxeMenus($configPath) { + $importCount = 0; + $menus = []; foreach (glob($configPath . '/*', GLOB_NOSORT) as $file) { if (!is_file($file) || !preg_match('~/[A-F0-9]{1,8}$~', $file)) continue; @@ -29,14 +37,53 @@ class IPxe unset($loc); $locations[] = $row; } - $menuId = self::insertMenu($content, 'Imported', false, 0, [], []); + $menu = PxeLinux::parsePxeLinux($content); + $key = $menu->hash(true); + if (isset($menus[$key])) { + $menuId = $menus[$key]; + $defId = null; + // Figure out the default label, get it's label name + foreach ($menu->sections as $section) { + if ($section->isDefault) { + $defId = $section; + } elseif ($defId === null && $section->label === $menu->timeoutLabel) { + $defId = $section; + } + } + if ($defId !== null) { + $defId = self::cleanLabelFixLocal($defId); + // Confirm it actually exists (it should since the menu seems identical) and get menuEntryId + $me = Database::queryFirst('SELECT m.defaultentryid, me.menuentryid FROM serversetup_bootentry be + INNER JOIN serversetup_menuentry me ON (be.entryid = me.entryid) + INNER JOIN serversetup_menu m ON (m.menuid = me.menuid) + WHERE be.entryid = :id AND me.menuid = :menuid', + ['id' => $defId, 'menuid' => $menuId]); + if ($me === false || $me['defaultentryid'] == $me['menuentryid']) { + $defId = null; // Not found, or is already default - don't override if it's the same + } else { + $defId = $me['menuentryid']; + } + } + } else { + $menuId = self::insertMenu($menu, 'Imported', false, 0, [], []); + $menus[$key] = $menuId; + $defId = null; + $importCount++; + } if ($menuId === false) continue; foreach ($locations as $loc) { - Database::exec('INSERT IGNORE INTO serversetup_menu_x_location (menuid, locationid) - VALUES (:menuid, :locationid)', ['menuid' => $menuId, 'locationid' => $loc['locationid']]); + if ($loc === false) + continue; + Database::exec('INSERT IGNORE INTO serversetup_menu_location (menuid, locationid, defaultentryid) + VALUES (:menuid, :locationid, :def)', [ + 'menuid' => $menuId, + 'locationid' => $loc['locationid'], + 'def' => $defId, + ]); } } + return $importCount; } public static function importLegacyMenu($force = false) @@ -76,16 +123,25 @@ class IPxe '', 'poweroff' => false, ]; - return self::insertMenu($pxeConfig, $menuTitle, $defaultLabel, $timeoutSecs, $prepend, $append); + return self::insertMenu(PxeLinux::parsePxeLinux($pxeConfig), $menuTitle, $defaultLabel, $timeoutSecs, $prepend, $append); } - private static function insertMenu($pxeConfig, $menuTitle, $defaultLabel, $defaultTimeoutSeconds, $prepend, $append) + /** + * @param PxeMenu $pxeMenu + * @param string $menuTitle + * @param string|false $defaultLabel + * @param $defaultTimeoutSeconds + * @param $prepend + * @param $append + * @return bool|int + */ + private static function insertMenu($pxeMenu, $menuTitle, $defaultLabel, $defaultTimeoutSeconds, $prepend, $append) { $timeoutMs = []; $menuEntries = $prepend; settype($menuEntries, 'array'); - if (!empty($pxeConfig)) { - $pxe = PxeLinux::parsePxeLinux($pxeConfig); + if (!empty($pxeMenu)) { + $pxe =& $pxeMenu; if (!empty($pxe->title)) { $menuTitle = $pxe->title; } @@ -95,11 +151,10 @@ class IPxe $timeoutMs[] = $pxe->timeoutMs; $timeoutMs[] = $pxe->totalTimeoutMs; foreach ($pxe->sections as $section) { - if ($section->localBoot || preg_match('/chain.c32$/i', $section->kernel)) { + if ($section->localBoot || preg_match('/chain\.c32$/i', $section->kernel)) { $menuEntries['localboot'] = 'localboot'; continue; } - $section->mangle(); if ($section->label === null) { if (!$section->isHidden && !empty($section->title)) { $menuEntries[] = $section->title; @@ -221,7 +276,7 @@ class IPxe 'data' => json_encode([ 'executable' => '/boot/default/kernel', 'initRd' => '/boot/default/initramfs-stage31', - 'commandLine' => 'slxbase=boot/default quiet splash loglevel=5 rd.systemd.show_status=auto ${ipappend1} ${ipappend2}', + 'commandLine' => 'slxbase=boot/default quiet splash loglevel=5 rd.systemd.show_status=auto intel_iommu=igfx_off ${ipappend1} ${ipappend2}', 'replace' => true, 'autoUnload' => true, 'resetConsole' => true, @@ -235,7 +290,7 @@ class IPxe 'data' => json_encode([ 'executable' => '/boot/default/kernel', 'initRd' => '/boot/default/initramfs-stage31', - 'commandLine' => 'slxbase=boot/default loglevel=7 ${ipappend1} ${ipappend2}', + 'commandLine' => 'slxbase=boot/default loglevel=7 intel_iommu=igfx_off ${ipappend1} ${ipappend2}', 'replace' => true, 'autoUnload' => true, 'resetConsole' => true, @@ -314,7 +369,7 @@ class IPxe */ private static function pxe2BootEntry($section) { - if (preg_match('/(pxechain.com|pxechn.c32)$/i', $section->kernel)) { + if (preg_match('/(pxechain\.com|pxechn\.c32)$/i', $section->kernel)) { // Chaining -- create script $args = preg_split('/\s+/', $section->append); $script = ''; diff --git a/modules-available/serversetup-bwlp/inc/pxelinux.inc.php b/modules-available/serversetup-bwlp/inc/pxelinux.inc.php index db3dac4b..1d022fef 100644 --- a/modules-available/serversetup-bwlp/inc/pxelinux.inc.php +++ b/modules-available/serversetup-bwlp/inc/pxelinux.inc.php @@ -86,6 +86,9 @@ class PxeLinux if ($section !== null) { $menu->sections[] = $section; } + foreach ($menu->sections as $section) { + $section->mangle(); + } return $menu; } @@ -131,6 +134,7 @@ class PxeLinux */ class PxeMenu { + /** * @var string menu title, shown at the top of the menu */ @@ -160,6 +164,40 @@ class PxeMenu * @var PxeSection[] list of sections the menu contains */ public $sections = []; + + public function hash($fuzzy) + { + $ctx = hash_init('md5'); + if (!$fuzzy) { + hash_update($ctx, $this->title); + hash_update($ctx, $this->timeoutLabel); + } + hash_update($ctx, $this->timeoutMs); + foreach ($this->sections as $section) { + if ($fuzzy) { + hash_update($ctx, mb_strtolower(preg_replace('/[^a-zA-Z0-9]/', '', $section->title))); + } else { + hash_update($ctx, $section->label); + hash_update($ctx, $section->title); + hash_update($ctx, $section->indent); + hash_update($ctx, $section->helpText); + hash_update($ctx, $section->isDefault); + hash_update($ctx, $section->hotkey); + } + hash_update($ctx, $section->kernel); + hash_update($ctx, $section->append); + hash_update($ctx, $section->ipAppend); + hash_update($ctx, $section->passwd); + hash_update($ctx, $section->isHidden); + hash_update($ctx, $section->isDisabled); + hash_update($ctx, $section->localBoot); + foreach ($section->initrd as $initrd) { + hash_update($ctx, $initrd); + } + } + return hash_final($ctx, false); + } + } /** @@ -170,6 +208,7 @@ class PxeMenu */ class PxeSection { + /** * @var string label used internally in PXEMENU definition to address this entry */ @@ -258,5 +297,6 @@ class PxeSection $this->initrd = []; } } + } diff --git a/modules-available/serversetup-bwlp/lang/de/messages.json b/modules-available/serversetup-bwlp/lang/de/messages.json index de48ef0b..0772a7e4 100644 --- a/modules-available/serversetup-bwlp/lang/de/messages.json +++ b/modules-available/serversetup-bwlp/lang/de/messages.json @@ -1,10 +1,10 @@ { - "boot-entry-created": "Booteintrag {{0}} erzeugt", - "boot-entry-updated": "Booteintrag {{0}} aktualisiert", - "bootentry-deleted": "Booteintrag gel\u00f6scht", + "boot-entry-created": "Men\u00fceintrag {{0}} erzeugt", + "boot-entry-updated": "Men\u00fceintrag {{0}} aktualisiert", + "bootentry-deleted": "Men\u00fceintrag gel\u00f6scht", "error-saving-entry": "Fehler beim Speichern des Eintrags {{0}}: {{1}}", "image-not-found": "USB-Image nicht gefunden. Generieren Sie das Bootmen\u00fc neu.", - "invalid-boot-entry": "Ung\u00fcltiger Booteintrag: {{0}}", + "invalid-boot-entry": "Ung\u00fcltiger Men\u00fceintrag: {{0}}", "invalid-ip": "Kein Interface ist auf die Adresse {{0}} konfiguriert", "invalid-menu-id": "Ung\u00fcltige Men\u00fc-ID: {{0}}", "localboot-invalid-method": "Ung\u00fcltige localboot-Methode: {{0}}", @@ -14,8 +14,8 @@ "menu-deleted": "Men\u00fc gel\u00f6scht", "menu-saved": "Men\u00fc wurde gespeichert", "menu-set-default": "Standardmen\u00fc wurde gesetzt", - "missing-bootentry-data": "Fehlende Daten f\u00fcr den Booteintrag", + "missing-bootentry-data": "Fehlende Daten f\u00fcr den Men\u00fceintrag", "no-ip-addr-set": "Bitte w\u00e4hlen Sie die prim\u00e4re IP-Adresse des Servers", "no-such-menu": "Men\u00fc mit ID {{0}} existiert nicht", "unknown-bootentry-type": "Unbekannter Eintrags-Typ: {{0}}" -} \ No newline at end of file +} diff --git a/modules-available/serversetup-bwlp/lang/de/module.json b/modules-available/serversetup-bwlp/lang/de/module.json index 31d563f0..9a8de39c 100644 --- a/modules-available/serversetup-bwlp/lang/de/module.json +++ b/modules-available/serversetup-bwlp/lang/de/module.json @@ -12,8 +12,8 @@ "module_name": "iPXE \/ Boot Menu", "page_title": "PXE- und Boot-Einstellungen", "submenu_address": "Server-Adresse", - "submenu_bootentry": "Booteintr\u00e4ge verwalten", + "submenu_bootentry": "Men\u00fceintr\u00e4ge verwalten", "submenu_download": "Downloads", "submenu_localboot": "HDD-Boot", "submenu_menu": "Men\u00fcs verwalten" -} \ No newline at end of file +} diff --git a/modules-available/serversetup-bwlp/lang/de/template-tags.json b/modules-available/serversetup-bwlp/lang/de/template-tags.json index a242be5e..198a1517 100644 --- a/modules-available/serversetup-bwlp/lang/de/template-tags.json +++ b/modules-available/serversetup-bwlp/lang/de/template-tags.json @@ -1,8 +1,9 @@ { "lang_active": "Aktiv", "lang_add": "Hinzuf\u00fcgen", - "lang_addBootentry": "Booteintrag hinzuf\u00fcgen", + "lang_addBootentry": "Men\u00fceintrag hinzuf\u00fcgen", "lang_addMenu": "Men\u00fc hinzuf\u00fcgen", + "lang_additionalInfoLink": "Weitere Informationen", "lang_archAgnostic": "Architekturunabh\u00e4ngig", "lang_archBoth": "BIOS und EFI", "lang_archSelector": "Architekturauswahl", @@ -10,13 +11,15 @@ "lang_biosOnly": "Nur BIOS", "lang_bootAddress": "Boot-Adresse des Servers", "lang_bootBehavior": "Standard-Bootverhalten", - "lang_bootEntryData": "Daten des Booteintrags", + "lang_bootEntryData": "Daten des Men\u00fceintrags", "lang_bootHint": "Das Bootmen\u00fc muss nach einer \u00c4nderung der IP-Adresse neu generiert werden. In der Regel geschieht dies automatisch, der Vorgang kann in der Sektion Bootmen\u00fc allerdings auch manuell ausgel\u00f6st werden.", "lang_bootInfo": "Hier k\u00f6nnen Anpassungen am Erscheinungsbild des Bootmen\u00fcs vorgenommen werden.", "lang_bootMenu": "Bootmen\u00fc", "lang_bootMenuCreate": "Bootmen\u00fc erzeugen", - "lang_bootentryDeleteConfirm": "Sind Sie sicher, dass Sie diesen Booteintrag l\u00f6schen wollen?", - "lang_bootentryTitle": "Booteintrag", + "lang_bootentryDeleteConfirm": "Sind Sie sicher, dass Sie diesen Men\u00fceintrag l\u00f6schen wollen?", + "lang_bootentryHead": "Men\u00fceintr\u00e4ge", + "lang_bootentryIntro": "Hier k\u00f6nnen Sie Men\u00fceintr\u00e4ge definieren, die sich sp\u00e4ter einem Men\u00fc zuweisen lassen. Ein Men\u00fceintrag besteht entweder aus einem zu ladenen Kernel\/Image plus optional initrd, oder aus einem iPXE-Script.", + "lang_bootentryTitle": "Men\u00fceintrag", "lang_chooseIP": "Bitte w\u00e4hlen Sie die IP-Adresse, \u00fcber die der Server von den Clients zum Booten angesprochen werden soll.", "lang_commandLine": "Command line", "lang_count": "Anzahl", @@ -26,7 +29,7 @@ "lang_editBuiltinWarn": "Achtung! Sie bearbeiten einen der vorgegebenen Eintr\u00e4ge! Bei einem Update k\u00f6nnten Ihre \u00c4nderungen wieder \u00fcberschrieben werden", "lang_editMenuHead": "Men\u00fc bearbeiten", "lang_efiOnly": "Nur EFI", - "lang_entryChooserTitle": "Booteintrag ausw\u00e4hlen", + "lang_entryChooserTitle": "Men\u00fceintrag ausw\u00e4hlen", "lang_entryId": "ID", "lang_entryTitle": "Bezeichnung", "lang_example": "Beispiel", @@ -40,6 +43,7 @@ "lang_idFormatHint": "(Max. 16 Zeichen, nur a-z 0-9 - _)", "lang_imageToLoad": "Zu ladendes Image (z.B. Kernel)", "lang_initRd": "Zu ladendes initramfs", + "lang_ipxeWikiUrl": "im iPXE Wiki", "lang_isDefault": "Standard", "lang_listOfMenus": "Men\u00fcliste", "lang_localBootDefault": "Standardm\u00e4\u00dfig verwendete Methode, um von Festplatte zu booten", @@ -49,7 +53,7 @@ "lang_localHDD": "Lokale HDD", "lang_locationCount": "Anzahl Orte", "lang_masterPassword": "Master-Passwort", - "lang_masterPasswordHelp": "Das Master-Passwort wird ben\u00f6tigt, um einen Booteintrag direkt am Client tempor\u00e4r durch Dr\u00fccken der Tab-Taste zu editieren. Da dies f\u00fcr Manipulation am Client genutzt werden kann, sollte diese Funktion unbedingt mit einem Passwort gesch\u00fctzt werden.", + "lang_masterPasswordHelp": "Das Master-Passwort wird ben\u00f6tigt, um einen Men\u00fceintrag direkt am Client tempor\u00e4r durch Dr\u00fccken der Tab-Taste zu editieren. Da dies f\u00fcr Manipulation am Client genutzt werden kann, sollte diese Funktion unbedingt mit einem Passwort gesch\u00fctzt werden.", "lang_menuCustom": "Benutzerdefinierter Men\u00fczusatz", "lang_menuCustomHint1": "Hier haben Sie die M\u00f6glichkeit, eigenen Men\u00fc-Code zum angezeigten PXE-Men\u00fc hinzuzuf\u00fcgen, um z.B. auf weitere PXE-Server zu verweisen. Das Format entspricht dem syslinux Men\u00fcformat.", "lang_menuCustomHint2": "Sie k\u00f6nnen ein oder mehrere Eintr\u00e4ge erzeugen. Wenn Sie einen Eintrag erzeugen m\u00f6chten, der automatisch gestartet wird, wenn der Benutzer keine Auswahl t\u00e4tigt, vergeben Sie als", @@ -58,16 +62,19 @@ "lang_menuDisplayTime": "Anzeigedauer des Men\u00fcs", "lang_menuEntryOverride": "Standardeintrag \u00fcberschreiben", "lang_menuGeneration": "Erzeugen des Bootmen\u00fcs", + "lang_menuListIntro": "Hier sehen Sie eine Liste aller vorhandenen Men\u00fcs, deren Zuordnung zu R\u00e4umen sowie die M\u00f6glichkeit, diese zu editieren oder l\u00f6schen. Um ein Men\u00fc einem bestimmten Raum zuzuweisen, besuchen Sie bitte den Men\u00fcpunkt \"R\u00e4ume\/Orte\".", "lang_menuLocations": "Zugewiesene Orte", "lang_menuTimeout": "Timeout", "lang_menuTitle": "Men\u00fc", "lang_moduleHeading": "iPXE \/ Boot Menu", - "lang_newBootEntryHead": "Neuer Booteintrag", + "lang_newBootEntryHead": "Neuer Men\u00fceintrag", "lang_newMenu": "Neues Men\u00fc", "lang_none": "(keine)", "lang_override": "\u00dcberschreiben", "lang_pxeBuilt": "PXE-Binary gebaut", "lang_recompileHint": "iPXE-Binaries jetzt neu kompilieren. Normalerweise wird dieser Vorgang bei \u00c4nderungen automatisch ausgef\u00fchrt. Sollten Bootprobleme auftreten, k\u00f6nnen Sie hier den Vorgang manuell ansto\u00dfen.", + "lang_refCount": "Referenzen", + "lang_referencingMenus": "Verkn\u00fcpfte Men\u00fcs", "lang_scriptContent": "Script", "lang_seconds": "Sekunden", "lang_set": "Setzen", @@ -84,4 +91,4 @@ "lang_usbImgHelpWindows": "Unter Windows muss zun\u00e4chst ein Programm besorgt werden, mit dem sich Images direkt auf einen USB-Stick schreiben lassen. Es gibt gleich mehrere kostenlose und quelloffene Programme, eines davon ist Rufus. Rufus wurde mit dem bwLehrpool-Image gestetet. Nach dem Starten des Programms ist lediglich das heruntergeladene Image zu \u00f6ffnen, sowie in der Liste der Laufwerke der richtige USB-Stick auszuw\u00e4hlen (damit Sie nicht versehentlich Daten auf dem falschen Laufwerk \u00fcberschreiben!)", "lang_useDefaultMenu": "\u00dcbergeordnetes Men\u00fc verwenden", "lang_useDefaultMenuEntry": "(Vorgabe des Men\u00fcs)" -} \ No newline at end of file +} diff --git a/modules-available/serversetup-bwlp/page.inc.php b/modules-available/serversetup-bwlp/page.inc.php index 6c32cb82..bb69fecf 100644 --- a/modules-available/serversetup-bwlp/page.inc.php +++ b/modules-available/serversetup-bwlp/page.inc.php @@ -32,12 +32,6 @@ class Page_ServerSetup extends Page Util::redirect('?do=Main'); } - if (Request::any('bla') == 'blu') { - IPxe::importLegacyMenu(); - IPxe::importPxeMenus('/srv/openslx/tftp/pxelinux.cfg'); - die('DONE'); - } - if (Request::any('action') === 'getimage') { User::assertPermission("download"); $this->handleGetImage(); @@ -277,7 +271,10 @@ class Page_ServerSetup extends Page { $allowEdit = User::hasPermission('ipxe.bootentry.edit'); - $res = Database::simpleQuery("SELECT entryid, hotkey, title, builtin FROM serversetup_bootentry"); + $res = Database::simpleQuery("SELECT be.entryid, be.hotkey, be.title, be.builtin, Count(*) AS refs FROM serversetup_bootentry be + INNER JOIN serversetup_menuentry sm USING (entryid) + GROUP BY be.entryid + ORDER BY be.title ASC"); $bootentryTable = []; while ($row = $res->fetch(PDO::FETCH_ASSOC)) { $bootentryTable[] = $row; @@ -295,8 +292,13 @@ class Page_ServerSetup extends Page // TODO Permission::addGlobalTags($perms, null, ['edit.menu', 'edit.address', 'download']); - $res = Database::simpleQuery("SELECT m.menuid, m.title, m.isdefault, GROUP_CONCAT(l.locationid) AS locations - FROM serversetup_menu m LEFT JOIN serversetup_menu_location l USING (menuid) GROUP BY menuid ORDER BY title"); + $res = Database::simpleQuery("SELECT m.menuid, m.title, m.isdefault, GROUP_CONCAT(l.locationid) AS locations, + GROUP_CONCAT(ll.locationname SEPARATOR ', ') AS locnames + FROM serversetup_menu m + LEFT JOIN serversetup_menu_location l USING (menuid) + LEFT JOIN location ll USING (locationid) + GROUP BY menuid + ORDER BY title"); $menuTable = []; while ($row = $res->fetch(PDO::FETCH_ASSOC)) { if (empty($row['locations'])) { @@ -351,6 +353,7 @@ class Page_ServerSetup extends Page Message::addError('invalid-menu-id', $id); Util::redirect('?do=serversetup&show=menu'); } + $highlight = Request::get('highlight', false, 'string'); if ($id !== 0 && !$this->hasMenuPermission($id, 'ipxe.menu.edit')) { $menu['readonly'] = 'readonly'; $menu['disabled'] = 'disabled'; @@ -361,12 +364,19 @@ class Page_ServerSetup extends Page } $menu['timeout'] = round($menu['timeoutms'] / 1000); - $menu['entries'] = Database::queryAll("SELECT menuentryid, entryid, hotkey, title, hidden, sortval, plainpass FROM + $menu['entries'] = []; + $res = Database::simpleQuery("SELECT menuentryid, entryid, hotkey, title, hidden, sortval, plainpass FROM serversetup_menuentry WHERE menuid = :id ORDER BY sortval ASC", compact('id')); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if ($row['entryid'] == $highlight) { + $row['highlight'] = 'active'; + } + $menu['entries'][] = $row; + } $menu['keys'] = array_map(function ($item) { return ['key' => $item]; }, MenuEntry::getKeyList()); $menu['entrylist'] = Database::queryAll("SELECT entryid, title, hotkey, data FROM serversetup_bootentry ORDER BY title ASC"); foreach ($menu['entrylist'] as &$bootentry) { - $bootentry['json'] = $bootentry['data']; + //$bootentry['json'] = $bootentry['data']; $bootentry['data'] = json_decode($bootentry['data'], true); if (array_key_exists('arch', $bootentry['data'])) { $bootentry['data']['PCBIOS'] = array('executable' => $bootentry['data']['executable']['PCBIOS'], @@ -386,7 +396,7 @@ class Page_ServerSetup extends Page $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_archBoth', true); } - } else { + } elseif (!array_key_exists('script', $bootentry['data'])) { $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_archAgnostic', true); $bootentry['data']['archAgnostic'] = array('executable' => $bootentry['data']['executable'], 'initRd' => $bootentry['data']['initRd'], @@ -428,8 +438,11 @@ class Page_ServerSetup extends Page } $entry->addFormFields($params); $params['title'] = $row['title']; - $params['oldentryid'] = $params['entryid'] = $row['entryid']; + $params['entryid'] = $row['entryid']; $params['builtin'] = $row['builtin']; + $params['menus'] = Database::queryAll('SELECT m.menuid, m.title FROM serversetup_menu m + INNER JOIN serversetup_menuentry me ON (me.menuid = m.menuid) + WHERE me.entryid = :entryid', ['entryid' => $row['entryid']]); } Render::addTemplate('ipxe-new-boot-entry', $params); diff --git a/modules-available/serversetup-bwlp/templates/bootentry-list.html b/modules-available/serversetup-bwlp/templates/bootentry-list.html index 929b8c47..0cf005c5 100644 --- a/modules-available/serversetup-bwlp/templates/bootentry-list.html +++ b/modules-available/serversetup-bwlp/templates/bootentry-list.html @@ -1,8 +1,15 @@ +

{{lang_bootentryHead}}

+ +

+ {{lang_bootentryIntro}} +

+ - + + @@ -16,6 +23,9 @@ + {{#entries}} - +
{{lang_bootentryTitle}}Hotkey{{lang_hotkey}}{{lang_refCount}} {{lang_edit}} {{lang_delete}}
{{hotkey}} + {{refs}} + {{#allowEdit}} diff --git a/modules-available/serversetup-bwlp/templates/ipxe-new-boot-entry.html b/modules-available/serversetup-bwlp/templates/ipxe-new-boot-entry.html index fe496029..7e82b5cc 100644 --- a/modules-available/serversetup-bwlp/templates/ipxe-new-boot-entry.html +++ b/modules-available/serversetup-bwlp/templates/ipxe-new-boot-entry.html @@ -14,7 +14,7 @@
- +
@@ -121,6 +121,13 @@
{{/builtin}} +

{{lang_referencingMenus}}:

+
+
diff --git a/modules-available/serversetup-bwlp/templates/menu-list.html b/modules-available/serversetup-bwlp/templates/menu-list.html index 67365a33..545f22a9 100644 --- a/modules-available/serversetup-bwlp/templates/menu-list.html +++ b/modules-available/serversetup-bwlp/templates/menu-list.html @@ -1,5 +1,9 @@

{{lang_listOfMenus}}

+

+ {{lang_menuListIntro}} +

+ @@ -17,7 +21,7 @@ {{title}}
- {{locationCount}} + {{locationCount}} {{^isdefault}} @@ -37,7 +41,7 @@ {{#allowEdit}} - + {{/allowEdit}} @@ -60,6 +64,8 @@ +
+ @@ -88,4 +94,7 @@ function deleteMenu(menuid) { $("#delete-menu-id").val(menuid); } + document.addEventListener('DOMContentLoaded', function() { + $('[data-toggle="tooltip"]').tooltip(); + }); \ No newline at end of file -- cgit v1.2.3-55-g7522