src/Security/Voter/UserRequest/UserRequestVoter.php line 14

Open in your IDE?
  1. <?php
  2. namespace App\Security\Voter\UserRequest;
  3. use App\Entity\User;
  4. use App\Manager\UserRightsManagerInterface;
  5. use Psr\Log\LoggerInterface;
  6. use Symfony\Component\PropertyAccess\PropertyAccess;
  7. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  8. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  9. use WebServiceCollectionBundle\Model\AtlasPce\UserRequestRequestContext;
  10. use WebServiceCollectionBundle\Model\AtlasPce\UserRequestRequestModel;
  11. class UserRequestVoter extends Voter
  12. {
  13.     public const VIEW_REQUEST_ATTR 'VIEW_REQUEST';
  14.     /**
  15.      * @var LoggerInterface
  16.      */
  17.     protected $logger;
  18.     public function __construct(
  19.         LoggerInterface $logger
  20.     ) {
  21.         $this->logger            $logger;
  22.     }
  23.     /**
  24.      * {@inheritdoc}
  25.      */
  26.     public function supports($attribute$subject)
  27.     {
  28.         $isView           = static::VIEW_REQUEST_ATTR === $attribute;
  29.         $isSubjectUrModel = ($subject instanceof UserRequestRequestModel);
  30.         return $isView && $isSubjectUrModel;
  31.     }
  32.     /**
  33.      * {@inheritdoc}
  34.      */
  35.     public function voteOnAttribute($attribute$subjectTokenInterface $token)
  36.     {
  37.         $user $token->getUser();
  38.         switch ($attribute) {
  39.             case static::VIEW_REQUEST_ATTR:
  40.                 return $this->mayView($subject$user);
  41.         }
  42.         throw new \LogicException('This code should not be reached!');
  43.     }
  44.     /**
  45.      * Test if a user is allowed to view a request.
  46.      *
  47.      * @param  UserRequestRequestModel  $subject
  48.      * @param  User                     $tokenAttributes
  49.      *
  50.      * @return bool
  51.      */
  52.     protected function mayView(UserRequestRequestModel $requestUser $user): bool
  53.     {
  54.         $propertyAccessor PropertyAccess::createPropertyAccessor();
  55.         $userRoles        $user->getRoles();
  56.         $userIsAdminOrSuezOrManager = (count(array_intersect(
  57.             $userRoles,
  58.             [
  59.                 UserRightsManagerInterface::ROLE_ADMIN,
  60.                 UserRightsManagerInterface::ROLE_SUEZ,
  61.                 UserRightsManagerInterface::ROLE_MANAGER,
  62.             ]
  63.         )));
  64.         $userId            $user->getId(); // use for validation
  65.         $requestId         $request->getId(); // just for logging purposes
  66.         $requestContexts   $request->getContexts();
  67.         $requestData       $request->getData();
  68.         $requestCreatorId  $propertyAccessor->getValue($requestData'[userId]');
  69.         // Logging time
  70.         $loggableContexts array_map(function(UserRequestRequestContext $context) {
  71.             return $context->getEnvelope();
  72.         }, $requestContexts);
  73.         $this->logger->info('[UserRequestVoter] Logged user Id: {userId}', ['userId' => $userId ]);
  74.         $this->logger->info('[UserRequestVoter] Request creator id: {requestCreatorId}', ['requestCreatorId' => $requestCreatorId ]);
  75.         $this->logger->info('[UserRequestVoter] Request Id: {requestId}', ['requestId' => $requestId ]);
  76.         $this->logger->info('[UserRequestVoter] Request contexts: {requestContexts}', [
  77.             'requestContexts' => json_encode($loggableContexts)
  78.         ]);
  79.         // Voting time
  80.         // Admins can see everything
  81.         if ($userIsAdminOrSuezOrManager) {
  82.             $this->logger->info('[UserRequestVoter] User is admin');
  83.             return true;
  84.         }
  85.         $this->logger->info('[UserRequestVoter] User is not an admin');
  86.         $areaRights        $user->getAreaRights();
  87.         $userNarrowestArea $areaRights->getNarrowestRight();
  88.         $this->logger->info('[UserRequestVoter] User narrowest area: {area}', ['area' => json_encode($userNarrowestArea) ]);
  89.         // Look if any context ID matches the user's narrowest area
  90.         $matchedContext array_filter($requestContexts, function (UserRequestRequestContext $context) use ($userNarrowestArea) {
  91.             return $context->getId() === $userNarrowestArea['id'];
  92.         });
  93.         $this->logger->info('[UserRequestVoter] matched: {matchedContext}', ['matchedContext' => json_encode($matchedContext) ]);
  94.         // If there is one context left, then the request is within the user's area.
  95.         if (!empty($matchedContext)) {
  96.             $this->logger->info('[UserRequestVoter] Request in user area');
  97.             return true;
  98.         }
  99.         $this->logger->info('[UserRequestVoter] Request not in user area');
  100.         // If the user is the creator of the request, they may view it.
  101.         if ((string) $userId === (string) $requestCreatorId) {
  102.             $this->logger->info('[UserRequestVoter] User created request');
  103.             return true;
  104.         }
  105.         $this->logger->info('[UserRequestVoter] User {id} did not create request (by {creator})', [
  106.             'id'      => $userId,
  107.             'creator' => $requestCreatorId,
  108.         ]);
  109.         // Otherwise, user may not see the request.
  110.         return false;
  111.     }
  112. }