diff --git a/src/Bundle/ChillMainBundle/Controller/SavedExportController.php b/src/Bundle/ChillMainBundle/Controller/SavedExportController.php index cb9d89215..22e4a6ba7 100644 --- a/src/Bundle/ChillMainBundle/Controller/SavedExportController.php +++ b/src/Bundle/ChillMainBundle/Controller/SavedExportController.php @@ -120,15 +120,15 @@ final readonly class SavedExportController #[Route(path: '/exports/saved/duplicate-from-saved-export/{id}/new', name: 'chill_main_export_saved_duplicate')] public function duplicate(SavedExport $previousSavedExport, Request $request): Response { - if (!$this->security->isGranted(SavedExportVoter::GENERATE, $previousSavedExport)) { - throw new AccessDeniedHttpException('Not allowed to see this saved export'); - } - $user = $this->security->getUser(); if (!$user instanceof User) { throw new AccessDeniedHttpException('only regular user can create a saved export'); } + if (!$this->security->isGranted(SavedExportVoter::EDIT, $previousSavedExport)) { + throw new AccessDeniedHttpException('Not allowed to edit this saved export'); + } + $savedExport = new SavedExport(); $savedExport ->setExportAlias($previousSavedExport->getExportAlias()) @@ -209,7 +209,7 @@ final readonly class SavedExportController #[Route(path: '/{_locale}/exports/saved/{savedExport}/edit-options/{exportGeneration}', name: 'chill_main_export_saved_options_edit')] public function updateOptionsFromGeneration(SavedExport $savedExport, ExportGeneration $exportGeneration, Request $request): Response { - if (!$this->security->isGranted(SavedExportVoter::EDIT, $savedExport)) { + if (!$this->security->isGranted(SavedExportVoter::DUPLICATE, $savedExport)) { throw new AccessDeniedHttpException('You are not allowed to access this saved export'); } diff --git a/src/Bundle/ChillMainBundle/Resources/views/SavedExport/index.html.twig b/src/Bundle/ChillMainBundle/Resources/views/SavedExport/index.html.twig index 4a9b9490e..40257a996 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/SavedExport/index.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/SavedExport/index.html.twig @@ -30,6 +30,10 @@

{% if app.user is same as saved.user %}{{ 'saved_export.Owner'|trans }}{% endif %}

+ {% else %} +

+ Partagé par {{ saved.user|chill_entity_render_box }} +

{% endif %}

{{ saved.description|chill_markdown_to_html }}

@@ -63,7 +67,9 @@ {% endif %} {# reminder: the controller already checked that the user can generate saved exports #}
  • {{ 'saved_export.update_filters_aggregators_and_execute'|trans }}
  • -
  • {{ 'saved_export.Duplicate'|trans }}
  • + {% if is_granted('CHILL_MAIN_EXPORT_SAVED_DUPLICATE', saved) %} +
  • {{ 'saved_export.Duplicate'|trans }}
  • + {% endif %} {% if is_granted('CHILL_MAIN_EXPORT_SAVED_DELETE', saved) %}
  • {{ 'Delete'|trans }}
  • {% endif %} diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/SavedExportVoter.php b/src/Bundle/ChillMainBundle/Security/Authorization/SavedExportVoter.php index 1d686dee4..aaf8b8010 100644 --- a/src/Bundle/ChillMainBundle/Security/Authorization/SavedExportVoter.php +++ b/src/Bundle/ChillMainBundle/Security/Authorization/SavedExportVoter.php @@ -15,6 +15,7 @@ use Chill\MainBundle\Entity\SavedExport; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Export\ExportManager; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; use Symfony\Component\Security\Core\Authorization\Voter\Voter; final class SavedExportVoter extends Voter @@ -25,6 +26,8 @@ final class SavedExportVoter extends Voter final public const GENERATE = 'CHILL_MAIN_EXPORT_SAVED_GENERATE'; + final public const DUPLICATE = 'CHILL_MAIN_EXPORT_SAVED_DUPLICATE'; + final public const SHARE = 'CHILL_MAIN_EXPORT_SAVED_SHARE'; private const ALL = [ @@ -32,9 +35,10 @@ final class SavedExportVoter extends Voter self::EDIT, self::GENERATE, self::SHARE, + self::DUPLICATE, ]; - public function __construct(private readonly ExportManager $exportManager) {} + public function __construct(private readonly ExportManager $exportManager, private readonly AccessDecisionManagerInterface $accessDecisionManager) {} protected function supports($attribute, $subject): bool { @@ -52,6 +56,7 @@ final class SavedExportVoter extends Voter return match ($attribute) { self::DELETE, self::EDIT, self::SHARE => $subject->getUser() === $token->getUser(), + self::DUPLICATE => $this->accessDecisionManager->decide($token, [ChillExportVoter::COMPOSE_EXPORT]) && $this->accessDecisionManager->decide($token, [self::EDIT], $subject) , self::GENERATE => $this->canUserGenerate($user, $subject), default => throw new \UnexpectedValueException('attribute not supported: '.$attribute), };