src/Security/Voter/UserVoter.php line 21

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Security\Voter;
  4. use App\Entity\Security\Administrator;
  5. use App\Entity\Security\Customer;
  6. use App\Entity\Security\Developer;
  7. use App\Entity\Security\Manager;
  8. use App\Entity\Security\RoleInterface;
  9. use App\Entity\Security\ShopManager;
  10. use App\Entity\Security\Support;
  11. use App\Entity\Security\User;
  12. use App\Repository\Shop\CustomerShopRepository;
  13. use App\Service\Security\CustomerService;
  14. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  15. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  16. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  17. class UserVoter extends Voter
  18. {
  19.     public const SHOW 'USER_SHOW';
  20.     public function __construct(
  21.         private AuthorizationCheckerInterface $authorizationChecker,
  22.         private CustomerService $customerService,
  23.         private CustomerShopRepository $customerShopRepository,
  24.     ) {
  25.     }
  26.     protected function supports(string $attributemixed $subject): bool
  27.     {
  28.         return self::SHOW === $attribute && $subject instanceof User;
  29.     }
  30.     protected function voteOnAttribute(string $attributemixed $subjectTokenInterface $token): bool
  31.     {
  32.         $loggedUser $token->getUser();
  33.         if (!$loggedUser instanceof User) {
  34.             return false;
  35.         }
  36.         return $loggedUser->getId() === $subject->getId() || $this->canView($loggedUser$subject);
  37.     }
  38.     private function canView(User $loggedUserUser $targetUser): bool
  39.     {
  40.         $targetRole = match (true) {
  41.             $targetUser instanceof Administrator => RoleInterface::ROLE_ADMIN,
  42.             $targetUser instanceof Developer => RoleInterface::ROLE_DEVELOPER,
  43.             $targetUser instanceof Support => RoleInterface::ROLE_SUPPORT,
  44.             $targetUser instanceof Manager => RoleInterface::ROLE_MANAGER,
  45.             $targetUser instanceof ShopManager => RoleInterface::ROLE_SHOP_MANAGER,
  46.             $targetUser instanceof Customer => RoleInterface::ROLE_CLIENT,
  47.             default => null,
  48.         };
  49.         if (!$this->authorizationChecker->isGranted($targetRole)) {
  50.             return false;
  51.         }
  52.         return $this->checkConstraints($loggedUser$targetUser);
  53.     }
  54.     private function checkConstraints(User $loggedUserUser $targetUser): bool
  55.     {
  56.         if ($loggedUser::class === $targetUser::class && !$loggedUser instanceof Administrator) {
  57.             return false;
  58.         }
  59.         return match (true) {
  60.             $loggedUser instanceof Administrator,
  61.             $loggedUser instanceof Developer,
  62.             $loggedUser instanceof Support => true,
  63.             $loggedUser instanceof Manager => match (true) {
  64.                 $targetUser instanceof Customer => $this->customerService->customerHasFranchise($targetUser$loggedUser->getFranchise()),
  65.                 $targetUser instanceof ShopManager => $targetUser->getShop()->getFranchise() === $loggedUser->getFranchise(),
  66.                 $targetUser instanceof Manager => false,
  67.                 default => false,
  68.             },
  69.             $loggedUser instanceof ShopManager => match (true) {
  70.                 $targetUser instanceof Customer => $this->customerShopRepository->exist($loggedUser->getShop()->getId(), $targetUser->getId()),
  71.                 $targetUser instanceof ShopManager => false,
  72.                 default => false,
  73.             },
  74.             default => false,
  75.         };
  76.     }
  77. }