Adjust global permissions

This commit is contained in:
Johannes Meyer 2021-02-18 08:52:57 +01:00
parent 429a70f05f
commit cc65164a67
23 changed files with 345 additions and 172 deletions

View File

@ -43,7 +43,7 @@ class AccountController extends Controller
$config = Config::app()->getSection('global');
$user = $this->Auth()->getUser();
if ($user->getAdditional('backend_type') === 'db') {
if ($user->can('*') || ! $user->can('no-user/password-change')) {
if ($user->can('user/password-change')) {
try {
$userBackend = UserBackend::create($user->getAdditional('backend_name'));
} catch (ConfigurationError $e) {

View File

@ -61,7 +61,7 @@ class AnnouncementsController extends Controller
*/
public function newAction()
{
$this->assertPermission('admin');
$this->assertPermission('application/announcements');
$form = $this->prepareForm()->add();
$form->handleRequest();
@ -73,7 +73,7 @@ class AnnouncementsController extends Controller
*/
public function updateAction()
{
$this->assertPermission('admin');
$this->assertPermission('application/announcements');
$form = $this->prepareForm()->edit($this->params->getRequired('id'));
try {
@ -89,7 +89,7 @@ class AnnouncementsController extends Controller
*/
public function removeAction()
{
$this->assertPermission('admin');
$this->assertPermission('application/announcements');
$form = $this->prepareForm()->remove($this->params->getRequired('id'));
try {

View File

@ -35,24 +35,33 @@ class ConfigController extends Controller
public function createApplicationTabs()
{
$tabs = $this->getTabs();
$tabs->add('general', array(
'title' => $this->translate('Adjust the general configuration of Icinga Web 2'),
'label' => $this->translate('General'),
'url' => 'config/general',
'baseTarget' => '_main'
));
$tabs->add('resource', array(
'title' => $this->translate('Configure which resources are being utilized by Icinga Web 2'),
'label' => $this->translate('Resources'),
'url' => 'config/resource',
'baseTarget' => '_main'
));
$tabs->add('authentication', array(
'title' => $this->translate('Configure the user and group backends'),
'label' => $this->translate('Authentication'),
'url' => 'config/userbackend',
'baseTarget' => '_main'
));
if ($this->hasPermission('config/general')) {
$tabs->add('general', array(
'title' => $this->translate('Adjust the general configuration of Icinga Web 2'),
'label' => $this->translate('General'),
'url' => 'config/general',
'baseTarget' => '_main'
));
}
if ($this->hasPermission('config/resources')) {
$tabs->add('resource', array(
'title' => $this->translate('Configure which resources are being utilized by Icinga Web 2'),
'label' => $this->translate('Resources'),
'url' => 'config/resource',
'baseTarget' => '_main'
));
}
if ($this->hasPermission('config/access-control/users')
|| $this->hasPermission('config/access-control/groups')
) {
$tabs->add('authentication', array(
'title' => $this->translate('Configure the user and group backends'),
'label' => $this->translate('Access Control Backends'),
'url' => 'config/userbackend',
'baseTarget' => '_main'
));
}
return $tabs;
}
@ -66,7 +75,15 @@ class ConfigController extends Controller
*/
public function indexAction()
{
$this->redirectNow('config/general');
if ($this->hasPermission('config/general')) {
$this->redirectNow('config/general');
} elseif ($this->hasPermission('config/resources')) {
$this->redirectNow('config/resource');
} elseif ($this->hasPermission('config/access-control/*')) {
$this->redirectNow('config/userbackend');
} else {
throw new SecurityException('No permission to configure Icinga Web 2');
}
}
/**
@ -76,7 +93,7 @@ class ConfigController extends Controller
*/
public function generalAction()
{
$this->assertPermission('config/application/general');
$this->assertPermission('config/general');
$form = new GeneralConfigForm();
$form->setIniConfig(Config::app());
$form->handleRequest();
@ -207,14 +224,17 @@ class ConfigController extends Controller
*/
public function userbackendAction()
{
$this->assertPermission('config/application/userbackend');
$this->assertPermission('config/application/usergroupbackend');
$form = new UserBackendReorderForm();
$form->setIniConfig(Config::app('authentication'));
$form->handleRequest();
if ($this->hasPermission('config/access-control/users')) {
$form = new UserBackendReorderForm();
$form->setIniConfig(Config::app('authentication'));
$form->handleRequest();
$this->view->form = $form;
}
if ($this->hasPermission('config/access-control/groups')) {
$this->view->backendNames = Config::app('groups');
}
$this->view->form = $form;
$this->view->backendNames = Config::app('groups');
$this->createApplicationTabs()->activate('authentication');
$this->view->title = $this->translate('Authentication');
$this->render('userbackend/reorder');
@ -225,7 +245,7 @@ class ConfigController extends Controller
*/
public function createuserbackendAction()
{
$this->assertPermission('config/application/userbackend');
$this->assertPermission('config/access-control/users');
$form = new UserBackendConfigForm();
$form
->setRedirectUrl('config/userbackend')
@ -238,7 +258,7 @@ class ConfigController extends Controller
try {
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
} catch (ConfigurationError $e) {
if ($this->hasPermission('config/application/resources')) {
if ($this->hasPermission('config/resources')) {
Notification::error($e->getMessage());
$this->redirectNow('config/createresource');
}
@ -272,7 +292,7 @@ class ConfigController extends Controller
*/
public function edituserbackendAction()
{
$this->assertPermission('config/application/userbackend');
$this->assertPermission('config/access-control/users');
$backendName = $this->params->getRequired('backend');
$form = new UserBackendConfigForm();
@ -311,7 +331,7 @@ class ConfigController extends Controller
*/
public function removeuserbackendAction()
{
$this->assertPermission('config/application/userbackend');
$this->assertPermission('config/access-control/users');
$backendName = $this->params->getRequired('backend');
$backendForm = new UserBackendConfigForm();
@ -344,7 +364,7 @@ class ConfigController extends Controller
*/
public function resourceAction()
{
$this->assertPermission('config/application/resources');
$this->assertPermission('config/resources');
$this->view->resources = Config::app('resources', true)->getConfigObject()
->setKeyColumn('name')
->select()
@ -358,7 +378,7 @@ class ConfigController extends Controller
*/
public function createresourceAction()
{
$this->assertPermission('config/application/resources');
$this->assertPermission('config/resources');
$this->getTabs()->add('resources/new', array(
'label' => $this->translate('New Resource'),
'url' => Url::fromRequest()
@ -379,7 +399,7 @@ class ConfigController extends Controller
*/
public function editresourceAction()
{
$this->assertPermission('config/application/resources');
$this->assertPermission('config/resources');
$this->getTabs()->add('resources/update', array(
'label' => $this->translate('Update Resource'),
'url' => Url::fromRequest()
@ -399,7 +419,7 @@ class ConfigController extends Controller
*/
public function removeresourceAction()
{
$this->assertPermission('config/application/resources');
$this->assertPermission('config/resources');
$this->getTabs()->add('resources/remove', array(
'label' => $this->translate('Remove Resource'),
'url' => Url::fromRequest()

View File

@ -33,7 +33,7 @@ class GroupController extends AuthBackendController
*/
public function listAction()
{
$this->assertPermission('config/authentication/groups/show');
$this->assertPermission('config/access-control/groups');
$this->createListTabs()->activate('group/list');
$backendNames = array_map(
function ($b) {
@ -90,7 +90,7 @@ class GroupController extends AuthBackendController
*/
public function showAction()
{
$this->assertPermission('config/authentication/groups/show');
$this->assertPermission('config/access-control/groups');
$groupName = $this->params->getRequired('group');
$backend = $this->getUserGroupBackend($this->params->getRequired('backend'));
@ -125,7 +125,7 @@ class GroupController extends AuthBackendController
$this->view->members = $members;
$this->createShowTabs($backend->getName(), $groupName)->activate('group/show');
if ($this->hasPermission('config/authentication/groups/edit') && $backend instanceof Reducible) {
if ($this->hasPermission('config/access-control/groups') && $backend instanceof Reducible) {
$removeForm = new Form();
$removeForm->setUidDisabled();
$removeForm->setAttrib('class', 'inline');
@ -161,7 +161,7 @@ class GroupController extends AuthBackendController
*/
public function addAction()
{
$this->assertPermission('config/authentication/groups/add');
$this->assertPermission('config/access-control/groups');
$backend = $this->getUserGroupBackend($this->params->getRequired('backend'), 'Icinga\Data\Extensible');
$form = new UserGroupForm();
$form->setRedirectUrl(Url::fromPath('group/list', array('backend' => $backend->getName())));
@ -176,7 +176,7 @@ class GroupController extends AuthBackendController
*/
public function editAction()
{
$this->assertPermission('config/authentication/groups/edit');
$this->assertPermission('config/access-control/groups');
$groupName = $this->params->getRequired('group');
$backend = $this->getUserGroupBackend($this->params->getRequired('backend'), 'Icinga\Data\Updatable');
@ -200,7 +200,7 @@ class GroupController extends AuthBackendController
*/
public function removeAction()
{
$this->assertPermission('config/authentication/groups/remove');
$this->assertPermission('config/access-control/groups');
$groupName = $this->params->getRequired('group');
$backend = $this->getUserGroupBackend($this->params->getRequired('backend'), 'Icinga\Data\Reducible');
@ -222,7 +222,7 @@ class GroupController extends AuthBackendController
*/
public function addmemberAction()
{
$this->assertPermission('config/authentication/groups/edit');
$this->assertPermission('config/access-control/groups');
$groupName = $this->params->getRequired('group');
$backend = $this->getUserGroupBackend($this->params->getRequired('backend'), 'Icinga\Data\Extensible');
@ -249,7 +249,7 @@ class GroupController extends AuthBackendController
*/
public function removememberAction()
{
$this->assertPermission('config/authentication/groups/edit');
$this->assertPermission('config/access-control/groups');
$this->assertHttpMethod('POST');
$groupName = $this->params->getRequired('group');
$backend = $this->getUserGroupBackend($this->params->getRequired('backend'), 'Icinga\Data\Reducible');
@ -368,26 +368,32 @@ class GroupController extends AuthBackendController
protected function createListTabs()
{
$tabs = $this->getTabs();
$tabs->add(
'role/list',
array(
'baseTarget' => '_main',
'label' => $this->translate('Roles'),
'title' => $this->translate(
'Configure roles to permit or restrict users and groups accessing Icinga Web 2'
),
'url' => 'role/list'
)
);
$tabs->add(
'user/list',
array(
'title' => $this->translate('List users of authentication backends'),
'label' => $this->translate('Users'),
'url' => 'user/list'
)
);
if ($this->hasPermission('config/access-control/roles')) {
$tabs->add(
'role/list',
array(
'baseTarget' => '_main',
'label' => $this->translate('Roles'),
'title' => $this->translate(
'Configure roles to permit or restrict users and groups accessing Icinga Web 2'
),
'url' => 'role/list'
)
);
}
if ($this->hasPermission('config/access-control/users')) {
$tabs->add(
'user/list',
array(
'title' => $this->translate('List users of authentication backends'),
'label' => $this->translate('Users'),
'url' => 'user/list'
)
);
}
$tabs->add(
'group/list',
array(
@ -396,6 +402,7 @@ class GroupController extends AuthBackendController
'url' => 'group/list'
)
);
return $tabs;
}
}

View File

@ -161,7 +161,7 @@ class NavigationController extends Controller
*/
public function sharedAction()
{
$this->assertPermission('config/application/navigation');
$this->assertPermission('config/navigation');
$ds = new ArrayDatasource($this->fetchSharedNavigationItemConfigs());
$query = $ds->select();
@ -259,7 +259,7 @@ class NavigationController extends Controller
$referrer = $this->params->get('referrer', 'index');
$user = $this->Auth()->getUser();
if ($user->can('config/application/navigation')) {
if ($user->can('config/navigation')) {
$itemOwner = $this->params->get('owner', $user->getUsername());
} else {
$itemOwner = $user->getUsername();
@ -354,7 +354,7 @@ class NavigationController extends Controller
*/
public function unshareAction()
{
$this->assertPermission('config/application/navigation');
$this->assertPermission('config/navigation');
$this->assertHttpMethod('POST');
// TODO: I'd like these being form fields

View File

@ -6,6 +6,7 @@ namespace Icinga\Controllers;
use Icinga\Authentication\RolesConfig;
use Icinga\Exception\NotFoundError;
use Icinga\Forms\Security\RoleForm;
use Icinga\Security\SecurityException;
use Icinga\Web\Controller\AuthBackendController;
/**
@ -22,6 +23,19 @@ class RoleController extends AuthBackendController
parent::init();
}
public function indexAction()
{
if ($this->hasPermission('config/access-control/roles')) {
$this->redirectNow('role/list');
} elseif ($this->hasPermission('config/access-control/users')) {
$this->redirectNow('user/list');
} elseif ($this->hasPermission('config/access-control/groups')) {
$this->redirectNow('group/list');
} else {
throw new SecurityException('No permission to configure Icinga Web 2');
}
}
/**
* List roles
*
@ -29,7 +43,7 @@ class RoleController extends AuthBackendController
*/
public function listAction()
{
$this->assertPermission('config/authentication/roles/show');
$this->assertPermission('config/access-control/roles');
$this->createListTabs()->activate('role/list');
$this->view->roles = (new RolesConfig())
->select();
@ -54,7 +68,7 @@ class RoleController extends AuthBackendController
*/
public function addAction()
{
$this->assertPermission('config/authentication/roles/add');
$this->assertPermission('config/access-control/roles');
$role = new RoleForm();
$role->setRedirectUrl('role/list');
@ -72,7 +86,7 @@ class RoleController extends AuthBackendController
*/
public function editAction()
{
$this->assertPermission('config/authentication/roles/edit');
$this->assertPermission('config/access-control/roles');
$name = $this->params->getRequired('role');
$role = new RoleForm();
@ -95,7 +109,7 @@ class RoleController extends AuthBackendController
*/
public function removeAction()
{
$this->assertPermission('config/authentication/roles/remove');
$this->assertPermission('config/access-control/roles');
$name = $this->params->getRequired('role');
$role = new RoleForm();
@ -128,25 +142,31 @@ class RoleController extends AuthBackendController
'Configure roles to permit or restrict users and groups accessing Icinga Web 2'
),
'url' => 'role/list'
)
);
if ($this->hasPermission('config/access-control/users')) {
$tabs->add(
'user/list',
array(
'title' => $this->translate('List users of authentication backends'),
'label' => $this->translate('Users'),
'url' => 'user/list'
)
);
}
if ($this->hasPermission('config/access-control/groups')) {
$tabs->add(
'group/list',
array(
'title' => $this->translate('List groups of user group backends'),
'label' => $this->translate('User Groups'),
'url' => 'group/list'
)
);
}
)
);
$tabs->add(
'user/list',
array(
'title' => $this->translate('List users of authentication backends'),
'label' => $this->translate('Users'),
'url' => 'user/list'
)
);
$tabs->add(
'group/list',
array(
'title' => $this->translate('List groups of user group backends'),
'label' => $this->translate('User Groups'),
'url' => 'group/list'
)
);
return $tabs;
}
}

View File

@ -33,7 +33,7 @@ class UserController extends AuthBackendController
*/
public function listAction()
{
$this->assertPermission('config/authentication/users/show');
$this->assertPermission('config/access-control/users');
$this->createListTabs()->activate('user/list');
$backendNames = array_map(
function ($b) {
@ -91,7 +91,7 @@ class UserController extends AuthBackendController
*/
public function showAction()
{
$this->assertPermission('config/authentication/users/show');
$this->assertPermission('config/access-control/users');
$userName = $this->params->getRequired('user');
$backend = $this->getUserBackend($this->params->getRequired('backend'));
@ -127,7 +127,7 @@ class UserController extends AuthBackendController
$memberships
);
if ($this->hasPermission('config/authentication/groups/edit')) {
if ($this->hasPermission('config/access-control/groups')) {
$extensibleBackends = $this->loadUserGroupBackends('Icinga\Data\Extensible');
$this->view->showCreateMembershipLink = ! empty($extensibleBackends);
} else {
@ -139,7 +139,7 @@ class UserController extends AuthBackendController
$this->view->memberships = $memberships;
$this->createShowTabs($backend->getName(), $userName)->activate('user/show');
if ($this->hasPermission('config/authentication/groups/edit')) {
if ($this->hasPermission('config/access-control/groups')) {
$removeForm = new Form();
$removeForm->setUidDisabled();
$removeForm->setAttrib('class', 'inline');
@ -170,7 +170,7 @@ class UserController extends AuthBackendController
$admissionLoader = new AdmissionLoader();
$admissionLoader->applyRoles($userObj);
$this->view->userObj = $userObj;
$this->view->allowedToEditRoles = $this->hasPermission('config/authentication/roles/edit');
$this->view->allowedToEditRoles = $this->hasPermission('config/access-control/groups');
}
/**
@ -178,7 +178,7 @@ class UserController extends AuthBackendController
*/
public function addAction()
{
$this->assertPermission('config/authentication/users/add');
$this->assertPermission('config/access-control/users');
$backend = $this->getUserBackend($this->params->getRequired('backend'), 'Icinga\Data\Extensible');
$form = new UserForm();
$form->setRedirectUrl(Url::fromPath('user/list', array('backend' => $backend->getName())));
@ -193,7 +193,7 @@ class UserController extends AuthBackendController
*/
public function editAction()
{
$this->assertPermission('config/authentication/users/edit');
$this->assertPermission('config/access-control/users');
$userName = $this->params->getRequired('user');
$backend = $this->getUserBackend($this->params->getRequired('backend'), 'Icinga\Data\Updatable');
@ -215,7 +215,7 @@ class UserController extends AuthBackendController
*/
public function removeAction()
{
$this->assertPermission('config/authentication/users/remove');
$this->assertPermission('config/access-control/users');
$userName = $this->params->getRequired('user');
$backend = $this->getUserBackend($this->params->getRequired('backend'), 'Icinga\Data\Reducible');
@ -237,7 +237,7 @@ class UserController extends AuthBackendController
*/
public function createmembershipAction()
{
$this->assertPermission('config/authentication/groups/edit');
$this->assertPermission('config/access-control/groups');
$userName = $this->params->getRequired('user');
$backend = $this->getUserBackend($this->params->getRequired('backend'));
@ -325,18 +325,21 @@ class UserController extends AuthBackendController
protected function createListTabs()
{
$tabs = $this->getTabs();
$tabs->add(
'role/list',
array(
'baseTarget' => '_main',
'label' => $this->translate('Roles'),
'title' => $this->translate(
'Configure roles to permit or restrict users and groups accessing Icinga Web 2'
),
'url' => 'role/list'
)
);
if ($this->hasPermission('config/access-control/roles')) {
$tabs->add(
'role/list',
array(
'baseTarget' => '_main',
'label' => $this->translate('Roles'),
'title' => $this->translate(
'Configure roles to permit or restrict users and groups accessing Icinga Web 2'
),
'url' => 'role/list'
)
);
}
$tabs->add(
'user/list',
array(
@ -345,14 +348,18 @@ class UserController extends AuthBackendController
'url' => 'user/list'
)
);
$tabs->add(
'group/list',
array(
'title' => $this->translate('List groups of user group backends'),
'label' => $this->translate('User Groups'),
'url' => 'group/list'
)
);
if ($this->hasPermission('config/access-control/groups')) {
$tabs->add(
'group/list',
array(
'title' => $this->translate('List groups of user group backends'),
'label' => $this->translate('User Groups'),
'url' => 'group/list'
)
);
}
return $tabs;
}
}

View File

@ -21,7 +21,7 @@ class UsergroupbackendController extends Controller
*/
public function init()
{
$this->assertPermission('config/application/usergroupbackend');
$this->assertPermission('config/access-control/users');
}
/**

View File

@ -299,7 +299,7 @@ class NavigationConfigForm extends ConfigForm
$shared = false;
$config = $this->getUserConfig($data['type']);
if ((isset($data['users']) && $data['users']) || (isset($data['groups']) && $data['groups'])) {
if ($this->getUser()->can('application/share/navigation')) {
if ($this->getUser()->can('user/share/navigation')) {
$data['owner'] = $this->getUser()->getUsername();
$config = $this->getShareConfig($data['type']);
$shared = true;
@ -370,7 +370,7 @@ class NavigationConfigForm extends ConfigForm
$config = $this->unshare($name, isset($data['parent']) ? $data['parent'] : null);
}
} elseif ((isset($data['users']) && $data['users']) || (isset($data['groups']) && $data['groups'])) {
if ($this->getUser()->can('application/share/navigation')) {
if ($this->getUser()->can('user/share/navigation')) {
// It is not shared yet but should be
$this->secondaryConfig = $config;
$config = $this->getShareConfig();
@ -580,7 +580,7 @@ class NavigationConfigForm extends ConfigForm
);
if ((! $itemForm->requiresParentSelection() || ! isset($formData['parent']) || ! $formData['parent'])
&& $this->getUser()->can('application/share/navigation')
&& $this->getUser()->can('user/share/navigation')
) {
$checked = isset($formData['shared']) ? null : (isset($formData['users']) || isset($formData['groups']));
@ -783,7 +783,7 @@ class NavigationConfigForm extends ConfigForm
return $this->getUserConfig();
} elseif ($this->getShareConfig()->hasSection($name)) {
if ($this->getShareConfig()->get($name, 'owner') === $this->getUser()->getUsername()
|| $this->getUser()->can('config/application/navigation')
|| $this->getUser()->can('user/share/navigation')
) {
return $this->getShareConfig();
}

View File

@ -255,7 +255,7 @@ class PreferenceForm extends Form
)
);
if (Auth::getInstance()->hasPermission('application/stacktraces')) {
if (Auth::getInstance()->hasPermission('user/application/stacktraces')) {
$this->addElement(
'checkbox',
'show_stacktraces',

View File

@ -6,6 +6,7 @@ namespace Icinga\Forms\Security;
use Icinga\Application\Hook\ConfigFormEventsHook;
use Icinga\Application\Icinga;
use Icinga\Application\Modules\Manager;
use Icinga\Authentication\AdmissionLoader;
use Icinga\Data\Filter\Filter;
use Icinga\Forms\ConfigForm;
use Icinga\Forms\RepositoryForm;
@ -50,33 +51,67 @@ class RoleForm extends RepositoryForm
$view = $this->getView();
$this->providedPermissions['application'] = [
$helper->filterName('no-user/password-change') => [
'name' => 'no-user/password-change',
'description' => $this->translate('Prohibit password changes in the account preferences')
],
$helper->filterName('application/share/navigation') => [
'name' => 'application/share/navigation',
'description' => $this->translate('Allow to share navigation items')
],
$helper->filterName('application/stacktraces') => [
'name' => 'application/stacktraces',
'description' => $this->translate(
'Allow to adjust in the preferences whether to show stacktraces'
)
$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('admin') => [
'name' => 'admin',
'description' => $this->translate(
'Grant admin permissions, e.g. manage announcements'
)
],
$helper->filterName('config/*') => [
'name' => 'config/*',
'description' => $this->translate('Allow config access')
'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')
]
];
@ -359,6 +394,12 @@ class RoleForm extends RepositoryForm
if (! empty($role->permissions) || ! empty($role->refusals)) {
$permissions = StringHelper::trimSplit($role->permissions);
$refusals = StringHelper::trimSplit($role->refusals);
list($permissions, $newRefusals) = AdmissionLoader::migrateLegacyPermissions($permissions);
if (! empty($newRefusals)) {
array_push($refusals, ...$newRefusals);
}
foreach ($this->providedPermissions as $moduleName => $permissionList) {
foreach ($permissionList as $name => $spec) {
if (in_array($spec['name'], $permissions, true)) {

View File

@ -10,7 +10,7 @@
</div>
<?php endif ?>
<div class="content">
<?php if ($this->hasPermission('admin')) {
<?php if ($this->hasPermission('application/announcements')) {
echo $this->qlink(
$this->translate('Create a New Announcement') ,
'announcements/new',
@ -41,7 +41,7 @@
<?php foreach ($this->announcements as $announcement): /** @var object $announcement */ ?>
<tr>
<td><?= $this->escape($announcement->author) ?></td>
<?php if ($this->hasPermission('admin')): ?>
<?php if ($this->hasPermission('application/announcements')): ?>
<td>
<a href="<?= $this->href('announcements/update', array('id' => $announcement->id)) ?>">
<?= $this->ellipsis($this->escape($announcement->message), 100) ?>
@ -52,7 +52,7 @@
<?php endif ?>
<td><?= $this->formatDateTime($announcement->start) ?></td>
<td><?= $this->formatDateTime($announcement->end) ?></td>
<?php if ($this->hasPermission('admin')): ?>
<?php if ($this->hasPermission('application/announcements')): ?>
<td class="icon-col"><?= $this->qlink(
null,
'announcements/remove',

View File

@ -2,6 +2,7 @@
<?= $tabs ?>
</div>
<div class="content">
<?php if ($this->auth()->hasPermission('config/access-control/users')): ?>
<h1><?= $this->translate('User Backends') ?></h1>
<?= $this->qlink(
$this->translate('Create a New User Backend') ,
@ -15,7 +16,9 @@
)
) ?>
<?= $form ?>
<?php endif ?>
<?php if ($this->auth()->hasPermission('config/access-control/groups')): ?>
<h1><?= $this->translate('User Group Backends') ?></h1>
<?= $this->qlink(
$this->translate('Create a New User Group Backend') ,
@ -68,4 +71,5 @@
<?php endforeach ?>
</tbody>
</table>
<?php endif ?>
</div>

View File

@ -22,8 +22,8 @@ if (! isset($backend)) {
echo $this->translate('No backend found which is able to list user groups') . '</div>';
return;
} else {
$extensible = $this->hasPermission('config/authentication/groups/add') && $backend instanceof Extensible;
$reducible = $this->hasPermission('config/authentication/groups/remove') && $backend instanceof Reducible;
$extensible = $this->hasPermission('config/access-control/groups') && $backend instanceof Extensible;
$reducible = $this->hasPermission('config/access-control/groups') && $backend instanceof Reducible;
}
?>

View File

@ -3,10 +3,10 @@
use Icinga\Data\Extensible;
use Icinga\Data\Updatable;
$extensible = $this->hasPermission('config/authentication/groups/add') && $backend instanceof Extensible;
$extensible = $this->hasPermission('config/access-control/groups') && $backend instanceof Extensible;
$editLink = null;
if ($this->hasPermission('config/authentication/groups/edit') && $backend instanceof Updatable) {
if ($this->hasPermission('config/access-control/groups') && $backend instanceof Updatable) {
$editLink = $this->qlink(
null,
'group/edit',
@ -83,7 +83,7 @@ if ($this->hasPermission('config/authentication/groups/edit') && $backend instan
<tr>
<td>
<?php if (
$this->hasPermission('config/authentication/users/show')
$this->hasPermission('config/access-control/users')
&& ($userBackend = $backend->getUserBackendName($member->user_name)) !== null
): ?>
<?= $this->qlink($member->user_name, 'user/show', array(

View File

@ -22,8 +22,8 @@ if (! isset($backend)) {
echo $this->translate('No backend found which is able to list users') . '</div>';
return;
} else {
$extensible = $this->hasPermission('config/authentication/users/add') && $backend instanceof Extensible;
$reducible = $this->hasPermission('config/authentication/users/remove') && $backend instanceof Reducible;
$extensible = $this->hasPermission('config/access-control/users') && $backend instanceof Extensible;
$reducible = $this->hasPermission('config/access-control/users') && $backend instanceof Reducible;
}
?>

View File

@ -11,7 +11,7 @@ use Icinga\Data\Selectable;
<?php endif ?>
<h2><?= $this->escape($user->user_name) ?></h2>
<?php
if ($this->hasPermission('config/authentication/users/edit') && $backend instanceof Updatable) {
if ($this->hasPermission('config/access-control/users') && $backend instanceof Updatable) {
echo $this->qlink(
$this->translate('Edit User'),
'user/edit',
@ -110,7 +110,7 @@ use Icinga\Data\Selectable;
<?php foreach ($memberships as $membership): ?>
<tr>
<td>
<?php if ($this->hasPermission('config/authentication/groups/show') && $membership->backend instanceof Selectable): ?>
<?php if ($this->hasPermission('config/access-control/groups') && $membership->backend instanceof Selectable): ?>
<?= $this->qlink($membership->group_name, 'group/show', array(
'backend' => $membership->backend->getName(),
'group' => $membership->group_name

View File

@ -110,12 +110,25 @@ a module permission in the format `module/<moduleName>` for each installed modul
### General Permissions
Name | Permits
--------------------------|-----------------------------------------------
\* | allow everything, including module-specific permissions
config/\* | allow all configuration actions
config/modules | allow enabling or disabling modules
module/`<moduleName>` | allow access to module `<moduleName>` (e.g. `module/monitoring`)
Name | Permits
-----------------------------|-----------------------------------------------
\* | allow everything, including module-specific permissions
application/announcements | allow to manage announcements
application/log | allow to view the application log
config/\* | allow full config access
config/access-control/\* | allow to fully manage access control
config/access-control/groups | allow to manage groups
config/access-control/roles | allow to manage roles
config/access-control/users | allow to manage user accounts
config/general | allow to adjust the general configuration
config/modules | allow to enable/disable and configure modules
config/navigation | allow to view and adjust shared navigation items
config/resources | allow to manage resources
user/\* | allow all account related functionalities
user/application/stacktraces | allow to adjust in the preferences whether to show stacktraces
user/password-change | allow password changes in the account preferences
user/share/navigation | allow to share navigation items
module/`<moduleName>` | allow access to module `<moduleName>` (e.g. `module/monitoring`)
### Monitoring Module Permissions

View File

@ -336,7 +336,7 @@ class Web extends EmbeddedWeb
$this->getRequest()->setUser($user);
$this->user = $user;
if ($user->can('application/stacktraces')) {
if ($user->can('user/application/stacktraces')) {
$displayExceptions = $this->user->getPreferences()->getValue(
'icingaweb',
'show_stacktraces'

View File

@ -17,6 +17,35 @@ use Icinga\Util\StringHelper;
*/
class AdmissionLoader
{
const LEGACY_PERMISSIONS = [
'admin' => 'application/announcements',
'application/stacktraces' => 'user/application/stacktraces',
'application/share/navigation' => 'user/share/navigation',
// Migrating config/application/* would include config/modules, so that's skipped
//'config/application/*' => 'config/*',
'config/application/general' => 'config/general',
'config/application/resources' => 'config/resources',
'config/application/navigation' => 'config/navigation',
'config/application/userbackend' => 'config/access-control/users',
'config/application/usergroupbackend' => 'config/access-control/groups',
'config/authentication/*' => 'config/access-control/*',
'config/authentication/users/*' => 'config/access-control/users',
'config/authentication/users/show' => 'config/access-control/users',
'config/authentication/users/add' => 'config/access-control/users',
'config/authentication/users/edit' => 'config/access-control/users',
'config/authentication/users/remove' => 'config/access-control/users',
'config/authentication/groups/*' => 'config/access-control/groups',
'config/authentication/groups/show' => 'config/access-control/groups',
'config/authentication/groups/edit' => 'config/access-control/groups',
'config/authentication/groups/add' => 'config/access-control/groups',
'config/authentication/groups/remove' => 'config/access-control/groups',
'config/authentication/roles/*' => 'config/access-control/roles',
'config/authentication/roles/show' => 'config/access-control/roles',
'config/authentication/roles/add' => 'config/access-control/roles',
'config/authentication/roles/edit' => 'config/access-control/roles',
'config/authentication/roles/remove' => 'config/access-control/roles'
];
/** @var Role[] */
protected $roles;
@ -84,6 +113,11 @@ class AdmissionLoader
$permissions = StringHelper::trimSplit($section->permissions);
$refusals = StringHelper::trimSplit($section->refusals);
list($permissions, $newRefusals) = self::migrateLegacyPermissions($permissions);
if (! empty($newRefusals)) {
array_push($refusals, ...$newRefusals);
}
$restrictions = $section->toArray();
unset($restrictions['users'], $restrictions['groups']);
unset($restrictions['refusals'], $restrictions['permissions']);
@ -176,4 +210,22 @@ class AdmissionLoader
$user->setPermissions($permissions);
$user->setRoles(array_values($roles));
}
public static function migrateLegacyPermissions(array $permissions)
{
$migratedGrants = [];
$refusals = [];
foreach ($permissions as $permission) {
if (array_key_exists($permission, self::LEGACY_PERMISSIONS)) {
$migratedGrants[] = self::LEGACY_PERMISSIONS[$permission];
} elseif ($permission === 'no-user/password-change') {
$refusals[] = 'user/password-change';
} else {
$migratedGrants[] = $permission;
}
}
return [$migratedGrants, $refusals];
}
}

View File

@ -4,6 +4,7 @@
namespace Icinga;
use DateTimeZone;
use Icinga\Authentication\AdmissionLoader;
use InvalidArgumentException;
use Icinga\Application\Config;
use Icinga\Authentication\Role;
@ -559,6 +560,15 @@ class User
*/
public function can($requiredPermission)
{
list($permissions, $refusals) = AdmissionLoader::migrateLegacyPermissions([$requiredPermission]);
if (! empty($permissions)) {
$requiredPermission = array_pop($permissions);
} elseif (! empty($refusals)) {
throw new InvalidArgumentException(
'Refusals are not supported anymore. Check for a grant instead!'
);
}
$granted = false;
foreach ($this->getRoles() as $role) {
if ($role->denies($requiredPermission)) {

View File

@ -67,24 +67,23 @@ class Menu extends Navigation
'icon' => 'wrench',
'description' => t('Open application configuration'),
'label' => t('Application'),
'url' => 'config/general',
'permission' => 'config/application/*',
'url' => 'config',
'priority' => 810
],
'authentication' => [
'icon' => 'users',
'description' => t('Open authentication configuration'),
'label' => t('Authentication'),
'permission' => 'config/authentication/*',
'description' => t('Open access control configuration'),
'label' => t('Access Control'),
'permission' => 'config/access-control/*',
'priority' => 830,
'url' => 'role/list'
'url' => 'role'
],
'navigation' => [
'icon' => 'sitemap',
'description' => t('Open shared navigation configuration'),
'label' => t('Shared Navigation'),
'url' => 'navigation/shared',
'permission' => 'config/application/navigation',
'permission' => 'config/navigation',
'priority' => 840,
],
'modules' => [

View File

@ -101,7 +101,7 @@ class ConfigController extends Controller
try {
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
} catch (ConfigurationError $e) {
if ($this->hasPermission('config/application/resources')) {
if ($this->hasPermission('config/resources')) {
Notification::error($e->getMessage());
$this->redirectNow('config/createresource');
}