Commit 4691e432 authored by catch's avatar catch

Issue #2293501 by dawehner, Wim Leers, znerol: Use route name and params...

Issue #2293501 by dawehner, Wim Leers, znerol: Use route name and params instead of _system_path in CsrfAccessCheck.
parent f99eb049
......@@ -8,6 +8,7 @@
namespace Drupal\Core\Access;
use Drupal\Core\Routing\Access\AccessInterface as RoutingAccessInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\HttpFoundation\Request;
......@@ -44,14 +45,21 @@ public function __construct(CsrfTokenGenerator $csrf_token) {
* The route to check against.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object.
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The route match object.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
public function access(Route $route, Request $request) {
// @todo Remove dependency on the internal _system_path attribute:
// https://www.drupal.org/node/2293501.
if ($this->csrfToken->validate($request->query->get('token'), $request->attributes->get('_system_path'))) {
public function access(Route $route, Request $request, RouteMatchInterface $route_match) {
$parameters = $route_match->getRawParameters();
$path = ltrim($route->getPath(), '/');
// Replace the path parameters with values from the parameters array.
foreach ($parameters as $param => $value) {
$path = str_replace("{{$param}}", $value, $path);
}
if ($this->csrfToken->validate($request->query->get('token'), $path)) {
$result = AccessResult::allowed();
}
else {
......
......@@ -51,4 +51,3 @@ public function processOutbound(Route $route, array &$parameters) {
}
}
......@@ -34,18 +34,18 @@ class CsrfAccessCheckTest extends UnitTestCase {
protected $accessCheck;
/**
* The mock user account.
* The mock route match.
*
* @var \Drupal\Core\Session\AccountInterface|\PHPUnit_Framework_MockObject_MockObject
* @var \Drupal\Core\RouteMatch\RouteMatchInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $account;
protected $routeMatch;
protected function setUp() {
$this->csrfToken = $this->getMockBuilder('Drupal\Core\Access\CsrfTokenGenerator')
->disableOriginalConstructor()
->getMock();
$this->account = $this->getMock('Drupal\Core\Session\AccountInterface');
$this->routeMatch = $this->getMock('Drupal\Core\Routing\RouteMatchInterface');
$this->accessCheck = new CsrfAccessCheck($this->csrfToken);
}
......@@ -56,14 +56,17 @@ protected function setUp() {
public function testAccessTokenPass() {
$this->csrfToken->expects($this->once())
->method('validate')
->with('test_query', '/test-path')
->with('test_query', 'test-path/42')
->will($this->returnValue(TRUE));
$route = new Route('/test-path', array(), array('_csrf_token' => 'TRUE'));
$request = Request::create('/test-path?token=test_query');
$request->attributes->set('_system_path', '/test-path');
$this->routeMatch->expects($this->once())
->method('getRawParameters')
->will($this->returnValue(array('node' => 42)));
$this->assertEquals(AccessResult::allowed()->setCacheable(FALSE), $this->accessCheck->access($route, $request, $this->account));
$route = new Route('/test-path/{node}', array(), array('_csrf_token' => 'TRUE'));
$request = Request::create('/test-path/42?token=test_query');
$this->assertEquals(AccessResult::allowed()->setCacheable(FALSE), $this->accessCheck->access($route, $request, $this->routeMatch));
}
/**
......@@ -72,14 +75,17 @@ public function testAccessTokenPass() {
public function testAccessTokenFail() {
$this->csrfToken->expects($this->once())
->method('validate')
->with('test_query', '/test-path')
->with('test_query', 'test-path')
->will($this->returnValue(FALSE));
$this->routeMatch->expects($this->once())
->method('getRawParameters')
->will($this->returnValue(array()));
$route = new Route('/test-path', array(), array('_csrf_token' => 'TRUE'));
$request = Request::create('/test-path?token=test_query');
$request->attributes->set('_system_path', '/test-path');
$this->assertEquals(AccessResult::forbidden()->setCacheable(FALSE), $this->accessCheck->access($route, $request, $this->account));
$this->assertEquals(AccessResult::forbidden()->setCacheable(FALSE), $this->accessCheck->access($route, $request, $this->routeMatch));
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment