src/AppBundle/Security/Voter/OperatorAccessVoter.php line 16

Open in your IDE?
  1. <?php
  2. namespace AppBundle\Security\Voter;
  3. use DomainBundle\Helper\ActorGetter;
  4. use Psr\Container\ContainerInterface;
  5. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  6. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  7. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  8. use Symfony\Contracts\Service\ServiceSubscriberInterface;
  9. /**
  10.  * Security voter that tests whether an operator is permitted
  11.  * to access the requested resource.
  12.  */
  13. class OperatorAccessVoter extends Voter implements ServiceSubscriberInterface
  14. {
  15.     const OPERATOR_ACCESS 'OPERATOR_ACCESS';
  16.     /**
  17.      * @var ContainerInterface
  18.      */
  19.     protected ContainerInterface $container;
  20.     /**
  21.      * @param ContainerInterface $container
  22.      */
  23.     public function __construct(ContainerInterface $container)
  24.     {
  25.         $this->container $container;
  26.     }
  27.     /**
  28.      * @inheritDoc
  29.      */
  30.     public static function getSubscribedServices(): array
  31.     {
  32.         return [
  33.             ActorGetter::class,
  34.             AuthorizationCheckerInterface::class,
  35.         ];
  36.     }
  37.     /**
  38.      * Gets the list of supported attributes.
  39.      */
  40.     protected function getSupportedAttributes(): array
  41.     {
  42.         return [
  43.             self::OPERATOR_ACCESS,
  44.         ];
  45.     }
  46.     /**
  47.      * @inheritDoc
  48.      */
  49.     public function supports($attribute$subject): bool
  50.     {
  51.         if (!in_array($attribute$this->getSupportedAttributes(), true)) {
  52.             return false;
  53.         }
  54.         return true;
  55.     }
  56.     /**
  57.      * @inheritDoc
  58.      */
  59.     protected function voteOnAttribute($attribute$subjectTokenInterface $token): bool
  60.     {
  61.         // Admins are always granted operator access
  62.         if ($this->getAuthorizationChecker()->isGranted('ROLE_ADMIN')) {
  63.             return true;
  64.         }
  65.         // Get the logged-in actor
  66.         $user $token->getUser();
  67.         $actor $this->getActorGetter()->getActorByUser($user);
  68.         // Deny access to non-operator users
  69.         if (!isset($actor['operator']['uuid'])) {
  70.             return false;
  71.         }
  72.         // Always grant access to null
  73.         if ($subject === null) {
  74.             return true;
  75.         }
  76.         // Get subject UUID
  77.         $subject = (is_array($subject) && isset($subject['uuid']))
  78.             ? $subject['uuid']
  79.             : $subject;
  80.         // Grant access if the actor and the subject are the same
  81.         return $actor['operator']['uuid']->equalTo($subject);
  82.     }
  83.     /**
  84.      * @return ActorGetter
  85.      */
  86.     protected function getActorGetter(): ActorGetter
  87.     {
  88.         return $this->container->get(ActorGetter::class);
  89.     }
  90.     /**
  91.      * @return AuthorizationCheckerInterface
  92.      */
  93.     protected function getAuthorizationChecker(): AuthorizationCheckerInterface
  94.     {
  95.         return $this->container->get(AuthorizationCheckerInterface::class);
  96.     }
  97. }