Skip to content
Advertisement

Check specific user permission in a twig view

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.

Advertisement

Answer

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 SymfonyComponentSecurityCoreRoleRoleHierarchyInterface).

// 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.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement