src/Security/Voters/Olympiad/ParticipantVoter.php line 14

  1. <?php
  2. namespace App\Security\Voters\Olympiad;
  3. use App\Entity\Common\Country;
  4. use App\Entity\Olympiad\Online\Participant;
  5. use App\Entity\Olympiad\Online\Participant\Result;
  6. use App\Service\Olympiads\Online\MoodleCourseChooser;
  7. use Doctrine\ORM\EntityManagerInterface;
  8. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  9. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  10. use Symfony\Component\Security\Core\Security;
  11. class ParticipantVoter extends Voter
  12. {
  13.     public const EDIT_PARTICIPANT 'participant_edit';
  14.     public const PARTICIPANT_APPLY_TEST 'participant_apply_test';
  15.     public const PARTICIPANT_VIEW_RESULT 'participant_view_result';
  16.     public const PARTICIPANT_VIEW_APPLY_TEST 'participant_view_apply_test';
  17.     public const VIEW_PARTICIPANT 'participant_view';
  18.     private Security $security;
  19.     private EntityManagerInterface $em;
  20.     private MoodleCourseChooser $moodleCourseChooser;
  21.     public function __construct(Security $securityEntityManagerInterface $emMoodleCourseChooser $moodleCourseChooser)
  22.     {
  23.         $this->security $security;
  24.         $this->em $em;
  25.         $this->moodleCourseChooser $moodleCourseChooser;
  26.     }
  27.     /**
  28.      * Determines if the attribute and subject are supported by this voter.
  29.      *
  30.      * @param string $attribute An attribute
  31.      * @param mixed $subject The subject to secure, e.g. an object the user wants to access or any other PHP type
  32.      *
  33.      * @return bool True if the attribute and subject are supported, false otherwise
  34.      */
  35.     protected function supports($attribute$subject): bool
  36.     {
  37.         if (!in_array($attribute, [self::EDIT_PARTICIPANTself::VIEW_PARTICIPANTself::PARTICIPANT_APPLY_TESTself::PARTICIPANT_VIEW_APPLY_TESTself::PARTICIPANT_VIEW_RESULT])) {
  38.             return false;
  39.         }
  40.         // only vote on Post objects inside this voter
  41.         if (!$subject instanceof Participant) {
  42.             return false;
  43.         }
  44.         return true;
  45.     }
  46.     /**
  47.      * Perform a single access check operation on a given attribute, subject and token.
  48.      * It is safe to assume that $attribute and $subject already passed the "supports()" method check.
  49.      *
  50.      * @param string $attribute
  51.      * @param Participant $subject
  52.      * @param TokenInterface $token
  53.      *
  54.      * @return bool
  55.      */
  56.     protected function voteOnAttribute($attribute$subjectTokenInterface $token): bool
  57.     {
  58.         switch ($attribute) {
  59.             case self::EDIT_PARTICIPANT:
  60.                 return ($subject->getState() == $subject::STATE_NEW
  61.                     && false == $subject->isCanceled()
  62.                     && $subject->getUser() == $token->getUser()
  63.                 );
  64.             case self::VIEW_PARTICIPANT:
  65.                 return $subject->getUser() == $token->getUser();
  66.             case self::PARTICIPANT_APPLY_TEST:
  67.                 return $this->isApplyTest($subject$token);
  68.             case self::PARTICIPANT_VIEW_APPLY_TEST:
  69.                 return $this->isViewApplyTest($subject$token);
  70.             case self::PARTICIPANT_VIEW_RESULT:
  71.                 return $this->isViewResult($subject$token);
  72.         }
  73.         throw new \LogicException('This code should not be reached!');
  74.     }
  75.     /**
  76.      * @param Participant $subject
  77.      * @param TokenInterface $token
  78.      * @return bool
  79.      */
  80.     protected function isApplyTest(Participant $subjectTokenInterface $token): bool
  81.     {
  82.         /*$correctState = $subject->getState() == $subject::STATE_SEND && $subject->isCanceled() == false && $subject->isConfirmed() == true;
  83.         $correctUser = $subject->getUser() == $token->getUser();
  84.         $correctTime = false;
  85.         $now = new \DateTime();
  86.         if ($subject->getDirection()->getTestTime()->getFrom() <= $now && $subject->getDirection()->getTestTime()->getTo() >= $now) {
  87.             $correctTime = true;
  88.         }
  89.         return ($correctState && $correctUser && $correctTime)||$this->security->isGranted('ROLE_ADMIN');
  90.         */
  91.         $correctState $subject->isCanceled() == false && $this->isParticipantActiveState($subject);
  92.         $correctUser $subject->getUser() == $token->getUser();
  93. //        $direction = $subject->getDirection();
  94.         $moodleCourse $this->moodleCourseChooser->choose($subject);
  95.         if (!$moodleCourse) {
  96.             return false;
  97.         }
  98. //        dump($moodleCourse);
  99.         /* if ($direction->getTestTime()->getFrom() <= $now && $direction->getTestTime()->getTo() >= $now) {
  100.          }*/
  101.         $rulesCheck $this->checkDirectionRules($subject);
  102.         /* $regionCorrect = false;
  103.          if ($direction->getId() == 1) {
  104.              $regionCorrect = true;
  105.          } elseif ($direction->getId() == 2) {
  106.              if ($subject->getCountry()
  107.                  && $subject->getCountry()->getId() == 173
  108.                  && $subject->getRegion()
  109.                  && $subject->getRegion()->getDistrict()->getId() == 1) {
  110.                  $regionCorrect = true;
  111.              }
  112.          }*/
  113.         return ($correctState && $correctUser && $rulesCheck   /*&& $regionCorrect*/) || $this->security->isGranted('ROLE_TEST_ANY_TIME');
  114.     }
  115.     /**
  116.      * @param Participant $subject
  117.      * @return bool
  118.      */
  119.     protected function isParticipantActiveState(Participant $subject): bool
  120.     {
  121.         return in_array($subject->getState(), [Participant::STATE_ACCEPTEDParticipant::STATE_SENDParticipant::STATE_NEW]);
  122.     }
  123.     /**
  124.      * @param Participant $subject
  125.      * @return bool
  126.      */
  127.     private function checkDirectionRules(Participant $subject): bool
  128.     {
  129.         $direction $subject->getDirection();
  130.         if ($direction->getApplyAllow() & $direction::APPLY_BY_TEST_TIME) {
  131.             $now = new \DateTime();
  132.             if ($direction->getTestTime()->getFrom() > $now || $direction->getTestTime()->getTo() < $now) {
  133.                 return false;
  134.             }
  135. //            if ($direction->getTestTime()->getFrom() <= $now && $direction->getTestTime()->getTo() >= $now) {
  136. //
  137. //            } else return false;
  138.         }
  139.         return $this->checkUserAccess($subject);
  140.     }
  141.     /**
  142.      * @param \App\Entity\Olympiad\Online\Direction|null $direction
  143.      * @param Participant $subject
  144.      * @return bool
  145.      */
  146.     private function checkUserAccess(Participant $subject): bool
  147.     {
  148.         $direction $subject->getDirection();
  149.         if ($direction->getApplyAllow() & $direction::APPLY_IMPLICIT) {
  150.             if (false == $subject->isApplyAllow()) {
  151.                 return false;
  152.             }
  153.         }
  154.         if ($direction->getApplyAllow() & $direction::APPLY_RULE_RUSSIAN) {
  155.             $country $subject->getCountry();
  156.             if (!$country || $country->getId() != Country::C_RUSSIA) {
  157.                 return false;
  158.             }
  159.         }
  160.         if ($direction->getApplyAllow() & $direction::APPLY_RULE_REGION_CFO) {
  161.             if (false == $this->checkDistrict($subject1)) {
  162.                 return false;
  163.             }
  164.         }
  165.         return true;
  166.     }
  167.     private function checkDistrict(Participant $participantint $districtId): bool
  168.     {
  169.         $region $participant->getRegion();
  170.         if (!$region || !$region->getDistrict()) {
  171.             return false;
  172.         }
  173.         return $region->getDistrict()->getId() == $districtId;
  174.     }
  175.     /**
  176.      * @param Participant $subject
  177.      * @param TokenInterface $token
  178.      * @return bool
  179.      */
  180.     protected function isViewApplyTest(Participant $subjectTokenInterface $token): bool
  181.     {
  182.         /*$corretState = $subject->getState() == $subject::STATE_SEND && $subject->isCanceled() == false && $subject->isConfirmed() == true;
  183.         $correctUser = $subject->getUser() == $token->getUser();
  184.         $correctTime = false;
  185.         $now = new \DateTime();
  186.         if ($subject->getDirection()->getTestTime()->getFrom() <= $now && $subject->getDirection()->getTestTime()->getTo() >= $now) {
  187.             $correctTime = true;
  188.         }
  189.         return ($corretState && $correctUser && $correctTime)||$this->security->isGranted('ROLE_ADMIN');
  190.         */
  191.         $corretState $subject->isCanceled() == false && $this->isParticipantActiveState($subject);
  192.         $correctUser $subject->getUser() == $token->getUser();
  193.         $moodleCourse $this->moodleCourseChooser->choose($subject);
  194.         if (!$moodleCourse) {
  195.             return false;
  196.         }
  197.         $userAccess $this->checkUserAccess($subject);
  198.         /* $regionCorrect = false;
  199.          if ($direction->getId() == 1) {
  200.              $regionCorrect = true;
  201.          } elseif ($direction->getId() == 2) {
  202.              if ($subject->getCountry()
  203.                  && $subject->getCountry()->getId() == 173
  204.                  && $subject->getRegion()
  205.                  && $subject->getRegion()->getDistrict()->getId() == 1) {
  206.                  $regionCorrect = true;
  207.              }
  208.          }*/
  209.         return ($corretState && $correctUser && $userAccess/* && $regionCorrect*/) || $this->security->isGranted('ROLE_TEST_ANY_TIME');
  210.     }
  211.     private function isViewResult(Participant $subjectTokenInterface $token): bool
  212.     {
  213.         $resultRepo $this->em->getRepository(Result::class);
  214.         $result $resultRepo->find($subject);
  215.         return !!$result;
  216.     }
  217. }