From edeb8edbea699dacc276091f41770d7902179e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 17 Apr 2025 17:34:09 +0200 Subject: [PATCH] Add role-based access controls for export functionality Introduced `CHILL_MAIN_COMPOSE_EXPORT` and `CHILL_MAIN_GENERATE_SAVED_EXPORT` roles for managing export creation and execution permissions. Updated access checks, menu routing, and templates to align with the new roles. Added a migration to extend existing permission groups with the `CHILL_MAIN_COMPOSE_EXPORT` role. --- .../Controller/ExportIndexController.php | 5 ++ .../Controller/SavedExportController.php | 5 +- .../ChillMainExtension.php | 4 ++ .../Resources/views/Export/_navbar.html.twig | 12 ++-- .../MenuBuilder/SectionMenuBuilder.php | 4 +- .../Authorization/ChillExportVoter.php | 44 ++++++++---- .../Authorization/SavedExportVoter.php | 2 +- .../migrations/Version20250417135712.php | 67 +++++++++++++++++++ .../translations/messages.fr.yml | 4 ++ .../ChillPersonExtension.php | 3 - 10 files changed, 123 insertions(+), 27 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/migrations/Version20250417135712.php diff --git a/src/Bundle/ChillMainBundle/Controller/ExportIndexController.php b/src/Bundle/ChillMainBundle/Controller/ExportIndexController.php index d65a6c55e..4f3de7aef 100644 --- a/src/Bundle/ChillMainBundle/Controller/ExportIndexController.php +++ b/src/Bundle/ChillMainBundle/Controller/ExportIndexController.php @@ -14,6 +14,7 @@ namespace Chill\MainBundle\Controller; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Export\ExportManager; use Chill\MainBundle\Repository\ExportGenerationRepository; +use Chill\MainBundle\Security\Authorization\ChillExportVoter; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Routing\Annotation\Route; @@ -40,6 +41,10 @@ final readonly class ExportIndexController throw new AccessDeniedHttpException('Only regular user can see this page'); } + if (!$this->security->isGranted(ChillExportVoter::COMPOSE_EXPORT)) { + throw new AccessDeniedHttpException(sprintf('Require the %s role', ChillExportVoter::COMPOSE_EXPORT)); + } + $exports = $this->exportManager->getExportsGrouped(true); $lastExecutions = []; diff --git a/src/Bundle/ChillMainBundle/Controller/SavedExportController.php b/src/Bundle/ChillMainBundle/Controller/SavedExportController.php index 8e08f67d6..b7e38f7f4 100644 --- a/src/Bundle/ChillMainBundle/Controller/SavedExportController.php +++ b/src/Bundle/ChillMainBundle/Controller/SavedExportController.php @@ -20,6 +20,7 @@ use Chill\MainBundle\Export\GroupedExportInterface; use Chill\MainBundle\Form\SavedExportType; use Chill\MainBundle\Repository\ExportGenerationRepository; use Chill\MainBundle\Repository\SavedExportRepositoryInterface; +use Chill\MainBundle\Security\Authorization\ChillExportVoter; use Chill\MainBundle\Security\Authorization\ExportGenerationVoter; use Chill\MainBundle\Security\Authorization\SavedExportVoter; use Doctrine\ORM\EntityManagerInterface; @@ -170,8 +171,8 @@ final readonly class SavedExportController { $user = $this->security->getUser(); - if (!$this->security->isGranted('ROLE_USER') || !$user instanceof User) { - throw new AccessDeniedHttpException(); + if (!$this->security->isGranted(ChillExportVoter::GENERATE_SAVED_EXPORT) || !$user instanceof User) { + throw new AccessDeniedHttpException(sprintf('Missing role: %s', ChillExportVoter::GENERATE_SAVED_EXPORT)); } $exports = array_filter( diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php index 9fa3b0f42..6b33b998d 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php @@ -78,6 +78,7 @@ use Chill\MainBundle\Form\RegroupmentType; use Chill\MainBundle\Form\UserGroupType; use Chill\MainBundle\Form\UserJobType; use Chill\MainBundle\Form\UserType; +use Chill\MainBundle\Security\Authorization\ChillExportVoter; use Misd\PhoneNumberBundle\Doctrine\DBAL\Types\PhoneNumberType; use Ramsey\Uuid\Doctrine\UuidType; use Symfony\Component\Config\FileLocator; @@ -332,6 +333,9 @@ class ChillMainExtension extends Extension implements 'strategy' => 'unanimous', 'allow_if_all_abstain' => false, ], + 'role_hierarchy' => [ + ChillExportVoter::COMPOSE_EXPORT => ChillExportVoter::GENERATE_SAVED_EXPORT, + ], ]); // add crud api diff --git a/src/Bundle/ChillMainBundle/Resources/views/Export/_navbar.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Export/_navbar.html.twig index ae62a6313..6ae68f240 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Export/_navbar.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Export/_navbar.html.twig @@ -1,9 +1,11 @@