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.
This commit is contained in:
Julie Lenaerts 2024-06-14 17:22:27 +02:00
parent 65c41e6fa9
commit d9e37d0958
2 changed files with 35 additions and 7 deletions

View File

@ -15,6 +15,7 @@ use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Security\Guard\DavTokenAuthenticationEventSubscriber; use Chill\DocStoreBundle\Security\Guard\DavTokenAuthenticationEventSubscriber;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter; use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
/** /**
* Voter for the content of a stored object. * Voter for the content of a stored object.
@ -23,6 +24,14 @@ use Symfony\Component\Security\Core\Authorization\Voter\Voter;
*/ */
class StoredObjectVoter extends 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 protected function supports($attribute, $subject): bool
{ {
return StoredObjectRoleEnum::tryFrom($attribute) instanceof StoredObjectRoleEnum return StoredObjectRoleEnum::tryFrom($attribute) instanceof StoredObjectRoleEnum
@ -43,13 +52,18 @@ class StoredObjectVoter extends Voter
return false; return false;
} }
$askedRole = StoredObjectRoleEnum::from($attribute); // Loop through context-specific voters
$tokenRoleAuthorization = foreach ($this->storedObjectVoters as $storedObjectVoter) {
$token->getAttribute(DavTokenAuthenticationEventSubscriber::ACTIONS); if ($storedObjectVoter->supports($attribute, $subject)) {
return $storedObjectVoter->voteOnAttribute($attribute, $subject, $token);
}
}
return match ($askedRole) { // User role-based fallback
StoredObjectRoleEnum::SEE => StoredObjectRoleEnum::EDIT === $tokenRoleAuthorization || StoredObjectRoleEnum::SEE === $tokenRoleAuthorization, if ($this->security->isGranted('ROLE_USER')) {
StoredObjectRoleEnum::EDIT => StoredObjectRoleEnum::EDIT === $tokenRoleAuthorization return true;
}; }
return false;
} }
} }

View File

@ -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