symfonydoctrine-odmuser-roles

get users who have a specific role


I need to get the list of all my users having a specific role, is there any way to do it easily? The solution I figured out for now would be to retrive all users then apply a filter on each using is granted function (which is hardcore)

PS: I don't like using the db request that skims over data and if the user role equals the wanted role it returns it, else it doesn't. Which means that we don't take into account users with super roles.


Solution

  • Because of the role hierarchy, I don't see a way to avoid grabbing all the users and then filtering. You could make a user role table and add all possible user roles but that would get out of date if you changed the hierarchy.

    However, once you have all the roles for a given user then you can test if a specific one is supported.

    There is a role hierarchy object to help.

    use Symfony\Component\Security\Core\Role\Role;
    use Symfony\Component\Security\Core\Role\RoleHierarchy;
    
    class RoleChecker
    {
        protected $roleHeirarchy;
    
        public function __construct(RoleHierarchy $roleHierarchy)
        {  
            $this->roleHierarchy = $roleHierarchy; // serviceId = security.role_hierarchy
        }
        protected function hasRole($roles,$targetRole)
        {
            $reachableRoles = $this->roleHierarchy->getReachableRoles($roles);
            foreach($reachableRoles as $role)
            {
                if ($role->getRole() == $targetRole) return true;
            }
            return false;
        }
    }
    
    # services.yml
    # You need to alias the security.role_hierarchy service
    cerad_core__role_hierarchy:
        alias: security.role_hierarchy
    

    You need to pass an array of role objects to hasRole. This is basically the same code that the security context object uses. I could not find another Symfony service just for this.

    The is also a parameter value called '%security.role_hierarchy.roles%' that comes in handy at times as well.