From af40ece400aa7a93f8029ff645530c2430428454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Adamczyk?= Date: Thu, 28 Jun 2018 15:39:28 +0200 Subject: [PATCH] EZP-29101: Implement permissions for Content Types --- .../Controller/ContentTypeController.php | 19 ++--- .../Controller/ContentTypeGroupController.php | 77 ++++++++++-------- .../views/admin/content_type/list.html.twig | 61 ++++++++------ .../views/admin/content_type/view.html.twig | 4 +- .../admin/content_type_group/list.html.twig | 81 +++++++++++-------- 5 files changed, 143 insertions(+), 99 deletions(-) diff --git a/src/bundle/Controller/ContentTypeController.php b/src/bundle/Controller/ContentTypeController.php index e246e5fd14..283067f4cb 100644 --- a/src/bundle/Controller/ContentTypeController.php +++ b/src/bundle/Controller/ContentTypeController.php @@ -22,9 +22,7 @@ use Pagerfanta\Adapter\ArrayAdapter; use Pagerfanta\Pagerfanta; use eZ\Publish\API\Repository\Exceptions\BadStateException; -use eZ\Publish\API\Repository\Exceptions\InvalidArgumentException; use eZ\Publish\API\Repository\Exceptions\NotFoundException; -use eZ\Publish\API\Repository\Exceptions\UnauthorizedException; use Symfony\Component\Form\FormInterface; use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; use Symfony\Component\Translation\Exception\InvalidArgumentException as TranslationInvalidArgumentException; @@ -32,6 +30,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Translation\TranslatorInterface; use eZ\Publish\API\Repository\UserService; +use eZ\Publish\Core\MVC\Symfony\Security\Authorization\Attribute; class ContentTypeController extends Controller { @@ -138,6 +137,9 @@ public function listAction(ContentTypeGroup $group, string $routeName, int $page 'form_content_types_delete' => $deleteContentTypesForm->createView(), 'group' => $group, 'route_name' => $routeName, + 'can_create' => $this->isGranted(new Attribute('class', 'create')), + 'can_update' => $this->isGranted(new Attribute('class', 'update')), + 'can_delete' => $this->isGranted(new Attribute('class', 'delete')), ]); } @@ -152,6 +154,7 @@ public function listAction(ContentTypeGroup $group, string $routeName, int $page */ public function addAction(ContentTypeGroup $group): Response { + $this->denyAccessUnlessGranted(new Attribute('class', 'create')); $mainLanguageCode = reset($this->languages); $createStruct = $this->contentTypeService->newContentTypeCreateStruct('__new__' . md5((string)microtime(true))); @@ -195,6 +198,7 @@ public function addAction(ContentTypeGroup $group): Response */ public function editAction(ContentTypeGroup $group, ContentType $contentType): Response { + $this->denyAccessUnlessGranted(new Attribute('class', 'update')); // Kernel does not allow editing the same Content Type simultaneously by more than one user. // So we need to catch 'BadStateException' and inform user about another user editing the Content Type try { @@ -302,12 +306,11 @@ public function updateAction(Request $request, ContentTypeGroup $group, ContentT * * @return \Symfony\Component\HttpFoundation\Response * - * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException - * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException * @throws \Symfony\Component\Translation\Exception\InvalidArgumentException */ public function deleteAction(Request $request, ContentTypeGroup $group, ContentType $contentType): Response { + $this->denyAccessUnlessGranted(new Attribute('class', 'delete')); $form = $this->createDeleteForm($group, $contentType); $form->handleRequest($request); @@ -343,16 +346,13 @@ public function deleteAction(Request $request, ContentTypeGroup $group, ContentT * * @return \Symfony\Component\HttpFoundation\Response * - * @throws BadStateException * @throws TranslationInvalidArgumentException * @throws InvalidOptionsException - * @throws UnauthorizedException - * @throws InvalidArgumentException - * @throws NotFoundException * @throws \InvalidArgumentException */ public function bulkDeleteAction(Request $request, ContentTypeGroup $group): Response { + $this->denyAccessUnlessGranted(new Attribute('class', 'delete')); $form = $this->formFactory->deleteContentTypes( new ContentTypesDeleteData() ); @@ -401,6 +401,7 @@ public function viewAction(ContentTypeGroup $group, ContentType $contentType): R 'content_type_group' => $group, 'content_type' => $contentType, 'field_definitions_by_group' => $fieldDefinitionsByGroup, + 'can_update' => $this->isGranted(new Attribute('class', 'update')), ]); } @@ -455,7 +456,7 @@ protected function createDeleteForm(ContentTypeGroup $group, ContentType $conten } /** - * @param ContentType[] $contentTypes + * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType[] $contentTypes * * @return array */ diff --git a/src/bundle/Controller/ContentTypeGroupController.php b/src/bundle/Controller/ContentTypeGroupController.php index dcdf1f05ad..bdd1dd0287 100644 --- a/src/bundle/Controller/ContentTypeGroupController.php +++ b/src/bundle/Controller/ContentTypeGroupController.php @@ -22,28 +22,24 @@ use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; -use eZ\Publish\API\Repository\Exceptions\InvalidArgumentException; -use eZ\Publish\API\Repository\Exceptions\NotFoundException; -use eZ\Publish\API\Repository\Exceptions\UnauthorizedException; -use Symfony\Component\Translation\Exception\InvalidArgumentException as TranslationInvalidArgumentException; use Symfony\Component\Translation\TranslatorInterface; +use eZ\Publish\Core\MVC\Symfony\Security\Authorization\Attribute; class ContentTypeGroupController extends Controller { - /** @var NotificationHandlerInterface */ + /** @var \EzSystems\EzPlatformAdminUi\Notification\NotificationHandlerInterface */ private $notificationHandler; - /** @var TranslatorInterface */ + /** @var \Symfony\Component\Translation\TranslatorInterface */ private $translator; - /** @var ContentTypeService */ + /** @var \eZ\Publish\API\Repository\ContentTypeService */ private $contentTypeService; - /** @var FormFactory */ + /** @var \EzSystems\EzPlatformAdminUi\Form\Factory\FormFactory */ private $formFactory; - /** @var SubmitHandler */ + /** @var \EzSystems\EzPlatformAdminUi\Form\SubmitHandler */ private $submitHandler; /** @var array */ @@ -53,13 +49,11 @@ class ContentTypeGroupController extends Controller private $defaultPaginationLimit; /** - * ContentTypeGroupController constructor. - * - * @param NotificationHandlerInterface $notificationHandler - * @param TranslatorInterface $translator - * @param ContentTypeService $contentTypeService - * @param FormFactory $formFactory - * @param SubmitHandler $submitHandler + * @param \EzSystems\EzPlatformAdminUi\Notification\NotificationHandlerInterface $notificationHandler + * @param \Symfony\Component\Translation\TranslatorInterface $translator + * @param \eZ\Publish\API\Repository\ContentTypeService $contentTypeService + * @param \EzSystems\EzPlatformAdminUi\Form\Factory\FormFactory $formFactory + * @param \EzSystems\EzPlatformAdminUi\Form\SubmitHandler $submitHandler * @param array $languages * @param int $defaultPaginationLimit */ @@ -82,9 +76,9 @@ public function __construct( } /** - * @param Request $request + * @param \Symfony\Component\HttpFoundation\Request $request * - * @return Response + * @return \Symfony\Component\HttpFoundation\Response */ public function listAction(Request $request): Response { @@ -100,7 +94,7 @@ public function listAction(Request $request): Response $pagerfanta->setMaxPerPage($this->defaultPaginationLimit); $pagerfanta->setCurrentPage(min($page, $pagerfanta->getNbPages())); - /** @var ContentTypeGroup[] $contentTypeGroupList */ + /** @var \eZ\Publish\API\Repository\Values\ContentType\ContentTypeGroup[] $contentTypeGroupList */ $contentTypeGroupList = $pagerfanta->getCurrentPageResults(); $deleteContentTypeGroupsForm = $this->formFactory->deleteContentTypeGroups( @@ -118,11 +112,20 @@ public function listAction(Request $request): Response 'form_content_type_groups_delete' => $deleteContentTypeGroupsForm->createView(), 'deletable' => $deletableContentTypeGroup, 'content_types_count' => $count, + 'can_create' => $this->isGranted(new Attribute('class', 'create')), + 'can_update' => $this->isGranted(new Attribute('class', 'update')), + 'can_delete' => $this->isGranted(new Attribute('class', 'delete')), ]); } + /** + * @param \Symfony\Component\HttpFoundation\Request $request + * + * @return \Symfony\Component\HttpFoundation\Response + */ public function createAction(Request $request): Response { + $this->denyAccessUnlessGranted(new Attribute('class', 'create')); $form = $this->formFactory->createContentTypeGroup( new ContentTypeGroupCreateData() ); @@ -159,8 +162,15 @@ public function createAction(Request $request): Response ]); } + /** + * @param \Symfony\Component\HttpFoundation\Request $request + * @param \eZ\Publish\API\Repository\Values\ContentType\ContentTypeGroup $group + * + * @return \Symfony\Component\HttpFoundation\Response + */ public function updateAction(Request $request, ContentTypeGroup $group): Response { + $this->denyAccessUnlessGranted(new Attribute('class', 'update')); $form = $this->formFactory->updateContentTypeGroup( new ContentTypeGroupUpdateData($group) ); @@ -199,8 +209,15 @@ public function updateAction(Request $request, ContentTypeGroup $group): Respons ]); } + /** + * @param \Symfony\Component\HttpFoundation\Request $request + * @param \eZ\Publish\API\Repository\Values\ContentType\ContentTypeGroup $group + * + * @return \Symfony\Component\HttpFoundation\Response + */ public function deleteAction(Request $request, ContentTypeGroup $group): Response { + $this->denyAccessUnlessGranted(new Attribute('class', 'delete')); $form = $this->formFactory->deleteContentTypeGroup( new ContentTypeGroupDeleteData($group) ); @@ -232,19 +249,13 @@ public function deleteAction(Request $request, ContentTypeGroup $group): Respons /** * Handles removing content type groups based on submitted form. * - * @param Request $request - * - * @return Response + * @param \Symfony\Component\HttpFoundation\Request $request * - * @throws TranslationInvalidArgumentException - * @throws InvalidOptionsException - * @throws UnauthorizedException - * @throws InvalidArgumentException - * @throws NotFoundException - * @throws \InvalidArgumentException + * @return \Symfony\Component\HttpFoundation\Response */ public function bulkDeleteAction(Request $request): Response { + $this->denyAccessUnlessGranted(new Attribute('class', 'delete')); $form = $this->formFactory->deleteContentTypeGroups( new ContentTypeGroupsDeleteData() ); @@ -276,11 +287,11 @@ public function bulkDeleteAction(Request $request): Response } /** - * @param Request $request - * @param ContentTypeGroup $group + * @param \Symfony\Component\HttpFoundation\Request $request + * @param \eZ\Publish\API\Repository\Values\ContentType\ContentTypeGroup $group * @param int $page * - * @return Response + * @return \Symfony\Component\HttpFoundation\Response */ public function viewAction(Request $request, ContentTypeGroup $group, int $page = 1): Response { @@ -292,7 +303,7 @@ public function viewAction(Request $request, ContentTypeGroup $group, int $page } /** - * @param ContentTypeGroup[] $contentTypeGroups + * @param \eZ\Publish\API\Repository\Values\ContentType\ContentTypeGroup[] $contentTypeGroups * * @return array */ diff --git a/src/bundle/Resources/views/admin/content_type/list.html.twig b/src/bundle/Resources/views/admin/content_type/list.html.twig index 5208b51253..c24f0fe88e 100644 --- a/src/bundle/Resources/views/admin/content_type/list.html.twig +++ b/src/bundle/Resources/views/admin/content_type/list.html.twig @@ -8,27 +8,36 @@
{{ 'content_type.view.list.title'|trans({ '%identifier%': content_type_group.identifier })|desc('Content Types in %identifier%') }}
- - - - - - {% set modal_data_target = 'delete-content-types-modal' %} - - {% include '@ezdesign/admin/bulk_delete_confirmation_modal.html.twig' with { - 'id': modal_data_target, - 'message': 'content_type.modal.message'|trans|desc('Do you want to delete Content Type?'), - 'data_click': '#content_types_delete_delete', - }%} + {% if can_create %} + + + + + + {% endif %} + {% if can_delete %} + {% set modal_data_target = 'delete-content-types-modal' %} + + {% include '@ezdesign/admin/bulk_delete_confirmation_modal.html.twig' with { + 'id': modal_data_target, + 'message': 'content_type.modal.message'|trans|desc('Do you want to delete Content Type?'), + 'data_click': '#content_types_delete_delete', + }%} + {% endif %}
@@ -51,7 +60,11 @@ {% for content_type in pager.currentPageResults %} - {{ form_widget(form_content_types_delete.content_types[content_type.id], {"disabled": not deletable[content_type.id]}) }} + {% if can_delete %} + {{ form_widget(form_content_types_delete.content_types[content_type.id], {"disabled": not deletable[content_type.id]}) }} + {% else %} + {% do form_content_types_delete.content_types.setRendered %} + {% endif %} {% set view_url = path('ezplatform.content_type.view', { @@ -65,7 +78,9 @@ {{ content_type.id }} {{ content_type.modificationDate | date }} - {{ macros.content_type_edit(content_type, content_type_group, 'btn btn-icon mx-3') }} + {% if can_update %} + {{ macros.content_type_edit(content_type, content_type_group, 'btn btn-icon mx-3') }} + {% endif %} {% endfor %} diff --git a/src/bundle/Resources/views/admin/content_type/view.html.twig b/src/bundle/Resources/views/admin/content_type/view.html.twig index da6c89765d..de956da7c4 100644 --- a/src/bundle/Resources/views/admin/content_type/view.html.twig +++ b/src/bundle/Resources/views/admin/content_type/view.html.twig @@ -50,7 +50,9 @@ {{ content_type.identifier }} {{ content_type.descriptions[language_code]|default('') }} - {{ macros.content_type_edit(content_type, content_type_group, 'btn btn-icon mx-3') }} + {% if can_update %} + {{ macros.content_type_edit(content_type, content_type_group, 'btn btn-icon mx-3') }} + {% endif %} diff --git a/src/bundle/Resources/views/admin/content_type_group/list.html.twig b/src/bundle/Resources/views/admin/content_type_group/list.html.twig index 59fd0d2185..2501f2186d 100644 --- a/src/bundle/Resources/views/admin/content_type_group/list.html.twig +++ b/src/bundle/Resources/views/admin/content_type_group/list.html.twig @@ -25,27 +25,36 @@
{{ 'content_type_group.view.list.title'|trans|desc('Content Type Groups') }}
- - - - - - {% set modal_data_target = 'delete-content-type-groups-modal' %} - - {% include '@ezdesign/admin/bulk_delete_confirmation_modal.html.twig' with { - 'id': modal_data_target, - 'message': 'content_type_group.modal.message'|trans|desc('Do you want to delete Content Type Group?'), - 'data_click': '#content_type_groups_delete_delete', - }%} + {% if can_create %} + + + + + + {% endif %} + {% if can_delete %} + {% set modal_data_target = 'delete-content-type-groups-modal' %} + + {% include '@ezdesign/admin/bulk_delete_confirmation_modal.html.twig' with { + 'id': modal_data_target, + 'message': 'content_type_group.modal.message'|trans|desc('Do you want to delete Content Type Group?'), + 'data_click': '#content_type_groups_delete_delete', + }%} + {% endif %}
@@ -67,7 +76,11 @@ {% for content_type_group in pager.currentPageResults %} - {{ form_widget(form_content_type_groups_delete.content_type_groups[content_type_group.id], {"disabled": not deletable[content_type_group.id]}) }} + {% if can_delete %} + {{ form_widget(form_content_type_groups_delete.content_type_groups[content_type_group.id], {"disabled": not deletable[content_type_group.id]}) }} + {% else %} + {% do form_content_type_groups_delete.content_type_groups.setRendered %} + {% endif %} {% set view_url = path('ezplatform.content_type_group.view', { @@ -79,17 +92,19 @@ {{ content_type_group.id }} {{ content_types_count[content_type_group.id] }} - {% set edit_url = path('ezplatform.content_type_group.update', { - contentTypeGroupId: content_type_group.id - }) %} - - - - - - + {% if can_update %} + {% set edit_url = path('ezplatform.content_type_group.update', { + contentTypeGroupId: content_type_group.id + }) %} + + + + + + {% endif %} {% endfor %}