src/Task/Application/Security/TaskVoter.php line 34

Open in your IDE?
  1. <?php
  2. /**
  3.  * This file is part of the educat package.
  4.  *
  5.  * (c) Solvee
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. declare(strict_types=1);
  11. namespace App\Task\Application\Security;
  12. use App\Common\MentorApplicants\MentorApplicantsProviderInterface;
  13. use App\Common\Model\Core\AccountInterface;
  14. use App\Common\Model\Core\UserInterface;
  15. use App\Common\Model\Task\TaskInterface;
  16. use App\Common\Security\ObjectOwnerVoterInterface;
  17. use App\Common\Security\ObjectOwnerVoterTrait;
  18. use App\Common\Security\VoterTrait;
  19. use App\ContentFile\Application\Security\ContentFileVoter;
  20. use LogicException;
  21. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  22. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  23. use Symfony\Component\Security\Core\Security;
  24. use function in_array;
  25. /**
  26.  * Class TaskVoter
  27.  *
  28.  * @author Kamil KozaczyƄski <kozaczynski.kamil@gmail.com>
  29.  */
  30. class TaskVoter extends Voter implements ObjectOwnerVoterInterface
  31. {
  32.     public const CREATE_TASK 'create_task';
  33.     use VoterTraitObjectOwnerVoterTrait;
  34.     /** @var MentorApplicantsProviderInterface */
  35.     private MentorApplicantsProviderInterface $mentorApplicantsProvider;
  36.     /**
  37.      * @param Security                          $security
  38.      * @param MentorApplicantsProviderInterface $mentorApplicantsProvider
  39.      */
  40.     public function __construct(
  41.         Security                          $security,
  42.         MentorApplicantsProviderInterface $mentorApplicantsProvider
  43.     ) {
  44.         $this->security                 $security;
  45.         $this->mentorApplicantsProvider $mentorApplicantsProvider;
  46.     }
  47.     /**
  48.      * @inheritDoc
  49.      */
  50.     protected function supports(string $attribute$subject): bool
  51.     {
  52.         if (!in_array(
  53.             $attribute,
  54.             [
  55.                 self::OBJECT_OWNER,
  56.                 self::CREATE_TASK,
  57.             ],
  58.             true
  59.         )) {
  60.             return false;
  61.         }
  62.         return $subject instanceof TaskInterface;
  63.     }
  64.     /**
  65.      * @param string         $attribute
  66.      * @param TaskInterface  $subject
  67.      * @param TokenInterface $token
  68.      *
  69.      * @return bool
  70.      */
  71.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  72.     {
  73.         $user $token->getUser();
  74.         if (!$user instanceof UserInterface) {
  75.             return false;
  76.         }
  77.         return match ($attribute) {
  78.             self::OBJECT_OWNER => $this->isObjectOwner($subject$user->getAccount()),
  79.             self::CREATE_TASK => $this->canCreateTask($subject$user->getAccount()),
  80.             default => throw new LogicException('This code should not be reached.')
  81.         };
  82.     }
  83.     /**
  84.      * @param TaskInterface    $task
  85.      * @param AccountInterface $account
  86.      *
  87.      * @return bool
  88.      */
  89.     private function canCreateTask(TaskInterface $taskAccountInterface $account): bool
  90.     {
  91.         if ($this->isAdmin()) {
  92.             return true;
  93.         }
  94.         if ($task->getMentor() &&
  95.             !$this->mentorApplicantsProvider->doesApplicantBelongToMentor($task->getApplicant(), $task->getMentor())) {
  96.             return false;
  97.         }
  98.         if (!$this->isObjectOwner($task$account)) {
  99.             return false;
  100.         }
  101.         foreach ($task->getContentFiles() as $contentFile) {
  102.             if (!$this->security->isGranted(ContentFileVoter::CAN_ACCESS$contentFile)) {
  103.                 return false;
  104.             }
  105.         }
  106.         return true;
  107.     }
  108. }