From dc09c9424a0cd1958736bb77e185ea71b4da08f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 3 Sep 2021 12:43:12 +0200 Subject: [PATCH] refactor ACL for easy voter. Apply on TaskVoter --- .../Authorization/PersonDocumentVoter.php | 33 ++-- .../Form/Event/CustomizeFormEvent.php | 36 ++++ .../Authorization/AbstractChillVoter.php | 12 +- .../Authorization/AuthorizationHelper.php | 154 ++++++++++-------- .../Security/Authorization/DefaultVoter.php | 69 ++++++++ .../Authorization/DefaultVoterFactory.php | 27 +++ .../Authorization/VoterFactoryInterface.php | 7 + .../Security/Authorization/VoterGenerator.php | 36 ++++ .../Authorization/VoterGeneratorInterface.php | 7 + .../Security/Authorization/VoterInterface.php | 7 + .../Resolver/CenterResolverDispatcherTest.php | 27 +++ .../config/services/security.yaml | 34 +++- .../Security/Authorization/TaskVoter.php | 93 +++++++---- .../config/services/security.yaml | 8 +- 14 files changed, 411 insertions(+), 139 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/Form/Event/CustomizeFormEvent.php create mode 100644 src/Bundle/ChillMainBundle/Security/Authorization/DefaultVoter.php create mode 100644 src/Bundle/ChillMainBundle/Security/Authorization/DefaultVoterFactory.php create mode 100644 src/Bundle/ChillMainBundle/Security/Authorization/VoterFactoryInterface.php create mode 100644 src/Bundle/ChillMainBundle/Security/Authorization/VoterGenerator.php create mode 100644 src/Bundle/ChillMainBundle/Security/Authorization/VoterGeneratorInterface.php create mode 100644 src/Bundle/ChillMainBundle/Security/Authorization/VoterInterface.php create mode 100644 src/Bundle/ChillMainBundle/Tests/Security/Resolver/CenterResolverDispatcherTest.php diff --git a/src/Bundle/ChillDocStoreBundle/Security/Authorization/PersonDocumentVoter.php b/src/Bundle/ChillDocStoreBundle/Security/Authorization/PersonDocumentVoter.php index 78429b439..c92971b8f 100644 --- a/src/Bundle/ChillDocStoreBundle/Security/Authorization/PersonDocumentVoter.php +++ b/src/Bundle/ChillDocStoreBundle/Security/Authorization/PersonDocumentVoter.php @@ -23,6 +23,7 @@ use Chill\MainBundle\Security\Authorization\AbstractChillVoter; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; use Chill\MainBundle\Security\ProvideRoleHierarchyInterface; use Chill\DocStoreBundle\Entity\PersonDocument; +use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher; use Chill\PersonBundle\Entity\Person; use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Security\Authorization\PersonVoter; @@ -42,30 +43,25 @@ class PersonDocumentVoter extends AbstractChillVoter implements ProvideRoleHiera const UPDATE = 'CHILL_PERSON_DOCUMENT_UPDATE'; const DELETE = 'CHILL_PERSON_DOCUMENT_DELETE'; - /** - * @var AuthorizationHelper - */ - protected $authorizationHelper; + protected AuthorizationHelper $authorizationHelper; - /** - * @var AccessDecisionManagerInterface - */ - protected $accessDecisionManager; + protected AccessDecisionManagerInterface $accessDecisionManager; - /** - * @var LoggerInterface - */ - protected $logger; + protected LoggerInterface $logger; + + protected CenterResolverDispatcher $centerResolverDispatcher; public function __construct( AccessDecisionManagerInterface $accessDecisionManager, AuthorizationHelper $authorizationHelper, - LoggerInterface $logger + LoggerInterface $logger//, + //CenterResolverDispatcher $centerResolverDispatcher ) { $this->accessDecisionManager = $accessDecisionManager; $this->authorizationHelper = $authorizationHelper; $this->logger = $logger; + //$this->centerResolverDispatcher = $centerResolverDispatcher; } public function getRoles() @@ -78,17 +74,18 @@ class PersonDocumentVoter extends AbstractChillVoter implements ProvideRoleHiera self::DELETE ]; } - + protected function supports($attribute, $subject) { if (\in_array($attribute, $this->getRoles()) && $subject instanceof PersonDocument) { return true; } - - if ($subject instanceof Person && $attribute === self::CREATE) { + + if ($subject instanceof Person + && \in_array($attribute, [self::CREATE, self::SEE])) { return true; } - + return false; } @@ -107,6 +104,8 @@ class PersonDocumentVoter extends AbstractChillVoter implements ProvideRoleHiera return false; } + $center = $this->centerResolverDispatcher->resolveCenter($subject); + if ($subject instanceof PersonDocument) { return $this->authorizationHelper->userHasAccess($token->getUser(), $subject, $attribute); diff --git a/src/Bundle/ChillMainBundle/Form/Event/CustomizeFormEvent.php b/src/Bundle/ChillMainBundle/Form/Event/CustomizeFormEvent.php new file mode 100644 index 000000000..43fab6f62 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Form/Event/CustomizeFormEvent.php @@ -0,0 +1,36 @@ +type = $type; + $this->builder = $builder; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * @return FormBuilderInterface + */ + public function getBuilder(): FormBuilderInterface + { + return $this->builder; + } +} diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/AbstractChillVoter.php b/src/Bundle/ChillMainBundle/Security/Authorization/AbstractChillVoter.php index 842fc5ecc..9131a6501 100644 --- a/src/Bundle/ChillMainBundle/Security/Authorization/AbstractChillVoter.php +++ b/src/Bundle/ChillMainBundle/Security/Authorization/AbstractChillVoter.php @@ -23,8 +23,8 @@ use Symfony\Component\Security\Core\Authorization\Voter\Voter; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; /** - * Voter for Chill software. - * + * Voter for Chill software. + * * This abstract Voter provide generic methods to handle object specific to Chill * * @@ -36,20 +36,20 @@ abstract class AbstractChillVoter extends Voter implements ChillVoterInterface { @trigger_error('This voter should implements the new `supports` ' . 'methods introduced by Symfony 3.0, and do not rely on ' - . 'getSupportedAttributes and getSupportedClasses methods.', + . 'getSupportedAttributes and getSupportedClasses methods.', E_USER_DEPRECATED); return \in_array($attribute, $this->getSupportedAttributes($attribute)) && \in_array(\get_class($subject), $this->getSupportedClasses()); } - + protected function voteOnAttribute($attribute, $subject, TokenInterface $token) { @trigger_error('This voter should implements the new `voteOnAttribute` ' . 'methods introduced by Symfony 3.0, and do not rely on ' . 'isGranted method', E_USER_DEPRECATED); - + return $this->isGranted($attribute, $subject, $token->getUser()); } - + } diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php index 697158bf8..ab1d1aed1 100644 --- a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php +++ b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php @@ -23,6 +23,8 @@ use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\HasCenterInterface; use Chill\MainBundle\Entity\HasScopeInterface; +use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Security\Core\Role\RoleHierarchyInterface; use Symfony\Component\Security\Core\Role\Role; use Chill\MainBundle\Entity\Scope; @@ -32,87 +34,97 @@ use Chill\MainBundle\Entity\GroupCenter; use Chill\MainBundle\Entity\RoleScope; /** - * Helper for authorizations. - * + * Helper for authorizations. + * * Provides methods for user and entities information. * * @author Julien Fastré */ class AuthorizationHelper { + protected RoleHierarchyInterface $roleHierarchy; + /** - * - * @var RoleHierarchyInterface - */ - protected $roleHierarchy; - - /** - * The role in a hierarchy, given by the parameter + * The role in a hierarchy, given by the parameter * `security.role_hierarchy.roles` from the container. * * @var string[] */ - protected $hierarchy; - - /** - * - * @var EntityManagerInterface - */ - protected $em; - + protected array $hierarchy; + + protected EntityManagerInterface $em; + + protected CenterResolverDispatcher $centerResolverDispatcher; + public function __construct( RoleHierarchyInterface $roleHierarchy, - $hierarchy, - EntityManagerInterface $em + ParameterBagInterface $parameterBag, + EntityManagerInterface $em, + CenterResolverDispatcher $centerResolverDispatcher ) { $this->roleHierarchy = $roleHierarchy; - $this->hierarchy = $hierarchy; + $this->hierarchy = $parameterBag->get('security.role_hierarchy.roles'); $this->em = $em; + $this->centerResolverDispatcher = $centerResolverDispatcher; } - + /** * Determines if a user is active on this center - * + * + * If + * * @param User $user - * @param Center $center + * @param Center|Center[] $center May be an array of center * @return bool */ - public function userCanReachCenter(User $user, Center $center) + public function userCanReachCenter(User $user, $center) { - foreach ($user->getGroupCenters() as $groupCenter) { - if ($center->getId() === $groupCenter->getCenter()->getId()) { - - return true; + if ($center instanceof \Traversable) { + foreach ($center as $c) { + if ($c->userCanReachCenter($user, $c)) { + return true; + } } + return false; + } elseif ($center instanceof Center) { + foreach ($user->getGroupCenters() as $groupCenter) { + if ($center->getId() === $groupCenter->getCenter()->getId()) { + return true; + } + } + + return false; } - - return false; + + throw new \UnexpectedValueException(sprintf("The entity given is not an ". + "instance of %s, %s given", Center::class, get_class($center))); } - + /** - * + * * Determines if the user has access to the given entity. - * + * * if the entity implements Chill\MainBundle\Entity\HasScopeInterface, * the scope is taken into account. - * + * * @param User $user - * @param HasCenterInterface $entity the entity may also implement HasScopeInterface + * @param mixed $entity the entity may also implement HasScopeInterface * @param string|Role $attribute * @return boolean true if the user has access */ - public function userHasAccess(User $user, HasCenterInterface $entity, $attribute) + public function userHasAccess(User $user, $entity, $attribute) { - - $center = $entity->getCenter(); - + if (NULL === $center = $this->centerResolverDispatcher->resolveCenter($entity)) { + return false; + } + if (!$this->userCanReachCenter($user, $center)) { return false; } - + foreach ($user->getGroupCenters() as $groupCenter){ //filter on center - if ($groupCenter->getCenter()->getId() === $entity->getCenter()->getId()) { + if ($groupCenter->getCenter() === $center) { $permissionGroup = $groupCenter->getPermissionsGroup(); //iterate on roleScopes foreach($permissionGroup->getRoleScopes() as $roleScope) { @@ -134,17 +146,17 @@ class AuthorizationHelper } } } - + } } - + return false; } - + /** * Get reachable Centers for the given user, role, * and optionnaly Scope - * + * * @param User $user * @param string|Role $role * @param null|Scope $scope @@ -156,7 +168,7 @@ class AuthorizationHelper $role = $role->getRole(); } $centers = array(); - + foreach ($user->getGroupCenters() as $groupCenter){ $permissionGroup = $groupCenter->getPermissionsGroup(); //iterate on roleScopes @@ -170,13 +182,13 @@ class AuthorizationHelper if ($scope->getId() == $roleScope->getScope()->getId()){ $centers[] = $groupCenter->getCenter(); break 1; - } + } } } } - + } - + return $centers; } @@ -203,10 +215,10 @@ class AuthorizationHelper return $results; } - + /** * Return all reachable scope for a given user, center and role - * + * * @deprecated Use getReachableCircles * * @param User $user @@ -222,10 +234,10 @@ class AuthorizationHelper return $this->getReachableCircles($user, $role, $center); } - + /** * Return all reachable circle for a given user, center and role - * + * * @param User $user * @param string|Role $role * @param Center $center @@ -237,7 +249,7 @@ class AuthorizationHelper $role = $role->getRole(); } $scopes = array(); - + foreach ($user->getGroupCenters() as $groupCenter){ if ($center->getId() === $groupCenter->getCenter()->getId()) { //iterate on permissionGroup @@ -251,12 +263,12 @@ class AuthorizationHelper } } } - + return $scopes; } - + /** - * + * * @param Role $role * @param Center $center * @param Scope $circle @@ -267,7 +279,7 @@ class AuthorizationHelper $parents = $this->getParentRoles($role); $parents[] = $role; $parentRolesString = \array_map(function(Role $r) { return $r->getRole(); }, $parents); - + $qb = $this->em->createQueryBuilder(); $qb ->select('u') @@ -278,21 +290,21 @@ class AuthorizationHelper ->where('gc.center = :center') ->andWhere($qb->expr()->in('rs.role', $parentRolesString)) ; - + $qb->setParameter('center', $center); - + if ($circle !== null) { $qb->andWhere('rs.scope = :circle') ->setParameter('circle', $circle) ; } - + return $qb->getQuery()->getResult(); } - + /** * Test if a parent role may give access to a given child role - * + * * @param Role $childRole The role we want to test if he is reachable * @param Role $parentRole The role which should give access to $childRole * @return boolean true if the child role is granted by parent role @@ -301,14 +313,14 @@ class AuthorizationHelper { $reachableRoles = $this->roleHierarchy ->getReachableRoleNames([$parentRole]); - + return in_array($childRole, $reachableRoles); } - + /** - * Return all the role which give access to the given role. Only the role + * Return all the role which give access to the given role. Only the role * which are registered into Chill are taken into account. - * + * * @param Role $role * @return Role[] the role which give access to the given $role */ @@ -319,18 +331,18 @@ class AuthorizationHelper $roles = \array_map( function($string) { return new Role($string); - }, + }, \array_keys($this->hierarchy) ); - + foreach ($roles as $r) { $childRoles = $this->roleHierarchy->getReachableRoleNames([$r->getRole()]); - + if (\in_array($role, $childRoles)) { $parentRoles[] = $r; } } - + return $parentRoles; } } diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/DefaultVoter.php b/src/Bundle/ChillMainBundle/Security/Authorization/DefaultVoter.php new file mode 100644 index 000000000..98882b876 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Security/Authorization/DefaultVoter.php @@ -0,0 +1,69 @@ +authorizationHelper = $authorizationHelper; + $this->centerResolverDispatcher = $centerResolverDispatcher; + $this->configuration = $configuration; + } + + public function supports($attribute, $subject): bool + { + foreach ($this->configuration as list($attributes, $subj)) { + if ($subj === null) { + if ($subject === null && \in_array($attribute, $attributes)) { + return true; + } + } elseif ($subject instanceof $subj) { + return \in_array($attribute, $attributes); + } + } + + return false; + } + + public function voteOnAttribute($attribute, $subject, $token): bool + { + if (!$token->getUser() instanceof User) { + return false; + } + + if (NULL === $subject) { + if (NULL === $center = $this->centerResolverDispatcher + ->resolveCenter($subject)) { + return false; + } + return $this->authorizationHelper->userCanReachCenter( + $token->getUser(), + $center + ); + } + + return $this->authorizationHelper->userHasAccess( + $token->getUser(), + $subject, + $attribute + ); + } +} diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/DefaultVoterFactory.php b/src/Bundle/ChillMainBundle/Security/Authorization/DefaultVoterFactory.php new file mode 100644 index 000000000..4f3f232d9 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Security/Authorization/DefaultVoterFactory.php @@ -0,0 +1,27 @@ +authorizationHelper = $authorizationHelper; + $this->centerResolverDispatcher = $centerResolverDispatcher; + } + + public function generate($context): VoterGeneratorInterface + { + return new VoterGenerator( + $this->authorizationHelper, + $this->centerResolverDispatcher + ); + } +} diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/VoterFactoryInterface.php b/src/Bundle/ChillMainBundle/Security/Authorization/VoterFactoryInterface.php new file mode 100644 index 000000000..b12739674 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Security/Authorization/VoterFactoryInterface.php @@ -0,0 +1,7 @@ +authorizationHelper = $authorizationHelper; + $this->centerResolverDispatcher = $centerResolverDispatcher; + } + + public function addCheckFor($subject, $attributes): self + { + $this->configuration[] = [$attributes, $subject]; + + return $this; + } + + public function build(): VoterInterface + { + return new DefaultVoter( + $this->authorizationHelper, + $this->centerResolverDispatcher, + $this->configuration + ); + } +} diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/VoterGeneratorInterface.php b/src/Bundle/ChillMainBundle/Security/Authorization/VoterGeneratorInterface.php new file mode 100644 index 000000000..0aaf04ecd --- /dev/null +++ b/src/Bundle/ChillMainBundle/Security/Authorization/VoterGeneratorInterface.php @@ -0,0 +1,7 @@ +dispatcher = self::$container->get(CenterResolverDispatcher::class); + } + + public function testResolveCenter() + { + $center = new Center(); + + $resolved = $this->dispatcher->resolveCenter($center); + + $this->assertSame($center, $resolved); + } +} diff --git a/src/Bundle/ChillMainBundle/config/services/security.yaml b/src/Bundle/ChillMainBundle/config/services/security.yaml index 474ac0093..405dce19b 100644 --- a/src/Bundle/ChillMainBundle/config/services/security.yaml +++ b/src/Bundle/ChillMainBundle/config/services/security.yaml @@ -3,12 +3,38 @@ services: autowire: true autoconfigure: true + # do not autowire the directory Security/Resolver + Chill\MainBundle\Security\Resolver\CenterResolverDispatcher: + arguments: + - !tagged_iterator chill_main.center_resolver + + # do not autowire the directory Security/Resolver + _instanceof: + Chill\MainBundle\Security\Resolver\CenterResolverInterface: + tags: + - chill_main.center_resolver + + # do not autowire the directory Security/Resolver + Chill\MainBundle\Security\Resolver\DefaultCenterResolver: + autoconfigure: true + autowire: true + + # do not autowire the directory Security/Resolver + Chill\MainBundle\Security\Resolver\ResolverTwigExtension: + autoconfigure: true + autowire: true + + # do not autowire the directory Security/Resolver + Chill\MainBundle\Security\Authorization\DefaultVoterFactory: + autowire: true + + # do not autowire the directory Security/Resolver + Chill\MainBundle\Security\Authorization\VoterFactoryInterface: '@Chill\MainBundle\Security\Authorization\DefaultVoterFactory' + chill.main.security.authorization.helper: class: Chill\MainBundle\Security\Authorization\AuthorizationHelper - arguments: - $roleHierarchy: "@security.role_hierarchy" - $hierarchy: "%security.role_hierarchy.roles%" - $em: '@Doctrine\ORM\EntityManagerInterface' + autowire: true + autoconfigure: true Chill\MainBundle\Security\Authorization\AuthorizationHelper: '@chill.main.security.authorization.helper' chill.main.role_provider: diff --git a/src/Bundle/ChillTaskBundle/Security/Authorization/TaskVoter.php b/src/Bundle/ChillTaskBundle/Security/Authorization/TaskVoter.php index 8b8bce839..7c4f2d4d9 100644 --- a/src/Bundle/ChillTaskBundle/Security/Authorization/TaskVoter.php +++ b/src/Bundle/ChillTaskBundle/Security/Authorization/TaskVoter.php @@ -18,7 +18,12 @@ namespace Chill\TaskBundle\Security\Authorization; +use Chill\EventBundle\Entity\Event; +use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Security\Authorization\AbstractChillVoter; +use Chill\MainBundle\Security\Authorization\VoterFactoryInterface; +use Chill\MainBundle\Security\Authorization\VoterInterface; +use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher; use Chill\TaskBundle\Entity\AbstractTask; use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; @@ -32,12 +37,7 @@ use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Chill\TaskBundle\Security\Authorization\AuthorizationEvent; -/** - * - * - * @author Julien Fastré - */ -class TaskVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface +final class TaskVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface { const CREATE = 'CHILL_TASK_TASK_CREATE'; const UPDATE = 'CHILL_TASK_TASK_UPDATE'; @@ -51,50 +51,52 @@ class TaskVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterf self::DELETE ]; - /** - * - * @var AuthorizationHelper - */ - protected $authorizationHelper; + protected AuthorizationHelper $authorizationHelper; - /** - * - * @var AccessDecisionManagerInterface - */ - protected $accessDecisionManager; + protected AccessDecisionManagerInterface $accessDecisionManager; - /** - * - * @var LoggerInterface - */ - protected $logger; - - /** - * - * @var EventDispatcherInterface - */ - protected $eventDispatcher; + protected LoggerInterface $logger; + + protected EventDispatcherInterface $eventDispatcher; + + protected CenterResolverDispatcher $centerResolverDispatcher; + + protected VoterInterface $voter; public function __construct( AccessDecisionManagerInterface $accessDecisionManager, AuthorizationHelper $authorizationHelper, EventDispatcherInterface $eventDispatcher, - LoggerInterface $logger + LoggerInterface $logger, + CenterResolverDispatcher $centerResolverDispatcher, + VoterFactoryInterface $voterFactory ) { $this->accessDecisionManager = $accessDecisionManager; $this->authorizationHelper = $authorizationHelper; $this->eventDispatcher = $eventDispatcher; $this->logger = $logger; + $this->centerResolverDispatcher = $centerResolverDispatcher; + + $this->voter = $voterFactory + ->generate(AbstractTask::class) + ->addCheckFor(AbstractTask::class, self::ROLES) + ->addCheckFor(Person::class, [self::SHOW]) + ->addCheckFor(null, [self::SHOW]) + ->build() + ; } public function supports($attribute, $subject) { + return $this->voter->supports($attribute, $subject); + /* return ($subject instanceof AbstractTask && in_array($attribute, self::ROLES)) || ($subject instanceof Person && \in_array($attribute, [ self::CREATE, self::SHOW ])) || (NULL === $subject && $attribute === self::SHOW ) ; + */ } /** @@ -111,40 +113,60 @@ class TaskVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterf if (!$token->getUser() instanceof User) { return false; } - + $event = new AuthorizationEvent($subject, $attribute, $token); - + $this->eventDispatcher->dispatch(AuthorizationEvent::VOTE, $event); - + if ($event->hasVote()) { - + $this->logger->debug("The TaskVoter is overriding by " .AuthorizationEvent::VOTE, [ 'vote' => $event->getVote(), 'task_id' => $subject->getId() ]); - + return $event->getVote(); } + // do pre-flight check, relying on other decision manager + // those pre-flight check concern associated entities + if ($subject instanceof AbstractTask) { + if (NULL !== $person = $subject->getPerson()) { + if (!$this->accessDecisionManager->decide($token, [PersonVoter::SEE], $person)) { + return false; + } + } elseif (false) { + // here will come the test if the task is associated to an accompanying course + } + } + + // do regular check. + return $this->voter->voteOnAttribute($attribute, $subject, $token); + + /* if ($subject instanceof AbstractTask) { if ($subject->getPerson() === null) { throw new \LogicException("You should associate a person with task " . "in order to check autorizations"); } - + $person = $subject->getPerson(); } elseif ($subject instanceof Person) { $person = $subject; } else { // subject is null. We check that at least one center is reachable $centers = $this->authorizationHelper->getReachableCenters($token->getUser(), new Role($attribute)); - + return count($centers) > 0; } if (!$this->accessDecisionManager->decide($token, [PersonVoter::SEE], $person)) { + return false; + } + $center = $this->centerResolverDispatcher->resolveCenter($subject); + if (NULL === $center) { return false; } @@ -153,6 +175,7 @@ class TaskVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterf $subject, $attribute ); + */ } public function getRoles() diff --git a/src/Bundle/ChillTaskBundle/config/services/security.yaml b/src/Bundle/ChillTaskBundle/config/services/security.yaml index e58fd19e3..c1d176637 100644 --- a/src/Bundle/ChillTaskBundle/config/services/security.yaml +++ b/src/Bundle/ChillTaskBundle/config/services/security.yaml @@ -1,11 +1,7 @@ services: chill_task.task_voter: class: Chill\TaskBundle\Security\Authorization\TaskVoter - arguments: - - "@security.access.decision_manager" - - "@chill.main.security.authorization.helper" - - '@Symfony\Component\EventDispatcher\EventDispatcherInterface' - - "@logger" + autowire: true + autoconfigure: true tags: - - { name: security.voter } - { name: chill.role }