diff --git a/core/modules/system/lib/Drupal/system/Tests/Routing/RouterRoleTest.php b/core/modules/system/lib/Drupal/system/Tests/Routing/RouterRoleTest.php new file mode 100644 index 0000000..2f2f5ed --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/Routing/RouterRoleTest.php @@ -0,0 +1,102 @@ + 'Router Role tests', + 'description' => 'Function Tests for the routing role system.', + 'group' => 'Routing', + ); + } + + /** + * Tests role requirements on routes. + */ + public function testRoleAccess() { + + // Setup two different roles used in the test. + $rid_1 = $this->drupalCreateRole(array(), 'role_test_1'); + $rid_2 = $this->drupalCreateRole(array(), 'role_test_2'); + + // Setup one user with the first role, one with the second, one with both + // and one final without any of these two roles. + $all_uids = array(); + $accounts = array(); + $account_1 = $this->drupalCreateUser(); + $account_1->roles[$rid_1] = $rid_1; + $account_1->save(); + $all_uids[] = $account_1->id(); + $accounts[$account_1->id()] = $account_1; + + $account_2 = $this->drupalCreateUser(); + $account_2->roles[$rid_2] = $rid_2; + $account_2->save(); + $all_uids[] = $account_2->id(); + $accounts[$account_2->id()] = $account_2; + + $account_12 = $this->drupalCreateUser(); + $account_12->roles[$rid_1] = $rid_1; + $account_12->roles[$rid_2] = $rid_2; + $account_12->save(); + $all_uids[] = $account_12->id(); + $accounts[$account_12->id()] = $account_12; + + $account_none = $this->drupalCreateUser(); + $all_uids[] = $account_none->id(); + $accounts[$account_none->id()] = $account_none; + + // Setup expected values, so which path can be access by which user. + $expected = array(); + $expected['test10'] = array($account_1->id(), $account_12->id()); + $expected['test11'] = array($account_2->id(), $account_12->id()); + $expected['test12'] = array($account_12->id()); + $expected['test13'] = array($account_1->id(), $account_2->id(), $account_12->id(), $account_none->id()); + + // @todo Decide whether it's worth to manipulate global $user; and directly + // check the access or call the actual pages. + foreach ($expected as $path => $uids) { + // Login for each user and check the access to the path. + foreach ($uids as $uid) { + $account = $accounts[$uid]; + $this->drupalLogin($account); + $this->drupalGet('/router_test/' . $path); + $this->assertResponse(200, format_string('Access granted for user with the roles %roles on path: %path', array( + '%roles' => implode(', ', $account->roles), + '%path' => $path, + ))); + } + // Check all users which don't have access. + foreach (array_diff($all_uids, $uids) as $uid) { + $account = $accounts[$uid]; + $this->drupalLogin($account); + $this->drupalGet('/router_test/' . $path); + $this->assertResponse(403, format_string('Access denied for user with the roles %roles on path: %path', array( + '%roles' => implode(', ', $account->roles), + '%path' => $path, + ))); + } + } + + } + +} diff --git a/core/modules/system/tests/modules/router_test/lib/Drupal/router_test/TestControllers.php b/core/modules/system/tests/modules/router_test/lib/Drupal/router_test/TestControllers.php index adb5c34..86342d5 100644 --- a/core/modules/system/tests/modules/router_test/lib/Drupal/router_test/TestControllers.php +++ b/core/modules/system/tests/modules/router_test/lib/Drupal/router_test/TestControllers.php @@ -14,6 +14,10 @@ */ class TestControllers { + public function test() { + return new Response('test'); + } + public function test1() { return new Response('test1'); } diff --git a/core/modules/system/tests/modules/router_test/router_test.routing.yml b/core/modules/system/tests/modules/router_test/router_test.routing.yml index 95b0cec..7bae9c0 100644 --- a/core/modules/system/tests/modules/router_test/router_test.routing.yml +++ b/core/modules/system/tests/modules/router_test/router_test.routing.yml @@ -53,3 +53,31 @@ router_test_9: requirements: _permission: 'access test7' _access_router_test: 'TRUE' + +router_test_10: + pattern: '/router_test/test10' + defaults: + _controller: '\Drupal\router_test\TestControllers::test' + requirements: + _role_id: 'role_test_1' + +router_test_11: + pattern: '/router_test/test11' + defaults: + _controller: '\Drupal\router_test\TestControllers::test' + requirements: + _role_id: 'role_test_2' + +router_test_12: + pattern: '/router_test/test12' + defaults: + _controller: '\Drupal\router_test\TestControllers::test' + requirements: + _role_id: 'role_test_1, role_test_2' + +router_test_13: + pattern: '/router_test/test13' + defaults: + _controller: '\Drupal\router_test\TestControllers::test' + requirements: + _access: 'TRUE' diff --git a/core/modules/user/lib/Drupal/user/Access/RoleAccessCheck.php b/core/modules/user/lib/Drupal/user/Access/RoleAccessCheck.php index 2343f41..02fa2f2 100644 --- a/core/modules/user/lib/Drupal/user/Access/RoleAccessCheck.php +++ b/core/modules/user/lib/Drupal/user/Access/RoleAccessCheck.php @@ -27,14 +27,16 @@ public function applies(Route $route) { * Implements AccessCheckInterface::access(). */ public function access(Route $route, Request $request) { - $rids = $route->getRequirement('_role_id'); + // Requirements just allow strings, so this might be a comma separated list. + $rid_string = $route->getRequirement('_role_id'); + $rids = array_map('trim', explode(',', $rid_string)); // @todo Replace the role check with a correctly injected and session-using // alternative. $account = $GLOBALS['user']; $roles = array_keys($account->roles); - $intersect = array_intersect(array_filter($rids), $roles); - if (!empty($intersect)) { + $diff = array_diff(array_filter($rids), $roles); + if (empty($diff)) { return TRUE; } else {