Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><code>RoleVoter</code> disregards the $object passed through from <code>SecurityContext-&gt;isGranted()</code>. This results in the <code>RoleHierarchyVoter</code> extracting roles from the <code>Token</code> instead of a provided <code>UserInterface</code> $object (if exists), so I had to find a different route.</p> <p>Maybe there is a better way to go about this and if there is I'd sure like to know, but this is the solution I came up with:</p> <p>First I implemented <code>ContainerAwareInterface</code> in my User class so I could access the security component from within it:</p> <pre><code>final class User implements AdvancedUserInterface, ContainerAwareInterface { // ... /** * @var ContainerInterface */ private $container; // ... public function setContainer(ContainerInterface $container = null) { if (null === $container) { throw new \Exception('First argument to User-&gt;setContainer() must be an instance of ContainerInterface'); } $this-&gt;container = $container; } // ... } </code></pre> <p>Then I defined a <code>hasRole()</code> method:</p> <pre><code>/** * @param string|\Symfony\Component\Security\Core\Role\RoleInterface $roleToCheck * @return bool * @throws \InvalidArgumentException */ public function hasRole($roleToCheck) { if (!is_string($roleToCheck)) { if (!($roleToCheck instanceof \Symfony\Component\Security\Core\Role\RoleInterface)) { throw new \InvalidArgumentException('First argument expects a string or instance of RoleInterface'); } $roleToCheck = $roleToCheck-&gt;getRole(); } /** * @var \Symfony\Component\Security\Core\SecurityContext $thisSecurityContext */ $thisSecurityContext = $this-&gt;container-&gt;get('security.context'); $clientUser = $thisSecurityContext-&gt;getToken()-&gt;getUser(); // determine if we're checking a role on the currently authenticated client user if ($this-&gt;equals($clientUser)) { // we are, so use the AccessDecisionManager and voter system instead return $thisSecurityContext-&gt;isGranted($roleToCheck); } /** * @var \Symfony\Component\Security\Core\Role\RoleHierarchy $thisRoleHierarchy */ $thisRoleHierarchy = $this-&gt;container-&gt;get('security.role_hierarchy'); $grantedRoles = $thisRoleHierarchy-&gt;getReachableRoles($this-&gt;getRoles()); foreach ($grantedRoles as $grantedRole) { if ($roleToCheck === $grantedRole-&gt;getRole()) { return TRUE; } } return FALSE; } </code></pre> <p>From a controller:</p> <pre><code>$user = new User(); $user-&gt;setContainer($this-&gt;container); var_dump($user-&gt;hasRole('ROLE_ADMIN')); var_dump($this-&gt;get('security.context')-&gt;isGranted('ROLE_ADMIN')); var_dump($this-&gt;get('security.context')-&gt;isGranted('ROLE_ADMIN', $user)); $user-&gt;addUserSecurityRole('ROLE_ADMIN'); var_dump($user-&gt;hasRole('ROLE_ADMIN')); </code></pre> <p>Output:</p> <pre><code>boolean false boolean true boolean true boolean true </code></pre> <p>Although it does not involve the <code>AccessDecisionManager</code> or registered voters (unless the instance being tested is the currently authenticated user), it is sufficient for my needs as I just need to ascertain whether or not a given user has a particular role.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload