src/Security/Voter/MeetingPollVoter.php line 22

Open in your IDE?
  1. <?php
  2. namespace App\Security\Voter;
  3. use App\Entity\MeetingPoll;
  4. use App\Entity\User;
  5. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  6. use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
  7. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  8. /**
  9.  * Permissions sur un {@see MeetingPoll} :
  10.  *  - VIEW   : tous les membres du workroom (délégué à WorkroomVoter::WORKROOM_VIEW)
  11.  *  - VOTE   : idem VIEW + sondage non clos
  12.  *  - EDIT   : owner uniquement (titre, description, deadline, options)
  13.  *  - DELETE : owner uniquement
  14.  *  - FINALIZE : owner uniquement
  15.  *
  16.  * Délégation : VIEW vérifie l'appartenance au workroom via le voter existant
  17.  * `WorkroomVoter` plutôt que de dupliquer la logique de membership.
  18.  */
  19. class MeetingPollVoter extends Voter
  20. {
  21.     public const POLL_VIEW 'meeting_poll_view';
  22.     public const POLL_VOTE 'meeting_poll_vote';
  23.     public const POLL_EDIT 'meeting_poll_edit';
  24.     public const POLL_DELETE 'meeting_poll_delete';
  25.     public const POLL_FINALIZE 'meeting_poll_finalize';
  26.     public function __construct(
  27.         private readonly AccessDecisionManagerInterface $decisionManager,
  28.     ) {}
  29.     protected function supports($attribute$subject): bool
  30.     {
  31.         return $subject instanceof MeetingPoll && in_array($attribute, [
  32.             self::POLL_VIEW,
  33.             self::POLL_VOTE,
  34.             self::POLL_EDIT,
  35.             self::POLL_DELETE,
  36.             self::POLL_FINALIZE,
  37.         ], true);
  38.     }
  39.     protected function voteOnAttribute($attribute$subjectTokenInterface $token): bool
  40.     {
  41.         $user $token->getUser();
  42.         if (!$user instanceof User) return false;
  43.         /** @var MeetingPoll $poll */
  44.         $poll $subject;
  45.         $workroom $poll->getWorkroom();
  46.         if (!$workroom) return false;
  47.         // VIEW = membre du workroom (délégué au voter workroom)
  48.         $isMember $this->decisionManager->decide($token, [WorkroomVoter::WORKROOM_VIEW], $workroom);
  49.         if (!$isMember) return false;
  50.         switch ($attribute) {
  51.             case self::POLL_VIEW:
  52.                 return true;
  53.             case self::POLL_VOTE:
  54.                 // Voter requis : sondage non clos. Si une deadline est passée
  55.                 // on accepte quand même tant que !isClosed (la deadline est
  56.                 // informative ; l'organisateur ferme manuellement).
  57.                 return !$poll->isClosed();
  58.             case self::POLL_EDIT:
  59.             case self::POLL_DELETE:
  60.             case self::POLL_FINALIZE:
  61.                 return $poll->getOwner()?->getId() === $user->getId();
  62.         }
  63.         return false;
  64.     }
  65. }