Tester un role d'un utilisateur arbitraire avec Symfony
Publié le 12/06/2022 • Actualisé le 12/06/2022
Dans ce bout de code, nous voyons comment tester un rôle d'un utilisateur arbitraire avec Symfony. Nous savons comment faire pour l'utilisateur courant grâce au service Symfony\Component\Security\Core\Security
, mais ça ne fonctionne pas avec un utilisateur arbitraire que l'on récupère de la base de données. On peut créer un objet UsernamePasswordToken
et appeler la fonction isGranted()
fonction sur le service AccessDecisionManager
comme montré ci-dessous.
<?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;
/**
* J'utilise un trait PHP afin d'isoler chaque snippet dans un fichier.
* Ce code doit être apellé d'un contrôleur Symfony étendant AbstractController (depuis Symfony 4.2)
* ou Symfony\Bundle\FrameworkBundle\Controller\Controller (Symfony <= 4.1).
* Les services sont injectés dans le constructeur du contrôleur principal.
*
* @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! 😁
}
}
Exécuter le snippet ≪ this.showUnitTest ? this.trans.hide_unit_test : this.trans.show_unit_test ≫ Plus sur Stackoverflow Lire la doc Snippet aléatoire
<?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]));
}
}