diff --git a/src/Bundle/ChillCalendarBundle/Menu/AccompanyingCourseMenuBuilder.php b/src/Bundle/ChillCalendarBundle/Menu/AccompanyingCourseMenuBuilder.php index 3bf1850a4..9f5d2c7ca 100644 --- a/src/Bundle/ChillCalendarBundle/Menu/AccompanyingCourseMenuBuilder.php +++ b/src/Bundle/ChillCalendarBundle/Menu/AccompanyingCourseMenuBuilder.php @@ -11,44 +11,41 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Menu; +use Chill\CalendarBundle\Security\Voter\CalendarVoter; use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Knp\Menu\MenuItem; +use Symfony\Bundle\SecurityBundle\SecurityBundle; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Security\Core\Security; use Symfony\Contracts\Translation\TranslatorInterface; class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface { - protected AuthorizationHelper $authorizationHelper; - - protected TokenStorageInterface $tokenStorage; + private Security $security; protected TranslatorInterface $translator; public function __construct( - TokenStorageInterface $tokenStorage, - AuthorizationHelper $authorizationHelper, + Security $security, TranslatorInterface $translator ) { + $this->security = $security; $this->translator = $translator; - $this->authorizationHelper = $authorizationHelper; - $this->tokenStorage = $tokenStorage; } public function buildMenu($menuId, MenuItem $menu, array $parameters) { $period = $parameters['accompanyingCourse']; - if (AccompanyingPeriod::STEP_DRAFT !== $period->getStep()) { - /* + if ($this->security->isGranted(CalendarVoter::SEE, $period)) { $menu->addChild($this->translator->trans('Calendar'), [ 'route' => 'chill_calendar_calendar_list', 'routeParameters' => [ 'accompanying_period_id' => $period->getId(), ], ]) ->setExtras(['order' => 35]); - */ } } diff --git a/src/Bundle/ChillCalendarBundle/Security/Voter/CalendarVoter.php b/src/Bundle/ChillCalendarBundle/Security/Voter/CalendarVoter.php new file mode 100644 index 000000000..5cfaea172 --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Security/Voter/CalendarVoter.php @@ -0,0 +1,79 @@ +security = $security; + $this->voterHelper = $voterHelperFactory + ->generate(self::class) + ->addCheckFor(AccompanyingPeriod::class, [self::SEE]) + ->build(); + } + + public function getRolesWithHierarchy(): array + { + return ['Calendar' => $this->getRoles()]; + } + + public function getRoles(): array + { + return [ + self::SEE, + ]; + } + + public function getRolesWithoutScope(): array + { + return []; + } + + protected function supports($attribute, $subject): bool + { + return $this->voterHelper->supports($attribute, $subject); + } + + protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool + { + if ($subject instanceof AccompanyingPeriod) { + switch ($attribute) { + case self::SEE: + + if ($subject->getStep() === AccompanyingPeriod::STEP_DRAFT) { + return false; + } + + // we first check here that the user has read access to the period + return $this->security->isGranted(AccompanyingPeriodVoter::SEE, $subject); + default: + throw new \LogicException('subject not implemented'); + } + } + + throw new \LogicException('attribute not implemented'); + } + + +}