src/Security/Voter/Users/UserVoter.php line 15

Open in your IDE?
  1. <?php
  2. namespace App\Security\Voter\Users;
  3. use App\Entity\Garages\Garage;
  4. use App\Entity\User;
  5. use App\Enum\MenuRolesManagerEnum;
  6. use App\Enum\UserRolesEnum;
  7. use App\Enum\VotersEnum;
  8. use App\Repository\Garages\GarageRepository;
  9. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  10. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  11. use Symfony\Component\Security\Core\Security;
  12. final class UserVoter extends Voter
  13. {
  14.     private Security $security;
  15.     private array $voters;
  16.     private GarageRepository $gr;
  17.     public function __construct(Security $securityGarageRepository $gr)
  18.     {
  19.         $this->security $security;
  20.         $this->voters = [
  21.             VotersEnum::LIST_USER,
  22.             VotersEnum::CREATE_USER,
  23.             VotersEnum::READ,
  24.             VotersEnum::UPDATE,
  25.             VotersEnum::DELETE,
  26.             VotersEnum::STATISTICS_LIST,
  27.             VotersEnum::STATISTICS_VIEW,
  28.             VotersEnum::STATISTICS_ENABLE,
  29.             VotersEnum::STATISTICS_DISABLE,
  30.             VotersEnum::STATISTICS_DOWNLOAD,
  31.         ];
  32.         $this->gr $gr;
  33.     }
  34.     protected function supports(string $attribute$subject): bool
  35.     {
  36.         // first check the $subject and last if the $attribute is supported,
  37.         // because there are attributes (with subject) used as well by other voters (like UPDATE, ...)
  38.         if ($subject && !$subject instanceof User) {
  39.             // only vote on these objects
  40.             return false;
  41.         }
  42.         if (in_array($attribute$this->voters)) {
  43.             // if the attribute is one we support
  44.             return true;
  45.         }
  46.         return false;
  47.     }
  48.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  49.     {
  50.         $user $token->getUser();
  51.         if (!$user instanceof User) {
  52.             // the user must be logged in; if not, deny access
  53.             return false;
  54.         }
  55.         switch ($attribute) {
  56.             case VotersEnum::LIST_USER:
  57.                 return $this->canList();
  58.             case VotersEnum::CREATE_USER:
  59.                 return $this->canCreate();
  60.             case VotersEnum::READ:
  61.                 return $this->canRead();
  62.             case VotersEnum::UPDATE:
  63.                 return $this->canUpdate($subject);
  64.             case VotersEnum::DELETE:
  65.                 return $this->canDelete($subject);
  66.             case VotersEnum::STATISTICS_LIST:
  67.                 return $this->canListStatistics($subject$user);
  68.             case VotersEnum::STATISTICS_VIEW:
  69.                 return $this->canViewStatistics($subject$user);
  70.             case VotersEnum::STATISTICS_ENABLE:
  71.                 return $this->canEnableStatistics($subject);
  72.             case VotersEnum::STATISTICS_DISABLE:
  73.                 return $this->canDisableStatistics($subject);
  74.             case VotersEnum::STATISTICS_DOWNLOAD:
  75.                 return $this->canDownloadStatistics($subject$user);
  76.         }
  77.         throw new \LogicException('This code should not be reached!');
  78.     }
  79.     private function canList(): bool
  80.     {
  81.         return $this->isAdminUser();
  82.     }
  83.     private function canCreate(): bool
  84.     {
  85.         return $this->isAdminUser();
  86.     }
  87.     private function canRead(): bool
  88.     {
  89.         return $this->isAdminUser();
  90.     }
  91.     private function canUpdate(User $subject): bool
  92.     {
  93.         if ((UserRolesEnum::ROLE_ADMIN === $subject->getUserRole()) || (UserRolesEnum::ROLE_SUPER_ADMIN === $subject->getUserRole())) {
  94.             // only users with ROLE_ADMIN can update ADMINS users
  95.             return $this->security->isGranted(UserRolesEnum::ROLE_ADMIN_LONG);
  96.         } else {
  97.             return $this->isAdminUser();
  98.         }
  99.     }
  100.     private function canDelete(User $user): bool
  101.     {
  102.         return $this->canUpdate($user);
  103.     }
  104.     private function canListStatistics(User $userUser $loggedUser): bool
  105.     {
  106.         if ($this->security->isGranted(UserRolesEnum::ROLE_COORDINATOR_LONG)) {
  107.             $found false;
  108.             $garages $this->gr->getEnabledGaragesByProvincesSortedByName($loggedUser->getWorkProvinces());
  109.             /** @var Garage $garage */
  110.             foreach ($garages as $garage) {
  111.                 if ($garage->isOwner($user)) {
  112.                     $found true;
  113.                     break;
  114.                 }
  115.             }
  116.             return $found && $user->isEnableStatisticsManagement();
  117.         }
  118.         return $this->isStatisticsAdminUser() && $user->isEnableStatisticsManagement();
  119.     }
  120.     private function canViewStatistics(User $userUser $loggedUser): bool
  121.     {
  122.         return $this->canListStatistics($user$loggedUser);
  123.     }
  124.     private function canEnableStatistics(User $user): bool
  125.     {
  126.         return $this->isStatisticsAdminUser() && !$user->isEnableStatisticsManagement();
  127.     }
  128.     private function canDisableStatistics(User $user): bool
  129.     {
  130.         return $this->isStatisticsAdminUser() && $user->isEnableStatisticsManagement();
  131.     }
  132.     private function canDownloadStatistics(User $userUser $loggedUser): bool
  133.     {
  134.         return $this->canListStatistics($user$loggedUser);
  135.     }
  136.     private function isStatisticsAdminUser(): bool
  137.     {
  138.         return ($this->isAdminUser() || $this->security->isGranted(MenuRolesManagerEnum::ROLE_MENU_BAROMETER_DATA)) && !$this->security->isGranted(UserRolesEnum::ROLE_COORDINATOR_LONG);
  139.     }
  140.     private function isAdminUser(): bool
  141.     {
  142.         return $this->security->isGranted(UserRolesEnum::ROLE_ADMIN_LONG);
  143.     }
  144. }