diff --git a/Menu/PersonMenuBuilder.php b/Menu/PersonMenuBuilder.php
index c7470fe2a..130622c2c 100644
--- a/Menu/PersonMenuBuilder.php
+++ b/Menu/PersonMenuBuilder.php
@@ -2,21 +2,15 @@
namespace Chill\EventBundle\Menu;
-use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Security\Core\Role\Role;
use Knp\Menu\MenuItem;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
-use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\EventBundle\Security\Authorization\EventVoter;
class PersonMenuBuilder implements LocalMenuBuilderInterface
{
- /**
- *
- * @var TokenStorageInterface
- */
- protected $tokenStorage;
/**
*
@@ -26,18 +20,16 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
/**
*
- * @var AuthorizationHelper
+ * @var AuthorizationCheckerInterface
*/
- protected $authorizationHelper;
+ protected $authorizationChecker;
public function __construct(
- AuthorizationHelper $authorizationHelper,
- TokenStorageInterface $tokenStorage,
+ AuthorizationCheckerInterface $authorizationChecker,
TranslatorInterface $translator
) {
- $this->tokenStorage = $tokenStorage;
+ $this->authorizationChecker = $authorizationChecker;
$this->translator = $translator;
- $this->authorizationHelper = $authorizationHelper;
}
@@ -46,11 +38,7 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
/* @var $person \Chill\PersonBundle\Entity\Person */
$person = $parameters['person'];
- $user = $this->tokenStorage->getToken()->getUser();
- $roleSee = new Role(EventVoter::SEE);
-
- // ASK use authorizationHelper or authorizationChecker ??
- if ($this->authorizationHelper->userHasAccess($user, $person, $roleSee)) {
+ if ($this->authorizationChecker->isGranted(EventVoter::SEE, $person)) {
$menu->addChild($this->translator->trans('Events participation'), [
'route' => 'chill_event__list_by_person',
diff --git a/Resources/config/services/authorization.yml b/Resources/config/services/authorization.yml
index d44f1e9d9..131469f65 100644
--- a/Resources/config/services/authorization.yml
+++ b/Resources/config/services/authorization.yml
@@ -2,7 +2,9 @@ services:
chill_event.event_voter:
class: Chill\EventBundle\Security\Authorization\EventVoter
arguments:
+ - "@security.access.decision_manager"
- "@chill.main.security.authorization.helper"
+ - "@logger"
tags:
- { name: chill.role }
- { name: security.voter }
diff --git a/Resources/config/services/menu.yml b/Resources/config/services/menu.yml
index 209d208a7..a2451122f 100644
--- a/Resources/config/services/menu.yml
+++ b/Resources/config/services/menu.yml
@@ -1,8 +1,7 @@
services:
Chill\EventBundle\Menu\PersonMenuBuilder:
arguments:
- $authorizationHelper: '@Chill\MainBundle\Security\Authorization\AuthorizationHelper'
- $tokenStorage: '@Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'
+ $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/Resources/views/Event/listByPerson.html.twig b/Resources/views/Event/listByPerson.html.twig
index 9c174bb92..cc99cff4f 100644
--- a/Resources/views/Event/listByPerson.html.twig
+++ b/Resources/views/Event/listByPerson.html.twig
@@ -50,7 +50,8 @@
-
- {% if is_granted('CHILL_EVENT_SEE_DETAILS', participation.event) %} #}
+ {#
+ {% if is_granted('CHILL_EVENT_SEE_DETAILS', participation.event) %}
{{ 'See'|trans }}
@@ -65,6 +66,7 @@
{{ 'Edit'|trans }}
{% endif %}
+ #}
|
diff --git a/Security/Authorization/EventVoter.php b/Security/Authorization/EventVoter.php
index 8f74e649a..77548f1a5 100644
--- a/Security/Authorization/EventVoter.php
+++ b/Security/Authorization/EventVoter.php
@@ -9,6 +9,10 @@ use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
use Chill\EventBundle\Entity\Event;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Entity\User;
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
+use Psr\Log\LoggerInterface;
+
/**
* Description of EventVoter
@@ -18,53 +22,114 @@ use Chill\MainBundle\Entity\User;
*/
class EventVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
{
-
const SEE = 'CHILL_EVENT_SEE';
const SEE_DETAILS = 'CHILL_EVENT_SEE_DETAILS';
const CREATE = 'CHILL_EVENT_CREATE';
const UPDATE = 'CHILL_EVENT_UPDATE';
+ const ROLES = [
+ self::SEE,
+ self::SEE_DETAILS,
+ self::CREATE,
+ self::UPDATE
+ ];
+
+ /**
+ * @var AuthorizationHelper
+ */
protected $authorizationHelper;
- public function __construct(AuthorizationHelper $helper)
+ /**
+ * @var AccessDecisionManagerInterface
+ */
+ protected $accessDecisionManager;
+
+ /**
+ * @var LoggerInterface
+ */
+ protected $logger;
+
+ public function __construct(
+ AccessDecisionManagerInterface $accessDecisionManager,
+ AuthorizationHelper $authorizationHelper,
+ LoggerInterface $logger
+ )
{
- $this->authorizationHelper = $helper;
+ $this->accessDecisionManager = $accessDecisionManager;
+ $this->authorizationHelper = $authorizationHelper;
+ $this->logger = $logger;
}
- protected function getSupportedAttributes()
+ public function supports($attribute, $subject)
{
- return array(self::SEE, self::SEE_DETAILS,
- self::CREATE, self::UPDATE);
+ return ($subject instanceof Event && in_array($attribute, self::ROLES))
+ ||
+ ($subject instanceof Person && \in_array($attribute, [ self::CREATE, self::SEE ]))
+ ||
+ (NULL === $subject && $attribute === self::SEE )
+ ;
}
-
- protected function getSupportedClasses()
+
+ /**
+ *
+ * @param string $attribute
+ * @param Event $subject
+ * @param TokenInterface $token
+ * @return boolean
+ */
+ protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
- return array(Event::class);
- }
-
- protected function isGranted($attribute, $event, $user = null)
- {
- if (!$user instanceof User) {
- return false;
- }
+ $this->logger->debug(sprintf("Voting from %s class", self::class));
- return $this->authorizationHelper->userHasAccess($user, $event, $attribute);
+ if (!$token->getUser() instanceof User) {
+ return false;
+ }
+
+ if ($subject instanceof Event) {
+ if ($subject->getPerson() === null) {
+ throw new \LogicException("You should associate a person with event "
+ . "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;
+ }
+
+ return $this->authorizationHelper->userHasAccess(
+ $token->getUser(),
+ $subject,
+ $attribute
+ );
}
-
+
+
public function getRoles()
{
- return $this->getSupportedAttributes();
+ return self::ROLES;
+ }
+
+ public function getRolesWithHierarchy()
+ {
+ return [
+ 'Event' => self::ROLES
+ ];
}
public function getRolesWithoutScope()
{
- return null;
+ return [];
}
-
- public function getRolesWithHierarchy()
- {
- return [ 'Event' => $this->getRoles() ];
- }
-
}