feat(core) : RBAC - filtrage sidebar par permission
Les items sidebar peuvent declarer une cle `permission` optionnelle. Le SidebarProvider verifie isGranted() et masque les items dont l'utilisateur ne possede pas la permission requise. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,8 @@ declare(strict_types=1);
|
|||||||
* This file defines the sidebar sections displayed in the frontend.
|
* This file defines the sidebar sections displayed in the frontend.
|
||||||
* Each item references the module that owns it via the `module` key.
|
* Each item references the module that owns it via the `module` key.
|
||||||
* Items whose module is not active (see config/modules.php) are filtered out.
|
* Items whose module is not active (see config/modules.php) are filtered out.
|
||||||
|
* Items may also declare a `permission` key (RBAC permission code) : the item
|
||||||
|
* is hidden from users who do not hold that permission.
|
||||||
*
|
*
|
||||||
* This config is decoupled from the modules themselves: you can freely
|
* This config is decoupled from the modules themselves: you can freely
|
||||||
* move an item from one section to another without touching the module code.
|
* move an item from one section to another without touching the module code.
|
||||||
@@ -33,16 +35,18 @@ return [
|
|||||||
'module' => 'core',
|
'module' => 'core',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'sidebar.core.roles',
|
'label' => 'sidebar.core.roles',
|
||||||
'to' => '/admin/roles',
|
'to' => '/admin/roles',
|
||||||
'icon' => 'mdi:shield-account-outline',
|
'icon' => 'mdi:shield-account-outline',
|
||||||
'module' => 'core',
|
'module' => 'core',
|
||||||
|
'permission' => 'core.roles.view',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'sidebar.core.users',
|
'label' => 'sidebar.core.users',
|
||||||
'to' => '/admin/users',
|
'to' => '/admin/users',
|
||||||
'icon' => 'mdi:account-group-outline',
|
'icon' => 'mdi:account-group-outline',
|
||||||
'module' => 'core',
|
'module' => 'core',
|
||||||
|
'permission' => 'core.users.view',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'sidebar.general.logout',
|
'label' => 'sidebar.general.logout',
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace App\Shared\Infrastructure\ApiPlatform\State;
|
|||||||
use ApiPlatform\Metadata\Operation;
|
use ApiPlatform\Metadata\Operation;
|
||||||
use ApiPlatform\State\ProviderInterface;
|
use ApiPlatform\State\ProviderInterface;
|
||||||
use App\Shared\Infrastructure\ApiPlatform\Resource\SidebarResource;
|
use App\Shared\Infrastructure\ApiPlatform\Resource\SidebarResource;
|
||||||
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @implements ProviderInterface<object>
|
* @implements ProviderInterface<object>
|
||||||
@@ -16,10 +17,10 @@ class SidebarProvider implements ProviderInterface
|
|||||||
/** @var list<string> */
|
/** @var list<string> */
|
||||||
private readonly array $activeModuleIds;
|
private readonly array $activeModuleIds;
|
||||||
|
|
||||||
/** @var list<array{label: string, icon: string, items: list<array{label: string, to: string, icon: string, module: string}>}> */
|
/** @var list<array{label: string, icon: string, items: list<array{label: string, to: string, icon: string, module: string, permission?: string}>}> */
|
||||||
private readonly array $sidebarConfig;
|
private readonly array $sidebarConfig;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct(private readonly Security $security)
|
||||||
{
|
{
|
||||||
$configDir = dirname(__DIR__, 5).'/config';
|
$configDir = dirname(__DIR__, 5).'/config';
|
||||||
|
|
||||||
@@ -58,6 +59,18 @@ class SidebarProvider implements ProviderInterface
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filtrage par permission RBAC : si l'item declare une permission
|
||||||
|
// requise et que l'utilisateur courant ne la possede pas, l'item
|
||||||
|
// est masque et sa route ajoutee aux routes desactivees.
|
||||||
|
$requiredPermission = $item['permission'] ?? null;
|
||||||
|
if (null !== $requiredPermission && !$this->security->isGranted($requiredPermission)) {
|
||||||
|
if (isset($item['to'])) {
|
||||||
|
$disabledRoutes[] = $item['to'];
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$items[] = [
|
$items[] = [
|
||||||
'label' => $item['label'],
|
'label' => $item['label'],
|
||||||
'to' => $item['to'],
|
'to' => $item['to'],
|
||||||
|
|||||||
Reference in New Issue
Block a user