diff --git a/DependencyInjection/ChillActivityExtension.php b/DependencyInjection/ChillActivityExtension.php index 844e13355..ab0059155 100644 --- a/DependencyInjection/ChillActivityExtension.php +++ b/DependencyInjection/ChillActivityExtension.php @@ -52,6 +52,7 @@ class ChillActivityExtension extends Extension implements PrependExtensionInterf $loader->load('services/export.yml'); $loader->load('services/repositories.yml'); $loader->load('services/fixtures.yml'); + $loader->load('services/menu.yml'); } public function prepend(ContainerBuilder $container) diff --git a/Menu/PersonMenuBuilder.php b/Menu/PersonMenuBuilder.php new file mode 100644 index 000000000..7c8092227 --- /dev/null +++ b/Menu/PersonMenuBuilder.php @@ -0,0 +1,83 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +namespace Chill\ActivityBundle\Menu; + +use Chill\MainBundle\Routing\LocalMenuBuilderInterface; +use Knp\Menu\MenuItem; +use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; +use Chill\ActivityBundle\Security\Authorization\ActivityVoter; +use Symfony\Component\Translation\TranslatorInterface; + +/** + * + * + * @author Julien Fastré + */ +class PersonMenuBuilder implements LocalMenuBuilderInterface +{ + /** + * + * @var TranslatorInterface + */ + protected $translator; + + /** + * + * @var AuthorizationCheckerInterface + */ + protected $authorizationChecker; + + public function __construct( + AuthorizationCheckerInterface $authorizationChecker, + TranslatorInterface $translator) + { + $this->translator = $translator; + $this->authorizationChecker = $authorizationChecker; + } + + + public function buildMenu($menuId, MenuItem $menu, array $parameters) + { + /* @var $person \Chill\PersonBundle\Entity\Person */ + $person = $parameters['person']; + + if ($this->authorizationChecker->isGranted(ActivityVoter::SEE, $person)) { + $menu->addChild( + $this->translator->trans('Activity list'), [ + 'route' => 'chill_activity_activity_list', + 'routeParameters' => [ 'person_id' => $person->getId() ], + ]) + ->setExtra('order', 201) + ; + } + if ($this->authorizationChecker->isGranted(ActivityVoter::CREATE, $person)) { + $menu->addChild( + $this->translator->trans('Add a new activity'), [ + 'route' => 'chill_activity_activity_new', + 'routeParameters' => [ 'person_id' => $person->getId() ], + ]) + ->setExtra('order', 200) + ; + } + } + + public static function getMenuIds(): array + { + return ['person']; + } +} diff --git a/Resources/config/routing/activity.yml b/Resources/config/routing/activity.yml index 6d287eec7..5b49b93e5 100644 --- a/Resources/config/routing/activity.yml +++ b/Resources/config/routing/activity.yml @@ -1,11 +1,6 @@ chill_activity_activity_list: path: /{_locale}/person/{person_id}/activity/ defaults: { _controller: "ChillActivityBundle:Activity:list" } - options: - menus: - person: - order: 201 - label: Activity list chill_activity_activity_show: path: /{_locale}/person/{person_id}/activity/{id}/show @@ -14,11 +9,6 @@ chill_activity_activity_show: chill_activity_activity_new: path: /{_locale}/person/{person_id}/activity/new defaults: { _controller: "ChillActivityBundle:Activity:new" } - options: - menus: - person: - order: 200 - label: Add a new activity chill_activity_activity_create: path: /{_locale}/person/{person_id}/activity/create diff --git a/Resources/config/services/menu.yml b/Resources/config/services/menu.yml new file mode 100644 index 000000000..a70eb0e05 --- /dev/null +++ b/Resources/config/services/menu.yml @@ -0,0 +1,7 @@ +services: + Chill\ActivityBundle\Menu\PersonMenuBuilder: + arguments: + $authorizationChecker: '@Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface' + $translator: '@Symfony\Component\Translation\TranslatorInterface' + tags: + - { name: 'chill.menu_builder' } \ No newline at end of file diff --git a/Security/Authorization/ActivityVoter.php b/Security/Authorization/ActivityVoter.php index 5d0d50906..79cb6d852 100644 --- a/Security/Authorization/ActivityVoter.php +++ b/Security/Authorization/ActivityVoter.php @@ -26,6 +26,8 @@ use Chill\MainBundle\Security\Authorization\AuthorizationHelper; use Chill\MainBundle\Security\ProvideRoleHierarchyInterface; use Chill\MainBundle\Entity\User; use Chill\ActivityBundle\Entity\Activity; +use Chill\PersonBundle\Entity\Person; +use Symfony\Component\Security\Core\Role\Role; /** * @@ -56,6 +58,10 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn { if ($subject instanceof Activity) { return \in_array($attribute, $this->getAttributes()); + } elseif ($subject instanceof Person) { + return $attribute === self::SEE + || + $attribute === self::CREATE; } else { return false; } @@ -66,6 +72,14 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn if (!$token->getUser() instanceof User) { return false; } + + if ($subject instanceof Person) { + $centers = $this->helper->getReachableCenters($token->getUser(), new Role($attribute)); + + return \in_array($subject->getCenter(), $centers); + } + + /* @var $subject Activity */ return $this->helper->userHasAccess($token->getUser(), $subject, $attribute); }