From d9e37d0958bf042f95e4a1b0b4927172ccc11d4c Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 14 Jun 2024 17:22:27 +0200 Subject: [PATCH] Refactorize StoredObjectVoter.php The StoredObjectVoter.php has been refactorized to handle context-specific voters.\ This way we can check if the context-specific voter should handle the authorization or not.\ If not, there is a simple fallback to check on the USER_ROLE. --- .../Authorization/StoredObjectVoter.php | 28 ++++++++++++++----- .../config/services/voter.yaml | 14 ++++++++++ 2 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 src/Bundle/ChillDocStoreBundle/config/services/voter.yaml diff --git a/src/Bundle/ChillDocStoreBundle/Security/Authorization/StoredObjectVoter.php b/src/Bundle/ChillDocStoreBundle/Security/Authorization/StoredObjectVoter.php index 2e253cf3c..ecfc56615 100644 --- a/src/Bundle/ChillDocStoreBundle/Security/Authorization/StoredObjectVoter.php +++ b/src/Bundle/ChillDocStoreBundle/Security/Authorization/StoredObjectVoter.php @@ -15,6 +15,7 @@ use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\Security\Guard\DavTokenAuthenticationEventSubscriber; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\Voter\Voter; +use Symfony\Component\Security\Core\Security; /** * Voter for the content of a stored object. @@ -23,6 +24,14 @@ use Symfony\Component\Security\Core\Authorization\Voter\Voter; */ class StoredObjectVoter extends Voter { + private $security; + private $storedObjectVoters; + + public function __construct(Security $security, iterable $storedObjectVoters) { + $this->security = $security; + $this->storedObjectVoters = $storedObjectVoters; + } + protected function supports($attribute, $subject): bool { return StoredObjectRoleEnum::tryFrom($attribute) instanceof StoredObjectRoleEnum @@ -43,13 +52,18 @@ class StoredObjectVoter extends Voter return false; } - $askedRole = StoredObjectRoleEnum::from($attribute); - $tokenRoleAuthorization = - $token->getAttribute(DavTokenAuthenticationEventSubscriber::ACTIONS); + // Loop through context-specific voters + foreach ($this->storedObjectVoters as $storedObjectVoter) { + if ($storedObjectVoter->supports($attribute, $subject)) { + return $storedObjectVoter->voteOnAttribute($attribute, $subject, $token); + } + } - return match ($askedRole) { - StoredObjectRoleEnum::SEE => StoredObjectRoleEnum::EDIT === $tokenRoleAuthorization || StoredObjectRoleEnum::SEE === $tokenRoleAuthorization, - StoredObjectRoleEnum::EDIT => StoredObjectRoleEnum::EDIT === $tokenRoleAuthorization - }; + // User role-based fallback + if ($this->security->isGranted('ROLE_USER')) { + return true; + } + + return false; } } diff --git a/src/Bundle/ChillDocStoreBundle/config/services/voter.yaml b/src/Bundle/ChillDocStoreBundle/config/services/voter.yaml new file mode 100644 index 000000000..922d29cba --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/config/services/voter.yaml @@ -0,0 +1,14 @@ +services: + _defaults: + autowire: true + autoconfigure: true + Chill\DocStoreBundle\Security\Authorization\StoredObjectVoter: + arguments: + $storedObjectVoters: + # context specific voters + - '@accompanying_course_document_voter' + tags: + - { name: security.voter } + + accompanying_course_document_voter: + class: Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter