2

I'm using SonataAdminBundle with Symfony 2.2 and want to display the dashboard blocks depending on what user is logged in.

e.g.

  • Users with Group Superadmin will see blocks 'UserManagement' and 'Messages'
  • Users with Group Staff will see only block 'Messages'

I read the whole documentation especially the security doc but found no info on how to restrict the dashboard view. I already implemented a filter which will will show no entries in the list view of an entity class if the user's permissions are not enough.

But it would be way better to not show him the blocks at all.

Any ideas on how to do this ?

cb0
  • 8,415
  • 9
  • 52
  • 80
  • you already have a filter blocking the the list view but you don't want to show it at all? please clarify :) – Nicolai Fröhlich Jun 12 '13 at 10:45
  • Yes I have. Now I don't want to show the block in the dashboard view at all. At the moment it displays the block in the dashboard and when I go to the list view my filter hides entries in the list from certain users. – cb0 Jun 12 '13 at 11:40

2 Answers2

4

Well, for anyone running into this, I solved it by simply returning an empty Response in execute(). My use-case was one where I wanted to show a block to users with a specific role: First I defined my service for using the security.context service like so:

sonata.block.service.foo:
    class: Acme\DemoBundle\Block\FooBlockService
    arguments: [ "sonata.block.service.foo", "@templating", "@doctrine", "@security.context" ]
    tags:
      - { name: sonata.block }

Then I defined the block service __construct() as:

//Acme\DemoBundle\Block\FooBlockService
public function __construct($name, EngineInterface $templating, $doctrine, $securityContext)
{
    parent::__construct($name, $templating);
    $this->doctrine = $doctrine;
    $this->securityContext = $securityContext;
}

Finally, in the execute function the first thing I did was check for a specific role on the user like so:

//Acme\DemoBundle\Block\FooBlockService
public function execute(BlockContextInterface $blockContext, Response $response = null)
{

    if( $this->securityContext->isGranted("ROLE_ACME_FOO") === false )
    {
        return new Response();
    }

    //... more code

This works, but it feels like a hack. Mainly, because the Block goes through all of its stages, and only on the output it return nothing, meaning overhead. A better solution would be to somehow prevent the entire Block from being loaded, based on some custom code.

In conclusion, this isn't the best way, but it worked for me!

Frank van Luijn
  • 470
  • 4
  • 16
  • Thanks very much for that!! I'll def. give it a try and accept if it solves the problem I still struggle with. – cb0 Feb 25 '14 at 18:13
  • You're welcome. Did this eventually solve your problem? I'm still thinking of other approaches myself as this isn't the cleanest. – Frank van Luijn Mar 10 '14 at 11:27
  • I'm with the same problem and solved with the same way before read your answer but this is terrible. In my panel it keep showing a black space because of columns class that I've added to block, for example ``{ position: top, type: my_block_name_service, class: col-xs-8 }``. This ``col-xs-8`` make the mess. – Cassiano Oct 13 '16 at 12:35
1

You can restrict access to block using roles, like this:

sonata_admin:
dashboard:
    blocks:
        - { position: top, type: your_service_block_name, class: 'col-xs-4', roles: [ROLE_SOME_NAME_HERE_, ROLE_SOME_NAME_HERE_2] }

You can check under SonataAdminBundle:Core:dashboard.html.twig how this roles works:

{% if block.roles|length == 0 or is_granted(block.roles) %}
<div class="{{ block.class }}">
    {{ sonata_block_render({ 'type': block.type, 'settings': block.settings}) }}
</div>{% endif %}
Cassiano
  • 562
  • 5
  • 16