Search code examples
phpsymfonysonata-admin

Remove the column 'impersonating' when user is granted ROLE_PREVIOUS_ADMIN


I have enabled impersonating in my Sonata project.

When a user with role 'ROLE_ALLOWED_TO_SWITCH' impersonate a user I want the column impersonating to be hidden when he goes to the user list while impersonating. A user can't impersonate while impersonating, an exception will be thrown. But I don't want the exception, I want either a nice message to display that it is not possible but rather hide the column completely so that the links are not even available.

if ($this->isGranted('ROLE_ALLOWED_TO_SWITCH')) {
    $listMapper
        ->add('impersonating', 'string',
            ['template' => 'SonataUserBundle:Admin:Field/impersonating.html.twig'])
    ;
}

How can I prevent this column from showing when the user has a role 'ROLE_PREVIOUS_ADMIN'? Because this doesn't want to work:

if ($this->isGranted('ROLE_ALLOWED_TO_SWITCH') && !$this->isGranted('ROLE_PREVIOUS_ADMIN')) {

This does remove the column for the impersonated user, but it also gets removed for the user that has the 'ROLE_ALLOWED_TO_SWITCH' role but not busy impersonating.


Solution

  • You condition and roles are fine, but the isGranted() function from Sonata admin class checks the Sonata-Role-Based only (see RoleSecurityHandler::isGranted()):

    public function isGranted(AdminInterface $admin, $attributes, $object = null)
    {
        // ...
    
        foreach ($attributes as $pos => $attribute) {
            $attributes[$pos] = sprintf($this->getBaseRole($admin), $attribute);
        }
    
        // ...
    }
    
    public function getBaseRole(AdminInterface $admin)
    {
        return 'ROLE_'.str_replace('.', '_', strtoupper($admin->getCode())).'_%s';
    }
    

    Therefore, you should check out the system roles into Sonata admin class by using the @security.authorization_checker Symfony service instead. For example, after inject it to the admin class, this should work:

    if ($this->authorizationChecker->isGranted('ROLE_ALLOWED_TO_SWITCH') 
        && !$this->authorizationChecker->isGranted('ROLE_PREVIOUS_ADMIN')) 
    {