diff --git a/application/controllers/ConfigController.php b/application/controllers/ConfigController.php index 148cbaa05..491a33ef3 100644 --- a/application/controllers/ConfigController.php +++ b/application/controllers/ConfigController.php @@ -37,7 +37,7 @@ class ConfigController extends ActionController $tabs = $this->getTabs(); $auth = $this->Auth(); $allowedActions = array(); - if ($auth->hasPermission('system/config/application')) { + if ($auth->hasPermission('config/application/general')) { $tabs->add('application', array( 'title' => $this->translate('Adjust the general configuration of Icinga Web 2'), 'label' => $this->translate('Application'), @@ -45,7 +45,7 @@ class ConfigController extends ActionController )); $allowedActions[] = 'application'; } - if ($auth->hasPermission('system/config/authentication')) { + if ($auth->hasPermission('config/application/authentication')) { $tabs->add('authentication', array( 'title' => $this->translate('Configure how users authenticate with and log into Icinga Web 2'), 'label' => $this->translate('Authentication'), @@ -53,7 +53,7 @@ class ConfigController extends ActionController )); $allowedActions[] = 'authentication'; } - if ($auth->hasPermission('system/config/resources')) { + if ($auth->hasPermission('config/application/resources')) { $tabs->add('resource', array( 'title' => $this->translate('Configure which resources are being utilized by Icinga Web 2'), 'label' => $this->translate('Resources'), @@ -61,7 +61,7 @@ class ConfigController extends ActionController )); $allowedActions[] = 'resource'; } - if ($auth->hasPermission('system/config/roles')) { + if ($auth->hasPermission('config/application/roles')) { $tabs->add('roles', array( 'title' => $this->translate( 'Configure roles to permit or restrict users and groups accessing Icinga Web 2' @@ -102,7 +102,7 @@ class ConfigController extends ActionController */ public function applicationAction() { - $this->assertPermission('system/config/application'); + $this->assertPermission('config/application/general'); $form = new GeneralConfigForm(); $form->setIniConfig(Config::app()); $form->handleRequest(); @@ -158,7 +158,7 @@ class ConfigController extends ActionController */ public function moduleenableAction() { - $this->assertPermission('system/config/modules'); + $this->assertPermission('config/modules'); $module = $this->getParam('name'); $manager = Icinga::app()->getModuleManager(); try { @@ -178,7 +178,7 @@ class ConfigController extends ActionController */ public function moduledisableAction() { - $this->assertPermission('system/config/modules'); + $this->assertPermission('config/modules'); $module = $this->getParam('name'); $manager = Icinga::app()->getModuleManager(); try { @@ -198,7 +198,7 @@ class ConfigController extends ActionController */ public function authenticationAction() { - $this->assertPermission('system/config/authentication'); + $this->assertPermission('config/application/authentication'); $form = new AuthenticationBackendReorderForm(); $form->setIniConfig(Config::app('authentication')); $form->handleRequest(); @@ -213,7 +213,7 @@ class ConfigController extends ActionController */ public function createauthenticationbackendAction() { - $this->assertPermission('system/config/authentication'); + $this->assertPermission('config/application/authentication'); $form = new AuthenticationBackendConfigForm(); $form->setTitle($this->translate('Create New Authentication Backend')); $form->addDescription($this->translate( @@ -235,7 +235,7 @@ class ConfigController extends ActionController */ public function editauthenticationbackendAction() { - $this->assertPermission('system/config/authentication'); + $this->assertPermission('config/application/authentication'); $form = new AuthenticationBackendConfigForm(); $form->setTitle($this->translate('Edit Backend')); $form->setIniConfig(Config::app('authentication')); @@ -253,7 +253,7 @@ class ConfigController extends ActionController */ public function removeauthenticationbackendAction() { - $this->assertPermission('system/config/authentication'); + $this->assertPermission('config/application/authentication'); $form = new ConfirmRemovalForm(array( 'onSuccess' => function ($form) { $configForm = new AuthenticationBackendConfigForm(); @@ -291,7 +291,7 @@ class ConfigController extends ActionController */ public function resourceAction() { - $this->assertPermission('system/config/resources'); + $this->assertPermission('config/application/resources'); $this->view->resources = Config::app('resources', true)->keys(); $this->view->tabs->activate('resource'); } @@ -301,7 +301,7 @@ class ConfigController extends ActionController */ public function createresourceAction() { - $this->assertPermission('system/config/resources'); + $this->assertPermission('config/application/resources'); $form = new ResourceConfigForm(); $form->setTitle($this->translate('Create A New Resource')); $form->addDescription($this->translate('Resources are entities that provide data to Icinga Web 2.')); @@ -318,7 +318,7 @@ class ConfigController extends ActionController */ public function editresourceAction() { - $this->assertPermission('system/config/resources'); + $this->assertPermission('config/application/resources'); $form = new ResourceConfigForm(); $form->setTitle($this->translate('Edit Existing Resource')); $form->setIniConfig(Config::app('resources')); @@ -334,7 +334,7 @@ class ConfigController extends ActionController */ public function removeresourceAction() { - $this->assertPermission('system/config/resources'); + $this->assertPermission('config/application/resources'); $form = new ConfirmRemovalForm(array( 'onSuccess' => function ($form) { $configForm = new ResourceConfigForm(); diff --git a/application/controllers/RolesController.php b/application/controllers/RolesController.php index bff5f70a1..d4b7b7c63 100644 --- a/application/controllers/RolesController.php +++ b/application/controllers/RolesController.php @@ -20,24 +20,24 @@ class RolesController extends ActionController */ public function init() { - $this->assertPermission('system/config/roles'); + $this->assertPermission('config/application/roles'); $tabs = $this->getTabs(); $auth = $this->Auth(); - if ($auth->hasPermission('system/config/application')) { + if ($auth->hasPermission('config/application/general')) { $tabs->add('application', array( 'title' => $this->translate('Adjust the general configuration of Icinga Web 2'), 'label' => $this->translate('Application'), 'url' => 'config' )); } - if ($auth->hasPermission('system/config/authentication')) { + if ($auth->hasPermission('config/application/authentication')) { $tabs->add('authentication', array( 'title' => $this->translate('Configure how users authenticate with and log into Icinga Web 2'), 'label' => $this->translate('Authentication'), 'url' => 'config/authentication' )); } - if ($auth->hasPermission('system/config/resources')) { + if ($auth->hasPermission('config/application/resources')) { $tabs->add('resource', array( 'title' => $this->translate('Configure which resources are being utilized by Icinga Web 2'), 'label' => $this->translate('Resources'), diff --git a/application/forms/Security/RoleForm.php b/application/forms/Security/RoleForm.php index 4b42cd88c..07b09ce17 100644 --- a/application/forms/Security/RoleForm.php +++ b/application/forms/Security/RoleForm.php @@ -21,13 +21,14 @@ class RoleForm extends ConfigForm * @var array */ protected $providedPermissions = array( - '*' => '*', - 'system/config/*' => 'system/config/*', - 'system/config/application' => 'system/config/application', - 'system/config/authentication' => 'system/config/authentication', - 'system/config/modules' => 'system/config/modules', - 'system/config/resources' => 'system/config/resources', - 'system/config/roles' => 'system/config/roles' + '*' => '*', + 'config/*' => 'config/*', + 'config/application/*' => 'config/application/*', + 'config/application/general' => 'config/application/general', + 'config/application/authentication' => 'config/application/authentication', + 'config/application/resources' => 'config/application/resources', + 'config/application/roles' => 'config/application/roles', + 'config/modules' => 'config/modules' ); /** @@ -38,8 +39,7 @@ class RoleForm extends ConfigForm protected $providedRestrictions = array(); /** - * (non-PHPDoc) - * @see \Icinga\Web\Form::init() For the method documentation. + * {@inheritdoc} */ public function init() { @@ -68,8 +68,7 @@ class RoleForm extends ConfigForm } /** - * (non-PHPDoc) - * @see \Icinga\Web\Form::createElements() For the method documentation. + * {@inheritdoc} */ public function createElements(array $formData = array()) { @@ -253,8 +252,7 @@ class RoleForm extends ConfigForm } /** - * (non-PHPDoc) - * @see \Zend_Form::getValues() For the method documentation. + * {@inheritdoc} */ public function getValues($suppressArrayNotation = false) { diff --git a/library/Icinga/User.php b/library/Icinga/User.php index 3bf0d0aa2..18d44af96 100644 --- a/library/Icinga/User.php +++ b/library/Icinga/User.php @@ -422,8 +422,16 @@ class User if (isset($this->permissions['*']) || isset($this->permissions[$permission])) { return true; } + // If the permission to check contains a wildcard, grant the permission if any permit related to the permission + // matches + $any = strpos($permission, '*'); foreach ($this->permissions as $permitted) { - $wildcard = strpos($permitted, '*'); + if ($any !== false) { + $wildcard = $any; + } else { + // If the permit contains a wildcard, grant the permission if it's related to the permit + $wildcard = strpos($permitted, '*'); + } if ($wildcard !== false) { if (substr($permission, 0, $wildcard) === substr($permitted, 0, $wildcard)) { return true; diff --git a/library/Icinga/Web/Menu.php b/library/Icinga/Web/Menu.php index 92ec20607..a4bf59605 100644 --- a/library/Icinga/Web/Menu.php +++ b/library/Icinga/Web/Menu.php @@ -75,6 +75,17 @@ class Menu implements RecursiveIterator */ protected $parent; + /** + * Permission a user is required to have granted to display the menu item + * + * If a permission is set, authentication is of course required. + * + * Note that only one required permission can be set yet. + * + * @var string|null + */ + protected $permission; + /** * Create a new menu * @@ -221,12 +232,14 @@ class Menu implements RecursiveIterator 'priority' => 200 )); $section->add(t('Configuration'), array( - 'url' => 'config', - 'priority' => 300 + 'url' => 'config', + 'permission' => 'config/application/*', + 'priority' => 300 )); $section->add(t('Modules'), array( - 'url' => 'config/modules', - 'priority' => 400 + 'url' => 'config/modules', + 'permission' => 'config/modules', + 'priority' => 400 )); if (Logger::writesToFile()) { @@ -442,15 +455,27 @@ class Menu implements RecursiveIterator } /** - * Set required Permissions + * Get the permission a user is required to have granted to display the menu item * - * @param $permission + * @return string|null + */ + public function getPermission() + { + return $this->permission; + } + + /** + * Set permission a user is required to have granted to display the menu item + * + * If a permission is set, authentication is of course required. + * + * @param string $permission * * @return $this */ - public function requirePermission($permission) + public function setPermission($permission) { - // Not implemented yet + $this->permission = (string) $permission; return $this; } diff --git a/library/Icinga/Web/Menu/PermittedMenuItemFilter.php b/library/Icinga/Web/Menu/PermittedMenuItemFilter.php new file mode 100644 index 000000000..7224c3589 --- /dev/null +++ b/library/Icinga/Web/Menu/PermittedMenuItemFilter.php @@ -0,0 +1,33 @@ +current(); + /** @var Menu $item */ + if (($permission = $item->getPermission()) !== null) { + $auth = Manager::getInstance(); + if (! $auth->isAuthenticated()) { + // Don't accept menu item because user is not authenticated and the menu item requires a permission + return false; + } + if (! $auth->getUser()->can($permission)) { + return false; + } + } + // Accept menu item if it does not require a permission + return true; + } +} diff --git a/library/Icinga/Web/MenuRenderer.php b/library/Icinga/Web/MenuRenderer.php index 78e910f61..7d2cd5ad3 100644 --- a/library/Icinga/Web/MenuRenderer.php +++ b/library/Icinga/Web/MenuRenderer.php @@ -6,6 +6,7 @@ namespace Icinga\Web; use Exception; use RecursiveIteratorIterator; use Icinga\Application\Logger; +use Icinga\Web\Menu\PermittedMenuItemFilter; /** * A renderer to draw a menu with its sub-menus using an unordered html list @@ -44,7 +45,7 @@ class MenuRenderer extends RecursiveIteratorIterator } else { $this->url = Url::fromPath($url); } - parent::__construct($menu, RecursiveIteratorIterator::CHILD_FIRST); + parent::__construct(new PermittedMenuItemFilter($menu), RecursiveIteratorIterator::CHILD_FIRST); } /**