diff --git a/core/core.services.yml b/core/core.services.yml index 9afeed2..a827835 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -425,6 +425,11 @@ services: class: Drupal\Core\Theme\ThemeAccessCheck tags: - { name: access_check } + access_check.custom: + class: Drupal\Core\Access\CustomAccessCheck + arguments: ['@controller_resolver'] + tags: + - { name: access_check } maintenance_mode_subscriber: class: Drupal\Core\EventSubscriber\MaintenanceModeSubscriber tags: diff --git a/core/lib/Drupal/Core/Access/CustomAccessCheck.php b/core/lib/Drupal/Core/Access/CustomAccessCheck.php new file mode 100644 index 0000000..159d9d5 --- /dev/null +++ b/core/lib/Drupal/Core/Access/CustomAccessCheck.php @@ -0,0 +1,62 @@ +controllerResolver = $controller_resolver; + } + + /** + * {@inheritdoc} + */ + public function appliesTo() { + return array('_custom_access'); + } + + /** + * {@inheritdoc} + */ + public function access(Route $route, Request $request) { + $access_controller = $route->getRequirement('_custom_access'); + + $controller = $this->controllerResolver->getControllerFromDefinition($access_controller); + $arguments = $this->controllerResolver->getArguments($request, $controller); + + return call_user_func_array($controller, $arguments); + } + +} diff --git a/core/modules/toolbar/lib/Drupal/toolbar/Access/SubtreeAccess.php b/core/modules/toolbar/lib/Drupal/toolbar/Access/SubtreeAccess.php deleted file mode 100644 index 131bc6a..0000000 --- a/core/modules/toolbar/lib/Drupal/toolbar/Access/SubtreeAccess.php +++ /dev/null @@ -1,34 +0,0 @@ -get('hash'); - return (user_access('access toolbar') && ($hash == _toolbar_get_subtrees_hash())) ? static::ALLOW : static::DENY; - } - -} diff --git a/core/modules/toolbar/lib/Drupal/toolbar/Routing/ToolbarController.php b/core/modules/toolbar/lib/Drupal/toolbar/Routing/ToolbarController.php index 7404555..3a7eb3c 100644 --- a/core/modules/toolbar/lib/Drupal/toolbar/Routing/ToolbarController.php +++ b/core/modules/toolbar/lib/Drupal/toolbar/Routing/ToolbarController.php @@ -7,12 +7,15 @@ namespace Drupal\toolbar\Routing; +use Drupal\Core\Access\AccessInterface; +use Drupal\Core\Controller\ControllerBase; use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Request; /** * Defines a controller for the toolbar module. */ -class ToolbarController { +class ToolbarController extends ControllerBase { /** * Returns the rendered subtree of each top-level toolbar link. @@ -27,4 +30,12 @@ public function subtreesJsonp() { return $response; } + /** + * Checks access for the subtree controller. + */ + public function checkSubTreeAccess(Request $request) { + $hash = $request->get('hash'); + return ($this->currentUser()->hasPermission('access toolbar') && ($hash == _toolbar_get_subtrees_hash())) ? AccessInterface::ALLOW : AccessInterface::DENY; + } + } diff --git a/core/modules/toolbar/toolbar.routing.yml b/core/modules/toolbar/toolbar.routing.yml index 609d0c7..a4aabb1 100644 --- a/core/modules/toolbar/toolbar.routing.yml +++ b/core/modules/toolbar/toolbar.routing.yml @@ -3,4 +3,4 @@ toolbar.subtrees: defaults: _controller: '\Drupal\toolbar\Routing\ToolbarController::subtreesJsonp' requirements: - _access_toolbar_subtree: 'TRUE' + _custom_access: '\Drupal\toolbar\Routing\ToolbarController::checkSubTreeAccess' diff --git a/core/modules/toolbar/toolbar.services.yml b/core/modules/toolbar/toolbar.services.yml index c700b62..7f26968 100644 --- a/core/modules/toolbar/toolbar.services.yml +++ b/core/modules/toolbar/toolbar.services.yml @@ -1,8 +1,4 @@ services: - access_check.toolbar_subtree: - class: Drupal\toolbar\Access\SubtreeAccess - tags: - - { name: access_check } cache.toolbar: class: Drupal\Core\Cache\CacheBackendInterface tags: diff --git a/core/tests/Drupal/Tests/Core/Access/CustomAccessCheckTest.php b/core/tests/Drupal/Tests/Core/Access/CustomAccessCheckTest.php new file mode 100644 index 0000000..5eb1305 --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Access/CustomAccessCheckTest.php @@ -0,0 +1,127 @@ + 'Custom access check', + 'description' => 'Tests the custom access checker.', + 'group' => 'Access' + ); + } + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + $this->controllerResolver = $this->getMock('Drupal\Core\Controller\ControllerResolverInterface'); + $this->accessChecker = new CustomAccessCheck($this->controllerResolver); + } + + + /** + * Tests the appliesTo method. + */ + public function testAppliesTo() { + $this->assertEquals($this->accessChecker->appliesTo(), array('_custom_access')); + } + + /** + * Test the access method. + */ + public function testAccess() { + $request = new Request(array()); + + $this->controllerResolver->expects($this->at(0)) + ->method('getControllerFromDefinition') + ->with('\Drupal\Tests\Core\Access\TestController::accessDeny') + ->will($this->returnValue(array(new TestController(), 'accessDeny'))); + + $this->controllerResolver->expects($this->at(1)) + ->method('getArguments') + ->will($this->returnValue(array())); + + $this->controllerResolver->expects($this->at(2)) + ->method('getControllerFromDefinition') + ->with('\Drupal\Tests\Core\Access\TestController::accessAllow') + ->will($this->returnValue(array(new TestController(), 'accessAllow'))); + + $this->controllerResolver->expects($this->at(3)) + ->method('getArguments') + ->will($this->returnValue(array())); + + $this->controllerResolver->expects($this->at(4)) + ->method('getControllerFromDefinition') + ->with('\Drupal\Tests\Core\Access\TestController::accessParameter') + ->will($this->returnValue(array(new TestController(), 'accessParameter'))); + + $this->controllerResolver->expects($this->at(5)) + ->method('getArguments') + ->will($this->returnValue(array('parameter' => 'TRUE'))); + + $route = new Route('/test-route', array(), array('_custom_access' => '\Drupal\Tests\Core\Access\TestController::accessDeny')); + $this->assertNull($this->accessChecker->access($route, $request)); + + $route = new Route('/test-route', array(), array('_custom_access' => '\Drupal\Tests\Core\Access\TestController::accessAllow')); + $this->assertTrue($this->accessChecker->access($route, $request)); + + $route = new Route('/test-route', array('parameter' => 'TRUE'), array('_custom_access' => '\Drupal\Tests\Core\Access\TestController::accessParameter')); + $this->assertTrue($this->accessChecker->access($route, $request)); + } + +} + +class TestController { + + public function accessAllow() { + return AccessInterface::ALLOW; + } + + public function accessDeny() { + return AccessInterface::DENY; + } + + public function accessParameter($parameter) { + if ($parameter == 'TRUE') { + return AccessInterface::ALLOW; + } + else { + return AccessInterface::DENY; + } + } + +}