Tester un role d'un utilisateur arbitraire avec Symfony

Publié le 12/06/2022 • Mis à jour le 12/06/2022


English language detected! 🇬🇧

  We noticed that your browser is using English. Do you want to read this post in this language?

Read the english version 🇬🇧 Close

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);

// src/Controller/Snippet/Snippet203Trait.php

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]));
    }
}