diff --git a/application/config/module.config.php b/application/config/module.config.php index ff2a42010..9bf8f9758 100644 --- a/application/config/module.config.php +++ b/application/config/module.config.php @@ -1,7 +1,47 @@ [ + Acl::ROLE_GLOBAL_ADMIN => [ + 'role' => Acl::ROLE_GLOBAL_ADMIN, + 'label' => 'Global Administrator', // @translate + 'admin' => true, + 'parents' => [], + ], + Acl::ROLE_SITE_ADMIN => [ + 'role' => Acl::ROLE_SITE_ADMIN, + 'label' => 'Supervisor', // @translate + 'admin' => true, + 'parents' => [], + ], + Acl::ROLE_EDITOR => [ + 'role' => Acl::ROLE_EDITOR, + 'label' => 'Editor', // @translate + 'admin' => false, + 'parents' => [], + ], + Acl::ROLE_REVIEWER => [ + 'role' => Acl::ROLE_REVIEWER, + 'label' => 'Reviewer', // @translate + 'admin' => false, + 'parents' => [], + ], + Acl::ROLE_AUTHOR => [ + 'role' => Acl::ROLE_AUTHOR, + 'label' => 'Author', // @translate + 'admin' => false, + 'parents' => [], + ], + Acl::ROLE_RESEARCHER => [ + 'role' => Acl::ROLE_RESEARCHER, + 'label' => 'Researcher', // @translate + 'admin' => false, + 'parents' => [], + ], + ], 'password' => [ 'min_length' => 6, 'min_lowercase' => null, diff --git a/application/src/Permissions/Acl.php b/application/src/Permissions/Acl.php index 202e68e0f..3fbdad5e0 100644 --- a/application/src/Permissions/Acl.php +++ b/application/src/Permissions/Acl.php @@ -3,9 +3,9 @@ use Omeka\Api\ResourceInterface; use Laminas\Authentication\AuthenticationServiceInterface; -use Laminas\Permissions\Acl\Acl as ZendAcl; +use Laminas\Permissions\Acl\Acl as LaminasAcl; -class Acl extends ZendAcl +class Acl extends LaminasAcl { const ROLE_GLOBAL_ADMIN = 'global_admin'; const ROLE_SITE_ADMIN = 'site_admin'; @@ -15,59 +15,42 @@ class Acl extends ZendAcl const ROLE_RESEARCHER = 'researcher'; /** - * @var array + * @var AuthenticationServiceInterface */ - protected $roleLabels = [ - self::ROLE_GLOBAL_ADMIN => 'Global Administrator', // @translate - self::ROLE_SITE_ADMIN => 'Supervisor', // @translate - self::ROLE_EDITOR => 'Editor', // @translate - self::ROLE_REVIEWER => 'Reviewer', // @translate - self::ROLE_AUTHOR => 'Author', // @translate - self::ROLE_RESEARCHER => 'Researcher', // @translate - ]; + protected $auth; /** - * Roles that are "admins" and restricted for editing. - * * @var array */ - protected $adminRoles = [ - self::ROLE_GLOBAL_ADMIN, - self::ROLE_SITE_ADMIN, - ]; - - /** - * @var AuthenticationServiceInterface - */ - protected $auth; + protected $configRoles; public function setAuthenticationService(AuthenticationServiceInterface $auth) { $this->auth = $auth; } - public function getAuthenticationService() + public function getAuthenticationService(): AuthenticationServiceInterface { return $this->auth; } + public function setConfigRoles(array $configRoles) + { + $this->configRoles = $configRoles; + } + /** * Get role names and their labels. * * @param bool $excludeAdminRoles Whether to only return the non-admin * roles. False by default, so all roles are returned. - * @return array */ - public function getRoleLabels($excludeAdminRoles = false) + public function getRoleLabels($excludeAdminRoles = false): array { - $labels = $this->roleLabels; - - if ($excludeAdminRoles) { - foreach ($this->adminRoles as $role) { - unset($labels[$role]); - } - } - return $labels; + $labels = array_column($this->configRoles, 'label', 'role'); + return $excludeAdminRoles + ? array_diff_key($labels, array_filter(array_column($this->configRoles, 'admin', 'role'))) + : $labels; } /** @@ -75,47 +58,47 @@ public function getRoleLabels($excludeAdminRoles = false) * * @param ResourceInterface|string $resource * @param string $privilege - * @return bool */ - public function userIsAllowed($resource = null, $privilege = null) + public function userIsAllowed($resource = null, $privilege = null): bool { - $auth = $this->auth; - $role = null; - if ($auth) { - $role = $auth->getIdentity(); - } + $role = $this->auth + ? $this->auth->getIdentity() + : null; return $this->isAllowed($role, $resource, $privilege); } /** * Determine whether the admin role is an "admin" role that carries * restrictions beyond other roles. - * - * @return bool */ - public function isAdminRole($role) + public function isAdminRole($role): bool { - return in_array($role, $this->adminRoles); + return !empty($this->configRoles[$role]['admin']); } /** * Add a role label to the ACL * - * @param $roleId - * @param $roleLabel + * @param string $roleId + * @param string $roleLabel + * + * @deprecated Use main config acl labels. */ public function addRoleLabel($roleId, $roleLabel) { - $this->roleLabels[$roleId] = $roleLabel; + $this->configRoles[$roleId]['label'] = $roleLabel; } /** * Remove a role label from the ACL * * @param $roleId + * + * @deprecated Will be removed in a future version. + * @todo Check the purpose of this method that is never used. */ public function removeRoleLabel($roleId) { - unset($this->roleLabels[$roleId]); + $this->configRoles[$roleId]['label'] = null; } } diff --git a/application/src/Service/AclFactory.php b/application/src/Service/AclFactory.php index 7aa7a778e..1c92c2aef 100644 --- a/application/src/Service/AclFactory.php +++ b/application/src/Service/AclFactory.php @@ -18,6 +18,16 @@ */ class AclFactory implements FactoryInterface { + /** + * @var \Laminas\ServiceManager\ServiceLocatorInterface + */ + protected $services; + + /** + * @var array + */ + protected $configRoles; + /** * Create the access control list. * @@ -28,11 +38,16 @@ public function __invoke(ContainerInterface $serviceLocator, $requestedName, arr { $acl = new Acl; + $this->services = $serviceLocator; + $auth = $serviceLocator->get('Omeka\AuthenticationService'); $acl->setAuthenticationService($auth); + $this->configRoles = $serviceLocator->get('Config')['roles']; + $acl->setConfigRoles($this->configRoles); + $this->addRoles($acl); - $this->addResources($acl, $serviceLocator); + $this->addResources($acl); $status = $serviceLocator->get('Omeka\Status'); if (!$status->isInstalled() @@ -54,12 +69,9 @@ public function __invoke(ContainerInterface $serviceLocator, $requestedName, arr */ protected function addRoles(Acl $acl) { - $acl->addRole(Acl::ROLE_RESEARCHER) - ->addRole(Acl::ROLE_AUTHOR) - ->addRole(Acl::ROLE_REVIEWER) - ->addRole(Acl::ROLE_EDITOR) - ->addRole(Acl::ROLE_SITE_ADMIN) - ->addRole(Acl::ROLE_GLOBAL_ADMIN); + foreach ($this->configRoles as $role => $roleData) { + $acl->addRole($role, empty($roleData['parents']) ? null : $roleData['parents']); + } } /** @@ -72,11 +84,10 @@ protected function addRoles(Acl $acl) * - Controller classes * * @param Acl $acl - * @param ContainerInterface $serviceLocator */ - protected function addResources(Acl $acl, ContainerInterface $serviceLocator) + protected function addResources(Acl $acl) { - $config = $serviceLocator->get('Config'); + $config = $this->services->get('Config'); // Add resources from configuration. if (isset($config['permissions']['acl_resources']) @@ -100,7 +111,7 @@ protected function addResources(Acl $acl, ContainerInterface $serviceLocator) // Add Doctrine entities as ACL resources. These resources are used to // set rules for access to specific entities. - $entities = $serviceLocator->get('Omeka\EntityManager')->getConfiguration() + $entities = $this->services->get('Omeka\EntityManager')->getConfiguration() ->getMetadataDriverImpl()->getAllClassNames(); foreach ($entities as $entityClass) { if (is_subclass_of($entityClass, 'Laminas\Permissions\Acl\Resource\ResourceInterface')) {