roles: Restructure form and utilize class `RolesConfig`
This commit is contained in:
parent
9de9fe8f39
commit
8310d9c781
|
@ -4,12 +4,10 @@
|
||||||
namespace Icinga\Controllers;
|
namespace Icinga\Controllers;
|
||||||
|
|
||||||
use Icinga\Application\Config;
|
use Icinga\Application\Config;
|
||||||
use Icinga\Exception\AlreadyExistsException;
|
use Icinga\Authentication\RolesConfig;
|
||||||
use Icinga\Exception\NotFoundError;
|
use Icinga\Exception\NotFoundError;
|
||||||
use Icinga\Forms\ConfirmRemovalForm;
|
|
||||||
use Icinga\Forms\Security\RoleForm;
|
use Icinga\Forms\Security\RoleForm;
|
||||||
use Icinga\Web\Controller\AuthBackendController;
|
use Icinga\Web\Controller\AuthBackendController;
|
||||||
use Icinga\Web\Notification;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manage user permissions and restrictions based on roles
|
* Manage user permissions and restrictions based on roles
|
||||||
|
@ -45,28 +43,13 @@ class RoleController extends AuthBackendController
|
||||||
public function addAction()
|
public function addAction()
|
||||||
{
|
{
|
||||||
$this->assertPermission('config/authentication/roles/add');
|
$this->assertPermission('config/authentication/roles/add');
|
||||||
$role = new RoleForm(array(
|
|
||||||
'onSuccess' => function (RoleForm $role) {
|
$role = new RoleForm();
|
||||||
$name = $role->getElement('name')->getValue();
|
$role->setRedirectUrl('role/list');
|
||||||
$values = $role->getValues();
|
$role->setRepository(new RolesConfig());
|
||||||
try {
|
$role->setSubmitLabel($this->translate('Create Role'));
|
||||||
$role->add($name, $values);
|
$role->add()->handleRequest();
|
||||||
} catch (AlreadyExistsException $e) {
|
|
||||||
$role->addError($e->getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ($role->save()) {
|
|
||||||
Notification::success(t('Role created'));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
));
|
|
||||||
$role
|
|
||||||
->setSubmitLabel($this->translate('Create Role'))
|
|
||||||
->setIniConfig(Config::app('roles', true))
|
|
||||||
->setRedirectUrl('role/list')
|
|
||||||
->handleRequest();
|
|
||||||
$this->renderForm($role, $this->translate('New Role'));
|
$this->renderForm($role, $this->translate('New Role'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,35 +61,20 @@ class RoleController extends AuthBackendController
|
||||||
public function editAction()
|
public function editAction()
|
||||||
{
|
{
|
||||||
$this->assertPermission('config/authentication/roles/edit');
|
$this->assertPermission('config/authentication/roles/edit');
|
||||||
|
|
||||||
$name = $this->params->getRequired('role');
|
$name = $this->params->getRequired('role');
|
||||||
$role = new RoleForm();
|
$role = new RoleForm();
|
||||||
|
$role->setRedirectUrl('role/list');
|
||||||
|
$role->setRepository(new RolesConfig());
|
||||||
$role->setSubmitLabel($this->translate('Update Role'));
|
$role->setSubmitLabel($this->translate('Update Role'));
|
||||||
|
$role->edit($name);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$role
|
$role->handleRequest();
|
||||||
->setIniConfig(Config::app('roles', true))
|
|
||||||
->load($name);
|
|
||||||
} catch (NotFoundError $e) {
|
} catch (NotFoundError $e) {
|
||||||
$this->httpNotFound($e->getMessage());
|
$this->httpNotFound($this->translate('Role not found'));
|
||||||
}
|
}
|
||||||
$role
|
|
||||||
->setOnSuccess(function (RoleForm $role) use ($name) {
|
|
||||||
$oldName = $name;
|
|
||||||
$name = $role->getElement('name')->getValue();
|
|
||||||
$values = $role->getValues();
|
|
||||||
try {
|
|
||||||
$role->update($name, $values, $oldName);
|
|
||||||
} catch (NotFoundError $e) {
|
|
||||||
$role->addError($e->getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ($role->save()) {
|
|
||||||
Notification::success(t('Role updated'));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
})
|
|
||||||
->setRedirectUrl('role/list')
|
|
||||||
->handleRequest();
|
|
||||||
$this->renderForm($role, $this->translate('Update Role'));
|
$this->renderForm($role, $this->translate('Update Role'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,35 +84,21 @@ class RoleController extends AuthBackendController
|
||||||
public function removeAction()
|
public function removeAction()
|
||||||
{
|
{
|
||||||
$this->assertPermission('config/authentication/roles/remove');
|
$this->assertPermission('config/authentication/roles/remove');
|
||||||
|
|
||||||
$name = $this->params->getRequired('role');
|
$name = $this->params->getRequired('role');
|
||||||
$role = new RoleForm();
|
$role = new RoleForm();
|
||||||
|
$role->setRedirectUrl('role/list');
|
||||||
|
$role->setRepository(new RolesConfig());
|
||||||
|
$role->setSubmitLabel($this->translate('Remove Role'));
|
||||||
|
$role->remove($name);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$role
|
$role->handleRequest();
|
||||||
->setIniConfig(Config::app('roles', true))
|
|
||||||
->load($name);
|
|
||||||
} catch (NotFoundError $e) {
|
} catch (NotFoundError $e) {
|
||||||
$this->httpNotFound($e->getMessage());
|
$this->httpNotFound($this->translate('Role not found'));
|
||||||
}
|
}
|
||||||
$confirmation = new ConfirmRemovalForm(array(
|
|
||||||
'onSuccess' => function (ConfirmRemovalForm $confirmation) use ($name, $role) {
|
$this->renderForm($role, $this->translate('Remove Role'));
|
||||||
try {
|
|
||||||
$role->remove($name);
|
|
||||||
} catch (NotFoundError $e) {
|
|
||||||
Notification::error($e->getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ($role->save()) {
|
|
||||||
Notification::success(t('Role removed'));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
));
|
|
||||||
$confirmation
|
|
||||||
->setSubmitLabel($this->translate('Remove Role'))
|
|
||||||
->setRedirectUrl('role/list')
|
|
||||||
->handleRequest();
|
|
||||||
$this->renderForm($confirmation, $this->translate('Remove Role'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,305 +3,321 @@
|
||||||
|
|
||||||
namespace Icinga\Forms\Security;
|
namespace Icinga\Forms\Security;
|
||||||
|
|
||||||
use LogicException;
|
|
||||||
use Zend_Form_Element;
|
|
||||||
use Icinga\Application\Icinga;
|
use Icinga\Application\Icinga;
|
||||||
use Icinga\Exception\AlreadyExistsException;
|
use Icinga\Application\Modules\Manager;
|
||||||
use Icinga\Exception\NotFoundError;
|
use Icinga\Data\Filter\Filter;
|
||||||
use Icinga\Forms\ConfigForm;
|
use Icinga\Forms\ConfigForm;
|
||||||
|
use Icinga\Forms\RepositoryForm;
|
||||||
use Icinga\Util\StringHelper;
|
use Icinga\Util\StringHelper;
|
||||||
|
use Zend_Form_Element;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Form for managing roles
|
* Form for managing roles
|
||||||
*/
|
*/
|
||||||
class RoleForm extends ConfigForm
|
class RoleForm extends RepositoryForm
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Provided permissions by currently loaded modules
|
* The name to use instead of `*`
|
||||||
|
*/
|
||||||
|
const WILDCARD_NAME = 'allAndEverything';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provided permissions by currently installed modules
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $providedPermissions;
|
protected $providedPermissions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provided restrictions by currently loaded modules
|
* Provided restrictions by currently installed modules
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $providedRestrictions;
|
protected $providedRestrictions;
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function init()
|
public function init()
|
||||||
{
|
{
|
||||||
$this->providedPermissions = array(
|
|
||||||
'*' => $this->translate('Allow everything') . ' (*)',
|
|
||||||
'application/share/navigation' => $this->translate('Allow to share navigation items')
|
|
||||||
. ' (application/share/navigation)',
|
|
||||||
'application/stacktraces' => $this->translate(
|
|
||||||
'Allow to adjust in the preferences whether to show stacktraces'
|
|
||||||
) . ' (application/stacktraces)',
|
|
||||||
'application/log' => $this->translate('Allow to view the application log')
|
|
||||||
. ' (application/log)',
|
|
||||||
'admin' => $this->translate(
|
|
||||||
'Grant admin permissions, e.g. manage announcements'
|
|
||||||
) . ' (admin)',
|
|
||||||
'config/*' => $this->translate('Allow config access') . ' (config/*)'
|
|
||||||
);
|
|
||||||
|
|
||||||
$helper = new Zend_Form_Element('bogus');
|
$helper = new Zend_Form_Element('bogus');
|
||||||
$this->providedRestrictions = array(
|
|
||||||
$helper->filterName('application/share/users') => array(
|
$this->providedPermissions['application'] = [
|
||||||
'name' => 'application/share/users',
|
$helper->filterName('application/share/navigation') => [
|
||||||
'description' => $this->translate(
|
'label' => $this->translate('Allow to share navigation items'),
|
||||||
'Restrict which users this role can share items and information with'
|
'name' => 'application/share/navigation'
|
||||||
)
|
],
|
||||||
),
|
$helper->filterName('application/stacktraces') => [
|
||||||
$helper->filterName('application/share/groups') => array(
|
'label' => $this->translate('Allow to adjust in the preferences whether to show stacktraces'),
|
||||||
'name' => 'application/share/groups',
|
'name' => 'application/stacktraces'
|
||||||
'description' => $this->translate(
|
],
|
||||||
'Restrict which groups this role can share items and information with'
|
$helper->filterName('application/log') => [
|
||||||
)
|
'label' => $this->translate('Allow to view the application log'),
|
||||||
)
|
'name' => 'application/log'
|
||||||
);
|
],
|
||||||
|
$helper->filterName('admin') => [
|
||||||
|
'label' => $this->translate('Grant admin permissions, e.g. manage announcements'),
|
||||||
|
'name' => 'admin'
|
||||||
|
],
|
||||||
|
$helper->filterName('config/*') => [
|
||||||
|
'label' => $this->translate('Allow config access'),
|
||||||
|
'name' => 'config/*'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->providedRestrictions['application'] = [
|
||||||
|
$helper->filterName('application/share/users') => [
|
||||||
|
'label' => $this->translate('Restrict which users this role can share items and information with'),
|
||||||
|
'name' => 'application/share/users'
|
||||||
|
],
|
||||||
|
$helper->filterName('application/share/groups') => [
|
||||||
|
'label' => $this->translate('Restrict which groups this role can share items and information with'),
|
||||||
|
'name' => 'application/share/groups'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
$mm = Icinga::app()->getModuleManager();
|
$mm = Icinga::app()->getModuleManager();
|
||||||
foreach ($mm->listInstalledModules() as $moduleName) {
|
foreach ($mm->listInstalledModules() as $moduleName) {
|
||||||
$modulePermission = $mm::MODULE_PERMISSION_NS . $moduleName;
|
$modulePermission = Manager::MODULE_PERMISSION_NS . $moduleName;
|
||||||
$this->providedPermissions[$modulePermission] = sprintf(
|
$this->providedPermissions[$moduleName][$helper->filterName($modulePermission)] = [
|
||||||
$this->translate('Allow access to module %s') . ' (%s)',
|
'label' => sprintf($this->translate('Allow access to module %s'), $moduleName),
|
||||||
$moduleName,
|
'name' => $modulePermission,
|
||||||
$modulePermission
|
'isUsagePerm' => true
|
||||||
);
|
];
|
||||||
|
|
||||||
$module = $mm->getModule($moduleName, false);
|
$module = $mm->getModule($moduleName, false);
|
||||||
foreach ($module->getProvidedPermissions() as $permission) {
|
$permissions = $module->getProvidedPermissions();
|
||||||
|
|
||||||
|
if (count($permissions) > 1) {
|
||||||
|
$this->providedPermissions[$moduleName][$helper->filterName($moduleName . '/*')] = [
|
||||||
|
'label' => $this->translate('Full Access'),
|
||||||
|
'name' => $moduleName . '/*',
|
||||||
|
'isFullPerm' => true
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($permissions as $permission) {
|
||||||
/** @var object $permission */
|
/** @var object $permission */
|
||||||
$this->providedPermissions[$permission->name] = $permission->description
|
$this->providedPermissions[$moduleName][$helper->filterName($permission->name)] = [
|
||||||
. ' (' . $permission->name . ')';
|
'label' => $permission->description,
|
||||||
|
'name' => $permission->name
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($module->getProvidedRestrictions() as $restriction) {
|
foreach ($module->getProvidedRestrictions() as $restriction) {
|
||||||
/** @var object $restriction */
|
$this->providedRestrictions[$moduleName][$helper->filterName($restriction->name)] = [
|
||||||
// Zend only permits alphanumerics, the underscore, the circumflex and any ASCII character in range
|
'label' => $restriction->description,
|
||||||
// \x7f to \xff (127 to 255)
|
'name' => $restriction->name
|
||||||
$name = $helper->filterName($restriction->name);
|
];
|
||||||
while (isset($this->providedRestrictions[$name])) {
|
}
|
||||||
// Because Zend_Form_Element::filterName() replaces any not permitted character with the empty
|
}
|
||||||
// string we may have duplicate names, e.g. 're/striction' and 'restriction'
|
}
|
||||||
$name .= '_';
|
|
||||||
|
protected function createFilter()
|
||||||
|
{
|
||||||
|
return Filter::where('name', $this->getIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createInsertElements(array $formData = array())
|
||||||
|
{
|
||||||
|
$this->addElement(
|
||||||
|
'text',
|
||||||
|
'name',
|
||||||
|
[
|
||||||
|
'required' => true,
|
||||||
|
'label' => $this->translate('Role Name'),
|
||||||
|
'description' => $this->translate('The name of the role')
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$this->addElement(
|
||||||
|
'textarea',
|
||||||
|
'users',
|
||||||
|
[
|
||||||
|
'label' => $this->translate('Users'),
|
||||||
|
'description' => $this->translate('Comma-separated list of users that are assigned to the role')
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$this->addElement(
|
||||||
|
'textarea',
|
||||||
|
'groups',
|
||||||
|
[
|
||||||
|
'label' => $this->translate('Groups'),
|
||||||
|
'description' => $this->translate('Comma-separated list of groups that are assigned to the role')
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$this->addElement(
|
||||||
|
'checkbox',
|
||||||
|
self::WILDCARD_NAME,
|
||||||
|
[
|
||||||
|
'autosubmit' => true,
|
||||||
|
'label' => $this->translate('Administrative Access'),
|
||||||
|
'description' => $this->translate('Everything is allowed')
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (! isset($formData[self::WILDCARD_NAME]) || ! $formData[self::WILDCARD_NAME]) {
|
||||||
|
foreach ($this->providedPermissions as $moduleName => $permissionList) {
|
||||||
|
$this->sortPermissions($permissionList);
|
||||||
|
|
||||||
|
$elements = [];
|
||||||
|
$hasFullPerm = false;
|
||||||
|
foreach ($permissionList as $name => $spec) {
|
||||||
|
$elements[] = $name;
|
||||||
|
$this->addElement(
|
||||||
|
'checkbox',
|
||||||
|
$name,
|
||||||
|
[
|
||||||
|
'ignore' => isset($spec['isUsagePerm']) ? false : $hasFullPerm,
|
||||||
|
'autosubmit' => isset($spec['isFullPerm']),
|
||||||
|
'disabled' => $hasFullPerm ?: null,
|
||||||
|
'value' => $hasFullPerm,
|
||||||
|
'label' => $spec['name'],
|
||||||
|
'description' => $spec['label']
|
||||||
|
]
|
||||||
|
);
|
||||||
|
if (isset($spec['isFullPerm'])) {
|
||||||
|
$hasFullPerm = isset($formData[$name]) && $formData[$name];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$this->providedRestrictions[$name] = array(
|
|
||||||
'description' => $restriction->description,
|
if (isset($this->providedRestrictions[$moduleName])) {
|
||||||
'name' => $restriction->name
|
foreach ($this->providedRestrictions[$moduleName] as $name => $spec) {
|
||||||
);
|
$elements[] = $name;
|
||||||
|
$this->addElement(
|
||||||
|
'text',
|
||||||
|
$name,
|
||||||
|
[
|
||||||
|
'label' => $spec['name'],
|
||||||
|
'description' => $spec['label']
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->addDisplayGroup($elements, $moduleName . '_elements', [
|
||||||
|
'legend' => $moduleName !== 'application'
|
||||||
|
? sprintf($this->translate('Module: %s'), $moduleName)
|
||||||
|
: 'Icinga Web 2',
|
||||||
|
'decorators' => [
|
||||||
|
'FormElements',
|
||||||
|
['Fieldset', ['class' => 'collapsible']]
|
||||||
|
]
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function createElements(array $formData = array())
|
|
||||||
{
|
|
||||||
$this->addElements(array(
|
|
||||||
array(
|
|
||||||
'text',
|
|
||||||
'name',
|
|
||||||
array(
|
|
||||||
'required' => true,
|
|
||||||
'label' => $this->translate('Role Name'),
|
|
||||||
'description' => $this->translate('The name of the role'),
|
|
||||||
'ignore' => true
|
|
||||||
),
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'textarea',
|
|
||||||
'users',
|
|
||||||
array(
|
|
||||||
'label' => $this->translate('Users'),
|
|
||||||
'description' => $this->translate('Comma-separated list of users that are assigned to the role')
|
|
||||||
),
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'textarea',
|
|
||||||
'groups',
|
|
||||||
array(
|
|
||||||
'label' => $this->translate('Groups'),
|
|
||||||
'description' => $this->translate('Comma-separated list of groups that are assigned to the role')
|
|
||||||
),
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'multiselect',
|
|
||||||
'permissions',
|
|
||||||
array(
|
|
||||||
'label' => $this->translate('Permissions Set'),
|
|
||||||
'description' => $this->translate(
|
|
||||||
'The permissions to grant. You may select more than one permission'
|
|
||||||
),
|
|
||||||
'multiOptions' => $this->providedPermissions,
|
|
||||||
'class' => 'grant-permissions'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
));
|
|
||||||
foreach ($this->providedRestrictions as $name => $spec) {
|
|
||||||
$this->addElement(
|
|
||||||
'text',
|
|
||||||
$name,
|
|
||||||
array(
|
|
||||||
'label' => $spec['name'],
|
|
||||||
'description' => $spec['description']
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load a role
|
|
||||||
*
|
|
||||||
* @param string $name The name of the role
|
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*
|
|
||||||
* @throws LogicException If the config is not set
|
|
||||||
* @throws NotFoundError If the given role does not exist
|
|
||||||
* @see ConfigForm::setConfig() For setting the config.
|
|
||||||
*/
|
|
||||||
public function load($name)
|
|
||||||
{
|
|
||||||
if (! isset($this->config)) {
|
|
||||||
throw new LogicException(sprintf('Can\'t load role \'%s\'. Config is not set', $name));
|
|
||||||
}
|
|
||||||
if (! $this->config->hasSection($name)) {
|
|
||||||
throw new NotFoundError(
|
|
||||||
$this->translate('Can\'t load role \'%s\'. Role does not exist'),
|
|
||||||
$name
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$role = $this->config->getSection($name)->toArray();
|
|
||||||
$role['permissions'] = ! empty($role['permissions'])
|
|
||||||
? StringHelper::trimSplit($role['permissions'])
|
|
||||||
: null;
|
|
||||||
$role['name'] = $name;
|
|
||||||
$restrictions = array();
|
|
||||||
foreach ($this->providedRestrictions as $name => $spec) {
|
|
||||||
if (isset($role[$spec['name']])) {
|
|
||||||
// Translate restriction names to filtered element names
|
|
||||||
$restrictions[$name] = $role[$spec['name']];
|
|
||||||
unset($role[$spec['name']]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$role = array_merge($role, $restrictions);
|
|
||||||
$this->populate($role);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a role
|
|
||||||
*
|
|
||||||
* @param string $name The name of the role
|
|
||||||
* @param array $values
|
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*
|
|
||||||
* @throws LogicException If the config is not set
|
|
||||||
* @throws AlreadyExistsException If the role to add already exists
|
|
||||||
* @see ConfigForm::setConfig() For setting the config.
|
|
||||||
*/
|
|
||||||
public function add($name, array $values)
|
|
||||||
{
|
|
||||||
if (! isset($this->config)) {
|
|
||||||
throw new LogicException(sprintf('Can\'t add role \'%s\'. Config is not set', $name));
|
|
||||||
}
|
|
||||||
if ($this->config->hasSection($name)) {
|
|
||||||
throw new AlreadyExistsException(
|
|
||||||
$this->translate('Can\'t add role \'%s\'. Role already exists'),
|
|
||||||
$name
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$this->config->setSection($name, $values);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a role
|
|
||||||
*
|
|
||||||
* @param string $name The name of the role
|
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*
|
|
||||||
* @throws LogicException If the config is not set
|
|
||||||
* @throws NotFoundError If the role does not exist
|
|
||||||
* @see ConfigForm::setConfig() For setting the config.
|
|
||||||
*/
|
|
||||||
public function remove($name)
|
|
||||||
{
|
|
||||||
if (! isset($this->config)) {
|
|
||||||
throw new LogicException(sprintf('Can\'t remove role \'%s\'. Config is not set', $name));
|
|
||||||
}
|
|
||||||
if (! $this->config->hasSection($name)) {
|
|
||||||
throw new NotFoundError(
|
|
||||||
$this->translate('Can\'t remove role \'%s\'. Role does not exist'),
|
|
||||||
$name
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$this->config->removeSection($name);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update a role
|
|
||||||
*
|
|
||||||
* @param string $name The possibly new name of the role
|
|
||||||
* @param array $values
|
|
||||||
* @param string $oldName The name of the role to update
|
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*
|
|
||||||
* @throws LogicException If the config is not set
|
|
||||||
* @throws NotFoundError If the role to update does not exist
|
|
||||||
* @see ConfigForm::setConfig() For setting the config.
|
|
||||||
*/
|
|
||||||
public function update($name, array $values, $oldName)
|
|
||||||
{
|
|
||||||
if (! isset($this->config)) {
|
|
||||||
throw new LogicException(sprintf('Can\'t update role \'%s\'. Config is not set', $name));
|
|
||||||
}
|
|
||||||
if ($name !== $oldName) {
|
|
||||||
// The permission got a new name
|
|
||||||
$this->remove($oldName);
|
|
||||||
$this->add($name, $values);
|
|
||||||
} else {
|
} else {
|
||||||
if (! $this->config->hasSection($name)) {
|
// Previously it was possible to define restrictions for super users, so make sure
|
||||||
throw new NotFoundError(
|
// to not remove any restrictions which were set before the enforced separation
|
||||||
$this->translate('Can\'t update role \'%s\'. Role does not exist'),
|
foreach ($this->providedRestrictions as $restrictionList) {
|
||||||
$name
|
foreach ($restrictionList as $name => $_) {
|
||||||
);
|
$this->addElement('hidden', $name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$this->config->setSection($name, $values);
|
|
||||||
}
|
}
|
||||||
return $this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function createDeleteElements(array $formData)
|
||||||
* {@inheritdoc}
|
{
|
||||||
*/
|
}
|
||||||
|
|
||||||
|
public function fetchEntry()
|
||||||
|
{
|
||||||
|
$role = parent::fetchEntry();
|
||||||
|
if ($role === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$values = [
|
||||||
|
'name' => $role->name,
|
||||||
|
'users' => $role->users,
|
||||||
|
'groups' => $role->groups,
|
||||||
|
self::WILDCARD_NAME => $role->permissions === '*'
|
||||||
|
];
|
||||||
|
|
||||||
|
if (! empty($role->permissions) && $role->permissions !== '*') {
|
||||||
|
$permissions = StringHelper::trimSplit($role->permissions);
|
||||||
|
foreach ($this->providedPermissions as $moduleName => $permissionList) {
|
||||||
|
foreach ($permissionList as $name => $spec) {
|
||||||
|
if (in_array($spec['name'], $permissions, true)) {
|
||||||
|
$values[$name] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->providedRestrictions as $moduleName => $restrictionList) {
|
||||||
|
foreach ($restrictionList as $name => $spec) {
|
||||||
|
if (isset($role->{$spec['name']})) {
|
||||||
|
$values[$name] = $role->{$spec['name']};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (object) $values;
|
||||||
|
}
|
||||||
|
|
||||||
public function getValues($suppressArrayNotation = false)
|
public function getValues($suppressArrayNotation = false)
|
||||||
{
|
{
|
||||||
$values = static::transformEmptyValuesToNull(parent::getValues($suppressArrayNotation));
|
$values = parent::getValues($suppressArrayNotation);
|
||||||
if (isset($values['permissions'])) {
|
|
||||||
$values['permissions'] = implode(', ', $values['permissions']);
|
foreach ($this->providedRestrictions as $moduleName => $restrictionList) {
|
||||||
}
|
foreach ($restrictionList as $name => $spec) {
|
||||||
$restrictions = array();
|
if (isset($values[$name])) {
|
||||||
foreach ($this->providedRestrictions as $name => $spec) {
|
$values[$spec['name']] = $values[$name];
|
||||||
if (isset($values[$name])) {
|
unset($values[$name]);
|
||||||
// Translate filtered element names to restriction names
|
}
|
||||||
$restrictions[$spec['name']] = $values[$name];
|
|
||||||
unset($values[$name]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$values = array_merge($values, $restrictions);
|
|
||||||
return $values;
|
$permissions = [];
|
||||||
|
if (isset($values[self::WILDCARD_NAME]) && $values[self::WILDCARD_NAME]) {
|
||||||
|
$permissions[] = '*';
|
||||||
|
} else {
|
||||||
|
foreach ($this->providedPermissions as $moduleName => $permissionList) {
|
||||||
|
foreach ($permissionList as $name => $spec) {
|
||||||
|
if (isset($values[$name]) && $values[$name]) {
|
||||||
|
$permissions[] = $spec['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($values[$name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($values[self::WILDCARD_NAME]);
|
||||||
|
$values['permissions'] = join(',', $permissions);
|
||||||
|
return ConfigForm::transformEmptyValuesToNull($values);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getInsertMessage($success)
|
||||||
|
{
|
||||||
|
return $success ? $this->translate('Role created') : $this->translate('Role creation failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getUpdateMessage($success)
|
||||||
|
{
|
||||||
|
return $success ? $this->translate('Role updated') : $this->translate('Role update failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getDeleteMessage($success)
|
||||||
|
{
|
||||||
|
return $success ? $this->translate('Role removed') : $this->translate('Role removal failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$aParts = explode('/', $a['name']);
|
||||||
|
$bParts = explode('/', $b['name']);
|
||||||
|
|
||||||
|
do {
|
||||||
|
$a = array_shift($aParts);
|
||||||
|
$b = array_shift($bParts);
|
||||||
|
} while ($a === $b);
|
||||||
|
|
||||||
|
return strnatcmp($a, $b);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue