src/Security/Voter/UserPreferenceVoter.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 MedBrief\MSR\Entity\UserPreference;
  6. use Override;
  7. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  8. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  9. use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
  10. use Symfony\Component\Security\Core\User\UserInterface;
  11. class UserPreferenceVoter implements VoterInterface
  12. {
  13. public const READ = 'READ';
  14. public const UPDATE = 'UPDATE';
  15. public const DELETE = 'DELETE';
  16. public function __construct(private readonly AuthorizationCheckerInterface $authorizationChecker)
  17. {
  18. }
  19. /**
  20. * Check if the attribute is supported by this voter.
  21. *
  22. * @param string $attribute The attribute to check.
  23. *
  24. * @return bool
  25. */
  26. public function supportsAttribute($attribute): bool
  27. {
  28. return in_array($attribute, [
  29. self::READ,
  30. self::UPDATE,
  31. self::DELETE,
  32. ]);
  33. }
  34. /**
  35. * Check if the class is supported by this voter.
  36. *
  37. * @param string $class The class name to check.
  38. *
  39. * @return bool
  40. */
  41. public function supportsClass($class): bool
  42. {
  43. return $class === UserPreference::class || is_subclass_of($class, UserPreference::class);
  44. }
  45. /**
  46. * @param mixed $entity
  47. */
  48. #[Override]
  49. public function vote(TokenInterface $token, $entity, array $attributes): int
  50. {
  51. // check if class of this object is supported by this voter
  52. if (!$this->supportsClass($entity && !is_array($entity) ? $entity::class : '')) {
  53. return VoterInterface::ACCESS_ABSTAIN;
  54. }
  55. // check if the voter is used correct, only allow one attribute
  56. if (count($attributes) !== 1) {
  57. throw new InvalidArgumentException('Only one attribute is allowed for MedBrief voters.');
  58. }
  59. // set the attribute to check against
  60. $attribute = $attributes[0];
  61. // check if the given attribute is covered by this voter
  62. if (!$this->supportsAttribute($attribute)) {
  63. return VoterInterface::ACCESS_ABSTAIN;
  64. }
  65. // get current logged in user
  66. /** @var User $user */
  67. $user = $token->getUser();
  68. // make sure there is a user object (i.e. that the user is logged in)
  69. if (!$user instanceof UserInterface) {
  70. return VoterInterface::ACCESS_DENIED;
  71. }
  72. // Admin users can do everything
  73. if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
  74. return VoterInterface::ACCESS_GRANTED;
  75. }
  76. // Only allow access to own preferences
  77. return $entity->getUser()?->getId() === $user->getId()
  78. ? VoterInterface::ACCESS_GRANTED
  79. : VoterInterface::ACCESS_DENIED;
  80. }
  81. }