src/Security/Voter/RoleInvitationVoter.php line 18

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace MedBrief\MSR\Security\Voter;
  4. use InvalidArgumentException;
  5. use MedBrief\MSR\Entity\Account;
  6. use MedBrief\MSR\Entity\Project;
  7. use MedBrief\MSR\Entity\RoleInvitation;
  8. use MedBrief\MSR\Entity\User;
  9. use MedBrief\MSR\Service\Role\RoleParserService;
  10. use Override;
  11. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  12. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  13. use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
  14. final class RoleInvitationVoter implements VoterInterface
  15. {
  16. public const REMIND = 'REMIND_ROLE_INVITATION';
  17. public function __construct(
  18. private readonly AuthorizationCheckerInterface $authorizationChecker,
  19. private readonly RoleParserService $roleParser
  20. ) {
  21. }
  22. public function supportsAttribute($attribute): bool
  23. {
  24. return self::REMIND === $attribute;
  25. }
  26. public function supportsClass($class): bool
  27. {
  28. return RoleInvitation::class === $class || is_subclass_of($class, RoleInvitation::class);
  29. }
  30. #[Override]
  31. public function vote(TokenInterface $token, $subject, array $attributes): int
  32. {
  33. if (!$subject instanceof RoleInvitation) {
  34. return self::ACCESS_ABSTAIN;
  35. }
  36. if (1 !== count($attributes)) {
  37. throw new InvalidArgumentException('Only one attribute is allowed for MedBrief voters.');
  38. }
  39. if (!$this->supportsAttribute($attributes[0])) {
  40. return self::ACCESS_ABSTAIN;
  41. }
  42. if (!$token->getUser() instanceof User) {
  43. return self::ACCESS_DENIED;
  44. }
  45. if ($this->authorizationChecker->isGranted('ROLE_SUPER_ADMIN')
  46. || $this->authorizationChecker->isGranted('ROLE_ADMIN')) {
  47. return self::ACCESS_GRANTED;
  48. }
  49. $parsedRole = $this->roleParser->parseRole($subject->getRole());
  50. if (false === $parsedRole) {
  51. return self::ACCESS_DENIED;
  52. }
  53. $roleSubject = $parsedRole->getSubject();
  54. if ($roleSubject instanceof Account
  55. && $this->authorizationChecker->isGranted('USER_ADMINISTRATION', $roleSubject)) {
  56. return self::ACCESS_GRANTED;
  57. }
  58. if ($roleSubject instanceof Project
  59. && ($this->authorizationChecker->isGranted('USER_ADMINISTRATION', $roleSubject)
  60. || $this->authorizationChecker->isGranted('MEDICAL_RECORDS_ADMINISTRATION', $roleSubject))) {
  61. return self::ACCESS_GRANTED;
  62. }
  63. return self::ACCESS_DENIED;
  64. }
  65. }