src/Security/Voter/EventVoter.php line 15

Open in your IDE?
  1. <?php
  2. namespace App\Security\Voter;
  3. use App\Entity\Client\Client;
  4. use App\Entity\Event\Action;
  5. use App\Entity\Event\Event;
  6. use App\Entity\Event\Notice;
  7. use App\Entity\User;
  8. use Doctrine\ORM\EntityManagerInterface;
  9. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  10. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  11. use Symfony\Component\Security\Core\Security;
  12. class EventVoter extends Voter
  13. {
  14. // these strings are just invented: you can use anything
  15. const VIEW = 'view';
  16. const EDIT = 'edit';
  17. const DELETE = 'delete';
  18. /**
  19. * @var Security
  20. */
  21. private Security $security;
  22. /**
  23. * @var EntityManagerInterface
  24. */
  25. private EntityManagerInterface $entityManager;
  26. public function __construct(Security $security, EntityManagerInterface $entityManager)
  27. {
  28. $this->security = $security;
  29. $this->entityManager = $entityManager;
  30. }
  31. protected function supports(string $attribute, $subject): bool
  32. {
  33. // if the attribute isn't one we support, return false
  34. if (!in_array($attribute, [self::VIEW, self::EDIT, self::DELETE], true)) {
  35. return false;
  36. }
  37. // only vote on `File` objects
  38. if (!$subject instanceof Event) {
  39. return false;
  40. }
  41. return true;
  42. }
  43. protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
  44. {
  45. $loggedUser = $token->getUser();
  46. if (!$loggedUser instanceof User) {
  47. // the user must be logged in; if not, deny access
  48. return false;
  49. }
  50. // you know $subject is a Post object, thanks to `supports()`
  51. /** @var Event $targetEvent */
  52. $targetEvent = $subject;
  53. switch ($attribute) {
  54. case self::VIEW:
  55. return $this->canSee($targetEvent, $loggedUser);
  56. case self::EDIT:
  57. return $this->canEdit($targetEvent, $loggedUser);
  58. case self::DELETE:
  59. return $this->canDelete($targetEvent, $loggedUser);
  60. }
  61. throw new \LogicException('This code should not be reached!');
  62. }
  63. /**
  64. * @param Event $targetEvent
  65. * @param User $loggedUser
  66. * @return bool
  67. */
  68. private function canSee(Event $targetEvent, User $loggedUser): bool
  69. {
  70. // sanity check (different client than logged user client)
  71. if ($targetEvent->getClient()->getId() !== $loggedUser->getClient()->getId()) {
  72. return false;
  73. }
  74. if ($targetEvent instanceof Notice && !$this->security->isGranted('ROLE_CAN_SEE_NOTICE_DETAIL')) {
  75. return false;
  76. }
  77. if ($targetEvent instanceof Action && !$this->security->isGranted('ROLE_CAN_SEE_ACTION_DETAIL')) {
  78. return false;
  79. }
  80. return true;
  81. }
  82. /**
  83. * @param Event $targetEvent
  84. * @param User $loggedUser
  85. * @return bool
  86. */
  87. private function canEdit(Event $targetEvent, User $loggedUser): bool
  88. {
  89. if (!$this->canSee($targetEvent, $loggedUser)) {
  90. return false;
  91. }
  92. if ($targetEvent instanceof Notice) {
  93. // Check specific permission for custom messages
  94. if ($targetEvent->isCustomMessage()) {
  95. if (!$this->security->isGranted('ROLE_CAN_EDIT_TYPE_CUSTOM_MESSAGE')) {
  96. return false;
  97. }
  98. } else {
  99. // Regular notices need standard edit permission
  100. if (!$this->security->isGranted('ROLE_CAN_EDIT_NOTICE')) {
  101. return false;
  102. }
  103. }
  104. }
  105. if ($targetEvent instanceof Action && !$this->security->isGranted('ROLE_CAN_EDIT_ACTION')) {
  106. return false;
  107. }
  108. return true;
  109. }
  110. /**
  111. * @param Event $targetEvent
  112. * @param User $loggedUser
  113. * @return bool
  114. */
  115. private function canDelete(Event $targetEvent, User $loggedUser): bool
  116. {
  117. if (!$this->canSee($targetEvent, $loggedUser)) {
  118. return false;
  119. }
  120. if ($targetEvent instanceof Notice && !$this->security->isGranted('ROLE_CAN_DELETE_NOTICE')) {
  121. return false;
  122. }
  123. if ($targetEvent instanceof Action && !$this->security->isGranted('ROLE_CAN_DELETE_ACTION')) {
  124. return false;
  125. }
  126. return true;
  127. }
  128. }