1

In a TWIG view of my Symfony 5 project, I have the following piece of code :

<table class="table table-hover table-striped datatable">
    <thead>
        <tr>
            <th>ID</th>
            <th>Username</th>
            <th>Email</th>
            <th>Created at</th>
        </tr>
    </thead>
    <tbody>
    {% for user in users %}
        <tr>
            <td>{{ user.id }}</td>
            <td>{{ user.name }}</td>
            <td>{{ user.email }}</td>
            <td>{{ user.createdAt|date('d/m/Y H:i') }}</td>
        </tr>
    {% endfor %}
    </tbody>
</table>

Nothing impressive. I wanted to know if there was a way to check if the user in my loop has a specific role, let's say ROLE_STAFF (More precisely, I want to check it against the hierarchy. If he has a role that "inherits" ROLE_STAFF, it should also satisfy the condition). I have seen this post but it's quite old, and I'm hoping maybe something has been implemented since the moment it was written.

I tried injecting the AccessDecisionManagerInterface in my User entity without any good result. My method (thereafter) does not work because $this->decisionManager is null. I guess it has not been injected properly. I inject it by the constructor :

public function __construct(AccessDecisionManagerInterface $decisionManager)
{
    $this->decisionManager = $decisionManager;
}

public function hasRolePermissions(string $role)
{
    $decisionManager = new AccessDecisionManager();
    $token = new UsernamePasswordToken($this, '', '', $this->getRoles());
    return $this->decisionManager->decide($token, [$role]);
}

Although a solution that does not use isGranted, like a service, or an injection, is perfectly acceptable to me, I would prefer to keep it simple. I was planning to build a twig function, but I would like to know if I'm reinventing the wheel or not. This seems a common enough issue, so I hope there is some built-in functionality I'm not aware of.

Altherius
  • 754
  • 7
  • 23
  • If it's a simple check, not involving authorization and you don't have role inheritance going on, why don't you just check against the role array in `user.roles`? – msg Apr 09 '20 at 02:25
  • The problem is that it involves hierarchy. If a user has the ROLE_ADMIN (which inherits from ROLE_STAFF) but not the ROLE_STAFF then I can't find him this way. – Altherius Apr 09 '20 at 07:48
  • This question is not a duplicate of the marked question. I wish to check the permissions of a user **which is not the current user** against the role hierarchy. – Altherius Apr 09 '20 at 13:00
  • Does this answer your question? [Get ROLE of a user not logged in TWIG Symfony2](https://stackoverflow.com/questions/9080530/get-role-of-a-user-not-logged-in-twig-symfony2) – Nico Haase Apr 09 '20 at 14:40

1 Answers1

1

You can use the RoleHierarchy class to find all "reachable" roles for a current user.

In the Symfony framework, this class is available as the security.role_hierarchy service (autowirable as Symfony\Component\Security\Core\Role\RoleHierarchyInterface).

// check for ROLE_STAFF while taking the role hierarchy into account
$isStaff = in_array(
    'ROLE_STAFF',
    $roleHierarchy->getReachableRoles($user->getRoles())
);

You can write a custom Twig extension (e.g. a custom Twig test) to be able to do this in your templates.

Wouter J
  • 41,455
  • 15
  • 107
  • 112
  • Thanks. I guess I had it right, I'll have to write my TWIG extension then. I wonder why it's not included in the framework, it seems pretty basic. – Altherius Apr 09 '20 at 14:57
  • Caveat : the name of the method in `RoleHierarchyInterface` is `getReachableRoleNames` as of Symfony 5.0.7 and not `getReachableRoles` – Altherius Apr 09 '20 at 17:06