src/Security/ConsultationVoter.php line 10

  1. <?php
  2. namespace App\Security;
  3. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  4. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  5. use App\Entity\User;
  6. use App\Entity\Consultation;
  7. class ConsultationVoter extends Voter
  8. {
  9.     const CAN_VIEW 'cv_canview';
  10.     const CAN_EDIT 'cv_canedit';
  11.     const CAN_REMOVE 'cv_canremove';
  12.     const CAN_RESTORE 'cv_canrestore';
  13.     const CAN_INTERVENTION 'cv_canintervention';
  14.     const CAN_SHARE 'cv_canshare';
  15.     const CAN_CHANGESTATUS 'cv_canchangestatus';
  16.     const CAN_ASKREASSIGN 'cv_canaskreassign';
  17.     const CAN_REASSIGN 'cv_canreassign';
  18.     const CAN_COMPLETE 'cv_cancomplete';
  19.     /**
  20.      * @param Consultation $subject
  21.      * @param User $user
  22.      * @return bool
  23.      */
  24.     private function hasAuth(Consultation $subjectUser $user)
  25.     {
  26.         if ($subject->isOwner($user)) {
  27.             return true;
  28.         } else {
  29.             $users $subject->getUsers();
  30.             if (!$users->contains($user)) {
  31.                 return false;
  32.             }
  33.             $userIndex $users->indexOf($user);
  34.             if (is_numeric($userIndex)) {
  35.                 /** @var \App\Entity\ConsultationUser $consultationUser */
  36.                 $consultationUser $subject->getConsultationUsers()->get($userIndex);
  37.                 /** @var $startDate \DateTime */
  38.                 $startDate $consultationUser->getStartDate();
  39.                 /** @var $endDate \DateTime */
  40.                 $endDate $consultationUser->getEndDate();
  41.                 /** @var $now \DateTime */
  42.                 $now = new \DateTime();
  43.                 return $subject->getRemove() === null
  44.                     && $startDate !== null
  45.                     && $endDate !== null
  46.                     && $startDate $now
  47.                     && $now $endDate;
  48.             }
  49.         }
  50.         return false;
  51.     }
  52.     /**
  53.      * Le statut limité ne donne que très peu de droit à une consultation, même
  54.      * à son propriétaire originel.
  55.      *
  56.      * @param Consultation $subject
  57.      * @return bool
  58.      */
  59.     private function isLimited(Consultation $subject)
  60.     {
  61.         return $subject->getRemove() !== null || $subject->getIsReassignStatus() || $subject->getIsCompleteStatus();
  62.     }
  63.     /**
  64.      * @param string $attribute
  65.      * @param Consultation $subject
  66.      * @param TokenInterface $token
  67.      * @return bool
  68.      */
  69.     protected function voteOnAttribute($attribute$subjectTokenInterface $token) : bool
  70.     {
  71.         $user $token->getUser();
  72.         if (!$user instanceof User) {
  73.             return false;
  74.         }
  75.         if ($attribute === self::CAN_VIEW) {
  76.             // Propriétaire (originel ou non) ou partages.
  77.             return $this->hasAuth($subject$user);
  78.         } else if ($attribute === self::CAN_INTERVENTION) {
  79.             // Saisie d'intervention.
  80.             return $this->hasAuth($subject$user) && !$this->isLimited($subject);
  81.         } else if ($attribute === self::CAN_EDIT
  82.             || $attribute === self::CAN_REMOVE
  83.             || $attribute === self::CAN_SHARE
  84.             || $attribute === self::CAN_CHANGESTATUS) {
  85.             // Uniquement le propriétaire originel à condition que la consultation ne se
  86.             // trouve pas dans un status limitant.
  87.             return $subject->isRealOwner($user) && !$this->isLimited($subject);
  88.         } else if ($attribute === self::CAN_ASKREASSIGN || $attribute === self::CAN_COMPLETE) {
  89.             // Uniquement le propriétaire originel à condition que la consultation
  90.             // ne soit pas en partage et ne se trouve pas dans un status limitant.
  91.             return $subject->isRealOwner($user) && $subject->getUsers()->count() === && !$this->isLimited($subject);
  92.         } else if ($attribute === self::CAN_RESTORE) {
  93.             return $subject->isRealOwner($user) && $subject->getRemove() !== null;
  94.         } else if ($attribute === self::CAN_REASSIGN) {
  95.             // Uniquement propriétaire de type superviseur.
  96.             return $subject->isOwner($user) && $subject->getIsReassignStatus() && $user->getIsSuperviseur();
  97.         }
  98.         return false;
  99.     }
  100.     /**
  101.      * @param string $attribute
  102.      * @param Consultation $subject
  103.      * @return bool
  104.      */
  105.     protected function supports($attribute$subject) : bool
  106.     {
  107.         if (!in_array($attribute, [
  108.             self::CAN_VIEW,
  109.             self::CAN_EDIT,
  110.             self::CAN_REMOVE,
  111.             self::CAN_RESTORE,
  112.             self::CAN_INTERVENTION,
  113.             self::CAN_SHARE,
  114.             self::CAN_CHANGESTATUS,
  115.             self::CAN_ASKREASSIGN,
  116.             self::CAN_REASSIGN,
  117.             self::CAN_COMPLETE
  118.         ])) {
  119.             return false;
  120.         }
  121.         if (!$subject instanceof Consultation) {
  122.             return false;
  123.         }
  124.         return true;
  125.     }
  126. }