授予用户 ROLE_PREVIOUS_ADMIN 后删除列 'impersonating'

Remove the column 'impersonating' when user is granted ROLE_PREVIOUS_ADMIN

我在我的 Sonata 项目中启用了模拟功能。

当角色为 'ROLE_ALLOWED_TO_SWITCH' 的用户模拟用户时,我希望在他模拟时转到用户列表时隐藏模拟列。用户在模拟时不能模拟,会抛出异常。但我不想要例外,我想要一个很好的消息来显示这是不可能的,而是完全隐藏该列,这样链接甚至都不可用。

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

当用户具有角色 'ROLE_PREVIOUS_ADMIN' 时,如何防止显示此列?因为这不起作用:

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

这确实删除了模拟用户的列,但对于具有 'ROLE_ALLOWED_TO_SWITCH' 角色但不忙于模拟的用户,它也会被删除。

您的条件和角色都很好,但是 Sonata admin class 中的 isGranted() 函数仅检查基于 Sonata-Role 的功能(参见 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';
}

因此,您应该改用 @security.authorization_checker Symfony 服务将系统角色签入 Sonata admin class。例如,将其注入管理员后 class,这应该有效:

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