Issue #3363423 by _shY, vbouchet: Use CallableResolver for \Drupal\Core\Access\CustomAccessCheck::access()
parent
d16f491577
commit
9e3a13aad4
|
@ -1336,7 +1336,7 @@ services:
|
||||||
- { name: access_check, applies_to: _access_theme }
|
- { name: access_check, applies_to: _access_theme }
|
||||||
access_check.custom:
|
access_check.custom:
|
||||||
class: Drupal\Core\Access\CustomAccessCheck
|
class: Drupal\Core\Access\CustomAccessCheck
|
||||||
arguments: ['@controller_resolver', '@access_arguments_resolver_factory']
|
arguments: ['@callable_resolver', '@access_arguments_resolver_factory']
|
||||||
tags:
|
tags:
|
||||||
- { name: access_check, applies_to: _custom_access }
|
- { name: access_check, applies_to: _custom_access }
|
||||||
access_check.csrf:
|
access_check.csrf:
|
||||||
|
|
|
@ -4,9 +4,10 @@ namespace Drupal\Core\Access;
|
||||||
|
|
||||||
use Drupal\Core\Controller\ControllerResolverInterface;
|
use Drupal\Core\Controller\ControllerResolverInterface;
|
||||||
use Drupal\Core\Routing\Access\AccessInterface as RoutingAccessInterface;
|
use Drupal\Core\Routing\Access\AccessInterface as RoutingAccessInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Drupal\Core\Routing\RouteMatchInterface;
|
use Drupal\Core\Routing\RouteMatchInterface;
|
||||||
use Drupal\Core\Session\AccountInterface;
|
use Drupal\Core\Session\AccountInterface;
|
||||||
|
use Drupal\Core\Utility\CallableResolver;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\Routing\Route;
|
use Symfony\Component\Routing\Route;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,11 +23,11 @@ use Symfony\Component\Routing\Route;
|
||||||
class CustomAccessCheck implements RoutingAccessInterface {
|
class CustomAccessCheck implements RoutingAccessInterface {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The controller resolver.
|
* The callable resolver.
|
||||||
*
|
*
|
||||||
* @var \Drupal\Core\Controller\ControllerResolverInterface
|
* @var \Drupal\Core\Utility\CallableResolver
|
||||||
*/
|
*/
|
||||||
protected $controllerResolver;
|
protected CallableResolver $callableResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The arguments resolver.
|
* The arguments resolver.
|
||||||
|
@ -38,13 +39,17 @@ class CustomAccessCheck implements RoutingAccessInterface {
|
||||||
/**
|
/**
|
||||||
* Constructs a CustomAccessCheck instance.
|
* Constructs a CustomAccessCheck instance.
|
||||||
*
|
*
|
||||||
* @param \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver
|
* @param \Drupal\Core\Utility\CallableResolver|\Drupal\Core\Controller\ControllerResolverInterface $callable_resolver
|
||||||
* The controller resolver.
|
* The callable resolver.
|
||||||
* @param \Drupal\Core\Access\AccessArgumentsResolverFactoryInterface $arguments_resolver_factory
|
* @param \Drupal\Core\Access\AccessArgumentsResolverFactoryInterface $arguments_resolver_factory
|
||||||
* The arguments resolver factory.
|
* The arguments resolver factory.
|
||||||
*/
|
*/
|
||||||
public function __construct(ControllerResolverInterface $controller_resolver, AccessArgumentsResolverFactoryInterface $arguments_resolver_factory) {
|
public function __construct(ControllerResolverInterface|CallableResolver $callable_resolver, AccessArgumentsResolverFactoryInterface $arguments_resolver_factory) {
|
||||||
$this->controllerResolver = $controller_resolver;
|
if ($callable_resolver instanceof ControllerResolverInterface) {
|
||||||
|
@trigger_error('Calling ' . __METHOD__ . '() with an argument of ControllerResolverInterface is deprecated in drupal:10.3.0 and is removed in drupal:11.0.0. Use \Drupal\Core\Utility\CallableResolver instead. See https://www.drupal.org/node/3397706', E_USER_DEPRECATED);
|
||||||
|
$callable_resolver = \Drupal::service('callable_resolver');
|
||||||
|
}
|
||||||
|
$this->callableResolver = $callable_resolver;
|
||||||
$this->argumentsResolverFactory = $arguments_resolver_factory;
|
$this->argumentsResolverFactory = $arguments_resolver_factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +71,7 @@ class CustomAccessCheck implements RoutingAccessInterface {
|
||||||
*/
|
*/
|
||||||
public function access(Route $route, RouteMatchInterface $route_match, AccountInterface $account, Request $request = NULL) {
|
public function access(Route $route, RouteMatchInterface $route_match, AccountInterface $account, Request $request = NULL) {
|
||||||
try {
|
try {
|
||||||
$callable = $this->controllerResolver->getControllerFromDefinition($route->getRequirement('_custom_access'));
|
$callable = $this->callableResolver->getCallableFromDefinition($route->getRequirement('_custom_access'));
|
||||||
}
|
}
|
||||||
catch (\InvalidArgumentException $e) {
|
catch (\InvalidArgumentException $e) {
|
||||||
// The custom access controller method was not found.
|
// The custom access controller method was not found.
|
||||||
|
|
|
@ -4,7 +4,6 @@ namespace Drupal\Tests\Core\Access;
|
||||||
|
|
||||||
use Drupal\Core\Access\AccessResult;
|
use Drupal\Core\Access\AccessResult;
|
||||||
use Drupal\Core\Access\CustomAccessCheck;
|
use Drupal\Core\Access\CustomAccessCheck;
|
||||||
use Drupal\Core\Controller\ControllerResolver;
|
|
||||||
use Drupal\Core\Routing\RouteMatchInterface;
|
use Drupal\Core\Routing\RouteMatchInterface;
|
||||||
use Drupal\Core\Session\AccountInterface;
|
use Drupal\Core\Session\AccountInterface;
|
||||||
use Drupal\Core\Utility\CallableResolver;
|
use Drupal\Core\Utility\CallableResolver;
|
||||||
|
@ -26,11 +25,11 @@ class CustomAccessCheckTest extends UnitTestCase {
|
||||||
protected $accessChecker;
|
protected $accessChecker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The mocked controller resolver.
|
* The mocked callable resolver.
|
||||||
*
|
*
|
||||||
* @var \Drupal\Core\Controller\ControllerResolverInterface|\PHPUnit\Framework\MockObject\MockObject
|
* @var \Drupal\Core\Utility\CallableResolver|\PHPUnit\Framework\MockObject\MockObject
|
||||||
*/
|
*/
|
||||||
protected $controllerResolver;
|
protected $callableResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The mocked arguments resolver.
|
* The mocked arguments resolver.
|
||||||
|
@ -45,9 +44,9 @@ class CustomAccessCheckTest extends UnitTestCase {
|
||||||
protected function setUp(): void {
|
protected function setUp(): void {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->controllerResolver = $this->createMock('Drupal\Core\Controller\ControllerResolverInterface');
|
$this->callableResolver = $this->createMock(CallableResolver::class);
|
||||||
$this->argumentsResolverFactory = $this->createMock('Drupal\Core\Access\AccessArgumentsResolverFactoryInterface');
|
$this->argumentsResolverFactory = $this->createMock('Drupal\Core\Access\AccessArgumentsResolverFactoryInterface');
|
||||||
$this->accessChecker = new CustomAccessCheck($this->controllerResolver, $this->argumentsResolverFactory);
|
$this->accessChecker = new CustomAccessCheck($this->callableResolver, $this->argumentsResolverFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,8 +55,9 @@ class CustomAccessCheckTest extends UnitTestCase {
|
||||||
public function testAccess() {
|
public function testAccess() {
|
||||||
$route_match = $this->createMock('Drupal\Core\Routing\RouteMatchInterface');
|
$route_match = $this->createMock('Drupal\Core\Routing\RouteMatchInterface');
|
||||||
|
|
||||||
$this->controllerResolver->expects($this->exactly(4))
|
$this->callableResolver
|
||||||
->method('getControllerFromDefinition')
|
->expects($this->exactly(4))
|
||||||
|
->method('getCallableFromDefinition')
|
||||||
->willReturnMap([
|
->willReturnMap([
|
||||||
['\Drupal\Tests\Core\Access\TestController::accessDeny', [new TestController(), 'accessDeny']],
|
['\Drupal\Tests\Core\Access\TestController::accessDeny', [new TestController(), 'accessDeny']],
|
||||||
['\Drupal\Tests\Core\Access\TestController::accessAllow', [new TestController(), 'accessAllow']],
|
['\Drupal\Tests\Core\Access\TestController::accessAllow', [new TestController(), 'accessAllow']],
|
||||||
|
@ -110,18 +110,17 @@ class CustomAccessCheckTest extends UnitTestCase {
|
||||||
* Tests the access method exception for invalid access callbacks.
|
* Tests the access method exception for invalid access callbacks.
|
||||||
*/
|
*/
|
||||||
public function testAccessException() {
|
public function testAccessException() {
|
||||||
$callableResolver = $this->createMock(CallableResolver::class);
|
// Create callableResolver mock to return InvalidArgumentException.
|
||||||
$callableResolver->method('getCallableFromDefinition')
|
$this->callableResolver = $this->getMockBuilder(CallableResolver::class)
|
||||||
->willThrowException(new \InvalidArgumentException());
|
->disableOriginalConstructor()
|
||||||
|
|
||||||
// Re-create the controllerResolver mock with proxy to original methods.
|
|
||||||
$this->controllerResolver = $this->getMockBuilder(ControllerResolver::class)
|
|
||||||
->setConstructorArgs([$callableResolver])
|
|
||||||
->enableProxyingToOriginalMethods()
|
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
// Overwrite the access checker using the newly mocked controller resolve.
|
$this->callableResolver->expects($this->any())
|
||||||
$this->accessChecker = new CustomAccessCheck($this->controllerResolver, $this->argumentsResolverFactory);
|
->method('getCallableFromDefinition')
|
||||||
|
->willThrowException(new \InvalidArgumentException());
|
||||||
|
|
||||||
|
// Overwrite the access checker using the newly mocked callable resolve.
|
||||||
|
$this->accessChecker = new CustomAccessCheck($this->callableResolver, $this->argumentsResolverFactory);
|
||||||
|
|
||||||
// Add a route with a _custom_access route that doesn't exist.
|
// Add a route with a _custom_access route that doesn't exist.
|
||||||
$route = new Route('/test-route', [], ['_custom_access' => '\Drupal\Tests\Core\Access\NonExistentController::nonExistentMethod']);
|
$route = new Route('/test-route', [], ['_custom_access' => '\Drupal\Tests\Core\Access\NonExistentController::nonExistentMethod']);
|
||||||
|
|
Loading…
Reference in New Issue