From 5b95336bac7f503f45aed53f49bd49b031c1715e Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 17 Jul 2024 13:10:51 +0200 Subject: [PATCH] Fix event and participation voters --- .../ChillEventBundle/Security/EventVoter.php | 62 ++++++------------- .../Security/ParticipationVoter.php | 59 ++++++------------ 2 files changed, 39 insertions(+), 82 deletions(-) diff --git a/src/Bundle/ChillEventBundle/Security/EventVoter.php b/src/Bundle/ChillEventBundle/Security/EventVoter.php index 0bcf9936c..e490e0518 100644 --- a/src/Bundle/ChillEventBundle/Security/EventVoter.php +++ b/src/Bundle/ChillEventBundle/Security/EventVoter.php @@ -12,15 +12,16 @@ declare(strict_types=1); namespace Chill\EventBundle\Security; use Chill\EventBundle\Entity\Event; +use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Security\Authorization\AbstractChillVoter; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; +use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface; +use Chill\MainBundle\Security\Authorization\VoterHelperInterface; use Chill\MainBundle\Security\ProvideRoleHierarchyInterface; use Chill\PersonBundle\Entity\Person; -use Chill\PersonBundle\Security\Authorization\PersonVoter; use Psr\Log\LoggerInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; /** * Description of EventVoter. @@ -42,61 +43,46 @@ class EventVoter extends AbstractChillVoter implements ProvideRoleHierarchyInter final public const UPDATE = 'CHILL_EVENT_UPDATE'; - /** - * @var AccessDecisionManagerInterface - */ - protected $accessDecisionManager; + final public const STATS = 'CHILL_EVENT_STATS'; - /** - * @var AuthorizationHelper - */ - protected $authorizationHelper; - - /** - * @var LoggerInterface - */ - protected $logger; + private readonly VoterHelperInterface $voterHelper; public function __construct( - AccessDecisionManagerInterface $accessDecisionManager, - AuthorizationHelper $authorizationHelper, - LoggerInterface $logger + private readonly AuthorizationHelper $authorizationHelper, + private readonly LoggerInterface $logger, + VoterHelperFactoryInterface $voterHelperFactory ) { - $this->accessDecisionManager = $accessDecisionManager; - $this->authorizationHelper = $authorizationHelper; - $this->logger = $logger; + $this->voterHelper = $voterHelperFactory + ->generate(self::class) + ->addCheckFor(null, [self::SEE]) + ->addCheckFor(Event::class, [...self::ROLES]) + ->addCheckFor(Person::class, [self::SEE, self::CREATE]) + ->addCheckFor(Center::class, [self::STATS]) + ->build(); } public function getRoles(): array { - return self::ROLES; + return [...self::ROLES, self::STATS]; } public function getRolesWithHierarchy(): array { return [ - 'Event' => self::ROLES, + 'Event' => $this->getRoles(), ]; } public function getRolesWithoutScope(): array { - return []; + return [self::ROLES, self::STATS]; } public function supports($attribute, $subject) { - return ($subject instanceof Event && \in_array($attribute, self::ROLES, true)) - || ($subject instanceof Person && \in_array($attribute, [self::CREATE, self::SEE], true)) - || (null === $subject && self::SEE === $attribute); + return $this->voterHelper->supports($attribute, $subject); } - /** - * @param string $attribute - * @param Event $subject - * - * @return bool - */ protected function voteOnAttribute($attribute, $subject, TokenInterface $token) { $this->logger->debug(sprintf('Voting from %s class', self::class)); @@ -118,15 +104,5 @@ class EventVoter extends AbstractChillVoter implements ProvideRoleHierarchyInter ->getReachableCenters($token->getUser(), $attribute); return \count($centers) > 0; - - if (!$this->accessDecisionManager->decide($token, [PersonVoter::SEE], $person)) { - return false; - } - - return $this->authorizationHelper->userHasAccess( - $token->getUser(), - $subject, - $attribute - ); } } diff --git a/src/Bundle/ChillEventBundle/Security/ParticipationVoter.php b/src/Bundle/ChillEventBundle/Security/ParticipationVoter.php index c2cb45206..368a47cab 100644 --- a/src/Bundle/ChillEventBundle/Security/ParticipationVoter.php +++ b/src/Bundle/ChillEventBundle/Security/ParticipationVoter.php @@ -12,15 +12,16 @@ declare(strict_types=1); namespace Chill\EventBundle\Security; use Chill\EventBundle\Entity\Participation; +use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Security\Authorization\AbstractChillVoter; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; +use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface; +use Chill\MainBundle\Security\Authorization\VoterHelperInterface; use Chill\MainBundle\Security\ProvideRoleHierarchyInterface; use Chill\PersonBundle\Entity\Person; -use Chill\PersonBundle\Security\Authorization\PersonVoter; use Psr\Log\LoggerInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; class ParticipationVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface { @@ -39,58 +40,48 @@ class ParticipationVoter extends AbstractChillVoter implements ProvideRoleHierar final public const UPDATE = 'CHILL_EVENT_PARTICIPATION_UPDATE'; - /** - * @var AccessDecisionManagerInterface - */ - protected $accessDecisionManager; + final public const STATS = 'CHILL_EVENT_PARTICIPATION_STATS'; - /** - * @var AuthorizationHelper - */ - protected $authorizationHelper; - - /** - * @var LoggerInterface - */ - protected $logger; + private readonly VoterHelperInterface $voterHelper; public function __construct( - AccessDecisionManagerInterface $accessDecisionManager, - AuthorizationHelper $authorizationHelper, - LoggerInterface $logger + private readonly AuthorizationHelper $authorizationHelper, + private readonly LoggerInterface $logger, + VoterHelperFactoryInterface $voterHelperFactory ) { - $this->accessDecisionManager = $accessDecisionManager; - $this->authorizationHelper = $authorizationHelper; - $this->logger = $logger; + $this->voterHelper = $voterHelperFactory + ->generate(self::class) + ->addCheckFor(null, [self::SEE]) + ->addCheckFor(Participation::class, [...self::ROLES]) + ->addCheckFor(Person::class, [self::SEE, self::CREATE]) + ->addCheckFor(Center::class, [self::STATS]) + ->build(); } public function getRoles(): array { - return self::ROLES; + return [...self::ROLES, self::STATS]; } public function getRolesWithHierarchy(): array { return [ - 'Event' => self::ROLES, + 'Participation' => $this->getRoles(), ]; } public function getRolesWithoutScope(): array { - return []; + return [self::ROLES, self::STATS]; } public function supports($attribute, $subject) { - return ($subject instanceof Participation && \in_array($attribute, self::ROLES, true)) - || ($subject instanceof Person && \in_array($attribute, [self::CREATE, self::SEE], true)) - || (null === $subject && self::SEE === $attribute); + return $this->voterHelper->supports($attribute, $subject); } /** - * @param string $attribute - * @param Participation $subject + * @param string $attribute * * @return bool */ @@ -115,15 +106,5 @@ class ParticipationVoter extends AbstractChillVoter implements ProvideRoleHierar ->getReachableCenters($token->getUser(), $attribute); return \count($centers) > 0; - - if (!$this->accessDecisionManager->decide($token, [PersonVoter::SEE], $person)) { - return false; - } - - return $this->authorizationHelper->userHasAccess( - $token->getUser(), - $subject, - $attribute - ); } }