Skip to content

Commit

Permalink
[Security] Fix access_control behavior with unanimous decision strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
chalasr authored and nicolas-grekas committed Mar 30, 2020
1 parent ab96e60 commit b413064
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 10 deletions.
10 changes: 1 addition & 9 deletions Firewall/AccessListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,7 @@ public function authenticate(RequestEvent $event)
$this->tokenStorage->setToken($token);
}

$granted = false;
foreach ($attributes as $key => $value) {
if ($this->accessDecisionManager->decide($token, [$key => $value], $request)) {
$granted = true;
break;
}
}

if (!$granted) {
if (!$this->accessDecisionManager->decide($token, $attributes, $request, true)) {
$exception = new AccessDeniedException();
$exception->setAttributes($attributes);
$exception->setSubject($request);
Expand Down
41 changes: 41 additions & 0 deletions Tests/Firewall/AccessListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Http\AccessMapInterface;
Expand Down Expand Up @@ -227,4 +228,44 @@ public function testHandleWhenTheSecurityTokenStorageHasNoToken()

$listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MASTER_REQUEST));
}

public function testHandleMWithultipleAttributesShouldBeHandledAsAnd()
{
$request = new Request();

$accessMap = $this->getMockBuilder('Symfony\Component\Security\Http\AccessMapInterface')->getMock();
$accessMap
->expects($this->any())
->method('getPatterns')
->with($this->equalTo($request))
->willReturn([['foo' => 'bar', 'bar' => 'baz'], null])
;

$authenticatedToken = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$authenticatedToken
->expects($this->any())
->method('isAuthenticated')
->willReturn(true)
;

$tokenStorage = new TokenStorage();
$tokenStorage->setToken($authenticatedToken);

$accessDecisionManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface')->getMock();
$accessDecisionManager
->expects($this->once())
->method('decide')
->with($this->equalTo($authenticatedToken), $this->equalTo(['foo' => 'bar', 'bar' => 'baz']), $this->equalTo($request), true)
->willReturn(true)
;

$listener = new AccessListener(
$tokenStorage,
$accessDecisionManager,
$accessMap,
$this->createMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')
);

$listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MASTER_REQUEST));
}
}
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
],
"require": {
"php": "^7.1.3",
"symfony/security-core": "^4.4",
"symfony/security-core": "^4.4.7",
"symfony/http-foundation": "^3.4.40|^4.4.7|^5.0.7",
"symfony/http-kernel": "^4.4",
"symfony/property-access": "^3.4|^4.0|^5.0"
Expand Down

0 comments on commit b413064

Please sign in to comment.