src/Security/Voter/OrthancAnnotationVoter.php line 14

Open in your IDE?
  1. <?php
  2. namespace MedBrief\MSR\Security\Voter;
  3. use InvalidArgumentException;
  4. use MedBrief\MSR\Entity\OrthancAnnotation;
  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 OrthancAnnotationVoter 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 function __construct(private readonly AuthorizationCheckerInterface $authorizationChecker)
  18. {
  19. }
  20. public function supportsAttribute($attribute): bool
  21. {
  22. return in_array($attribute, [
  23. self::CREATE,
  24. self::READ,
  25. self::UPDATE,
  26. self::DELETE,
  27. self::ADMINISTRATION,
  28. ]);
  29. }
  30. public function supportsClass($class): bool
  31. {
  32. $supportedClass = OrthancAnnotation::class;
  33. return $supportedClass === $class || is_subclass_of($class, $supportedClass);
  34. }
  35. /**
  36. *
  37. * @param mixed $entity
  38. */
  39. #[Override]
  40. public function vote(TokenInterface $token, $entity, array $attributes)
  41. {
  42. /**
  43. * START: This is common code for all Voter::vote() methods
  44. */
  45. // check if class of this object is supported by this voter
  46. if (!$this->supportsClass($entity && !is_array($entity) ? $entity::class : '')) {
  47. return VoterInterface::ACCESS_ABSTAIN;
  48. }
  49. // check if the voter is used correct, only allow one attribute
  50. // this isn't a requirement, it's just one easy way for you to
  51. // design your voter
  52. if (1 !== count($attributes)) {
  53. throw new InvalidArgumentException(
  54. 'Only one attribute is allowed for medbrief Voters.'
  55. );
  56. }
  57. // set the attribute to check against
  58. $attribute = $attributes[0];
  59. // check if the given attribute is covered by this voter
  60. if (!$this->supportsAttribute($attribute)) {
  61. return VoterInterface::ACCESS_ABSTAIN;
  62. }
  63. // get current logged in user
  64. $user = $token->getUser();
  65. // make sure there is a user object (i.e. that the user is logged in)
  66. if (!$user instanceof UserInterface) {
  67. return VoterInterface::ACCESS_DENIED;
  68. }
  69. // Admin and Super admin users can do everything.
  70. if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
  71. return VoterInterface::ACCESS_GRANTED;
  72. }
  73. /**
  74. * END: Common code for all Voter:vote() methods. Put custom logic below.
  75. */
  76. // Check if the user has access to the Document in order to determine if they can see the annotations.
  77. if ($entity->getDocument()) {
  78. // Retrieve the Document...
  79. $document = $entity->getDocument();
  80. // You need to be able to read the Project the Document
  81. if ($document && $document->getProject() && $this->authorizationChecker->isGranted('READ', $document->getProject())) {
  82. // The basic permissions for a Project is enough to allow CREATE of annotations.
  83. if ($attribute === self::CREATE) {
  84. return VoterInterface::ACCESS_GRANTED;
  85. }
  86. // If you can see an annotation, you can update or delete it at this time, due to a limitation of the
  87. // Osimis viewer.
  88. if ($attribute === self::READ || $attribute === self::UPDATE || $attribute === self::DELETE) {
  89. // If the annotation is public, everyone can see it.
  90. if ($user->isAccountAdministrator()) {
  91. // If the user is an account level administrator, they can see all annotations.
  92. return VoterInterface::ACCESS_GRANTED;
  93. } elseif ($this->authorizationChecker->isGranted('ROLE_PROJECT_' . $document->getProject()->getId() . '_PROJECTMANAGER')) {
  94. // If the user is a project manager for the Matter the document belongs to, they can see all annotations.
  95. return VoterInterface::ACCESS_GRANTED;
  96. } elseif ($entity->getCreator()->getId() == $user->getId()) {
  97. // Everyone can see their annotations
  98. return VoterInterface::ACCESS_GRANTED;
  99. }
  100. }
  101. }
  102. }
  103. // If we get to the end of this function, then no decisions have been
  104. // made so we deny access
  105. return VoterInterface::ACCESS_DENIED;
  106. }
  107. }