diff --git a/DependencyInjection/ChillPersonExtension.php b/DependencyInjection/ChillPersonExtension.php index 31d68701c..29fe2d828 100644 --- a/DependencyInjection/ChillPersonExtension.php +++ b/DependencyInjection/ChillPersonExtension.php @@ -26,6 +26,7 @@ use Symfony\Component\DependencyInjection\Loader; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; use Chill\MainBundle\DependencyInjection\MissingBundleException; use Chill\PersonBundle\Security\Authorization\PersonVoter; +use Chill\MainBundle\Security\Authorization\ChillExportVoter; use Chill\PersonBundle\Doctrine\DQL\AddressPart; /** @@ -60,6 +61,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac $loader->load('services/fixtures.yml'); $loader->load('services/controller.yml'); $loader->load('services/search.yml'); + $loader->load('services/menu.yml'); } private function handlePersonFieldsParameters(ContainerBuilder $container, $config) @@ -163,7 +165,9 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac $container->prependExtensionConfig('security', array( 'role_hierarchy' => array( 'CHILL_PERSON_UPDATE' => array('CHILL_PERSON_SEE'), - 'CHILL_PERSON_CREATE' => array('CHILL_PERSON_SEE') + 'CHILL_PERSON_CREATE' => array('CHILL_PERSON_SEE'), + PersonVoter::LISTS => [ ChillExportVoter::EXPORT ], + PersonVoter::STATS => [ ChillExportVoter::EXPORT ] ) )); } diff --git a/Menu/SectionMenuBuilder.php b/Menu/SectionMenuBuilder.php new file mode 100644 index 000000000..9a4380144 --- /dev/null +++ b/Menu/SectionMenuBuilder.php @@ -0,0 +1,61 @@ + + * + * 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\PersonBundle\Menu; + +use Chill\MainBundle\Routing\LocalMenuBuilderInterface; +use Knp\Menu\MenuItem; +use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; +use Chill\PersonBundle\Security\Authorization\PersonVoter; + +/** + * + * + * @author Julien Fastré + */ +class SectionMenuBuilder implements LocalMenuBuilderInterface +{ + /** + * + * @var AuthorizationCheckerInterface + */ + protected $authorizationChecker; + + public function __construct(AuthorizationCheckerInterface $authorizationChecker) + { + $this->authorizationChecker = $authorizationChecker; + } + + + public function buildMenu($menuId, MenuItem $menu, array $parameters) + { + if ($this->authorizationChecker->isGranted(PersonVoter::CREATE)) { + $menu->addChild('Add a person', [ + 'route' => 'chill_person_new' + ]) + ->setExtras([ + 'order' => 10, + 'icons' => [ 'plus' ] + ]); + } + } + + public static function getMenuIds(): array + { + return [ 'section' ]; + } +} diff --git a/Resources/config/routing.yml b/Resources/config/routing.yml index 6792ca184..56244cae3 100644 --- a/Resources/config/routing.yml +++ b/Resources/config/routing.yml @@ -18,12 +18,6 @@ chill_person_general_update: chill_person_new: path: /{_locale}/person/new defaults: {_controller: ChillPersonBundle:Person:new } - options: - menus: - section: - order: 10 - label: Add a person - icons: [plus] chill_person_review: path: /{_locale}/person/review diff --git a/Resources/config/services/menu.yml b/Resources/config/services/menu.yml new file mode 100644 index 000000000..09b24d86b --- /dev/null +++ b/Resources/config/services/menu.yml @@ -0,0 +1,6 @@ +services: + Chill\PersonBundle\Menu\SectionMenuBuilder: + arguments: + $authorizationChecker: '@Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface' + tags: + - { name: 'chill.menu_builder' } diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml index d8ecaba1c..9fe24c79b 100644 --- a/Resources/translations/messages.fr.yml +++ b/Resources/translations/messages.fr.yml @@ -139,6 +139,7 @@ Add an address: Ajouter une adresse Back to the person details: Retour aux détails de la personne #timeline +Timeline: Historique Closing the accompanying period: Fermeture de la période d'accompagnement Opening the accompanying period: Ouverture d'une période d'accompagnement diff --git a/Security/Authorization/PersonVoter.php b/Security/Authorization/PersonVoter.php index 9b4899c65..1d3229567 100644 --- a/Security/Authorization/PersonVoter.php +++ b/Security/Authorization/PersonVoter.php @@ -26,6 +26,7 @@ use Chill\MainBundle\Security\ProvideRoleHierarchyInterface; use Chill\PersonBundle\Entity\Person; use Chill\MainBundle\Entity\Center; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Role\Role; /** * @@ -61,6 +62,8 @@ class PersonVoter extends AbstractChillVoter implements ProvideRoleHierarchyInte return \in_array($attribute, [ self::STATS, self::LISTS ]); + } elseif ($subject === null) { + return $attribute === self::CREATE; } else { return false; } @@ -72,6 +75,13 @@ class PersonVoter extends AbstractChillVoter implements ProvideRoleHierarchyInte return false; } + if ($subject === null) { + $centers = $this->helper->getReachableCenters($token->getUser(), + new Role($attribute)); + + return count($centers) > 0; + } + return $this->helper->userHasAccess($token->getUser(), $subject, $attribute); }