diff --git a/role_delegation.routing.yml b/role_delegation.routing.yml index f33a2e5..6c602b6 100644 --- a/role_delegation.routing.yml +++ b/role_delegation.routing.yml @@ -4,6 +4,6 @@ role_delegation.edit_form: _controller: '\Drupal\role_delegation\Controller\RoleDelegationController::editForm' _title: 'Roles' requirements: - _custom_access: '\Drupal\role_delegation\Access\RoleDelegationAccessCheck::access' + _role_delegation_access_check: 'TRUE' options: _admin_route: TRUE diff --git a/src/Access/RoleDelegationAccessCheck.php b/src/Access/RoleDelegationAccessCheck.php index c4606bd..e4e9542 100644 --- a/src/Access/RoleDelegationAccessCheck.php +++ b/src/Access/RoleDelegationAccessCheck.php @@ -17,30 +17,27 @@ use Drupal\role_delegation\RoleDelegationPermissions; class RoleDelegationAccessCheck implements AccessInterface { /** - * A custom access check. + * Custom access check for the /user/%/roles page. * * @param \Drupal\Core\Session\AccountInterface $account * Run access checks for this account. + * + * @return \Drupal\Core\Access\AccessResultInterface + * The access result. */ public function access(AccountInterface $account) { - // Check access to user profile page. - if($account->hasPermission('access user profiles')) { - return AccessResult::forbidden()->cachePerPermissions(); - } - // Check if they can edit users. In that case, the Roles tab is not needed. - if ($account->hasPermission('administer users')) { - return AccessResult::forbidden()->cachePerPermissions(); - } - // Check access to role assignment page. - if ($account->hasPermission('administer permissions')) { - return AccessResult::allowed()->cachePerPermissions(); - } + // If the user has any of the "assign custom role" permissions then we give + // them access to the form. $perms = new RoleDelegationPermissions(); - foreach ($perms->rolePermissions() as $perm) { + foreach ($perms->rolePermissions() as $perm => $title) { if ($account->hasPermission($perm)) { return AccessResult::allowed()->cachePerPermissions(); } } - return AccessResult::forbidden(); + + // If the user can administer all permissions then they can also view the + // roles page. + return AccessResult::allowedIfHasPermission($account, 'assign all roles'); } + } diff --git a/tests/Kernel/AccessTest.php b/tests/Kernel/AccessTest.php new file mode 100644 index 0000000..68f5488 --- /dev/null +++ b/tests/Kernel/AccessTest.php @@ -0,0 +1,72 @@ +installSchema('system', 'sequences'); + $this->installEntitySchema('user'); + $this->accessChecker = $this->container->get('role_delegation.access_checker'); + + // User 1 is still a super user so we create that user first so moving + // forward we're just using normal users. + $this->createUser([]); + } + + /** + * Test the access checker for user/%/roles + */ + public function testRoleDelegationAccess() { + // Anonymous users can never access the roles page. + $account = $this->createUser([]); + $this->assertEquals(FALSE, $this->accessChecker->access($account)->isAllowed()); + + // Users with "administer permissions" cannot view the page, they must use + // the normal user edit page or also "have assign all roles". + $account = $this->createUser(['administer permissions']); + $this->assertEquals(FALSE, $this->accessChecker->access($account)->isAllowed()); + + // Users with a custom "assign %custom role" permission should be able to + // see the role admin page. + $role = $this->createRole([]); + $account = $this->createUser([sprintf('assign %s role', $role)]); + $this->assertEquals(TRUE, $this->accessChecker->access($account)->isAllowed()); + + // Users with 'assign all roles' can view the page. + $account = $this->createUser(['assign all roles']); + $this->assertEquals(TRUE, $this->accessChecker->access($account)->isAllowed()); + } + +}