vendor/symfony/workflow/EventListener/GuardListener.php line 46

  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\Workflow\EventListener;
  11. use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
  12. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  13. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  14. use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
  15. use Symfony\Component\Validator\Validator\ValidatorInterface;
  16. use Symfony\Component\Workflow\Event\GuardEvent;
  17. use Symfony\Component\Workflow\TransitionBlocker;
  18. /**
  19.  * @author GrĂ©goire Pineau <lyrixx@lyrixx.info>
  20.  */
  21. class GuardListener
  22. {
  23.     private array $configuration;
  24.     private ExpressionLanguage $expressionLanguage;
  25.     private TokenStorageInterface $tokenStorage;
  26.     private AuthorizationCheckerInterface $authorizationChecker;
  27.     private AuthenticationTrustResolverInterface $trustResolver;
  28.     private ?RoleHierarchyInterface $roleHierarchy;
  29.     private ?ValidatorInterface $validator;
  30.     public function __construct(array $configurationExpressionLanguage $expressionLanguageTokenStorageInterface $tokenStorageAuthorizationCheckerInterface $authorizationCheckerAuthenticationTrustResolverInterface $trustResolverRoleHierarchyInterface $roleHierarchy nullValidatorInterface $validator null)
  31.     {
  32.         $this->configuration $configuration;
  33.         $this->expressionLanguage $expressionLanguage;
  34.         $this->tokenStorage $tokenStorage;
  35.         $this->authorizationChecker $authorizationChecker;
  36.         $this->trustResolver $trustResolver;
  37.         $this->roleHierarchy $roleHierarchy;
  38.         $this->validator $validator;
  39.     }
  40.     public function onTransition(GuardEvent $eventstring $eventName)
  41.     {
  42.         if (!isset($this->configuration[$eventName])) {
  43.             return;
  44.         }
  45.         $eventConfiguration = (array) $this->configuration[$eventName];
  46.         foreach ($eventConfiguration as $guard) {
  47.             if ($guard instanceof GuardExpression) {
  48.                 if ($guard->getTransition() !== $event->getTransition()) {
  49.                     continue;
  50.                 }
  51.                 $this->validateGuardExpression($event$guard->getExpression());
  52.             } else {
  53.                 $this->validateGuardExpression($event$guard);
  54.             }
  55.         }
  56.     }
  57.     private function validateGuardExpression(GuardEvent $eventstring $expression)
  58.     {
  59.         if (!$this->expressionLanguage->evaluate($expression$this->getVariables($event))) {
  60.             $blocker TransitionBlocker::createBlockedByExpressionGuardListener($expression);
  61.             $event->addTransitionBlocker($blocker);
  62.         }
  63.     }
  64.     // code should be sync with Symfony\Component\Security\Core\Authorization\Voter\ExpressionVoter
  65.     private function getVariables(GuardEvent $event): array
  66.     {
  67.         $token $this->tokenStorage->getToken();
  68.         $variables = [
  69.             'subject' => $event->getSubject(),
  70.             // needed for the is_granted expression function
  71.             'auth_checker' => $this->authorizationChecker,
  72.             // needed for the is_* expression function
  73.             'trust_resolver' => $this->trustResolver,
  74.             // needed for the is_valid expression function
  75.             'validator' => $this->validator,
  76.         ];
  77.         if (null === $token) {
  78.             return $variables + [
  79.                 'token' => null,
  80.                 'user' => null,
  81.                 'role_names' => [],
  82.             ];
  83.         }
  84.         return $variables + [
  85.             'token' => $token,
  86.             'user' => $token->getUser(),
  87.             'role_names' => $this->roleHierarchy->getReachableRoleNames($token->getRoleNames()),
  88.         ];
  89.     }
  90. }