Merge branch 'feature/protected-menu-8720'

resolves #8720
This commit is contained in:
Eric Lippmann 2015-03-13 04:26:19 +01:00
commit e36c430bb3
7 changed files with 107 additions and 42 deletions

View File

@ -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();

View File

@ -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'),

View File

@ -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)
{

View File

@ -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;

View File

@ -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;
}

View File

@ -0,0 +1,33 @@
<?php
namespace Icinga\Web\Menu;
use RecursiveFilterIterator;
use Icinga\Authentication\Manager;
use Icinga\Web\Menu;
class PermittedMenuItemFilter extends RecursiveFilterIterator
{
/**
* Accept menu items that are permitted to the user
*
* @return bool Whether the user has the required permission granted to display the menu item
*/
public function accept()
{
$item = $this->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;
}
}

View File

@ -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);
}
/**