diff --git a/application/forms/Security/RoleForm.php b/application/forms/Security/RoleForm.php index a2eaf0ea3..4afd48b8c 100644 --- a/application/forms/Security/RoleForm.php +++ b/application/forms/Security/RoleForm.php @@ -12,7 +12,6 @@ use Icinga\Forms\ConfigForm; use Icinga\Forms\RepositoryForm; use Icinga\Util\StringHelper; use Icinga\Web\Notification; -use Zend_Form_Element; /** * Form for managing roles @@ -47,133 +46,7 @@ class RoleForm extends RepositoryForm { $this->setAttrib('class', self::DEFAULT_CLASSES . ' role-form'); - $helper = new Zend_Form_Element('bogus'); - $view = $this->getView(); - - $this->providedPermissions['application'] = [ - $helper->filterName('application/announcements') => [ - 'name' => 'application/announcements', - 'description' => $this->translate('Allow to manage announcements') - ], - $helper->filterName('application/log') => [ - 'name' => 'application/log', - 'description' => $this->translate('Allow to view the application log') - ], - $helper->filterName('config/*') => [ - 'name' => 'config/*', - 'description' => $this->translate('Allow full config access') - ], - $helper->filterName('config/general') => [ - 'name' => 'config/general', - 'description' => $this->translate('Allow to adjust the general configuration') - ], - $helper->filterName('config/modules') => [ - 'name' => 'config/modules', - 'description' => $this->translate('Allow to enable/disable and configure modules') - ], - $helper->filterName('config/resources') => [ - 'name' => 'config/resources', - 'description' => $this->translate('Allow to manage resources') - ], - $helper->filterName('config/navigation') => [ - 'name' => 'config/navigation', - 'description' => $this->translate('Allow to view and adjust shared navigation items') - ], - $helper->filterName('config/access-control/*') => [ - 'name' => 'config/access-control/*', - 'description' => $this->translate('Allow to fully manage access-control') - ], - $helper->filterName('config/access-control/users') => [ - 'name' => 'config/access-control/users', - 'description' => $this->translate('Allow to manage user accounts') - ], - $helper->filterName('config/access-control/groups') => [ - 'name' => 'config/access-control/groups', - 'description' => $this->translate('Allow to manage user groups') - ], - $helper->filterName('config/access-control/roles') => [ - 'name' => 'config/access-control/roles', - 'description' => $this->translate('Allow to manage roles') - ], - $helper->filterName('user/*') => [ - 'name' => 'user/*', - 'description' => $this->translate('Allow all account related functionalities') - ], - $helper->filterName('user/password-change') => [ - 'name' => 'user/password-change', - 'description' => $this->translate('Allow password changes in the account preferences') - ], - $helper->filterName('user/application/stacktraces') => [ - 'name' => 'user/application/stacktraces', - 'description' => $this->translate( - 'Allow to adjust in the preferences whether to show stacktraces' - ) - ], - $helper->filterName('user/share/navigation') => [ - 'name' => 'user/share/navigation', - 'description' => $this->translate('Allow to share navigation items') - ] - ]; - - $this->providedRestrictions['application'] = [ - $helper->filterName('application/share/users') => [ - 'name' => 'application/share/users', - 'description' => $this->translate( - 'Restrict which users this role can share items and information with' - ) - ], - $helper->filterName('application/share/groups') => [ - 'name' => 'application/share/groups', - 'description' => $this->translate( - 'Restrict which groups this role can share items and information with' - ) - ] - ]; - - $mm = Icinga::app()->getModuleManager(); - foreach ($mm->listInstalledModules() as $moduleName) { - $modulePermission = Manager::MODULE_PERMISSION_NS . $moduleName; - $this->providedPermissions[$moduleName][$helper->filterName($modulePermission)] = [ - 'isUsagePerm' => true, - 'name' => $modulePermission, - 'label' => $view->escape($this->translate('General Module Access')), - 'description' => sprintf($this->translate('Allow access to module %s'), $moduleName) - ]; - - $module = $mm->getModule($moduleName, false); - $permissions = $module->getProvidedPermissions(); - - $this->providedPermissions[$moduleName][$helper->filterName($moduleName . '/*')] = [ - 'isFullPerm' => true, - 'name' => $moduleName . '/*', - 'label' => $view->escape($this->translate('Full Module Access')) - ]; - - foreach ($permissions as $permission) { - /** @var object $permission */ - $this->providedPermissions[$moduleName][$helper->filterName($permission->name)] = [ - 'name' => $permission->name, - 'label' => preg_replace( - '~^(\w+)(\/.*)~', - '$1$2', - $view->escape($permission->name) - ), - 'description' => $permission->description - ]; - } - - foreach ($module->getProvidedRestrictions() as $restriction) { - $this->providedRestrictions[$moduleName][$helper->filterName($restriction->name)] = [ - 'name' => $restriction->name, - 'label' => preg_replace( - '~^(\w+)(\/.*)~', - '$1$2', - $view->escape($restriction->name) - ), - 'description' => $restriction->description - ]; - } - } + list($this->providedPermissions, $this->providedRestrictions) = static::collectProvidedPrivileges(); } protected function createFilter() @@ -273,14 +146,14 @@ class RoleForm extends RepositoryForm $hasFullPerm = false; foreach ($permissionList as $name => $spec) { - $elementName = $name; + $elementName = $this->filterName($name); if ($hasFullPerm || $hasAdminPerm) { $elementName .= '_fake'; } $denyCheckbox = null; if (! isset($spec['isFullPerm']) - && substr($spec['name'], 0, strlen(self::DENY_PREFIX)) !== self::DENY_PREFIX + && substr($name, 0, strlen(self::DENY_PREFIX)) !== self::DENY_PREFIX ) { $denyCheckbox = $this->createElement('checkbox', self::DENY_PREFIX . $name, [ 'decorators' => ['ViewHelper'] @@ -302,9 +175,13 @@ class RoleForm extends RepositoryForm // Adds a zero-width char after each slash to help browsers break onto newlines '~(?$1$2', + $name + ) ), - 'description' => isset($spec['description']) ? $spec['description'] : $spec['name'], + 'description' => isset($spec['description']) ? $spec['description'] : $name, 'decorators' => array_merge( array_slice(self::$defaultElementDecorators, 0, 3), [['Callback', ['callback' => function () use ($denyCheckbox) { @@ -320,11 +197,12 @@ class RoleForm extends RepositoryForm if ($hasFullPerm || $hasAdminPerm) { // Add a hidden element to preserve the configured permission value - $this->addElement('hidden', $name); + $this->addElement('hidden', $this->filterName($name)); } if (isset($spec['isFullPerm'])) { - $hasFullPerm = isset($formData[$name]) && $formData[$name]; + $filteredName = $this->filterName($name); + $hasFullPerm = isset($formData[$filteredName]) && $formData[$filteredName]; } } @@ -336,23 +214,28 @@ class RoleForm extends RepositoryForm ]); foreach ($this->providedRestrictions[$moduleName] as $name => $spec) { - $elements[] = $name; + $elementName = $this->filterName($name); + $elements[] = $elementName; $this->addElement( 'text', - $name, + $elementName, [ 'label' => preg_replace( // Adds a zero-width char after each slash to help browsers break onto newlines '~(?$1$2', + $name + ) ), 'description' => $spec['description'], 'style' => $isUnrestricted ? 'text-decoration:line-through;' : '', 'readonly' => $isUnrestricted ?: null ] ) - ->getElement($name) + ->getElement($elementName) ->getDecorator('Label') ->setOption('escape', false); } @@ -402,11 +285,11 @@ class RoleForm extends RepositoryForm foreach ($this->providedPermissions as $moduleName => $permissionList) { foreach ($permissionList as $name => $spec) { - if (in_array($spec['name'], $permissions, true)) { - $values[$name] = 1; + if (in_array($name, $permissions, true)) { + $values[$this->filterName($name)] = 1; } - if (in_array($spec['name'], $refusals, true)) { + if (in_array($name, $refusals, true)) { $values[$this->filterName(self::DENY_PREFIX . $name)] = 1; } } @@ -415,8 +298,8 @@ class RoleForm extends RepositoryForm foreach ($this->providedRestrictions as $moduleName => $restrictionList) { foreach ($restrictionList as $name => $spec) { - if (isset($role->{$spec['name']})) { - $values[$name] = $role->{$spec['name']}; + if (isset($role->$name)) { + $values[$this->filterName($name)] = $role->$name; } } } @@ -430,9 +313,10 @@ class RoleForm extends RepositoryForm foreach ($this->providedRestrictions as $moduleName => $restrictionList) { foreach ($restrictionList as $name => $spec) { - if (isset($values[$name])) { - $values[$spec['name']] = $values[$name]; - unset($values[$name]); + $elementName = $this->filterName($name); + if (isset($values[$elementName])) { + $values[$name] = $values[$elementName]; + unset($values[$elementName]); } } } @@ -445,16 +329,17 @@ class RoleForm extends RepositoryForm $refusals = []; foreach ($this->providedPermissions as $moduleName => $permissionList) { foreach ($permissionList as $name => $spec) { - if (isset($values[$name]) && $values[$name]) { - $permissions[] = $spec['name']; + $elementName = $this->filterName($name); + if (isset($values[$elementName]) && $values[$elementName]) { + $permissions[] = $name; } $denyName = $this->filterName(self::DENY_PREFIX . $name); if (isset($values[$denyName]) && $values[$denyName]) { - $refusals[] = $spec['name']; + $refusals[] = $name; } - unset($values[$name], $values[$denyName]); + unset($values[$elementName], $values[$denyName]); } } @@ -481,15 +366,15 @@ class RoleForm extends RepositoryForm protected function sortPermissions(&$permissions) { - return uasort($permissions, function ($a, $b) { - if (isset($a['isUsagePerm'])) { - return isset($b['isFullPerm']) ? 1 : -1; - } elseif (isset($b['isUsagePerm'])) { - return isset($a['isFullPerm']) ? -1 : 1; + return uksort($permissions, function ($a, $b) use ($permissions) { + if (isset($permissions[$a]['isUsagePerm'])) { + return isset($permissions[$b]['isFullPerm']) ? 1 : -1; + } elseif (isset($permissions[$b]['isUsagePerm'])) { + return isset($permissions[$a]['isFullPerm']) ? -1 : 1; } - $aParts = explode('/', $a['name']); - $bParts = explode('/', $b['name']); + $aParts = explode('/', $a); + $bParts = explode('/', $b); do { $a = array_shift($aParts); @@ -566,4 +451,102 @@ class RoleForm extends RepositoryForm )); } } + + /** + * Collect permissions and restrictions provided by Icinga Web 2 and modules + * + * @return array[$permissions, $restrictions] + */ + public static function collectProvidedPrivileges() + { + $providedPermissions['application'] = [ + 'application/announcements' => [ + 'description' => t('Allow to manage announcements') + ], + 'application/log' => [ + 'description' => t('Allow to view the application log') + ], + 'config/*' => [ + 'description' => t('Allow full config access') + ], + 'config/general' => [ + 'description' => t('Allow to adjust the general configuration') + ], + 'config/modules' => [ + 'description' => t('Allow to enable/disable and configure modules') + ], + 'config/resources' => [ + 'description' => t('Allow to manage resources') + ], + 'config/navigation' => [ + 'description' => t('Allow to view and adjust shared navigation items') + ], + 'config/access-control/*' => [ + 'description' => t('Allow to fully manage access-control') + ], + 'config/access-control/users' => [ + 'description' => t('Allow to manage user accounts') + ], + 'config/access-control/groups' => [ + 'description' => t('Allow to manage user groups') + ], + 'config/access-control/roles' => [ + 'description' => t('Allow to manage roles') + ], + 'user/*' => [ + 'description' => t('Allow all account related functionalities') + ], + 'user/password-change' => [ + 'description' => t('Allow password changes in the account preferences') + ], + 'user/application/stacktraces' => [ + 'description' => t('Allow to adjust in the preferences whether to show stacktraces') + ], + 'user/share/navigation' => [ + 'description' => t('Allow to share navigation items') + ] + ]; + + $providedRestrictions['application'] = [ + 'application/share/users' => [ + 'description' => t('Restrict which users this role can share items and information with') + ], + 'application/share/groups' => [ + 'description' => t('Restrict which groups this role can share items and information with') + ] + ]; + + $mm = Icinga::app()->getModuleManager(); + foreach ($mm->listInstalledModules() as $moduleName) { + $modulePermission = Manager::MODULE_PERMISSION_NS . $moduleName; + $providedPermissions[$moduleName][$modulePermission] = [ + 'isUsagePerm' => true, + 'label' => t('General Module Access'), + 'description' => sprintf(t('Allow access to module %s'), $moduleName) + ]; + + $module = $mm->getModule($moduleName, false); + $permissions = $module->getProvidedPermissions(); + + $providedPermissions[$moduleName][$moduleName . '/*'] = [ + 'isFullPerm' => true, + 'label' => t('Full Module Access') + ]; + + foreach ($permissions as $permission) { + /** @var object $permission */ + $providedPermissions[$moduleName][$permission->name] = [ + 'description' => $permission->description + ]; + } + + foreach ($module->getProvidedRestrictions() as $restriction) { + $providedRestrictions[$moduleName][$restriction->name] = [ + 'description' => $restriction->description + ]; + } + } + + return [$providedPermissions, $providedRestrictions]; + } }