src/Security/Voter/LearningCourses/LearningCourseSecurityVoter.php line 16

Open in your IDE?
  1. <?php
  2. namespace App\Security\Voter\LearningCourses;
  3. use App\Entity\LearningCourses\LearningCourse;
  4. use App\Entity\User;
  5. use App\Enum\MenuRolesAssociatedEnum;
  6. use App\Enum\MenuRolesManagerEnum;
  7. use App\Enum\UserRolesEnum;
  8. use App\Enum\VotersEnum;
  9. use LogicException;
  10. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  11. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  12. use Symfony\Component\Security\Core\Security;
  13. final class LearningCourseSecurityVoter extends Voter
  14. {
  15.     private Security $security;
  16.     private array $voters;
  17.     public function __construct(Security $security)
  18.     {
  19.         $this->security $security;
  20.         $this->voters = [
  21.             VotersEnum::LIST_LEARNING_COURSE,
  22.             VotersEnum::LIST_LEARNING_COURSE_ASSOCIATED,
  23.             VotersEnum::CREATE_LEARNING_COURSE,
  24.             VotersEnum::READ,
  25.             VotersEnum::UPDATE,
  26.             VotersEnum::DELETE,
  27.             VotersEnum::VIEW,
  28.             VotersEnum::EXPORT_LEARNING_COURSE_REGISTRATIONS,
  29.             VotersEnum::OWN,
  30.             VotersEnum::ACTIVATE,
  31.             VotersEnum::DEACTIVATE,
  32.             VotersEnum::REPORT_LEARNING_COURSE_REGISTRATIONS,
  33.         ];
  34.     }
  35.     protected function supports(string $attribute$subject): bool
  36.     {
  37.         // first check the $subject and last if the $attribute is supported,
  38.         // because there are attributes (with subject) used as well by other voters (like UPDATE, ...)
  39.         if ($subject && !$subject instanceof LearningCourse) {
  40.             // only vote on these objects
  41.             return false;
  42.         }
  43.         if (in_array($attribute$this->voters)) {
  44.             // if the attribute is one we support
  45.             return true;
  46.         }
  47.         return false;
  48.     }
  49.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  50.     {
  51.         $user $token->getUser();
  52.         if (!$user instanceof User) {
  53.             // the user must be logged in; if not, deny access
  54.             return false;
  55.         }
  56.         // you know $subject is a LearningCourse object, thanks to `supports()`
  57.         /** @var LearningCourse $learningCourse */
  58.         $learningCourse $subject;
  59.         switch ($attribute) {
  60.             case VotersEnum::LIST_LEARNING_COURSE:
  61.                 return $this->canList();
  62.             case VotersEnum::LIST_LEARNING_COURSE_ASSOCIATED:
  63.                 return $this->canListAssociated();
  64.             case VotersEnum::CREATE_LEARNING_COURSE:
  65.                 return $this->canCreate();
  66.             case VotersEnum::READ:
  67.                 return $this->canRead();
  68.             case VotersEnum::UPDATE:
  69.                 return $this->canUpdate();
  70.             case VotersEnum::DELETE:
  71.                 return $this->canDelete();
  72.             case VotersEnum::VIEW:
  73.                 return $this->canView($learningCourse);
  74.             case VotersEnum::EXPORT_LEARNING_COURSE_REGISTRATIONS:
  75.                 return $this->canExport();
  76.             case VotersEnum::OWN:
  77.                 return $this->isOwner($learningCourse$user);
  78.             case VotersEnum::ACTIVATE:
  79.                 return $this->canActivate($learningCourse);
  80.             case VotersEnum::DEACTIVATE:
  81.                 return $this->canDeactivate($learningCourse);
  82.             case VotersEnum::REPORT_LEARNING_COURSE_REGISTRATIONS:
  83.                 return $this->canReport();
  84.         }
  85.         throw new LogicException('This code should not be reached!');
  86.     }
  87.     private function canList(): bool
  88.     {
  89.         return $this->isAdminUser();
  90.     }
  91.     private function canListAssociated(): bool
  92.     {
  93.         return $this->isAdminUser()
  94.             || $this->security->isGranted(MenuRolesAssociatedEnum::ROLE_MENU_LEARNING_PLATFORM_ASOCIATED)
  95.             || $this->security->isGranted(UserRolesEnum::ROLE_ASSOCIATED_EMPLOYEE_LONG)
  96.             ;
  97.     }
  98.     private function canCreate(): bool
  99.     {
  100.         return $this->isAdminUser();
  101.     }
  102.     private function canRead(): bool
  103.     {
  104.         return $this->isAdminUser();
  105.     }
  106.     private function canUpdate(): bool
  107.     {
  108.         return $this->isAdminUser();
  109.     }
  110.     private function canDelete(): bool
  111.     {
  112.         return $this->isAdminUser();
  113.     }
  114.     private function canView(LearningCourse $learningCourse): bool
  115.     {
  116.         return $this->isAdminUser() && $learningCourse->isActive();
  117.     }
  118.     private function canExport(): bool
  119.     {
  120.         return $this->isAdminUser();
  121.     }
  122.     private function isOwner(LearningCourse $learningCourseUser $user): bool
  123.     {
  124.         if ($this->isAdminUser() || $this->security->isGranted(UserRolesEnum::ROLE_COORDINATOR_LONG)) {
  125.             return true;
  126.         } else {
  127.             if ($user->hasRole(UserRolesEnum::ROLE_ASSOCIATED_LONG)) {
  128.                 foreach ($learningCourse->getAssociatedUsers() as $associatedUser) {
  129.                     if ($associatedUser->getId() === $user->getId()) {
  130.                         return true;
  131.                     }
  132.                 }
  133.             } elseif ($user->hasRole(UserRolesEnum::ROLE_ASSOCIATED_EMPLOYEE_LONG)) {
  134.                 /** @var User $associatedUser */
  135.                 foreach ($learningCourse->getAssociatedUsers() as $associatedUser) {
  136.                     foreach ($associatedUser->getGarages() as $garage) {
  137.                         if ($garage->getId() === $user->getId()) {
  138.                             return true;
  139.                         }
  140.                     }
  141.                 }
  142.             }
  143.         }
  144.         return false;
  145.     }
  146.     private function canActivate(LearningCourse $learningCourse): bool
  147.     {
  148.         return $this->canCreate() && !$learningCourse->isActive();
  149.     }
  150.     private function canDeactivate(LearningCourse $learningCourse): bool
  151.     {
  152.         return $this->canCreate() && $learningCourse->isActive();
  153.     }
  154.     private function canReport(): bool
  155.     {
  156.         return $this->isAdminUser();
  157.     }
  158.     private function isAdminUser(): bool
  159.     {
  160.         return $this->security->isGranted(MenuRolesManagerEnum::ROLE_MENU_LEARNING_PLATFORM);
  161.     }
  162. }