src/Security/Voter/ExpertReportRequestDetailVoter.php line 13

Open in your IDE?
  1. <?php
  2. namespace MedBrief\MSR\Security\Voter;
  3. use InvalidArgumentException;
  4. use MedBrief\MSR\Entity\ExpertReportRequestDetail;
  5. use Override;
  6. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  7. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  8. use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
  9. use Symfony\Component\Security\Core\User\UserInterface;
  10. class ExpertReportRequestDetailVoter implements VoterInterface
  11. {
  12. public const UPDATE = 'UPDATE';
  13. public const DELETE = 'DELETE';
  14. public function __construct(private readonly AuthorizationCheckerInterface $authorizationChecker)
  15. {
  16. }
  17. public function supportsAttribute($attribute): bool
  18. {
  19. return in_array($attribute, [
  20. self::UPDATE,
  21. self::DELETE,
  22. ]);
  23. }
  24. public function supportsClass($class): bool
  25. {
  26. $supportedClass = ExpertReportRequestDetail::class;
  27. return $supportedClass === $class || is_subclass_of($class, $supportedClass);
  28. }
  29. #[Override]
  30. public function vote(TokenInterface $token, $entity, array $attributes)
  31. {
  32. if (!$this->supportsClass($entity && !is_array($entity) ? $entity::class : '')) {
  33. return VoterInterface::ACCESS_ABSTAIN;
  34. }
  35. if (1 !== count($attributes)) {
  36. throw new InvalidArgumentException(
  37. 'Only one attribute is allowed for Medbrief Voters.'
  38. );
  39. }
  40. $attribute = $attributes[0];
  41. if (!$this->supportsAttribute($attribute)) {
  42. return VoterInterface::ACCESS_ABSTAIN;
  43. }
  44. $user = $token->getUser();
  45. if (!$user instanceof UserInterface) {
  46. return VoterInterface::ACCESS_DENIED;
  47. }
  48. // Admin users can do everything
  49. if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
  50. return VoterInterface::ACCESS_GRANTED;
  51. }
  52. // Follow other *RequestDetailVoter patterns: only the creator (or ROLE_ADMIN above) may UPDATE/DELETE.
  53. if (in_array($attribute, [self::UPDATE, self::DELETE], true)
  54. && $entity->getCreator()
  55. && $entity->getCreator()->getId() === $user->getId()
  56. ) {
  57. return VoterInterface::ACCESS_GRANTED;
  58. }
  59. return VoterInterface::ACCESS_DENIED;
  60. }
  61. }