src/Security/Voter/UserVoter.php line 14

Open in your IDE?
  1. <?php
  2. namespace MedBrief\MSR\Security\Voter;
  3. use InvalidArgumentException;
  4. use MedBrief\MSR\Entity\User;
  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 UserVoter implements VoterInterface
  11. {
  12. public const CREATE = 'CREATE';
  13. public const READ = 'READ';
  14. public const UPDATE = 'UPDATE';
  15. public const DELETE = 'DELETE';
  16. public const ADMINISTRATION = 'ADMINISTRATION';
  17. public const SIMULATE = 'SIMULATE';
  18. public const SIMULATE_WITH_TFA = 'SIMULATE_WITH_TFA';
  19. public const MANAGE_LINKED_EMAIL_ADDRESS = 'MANAGE_LINKED_EMAIL_ADDRESS';
  20. public const CREATE_LINKED_EMAIL_ADDRESS_INVITATION = 'CREATE_LINKED_EMAIL_ADDRESS_INVITATION';
  21. public function __construct(
  22. private readonly AuthorizationCheckerInterface $authorizationChecker
  23. ) {
  24. }
  25. public function supportsAttribute($attribute): bool
  26. {
  27. return in_array($attribute, [
  28. self::CREATE,
  29. self::READ,
  30. self::UPDATE,
  31. self::DELETE,
  32. self::ADMINISTRATION,
  33. self::SIMULATE,
  34. self::SIMULATE_WITH_TFA,
  35. self::MANAGE_LINKED_EMAIL_ADDRESS,
  36. self::CREATE_LINKED_EMAIL_ADDRESS_INVITATION,
  37. ]);
  38. }
  39. public function supportsClass($class): bool
  40. {
  41. $supportedClass = User::class;
  42. return $supportedClass === $class || is_subclass_of($class, $supportedClass);
  43. }
  44. /**
  45. *
  46. * @param mixed $entity
  47. */
  48. #[Override]
  49. public function vote(TokenInterface $token, $entity, array $attributes)
  50. {
  51. /**
  52. * START: This is common code for all Voter::vote() methods
  53. */
  54. // check if class of this object is supported by this voter
  55. if (!$this->supportsClass($entity && !is_array($entity) ? $entity::class : '')) {
  56. return VoterInterface::ACCESS_ABSTAIN;
  57. }
  58. // check if the voter is used correct, only allow one attribute
  59. // this isn't a requirement, it's just one easy way for you to
  60. // design your voter
  61. if (1 !== count($attributes)) {
  62. throw new InvalidArgumentException(
  63. 'Only one attribute is allowed for medbrief Voters.'
  64. );
  65. }
  66. // set the attribute to check against
  67. $attribute = $attributes[0];
  68. // check if the given attribute is covered by this voter
  69. if (!$this->supportsAttribute($attribute)) {
  70. return VoterInterface::ACCESS_ABSTAIN;
  71. }
  72. // get current logged in user
  73. /** @var User $user */
  74. $user = $token->getUser();
  75. // make sure there is a user object (i.e. that the user is logged in)
  76. if (!$user instanceof UserInterface) {
  77. return VoterInterface::ACCESS_DENIED;
  78. }
  79. // Super Admin users can do everything
  80. if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
  81. return VoterInterface::ACCESS_GRANTED;
  82. }
  83. /**
  84. * END: Common code for all Voter:vote() methods. Put custom logic below.
  85. */
  86. // If we are looking if the user can manage the linked email addresses for this user
  87. if ($attribute === self::MANAGE_LINKED_EMAIL_ADDRESS && $user->getId() === $entity->getId()) {
  88. return VoterInterface::ACCESS_GRANTED;
  89. }
  90. // If we are looking if the user can create a linked email addresses for this user
  91. if ($attribute === self::CREATE_LINKED_EMAIL_ADDRESS_INVITATION && $user->getId() === $entity->getId()) {
  92. return VoterInterface::ACCESS_GRANTED;
  93. }
  94. // If we get to the end of this function, then no decisions have been
  95. // made so we deny access
  96. return VoterInterface::ACCESS_DENIED;
  97. }
  98. }