Skip to content

Commit 111af45

Browse files
bug symfony#49493 [FrameworkBundle] Fix denyAccessUnlessGranted for mixed attributes (delbertooo)
This PR was submitted for the 6.2 branch but it was merged into the 5.4 branch instead. Discussion ---------- [FrameworkBundle] Fix denyAccessUnlessGranted for mixed attributes | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no | Deprecations? |no | Tickets | - | License | MIT | Doc PR | - Checking authorization against anything that isn't `array|string` will cause PHP errors now. The method `AbstractController::denyAccessUnlessGranted()` sets the given *single* attribute into the exception in case of denied access. The `AuthorizationCheckerInterface` defines that the attribute can be anything, even objects. The parameter type hint `array|string` of `AccessDeniedException::setAttributes()` want's an array of attributes (or a string for convenience). # Example ```php use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; class MyCustomAttribute { } class ProfileController extends AbstractController { public function index(): Response { $this->denyAccessUnlessGranted(new MyCustomAttribute()); // 💥 ERROR: Symfony\Component\Security\Core\Exception\AccessDeniedException::setAttributes(): Argument #1 ($attributes) must be of type array|string, [...] $user = $this->getUser(); return new Response('Well hi there '.$user->getFirstName()); } } ``` # The fix As the given attribute is a *single* attribute: always wrap it into an array when creating the exception, because the exception expects an array of attributes. Commits ------- 9ed77f3 [FrameworkBundle] Fix denyAccessUnlessGranted for mixed attributes
2 parents 01a222b + 9ed77f3 commit 111af45

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ protected function denyAccessUnlessGranted($attribute, $subject = null, string $
239239
{
240240
if (!$this->isGranted($attribute, $subject)) {
241241
$exception = $this->createAccessDeniedException($message);
242-
$exception->setAttributes($attribute);
242+
$exception->setAttributes([$attribute]);
243243
$exception->setSubject($subject);
244244

245245
throw $exception;

src/Symfony/Bundle/FrameworkBundle/Tests/Controller/AbstractControllerTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,40 @@ public function testdenyAccessUnlessGranted()
387387
$controller->denyAccessUnlessGranted('foo');
388388
}
389389

390+
/**
391+
* @dataProvider provideDenyAccessUnlessGrantedSetsAttributesAsArray
392+
*/
393+
public function testdenyAccessUnlessGrantedSetsAttributesAsArray($attribute, $exceptionAttributes)
394+
{
395+
$authorizationChecker = $this->createMock(AuthorizationCheckerInterface::class);
396+
$authorizationChecker->method('isGranted')->willReturn(false);
397+
398+
$container = new Container();
399+
$container->set('security.authorization_checker', $authorizationChecker);
400+
401+
$controller = $this->createController();
402+
$controller->setContainer($container);
403+
404+
try {
405+
$controller->denyAccessUnlessGranted($attribute);
406+
$this->fail('there was no exception to check');
407+
} catch (AccessDeniedException $e) {
408+
$this->assertSame($exceptionAttributes, $e->getAttributes());
409+
}
410+
}
411+
412+
public static function provideDenyAccessUnlessGrantedSetsAttributesAsArray()
413+
{
414+
$obj = new \stdClass();
415+
$obj->foo = 'bar';
416+
417+
return [
418+
'string attribute' => ['foo', ['foo']],
419+
'array attribute' => [[1, 3, 3, 7], [[1, 3, 3, 7]]],
420+
'object attribute' => [$obj, [$obj]],
421+
];
422+
}
423+
390424
public function testRenderViewTwig()
391425
{
392426
$twig = $this->createMock(Environment::class);

0 commit comments

Comments
 (0)