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::LIST_ASSOCIATED_EMPLOYEE,
  23.             VotersEnum::CREATE_USER,
  24.             VotersEnum::CREATE_ASSOCIATED_EMPLOYEE,
  25.             VotersEnum::READ,
  26.             VotersEnum::UPDATE,
  27.             VotersEnum::DELETE,
  28.             VotersEnum::STATISTICS_LIST,
  29.             VotersEnum::STATISTICS_VIEW,
  30.             VotersEnum::STATISTICS_ENABLE,
  31.             VotersEnum::STATISTICS_DISABLE,
  32.             VotersEnum::STATISTICS_DOWNLOAD,
  33.         ];
  34.         $this->gr $gr;
  35.     }
  36.     protected function supports(string $attribute$subject): bool
  37.     {
  38.         // first check the $subject and last if the $attribute is supported,
  39.         // because there are attributes (with subject) used as well by other voters (like UPDATE, ...)
  40.         if ($subject && !$subject instanceof User) {
  41.             // only vote on these objects
  42.             return false;
  43.         }
  44.         if (in_array($attribute$this->voters)) {
  45.             // if the attribute is one we support
  46.             return true;
  47.         }
  48.         return false;
  49.     }
  50.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  51.     {
  52.         $user $token->getUser();
  53.         if (!$user instanceof User) {
  54.             // the user must be logged in; if not, deny access
  55.             return false;
  56.         }
  57.         switch ($attribute) {
  58.             case VotersEnum::LIST_USER:
  59.                 return $this->canList();
  60.             case VotersEnum::LIST_ASSOCIATED_EMPLOYEE:
  61.                 return $this->canListAssociatedEmployee();
  62.             case VotersEnum::CREATE_USER:
  63.                 return $this->canCreate();
  64.             case VotersEnum::CREATE_ASSOCIATED_EMPLOYEE:
  65.                 return $this->canCreateAssociatedEmployee();
  66.             case VotersEnum::READ:
  67.                 return $this->canRead($subject$user);
  68.             case VotersEnum::UPDATE:
  69.                 return $this->canUpdate($subject$user);
  70.             case VotersEnum::DELETE:
  71.                 return $this->canDelete($subject$user);
  72.             case VotersEnum::STATISTICS_LIST:
  73.                 return $this->canListStatistics($subject$user);
  74.             case VotersEnum::STATISTICS_VIEW:
  75.                 return $this->canViewStatistics($subject$user);
  76.             case VotersEnum::STATISTICS_ENABLE:
  77.                 return $this->canEnableStatistics($subject);
  78.             case VotersEnum::STATISTICS_DISABLE:
  79.                 return $this->canDisableStatistics($subject);
  80.             case VotersEnum::STATISTICS_DOWNLOAD:
  81.                 return $this->canDownloadStatistics($subject$user);
  82.         }
  83.         throw new \LogicException('This code should not be reached!');
  84.     }
  85.     private function canList(): bool
  86.     {
  87.         return $this->isAdminUser();
  88.     }
  89.     private function canListAssociatedEmployee(): bool
  90.     {
  91.         return $this->isAdminUser() || $this->isAssociatedUser();
  92.     }
  93.     private function canCreate(): bool
  94.     {
  95.         return $this->isAdminUser();
  96.     }
  97.     private function canCreateAssociatedEmployee(): bool
  98.     {
  99.         return $this->isAdminUser() || $this->isAssociatedUser();
  100.     }
  101.     private function canRead(User $subjectUser $loggedUser): bool
  102.     {
  103.         return $this->isAdminUser() || $this->isMyEmployee($subject$loggedUser);
  104.     }
  105.     private function canUpdate(User $subjectUser $loggedUser): bool
  106.     {
  107.         if ((UserRolesEnum::ROLE_ADMIN === $subject->getUserRole()) || (UserRolesEnum::ROLE_SUPER_ADMIN === $subject->getUserRole())) {
  108.             // only users with ROLE_ADMIN can update ADMINS users
  109.             return $this->security->isGranted(UserRolesEnum::ROLE_ADMIN_LONG);
  110.         } else {
  111.             return $this->isAdminUser() || $this->isMyEmployee($subject$loggedUser);
  112.         }
  113.     }
  114.     private function canDelete(User $subjectUser $loggedUser): bool
  115.     {
  116.         return $this->canUpdate($subject$loggedUser);
  117.     }
  118.     private function canListStatistics(User $userUser $loggedUser): bool
  119.     {
  120.         if ($this->security->isGranted(UserRolesEnum::ROLE_COORDINATOR_LONG)) {
  121.             $found false;
  122.             $garages $this->gr->getEnabledGaragesByProvincesSortedByName($loggedUser->getWorkProvinces());
  123.             /** @var Garage $garage */
  124.             foreach ($garages as $garage) {
  125.                 if ($garage->isOwner($user)) {
  126.                     $found true;
  127.                     break;
  128.                 }
  129.             }
  130.             return $found && $user->isEnableStatisticsManagement();
  131.         }
  132.         return $this->isStatisticsAdminUser() && $user->isEnableStatisticsManagement();
  133.     }
  134.     private function canViewStatistics(User $userUser $loggedUser): bool
  135.     {
  136.         return $this->canListStatistics($user$loggedUser);
  137.     }
  138.     private function canEnableStatistics(User $user): bool
  139.     {
  140.         return $this->isStatisticsAdminUser() && !$user->isEnableStatisticsManagement();
  141.     }
  142.     private function canDisableStatistics(User $user): bool
  143.     {
  144.         return $this->isStatisticsAdminUser() && $user->isEnableStatisticsManagement();
  145.     }
  146.     private function canDownloadStatistics(User $userUser $loggedUser): bool
  147.     {
  148.         return $this->canListStatistics($user$loggedUser);
  149.     }
  150.     private function isStatisticsAdminUser(): bool
  151.     {
  152.         return ($this->isAdminUser() || $this->security->isGranted(MenuRolesManagerEnum::ROLE_MENU_BAROMETER_DATA)) && !$this->security->isGranted(UserRolesEnum::ROLE_COORDINATOR_LONG);
  153.     }
  154.     private function isAdminUser(): bool
  155.     {
  156.         return $this->security->isGranted(UserRolesEnum::ROLE_ADMIN_LONG);
  157.     }
  158.     private function isAssociatedUser(): bool
  159.     {
  160.         return $this->security->isGranted(UserRolesEnum::ROLE_ASSOCIATED_LONG);
  161.     }
  162.     private function isMyEmployee(User $employeeUser $loggedUser): bool
  163.     {
  164.         $employeeGarage $employee->getEmployeeGarage();
  165.         if ($employeeGarage) {
  166.             /** @var Garage $garage */
  167.             foreach ($loggedUser->getGarages() as $garage) {
  168.                 if ($employeeGarage->getId() === $garage->getId()) {
  169.                     return true;
  170.                 }
  171.             }
  172.         }
  173.         return false;
  174.     }
  175. }