mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Add and enforce 'DUPLICATE' permissions for Saved Exports
Introduce a new 'DUPLICATE' permission in SavedExportVoter and update related logic in the controller and templates to enforce this rule. Ensure only authorized users can duplicate exports and adjust UI elements accordingly for better permission handling.
This commit is contained in:
parent
e79d6d670b
commit
e89f5e4713
@ -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');
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,10 @@
|
||||
<p class="card-text tags">
|
||||
{% if app.user is same as saved.user %}<span class="badge bg-primary">{{ 'saved_export.Owner'|trans }}</span>{% endif %}
|
||||
</p>
|
||||
{% else %}
|
||||
<p class="card-text tags">
|
||||
Partagé par <span class="badge-user">{{ saved.user|chill_entity_render_box }}</span>
|
||||
</p>
|
||||
{% endif %}
|
||||
<p class="card-text my-3">{{ saved.description|chill_markdown_to_html }}</p>
|
||||
</div>
|
||||
@ -63,7 +67,9 @@
|
||||
{% endif %}
|
||||
{# reminder: the controller already checked that the user can generate saved exports #}
|
||||
<li><a href="{{ chill_path_add_return_path('chill_main_export_new', {'alias': saved.exportAlias,'from_saved': saved.id }) }}" class="dropdown-item"><i class="fa fa-pencil"></i> {{ 'saved_export.update_filters_aggregators_and_execute'|trans }}</a></li>
|
||||
<li><a href="{{ chill_path_add_return_path('chill_main_export_saved_duplicate', {'id': saved.id}) }}" class="dropdown-item"><i class="fa fa-copy"></i> {{ 'saved_export.Duplicate'|trans }}</a></li>
|
||||
{% if is_granted('CHILL_MAIN_EXPORT_SAVED_DUPLICATE', saved) %}
|
||||
<li><a href="{{ chill_path_add_return_path('chill_main_export_saved_duplicate', {'id': saved.id}) }}" class="dropdown-item"><i class="fa fa-copy"></i> {{ 'saved_export.Duplicate'|trans }}</a></li>
|
||||
{% endif %}
|
||||
{% if is_granted('CHILL_MAIN_EXPORT_SAVED_DELETE', saved) %}
|
||||
<li><a href="{{ chill_path_add_return_path('chill_main_export_saved_delete', {'id': saved.id }) }}" class="dropdown-item"><i class="fa fa-trash"></i> {{ 'Delete'|trans }}</a></li>
|
||||
{% endif %}
|
||||
|
@ -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),
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user