I have a Symfony 5.4 project using sonata-project/admin-bundle
4.9 and sonata-project/user-bundle
5.0.0-rc.1 and I want to let only the users with role ROLE_ADMIN
to manage the users (CREATE/LIST/EDIT/DELETE), for other roles I want to hide the navbar menu entry and the dashboard entry for "Users".
In my config/packages/sonata_admin.yml
I tried to specify a sonata.user.block.menu
entry as found in some old questions but it seems that it does not exists anymore as the following error is thrown:
An exception has been thrown during the rendering of a template ("The block type "sonata.user.block.menu" does not exist").
As default I had only one admin_list block, I tried adding a sonata.block.service.rss and it is shown correctly in the dashboard but I can't find how to manage the Users block.
sonata_admin:
title: 'Sonata Admin'
dashboard:
blocks:
- { type: sonata.admin.block.admin_list, position: left }
#- { type: sonata.user.block.menu, position: right, roles: [ROLE_ADMIN]}
#- { type: sonata.block.service.rss, position: right, roles: [ROLE_ADMIN]}
templates:
layout: sonataLayout.html.twig
sonata_block:
blocks:
sonata.admin.block.admin_list:
contexts: [admin]
Any hints? Explicative picture following.
CodePudding user response:
Note. "Disabled both based on Role". It`s not "just add/change 2 lines"
IMHO. "Basic" Sonata Admin`s configuration isn't too obvious. Therefore customize as much as possible -> to have more control.
I only could suggest U -> go this "right way" (surely,IMHO)
- Create/manage the admin-menu with a event listener. U may read/check good example there Using events to allow a menu to be extended and the official -> Sonata Admin -> KnpMenu
With such approach -> U can easy manage menu items by your Roles. other advantages surely
From the very beginning -> create the custom templates. If U follow Flex &
/templates/admin
is the folder for Sonata Admin:// config/packages/sonata_admin: sonata_admin .... templates: .... layout: '/admin/standard_layout.html.twig' knp_menu_template: '/admin/menu/knp_menu.html.twig' dashboard: 'admin...
2* E.g. to extend the default layout. If your specific template do:
{% extends '@SonataAdmin/standard_layout.html.twig' %}
{% block sonata_nav %}
...
After these steps -> much more easy to control views by your Roles
CodePudding user response:
So, as per documentation I added an event listener for the Menu and I was able to remove the entry from the left panel like this
//src/EventListener/MenuBuilderListener.php
<?php
namespace App\EventListener;
use Sonata\AdminBundle\Event\ConfigureMenuEvent;
use Symfony\Component\Security\Core\Security;
final class MenuBuilderListener
{
private $security;
public function __construct( Security $security)
{
$this->security = $security;
}
public function manageMenuItems(ConfigureMenuEvent $event): void
{
$menu = $event->getMenu();
$user = $this->security->getUser();
if(!$user->hasRole("ROLE_ADMIN")){
$menu->removeChild('sonata_user');
}
}
}
With the service registered here
//config/services.yaml
app.menu_listener:
class: App\EventListener\MenuBuilderListener
tags:
- { name: kernel.event_listener, event: sonata.admin.event.configure.menu.sidebar, method: manageMenuItems }
Then I added a firewall entry to manage permissions
//config/packages/security.yaml
access_control:
- { path: ^/admin/app/sonatauseruser/, role: [ROLE_ADMIN]}
Till now I was not able to remove the Users entry from the dashboard, I tried to extend the dashboard twig template but it seems that the Users entry is added somehow later.
{% extends '@SonataAdmin/Core/dashboard.html.twig' %}
{% block content %}
{% set has_left = false %}
{% dump(blocks.left) %} //this shows only the admin group and not the user group
{% for block in blocks.left %}
{% if not has_left and (block.roles|length == 0 or is_granted_affirmative(block.roles)) %}
{% set has_left = true %}
{% endif %}
{% endfor %}
....
{{ sonata_block_render_event('sonata.admin.dashboard.top') }}
....
{{ sonata_block_render_event('sonata.admin.dashboard.bottom') }}
I also tried to bind both the render events .top and .bottom to a ConfigureEvent Listener but they are not fired (not sure if this is the right class of listener).
For now I found a sub optimal solution, I did an override of the userAdmin class like this
<?php
namespace App\Admin;
use Sonata\UserBundle\Admin\Model\UserAdmin as BaseType;
class UserAdmin extends BaseType
{
protected function configureDashboardActions(array $actions): array
{
$actions = parent::configureDashboardActions($actions);
unset($actions['list']);
unset($actions['create']);
return $actions;
}
}
And registered it in
//config/packages/sonata_user.yaml
sonata_user:
admin:
user:
class: App\Admin\UserAdmin
controller: SonataAdminBundle:CRUD
So the "Users" dashboard element is shown without any action available.