Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is granted for other user

Tags:

symfony

After i read this chapter in cookbook

http://symfony.com/doc/current/cookbook/security/entity_provider.html

i create a entity "User" which implements the "AdvancedUserInterface" and a entity "Roles" which implements the "RoleInterface". Also i create a role structure in my "security.yml".

The relation between user and roles is a "ManyToMany" relation.

Everything is fine.

For the logged in user i can check a grant like this:

$this->get('security.context')->isGranted("ROLE_EDITOR");

But how can i check this grant for other user in database?

There is something like?

$this->get('security.context')->isGranted("ROLE_EDITOR", $user);
like image 647
smartcoderx Avatar asked Jun 30 '15 14:06

smartcoderx


2 Answers

Symfony 5 answer:

namespace App\Controller;

...
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
use Symfony\Component\Security\Core\Role\RoleHierarchy;

class UserController extends AbstractController
{
    private $roleHierarchy;

    /**
     * @Route("/users", name="users")
     */
    public function usersIndex(RoleHierarchyInterface $roleHierarchy)
    {
        $this->roleHierarchy = $roleHierarchy;

        // your user service or your Doctrine code here
        $users = ...

        foreach ($users as $user) {
            $roles = $roleHierarchy->getReachableRoleNames($user->getRoles());
            \dump($roles);

            if ($this->isGranted($user, 'ROLE_SUPER_ADMIN')) {
                ...
            }
        }
        ...
    }

    private function isGranted(User $user, string $role): bool 
    {
        $reachableRoles = $this->roleHierarchy->getReachableRoleNames($user->getRoles());

        foreach ($reachableRoles as $reachableRole) {
            if ($reachableRole === $role) {
                return true;
            }
        }

        return false;
    }
}

Note: I put everything in the controller for the sake of simplicity here, but of course I'd recommend to move the Role Management code into a separate service like @leberknecht's answer.

like image 142
Erdal G. Avatar answered Sep 30 '22 19:09

Erdal G.


Dont know if there is something build-in by now, but its pretty straight-forward to build:

class RoleCheckerService
{
    private const PROVIDER_KEY = 'role-check';
    /**
     * @var RoleHierarchyInterface
     */
    private $roleHierarchy;

    public function __construct(RoleHierarchyInterface $roleHierarchy)
    {
        $this->roleHierarchy = $roleHierarchy;
    }

    final public function isGranted(User $user, string $role): bool 
    {
        $token = new PreAuthenticatedToken($user, null, self::PROVIDER_KEY, $user->getRoles());
        $reachableRoles = $this->roleHierarchy->getReachableRoles($token->getRoles());

        foreach ($reachableRoles as $reachableRole) {
            if ($reachableRole->getRole() === $role) {
                return true;
            }
        }

        return false;
    }
}
like image 29
leberknecht Avatar answered Sep 30 '22 17:09

leberknecht