Search code examples
phpsymfonyauthenticationsonata-adminsonata-user-bundle

Sonata Admin: isGranted() always returns true in Admin class, but correct boolean in template


I'm using SonataAdminBundle and SonataUserBundle in a Symfony 2 project. The installed packages are:

$ composer show | grep symfony
friendsofsymfony/rest-bundle             1.7.7              This Bundle provides various tools to rapidly develop RESTful API's with Symfony
friendsofsymfony/user-bundle             v1.3.6             Symfony FOSUserBundle
symfony/assetic-bundle                   v2.8.0             Integrates Assetic into Symfony2
symfony/css-selector                     v2.8.6             Symfony CssSelector Component
symfony/dom-crawler                      v2.8.6             Symfony DomCrawler Component
symfony/monolog-bundle                   2.11.1             Symfony MonologBundle
symfony/polyfill-apcu                    v1.1.1             Symfony polyfill backporting apcu_* functions to lower PHP versions
symfony/polyfill-mbstring                v1.1.1             Symfony polyfill for the Mbstring extension
symfony/swiftmailer-bundle               v2.3.11            Symfony SwiftmailerBundle
symfony/symfony                          v2.7.13            The Symfony PHP framework

$ composer show | grep sonata
sonata-project/admin-bundle              2.3.10             Symfony SonataAdminBundle
sonata-project/block-bundle              2.2.15             Symfony SonataBlockBundle
sonata-project/cache                     1.0.7              Cache library
sonata-project/core-bundle               2.3.11             Symfony SonataCoreBundle
sonata-project/doctrine-extensions       1.0.2              Doctrine2 behavioral extensions
sonata-project/doctrine-orm-admin-bundle 2.3.4              Symfony Sonata / Integrate Doctrine ORM into the SonataAdminBundle
sonata-project/easy-extends-bundle       2.1.10             Symfony SonataEasyExtendsBundle
sonata-project/exporter                  1.4.1              Lightweight Exporter library
sonata-project/google-authenticator      1.0.2              Library to integrate Google Authenticator into a PHP project
sonata-project/user-bundle               2.2.5              Symfony SonataUserBundle

The roles in the security.yml configuration file:

role_hierarchy:
    ROLE_ADMIN:       [ROLE_USER, ROLE_SONATA_ADMIN]
    ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

Logged in with a user that has ROLE_ADMIN only, the following dumps from my UserAdmin class:

dump($this->isGranted('ROLE_ALLOWED_TO_SWITCH'));
dump($this->isGranted('ROLE_BLA_BLA_BLA'));
dump($this->isGranted('ROLE_USER'));

print in Symfony toolbar (on dev environment)

true
true
true

While if I put the dumps in an overridden Sonata template like app/Resources/SonataAdminBundle/views/CRUD/[anytemplate].html.twig,

{{ dump(is_granted('ROLE_ALLOWED_TO_SWITCH')) }}
{{ dump(is_granted('ROLE_BLA_BLA_BLA')) }}
{{ dump(is_granted('ROLE_USER')) }}

the correct values are returned.

false
false
true

I got into this because this line here, in SonataUserBundle, had no effect: https://github.com/sonata-project/SonataUserBundle/blob/3.x/Admin/Model/UserAdmin.php#L95

The isGranted() usage is described here: http://symfony.com/doc/current/bundles/SonataAdminBundle/reference/security.html#usage

Am I doing something wrong or is this a bug?

Edit:

Thanks to @mickadoo's comment I noticed that I had the default handler sonata.admin.security.handler.noop, which is said to always return true, whatever that means. I set it up with sonata.admin.security.handler.role and created some roles (ROLE_SONATA_USER_ADMIN_USER_LIST and ROLE_SONATA_USER_ADMIN_USER_VIEW) and now it returns the correct value for $this->isGranted('LIST') or $this->isGranted('VIEW'), but always returns false for $this->isGranted('ROLE_USER') or $this->isGranted('ROLE_ALLOWED_TO_SWITCH').

How can I check this roles?


Solution

  • Generic, non-entity roles, like ROLE_USER, ROLE_ADMIN, ROLE_SUPER_ADMIN, ROLE_{CUSTOM_STRING} should be checked using the default Symfony security context.

    In the Admin class:

    $securityContext = $this->getConfigurationPool()->getContainer()->get('security.context');
    
    if ($securityContext->isGranted('ROLE_USER')) {
        // Your PHP code here
    }
    

    In Twig template:

    {% if is_granted('ROLE_USER') %}
        Your HTML/Twig content here.
    {% endif %}
    

    Entity actions roles like ROLE_SONATA_USER_ADMIN_USER_LIST, ROLE_SONATA_USER_ADMIN_USER_VIEW, ROLE_{CUSTOM_SONATA_ADMIN_SERVICE_NAME}_{ACTION} can be checked using the Sonata Admin helper or the Symfony security context.

    In the Admin class:

    // Using Symfony security context
    $securityContext = $this->getConfigurationPool()->getContainer()->get('security.context');
    
    if ($securityContext->isGranted('ROLE_SONATA_USER_ADMIN_USER_LIST')) {
        // your code here
    }
    
    // Using Sonata helper for shorter syntax
    if ($this->isGranted('LIST')) {
        // your code here
    }
    

    In Twig template:

    <!-- Using Symfony security context -->
    {% if is_granted('ROLE_SONATA_USER_ADMIN_USER_LIST') %}
        Your HTML/Twig content here.
    {% endif %}
    
    <!-- Using Sonata helper -->
    {% if admin.isGranted('LIST') %}
        Your HTML/Twig content here.
    {% endif %}