Testing a role of an arbitrary user with Symfony
Published on 2022-06-12 • Modified on 2022-06-12
In this snippet, we see how to test a role of an arbitrary user with Symfony. We know to do it for the current user, thanks to the Symfony\Component\Security\Core\Security
service, but it doesn't work on a given user we would retrieve from the database. We can create a UsernamePasswordToken
object and call the isGranted()
function on the AccessDecisionManager
service as shown below.
<?php
declare(strict_types=1);
namespace App\Controller\Snippet;
use App\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
/**
* I am using a PHP trait to isolate each snippet in a file.
* This code should be called from a Symfony controller extending AbstractController (as of Symfony 4.2)
* or Symfony\Bundle\FrameworkBundle\Controller\Controller (Symfony <= 4.1).
* Services are injected in the main controller constructor.
*
* @property AccessDecisionManagerInterface $accessDecisionManager
*/
trait Snippet203Trait
{
public function snippet203(): void
{
$user = new User();
$user->setRoles([User::ROLE_READER]);
$token = new UsernamePasswordToken($user, 'none', $user->getRoles());
$isGrandedUser = $this->accessDecisionManager->decide($token, [User::ROLE_USER]);
echo 'Granted ROLE_USER: '.($isGrandedUser ? 'yes' : 'no').PHP_EOL;
$isGrandedReader = $this->accessDecisionManager->decide($token, [User::ROLE_READER]);
echo 'Granted ROLE_READER: '.($isGrandedReader ? 'yes' : 'no').PHP_EOL;
$isGrandedAdmin = $this->accessDecisionManager->decide($token, [User::ROLE_ADMIN]);
echo 'Granted ROLE_ADMIN: '.($isGrandedAdmin ? 'yes' : 'no').PHP_EOL;
// That's it! 😁
}
}
Run this snippet ≪ this.showUnitTest ? this.trans.hide_unit_test : this.trans.show_unit_test ≫ More on Stackoverflow Read the doc Random snippet
<?php
declare(strict_types=1);
namespace App\Tests\Integration\Controller\Snippets;
use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
/**
* @see Snippet203Trait
*/
final class Snippet203Test extends KernelTestCase
{
private AccessDecisionManagerInterface $accessDecisionManager;
protected function setUp(): void
{
$this->accessDecisionManager = self::getContainer()->get(AccessDecisionManagerInterface::class);
}
/**
* @return iterable<int, array{0: string, 1: bool, 2: bool, 3: bool}>
*/
public function providerSnippet203(): iterable
{
yield [User::ROLE_USER, true, false, false];
yield [User::ROLE_READER, true, true, false];
yield [User::ROLE_ADMIN, true, true, true];
}
/**
* @dataProvider providerSnippet203
*
* @see Snippet203Trait::snippet203
*/
public function testSnippet203(string $role, bool $isGrandedUser, bool $isGrandedReader, bool $isGrandedAdmin): void
{
$user = new User();
$user->setRoles([$role]);
$token = new UsernamePasswordToken($user, 'none', $user->getRoles());
self::assertSame($isGrandedUser, $this->accessDecisionManager->decide($token, [User::ROLE_USER]));
self::assertSame($isGrandedReader, $this->accessDecisionManager->decide($token, [User::ROLE_READER]));
self::assertSame($isGrandedAdmin, $this->accessDecisionManager->decide($token, [User::ROLE_ADMIN]));
}
}