Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
EZP-29742: Implement permissions for Content/Create in Content item v…
…iew (#713)

* EZP-29742: Implement permissions for Content/Create in Content item view

* EZP-29742: Implement permissions for Content/Create in Content item view - refactor for assign section

* EZP-29742: Implement permissions for Content/Create in Content item view - part 1

* EZP-29742: Implement permissions for Content/Create in Content item view - choice loaders

* EZP-29742: Implement permissions for Content/Create in Content item view - content create policy in UDW
  • Loading branch information
mikadamczyk authored and Łukasz Serwatka committed Nov 20, 2018
1 parent 54fe958 commit deb399f
Show file tree
Hide file tree
Showing 22 changed files with 1,018 additions and 180 deletions.
17 changes: 13 additions & 4 deletions src/bundle/Controller/DashboardController.php
Expand Up @@ -11,25 +11,34 @@
use EzSystems\EzPlatformAdminUi\Form\Data\Content\Draft\ContentEditData;
use EzSystems\EzPlatformAdminUi\Form\Factory\FormFactory;
use eZ\Publish\API\Repository\PermissionResolver;
use Symfony\Component\HttpFoundation\Response;

class DashboardController extends Controller
{
/** @var \EzSystems\EzPlatformAdminUi\Form\Factory\FormFactory */
protected $formFactory;

/** @var \eZ\Publish\API\Repository\PermissionResolver */
private $permissionResolver;

/**
* @param \EzSystems\EzplatformAdminUi\Form\Factory\FormFactory $formFactory
* @param \EzSystems\EzPlatformAdminUi\Form\Factory\FormFactory $formFactory
* @param \eZ\Publish\API\Repository\PermissionResolver $permissionResolver
*/
public function __construct(FormFactory $formFactory, PermissionResolver $permissionResolver)
{
public function __construct(
FormFactory $formFactory,
PermissionResolver $permissionResolver
) {
$this->formFactory = $formFactory;
$this->permissionResolver = $permissionResolver;
}

public function dashboardAction()
/**
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
*/
public function dashboardAction(): Response
{
$editForm = $this->formFactory->contentEdit(
new ContentEditData()
Expand Down
37 changes: 9 additions & 28 deletions src/bundle/Controller/SectionController.php
Expand Up @@ -31,7 +31,7 @@
use EzSystems\EzPlatformAdminUi\Form\SubmitHandler;
use EzSystems\EzPlatformAdminUi\Notification\NotificationHandlerInterface;
use EzSystems\EzPlatformAdminUi\UI\Service\PathService;
use EzSystems\EzPlatformAdminUi\Util\PermissionUtil;
use EzSystems\EzPlatformAdminUi\Permission\PermissionCheckerInterface;
use EzSystems\EzPlatformAdminUiBundle\View\EzPagerfantaView;
use EzSystems\EzPlatformAdminUiBundle\View\Template\EzPagerfantaTemplate;
use Pagerfanta\Adapter\ArrayAdapter;
Expand Down Expand Up @@ -80,8 +80,8 @@ class SectionController extends Controller
/** @var \eZ\Publish\API\Repository\PermissionResolver */
private $permissionResolver;

/** @var \EzSystems\EzPlatformAdminUi\Util\PermissionUtil */
private $permissionUtil;
/** @var \EzSystems\EzPlatformAdminUi\Permission\PermissionCheckerInterface */
private $permissionChecker;

/** @var int */
private $defaultPaginationLimit;
Expand All @@ -99,7 +99,7 @@ class SectionController extends Controller
* @param \eZ\Publish\API\Repository\LocationService $locationService
* @param \EzSystems\EzPlatformAdminUi\UI\Service\PathService $pathService
* @param \eZ\Publish\API\Repository\PermissionResolver $permissionResolver
* @param \EzSystems\EzPlatformAdminUi\Util\PermissionUtil $permissionUtil
* @param \EzSystems\EzPlatformAdminUi\Permission\PermissionCheckerInterface $permissionChecker
* @param int $defaultPaginationLimit
*/
public function __construct(
Expand All @@ -115,7 +115,7 @@ public function __construct(
LocationService $locationService,
PathService $pathService,
PermissionResolver $permissionResolver,
PermissionUtil $permissionUtil,
PermissionCheckerInterface $permissionChecker,
int $defaultPaginationLimit
) {
$this->notificationHandler = $notificationHandler;
Expand All @@ -131,7 +131,7 @@ public function __construct(
$this->pathService = $pathService;
$this->defaultPaginationLimit = $defaultPaginationLimit;
$this->permissionResolver = $permissionResolver;
$this->permissionUtil = $permissionUtil;
$this->permissionChecker = $permissionChecker;
}

public function performAccessCheck(): void
Expand Down Expand Up @@ -518,31 +518,12 @@ private function canUserAssignSectionToSomeContent(Section $section): bool
return $hasAccess;
}

if (!empty($restrictedNewSections = $this->getRestrictedNewSectionsIds($hasAccess))) {
return in_array($section->id, $restrictedNewSections, true);
$restrictedNewSections = $this->permissionChecker->getRestrictions($hasAccess, NewSectionLimitation::class);
if (!empty($restrictedNewSections)) {
return in_array($section->id, array_map('intval', $restrictedNewSections), true);
}

// If a user has other limitation than NewSectionLimitation, then a decision will be taken later, based on selected Content.
return true;
}

/**
* @param array $hasAccess
*
* @return int[]
*/
private function getRestrictedNewSectionsIds(array $hasAccess): array
{
$restrictedSectionsIds = [];

foreach ($this->permissionUtil->flattenArrayOfLimitations($hasAccess) as $limitation) {
if ($limitation instanceof NewSectionLimitation) {
foreach ($limitation->limitationValues as $sectionsId) {
$restrictedSectionsIds[] = (int)$sectionsId;
}
}
}

return array_unique($restrictedSectionsIds);
}
}
27 changes: 2 additions & 25 deletions src/bundle/Resources/config/services.yml
Expand Up @@ -18,6 +18,8 @@ imports:
- { resource: services/translation.yml }
- { resource: services/user_settings.yml }
- { resource: services/rest.yml }
- { resource: services/permissions.yml }
- { resource: services/forms.yml }

services:
_defaults:
Expand Down Expand Up @@ -76,22 +78,6 @@ services:
tags:
- {name: kernel.event_subscriber}

EzSystems\EzPlatformAdminUi\Form\SubmitHandler: ~

EzSystems\EzPlatformAdminUi\Form\Type\:
resource: '../../../lib/Form/Type'

EzSystems\EzPlatformAdminUi\Form\DataMapper\:
resource: '../../../lib/Form/DataMapper'

EzSystems\EzPlatformAdminUi\Form\Type\Language\LanguageChoiceType:
arguments:
$siteAccessLanguages: '$languages$'

EzSystems\EzPlatformAdminUi\Form\Type\Policy\PolicyChoiceType:
arguments:
$policyMap: "%ezpublish.api.role.policy_map%"

EzSystems\EzPlatformAdminUi\UI\Dataset\DatasetFactory:
arguments:
$userContentTypeIdentifier: '$user_content_type_identifier$'
Expand All @@ -105,16 +91,10 @@ services:
tags:
- { name: form.type }

EzSystems\EzPlatformAdminUi\Form\Factory\FormFactory: ~

EzSystems\EzPlatformAdminUi\Notification\FlashBagNotificationHandler: ~

EzSystems\EzPlatformAdminUi\Notification\NotificationHandlerInterface: '@EzSystems\EzPlatformAdminUi\Notification\FlashBagNotificationHandler'

EzSystems\EzPlatformAdminUi\Form\Type\Extension\Content\ContentEditTypeExtension:
tags:
- { name: form.type_extension, extended_type: EzSystems\RepositoryForms\Form\Type\Content\ContentEditType }

EzSystems\EzPlatformAdminUi\RepositoryForms\View\ViewParametersListener:
public: true
tags:
Expand All @@ -139,9 +119,6 @@ services:
tags:
- { name: knp_menu.voter }

EzSystems\EzPlatformAdminUi\Form\EventListener\:
resource: '../../../lib/Form/EventListener'

EzSystems\EzPlatformAdminUi\RepositoryForms\Dispatcher\ContentOnTheFlyDispatcher:
calls:
- [setEventDispatcher, ["@event_dispatcher"]]
Expand Down
49 changes: 49 additions & 0 deletions src/bundle/Resources/config/services/forms.yml
@@ -0,0 +1,49 @@
services:
_defaults:
autowire: true
autoconfigure: true
public: false

EzSystems\EzPlatformAdminUi\Form\SubmitHandler: ~

EzSystems\EzPlatformAdminUi\Form\Factory\FormFactory: ~

EzSystems\EzPlatformAdminUi\Form\DataMapper\:
resource: '../../../lib/Form/DataMapper'

EzSystems\EzPlatformAdminUi\Form\Type\:
resource: '../../../lib/Form/Type'

EzSystems\EzPlatformAdminUi\Form\EventListener\:
resource: '../../../lib/Form/EventListener'

EzSystems\EzPlatformAdminUi\Form\Type\Extension\Content\ContentEditTypeExtension:
tags:
- { name: form.type_extension, extended_type: EzSystems\RepositoryForms\Form\Type\Content\ContentEditType }

EzSystems\EzPlatformAdminUi\Form\Type\Policy\PolicyChoiceType:
arguments:
$policyMap: "%ezpublish.api.role.policy_map%"

EzSystems\EzPlatformAdminUi\Form\Type\Content\Draft\ContentCreateType:
arguments:
$contentTypeChoiceLoader: '@EzSystems\EzPlatformAdminUi\Form\Type\ChoiceList\Loader\PermissionAwareContentTypeChoiceLoader'
$languageChoiceLoader: '@EzSystems\EzPlatformAdminUi\Form\Type\ChoiceList\Loader\PermissionAwareLanguageChoiceLoader'

EzSystems\EzPlatformAdminUi\Form\Type\ChoiceList\Loader\ContentTypeChoiceLoader: ~

EzSystems\EzPlatformAdminUi\Form\Type\ChoiceList\Loader\LanguageChoiceLoader:
arguments:
$siteAccessLanguages: '$languages$'

EzSystems\EzPlatformAdminUi\Form\Type\ChoiceList\Loader\PermissionAwareContentTypeChoiceLoader:
arguments:
$decorated: '@EzSystems\EzPlatformAdminUi\Form\Type\ChoiceList\Loader\ContentTypeChoiceLoader'
$module: 'content'
$function: 'create'

EzSystems\EzPlatformAdminUi\Form\Type\ChoiceList\Loader\PermissionAwareLanguageChoiceLoader:
arguments:
$decorated: '@EzSystems\EzPlatformAdminUi\Form\Type\ChoiceList\Loader\LanguageChoiceLoader'
$module: 'content'
$function: 'create'
10 changes: 10 additions & 0 deletions src/bundle/Resources/config/services/permissions.yml
@@ -0,0 +1,10 @@
services:
_defaults:
autowire: true
autoconfigure: true
public: false

EzSystems\EzPlatformAdminUi\Permission\PermissionChecker: ~

EzSystems\EzPlatformAdminUi\Permission\PermissionCheckerInterface:
alias: EzSystems\EzPlatformAdminUi\Permission\PermissionChecker
4 changes: 4 additions & 0 deletions src/bundle/Resources/public/scss/_forms.scss
Expand Up @@ -101,3 +101,7 @@ form:not(.form-inline) {
position: absolute;
}
}

.ez-content-create[readonly] {
pointer-events: none;
}
Expand Up @@ -4,14 +4,14 @@
<div class="ez-extra-actions__header">{{ 'content.create.choose_content_type'|trans|desc('Create your content') }}</div>
<div class="ez-extra-actions__content">
{{ form_start(form, { 'action': path('ezplatform.content.create'), 'attr': { 'autocomplete': 'off' } }) }}
{% if form.language.vars.choices|length == 1 %}
{{ form_widget(form.language, {'attr': {'hidden': true}}) }}
{% else %}
<div class="ez-extra-actions__section-header">{{ 'content.create.select_language'|trans|desc('Select language') }}</div>
<div class="ez-extra-actions__section-content">
<div class="ez-extra-actions__section-header">{{ 'content.create.select_language'|trans|desc('Select language') }}</div>
<div class="ez-extra-actions__section-content">
{% if form.language.vars.choices|length == 1 %}
{{ form_widget(form.language, {'attr': {'class': 'ez-content-create', 'readonly': true}}) }}
{% else %}
{{ form_widget(form.language) }}
</div>
{% endif %}
{% endif %}
</div>
<div class="ez-extra-actions__section-header">{{ 'content.create.select_content_type'|trans|desc('Select Content Type') }}</div>
<div class="ez-extra-actions__section-content ez-extra-actions__section-content--content-type">
<div class="ez-instant-filter">
Expand Down
7 changes: 5 additions & 2 deletions src/bundle/Resources/views/dashboard/dashboard.html.twig
Expand Up @@ -12,8 +12,11 @@
<div class="container ez-dashboard__header">
<h1 class="py-3">{{ 'my.dashboard'|trans|desc('My dashboard') }}</h1>
<div class="ez-dashboard__create">
<button type="button" class="btn btn-primary ez-btn--cotf-create" data-udw-config="{{ ez_udw_config('create', {}) }}" {% if not can_create_content %}disabled{% endif %}>
<svg class="ez-icon ez-icon--medium ez-icon--light">
<button
class="btn btn-primary ez-btn--cotf-create"
data-udw-config="{{ ez_udw_config('create', {'type': 'content_create'}) }}"
{% if not can_create_content %}disabled{% endif %}>
<svg class="ez-icon ez-icon--medium ez-icon--light ez-icon-create">
<use xlink:href="{{ asset('bundles/ezplatformadminui/img/ez-icons.svg') }}#create"></use>
</svg>
<span>{{ 'dashboard.create'|trans|desc('Create') }}</span>
Expand Down
89 changes: 89 additions & 0 deletions src/lib/Form/Type/ChoiceList/Loader/ContentTypeChoiceLoader.php
@@ -0,0 +1,89 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace EzSystems\EzPlatformAdminUi\Form\Type\ChoiceList\Loader;

use eZ\Publish\API\Repository\ContentTypeService;
use Symfony\Component\Form\ChoiceList\ArrayChoiceList;
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;

class ContentTypeChoiceLoader implements ChoiceLoaderInterface
{
/** @var \eZ\Publish\API\Repository\ContentTypeService */
protected $contentTypeService;

/**
* @param \eZ\Publish\API\Repository\ContentTypeService $contentTypeService
*/
public function __construct(ContentTypeService $contentTypeService)
{
$this->contentTypeService = $contentTypeService;
}

/**
* {@inheritdoc}
*/
public function getChoiceList(): array
{
$contentTypes = [];
$contentTypeGroups = $this->contentTypeService->loadContentTypeGroups();
foreach ($contentTypeGroups as $contentTypeGroup) {
$contentTypes[$contentTypeGroup->identifier] = $this->contentTypeService->loadContentTypes($contentTypeGroup);
}

return $contentTypes;
}

/**
* {@inheritdoc}
*/
public function loadChoiceList($value = null)
{
$choices = $this->getChoiceList();

return new ArrayChoiceList($choices, $value);
}

/**
* {@inheritdoc}
*/
public function loadChoicesForValues(array $values, $value = null)
{
// Optimize
$values = array_filter($values);
if (empty($values)) {
return [];
}

// If no callable is set, values are the same as choices
if (null === $value) {
return $values;
}

return $this->loadChoiceList($value)->getChoicesForValues($values);
}

/**
* {@inheritdoc}
*/
public function loadValuesForChoices(array $choices, $value = null)
{
// Optimize
$choices = array_filter($choices);
if (empty($choices)) {
return [];
}

// If no callable is set, choices are the same as values
if (null === $value) {
return $choices;
}

return $this->loadChoiceList($value)->getValuesForChoices($choices);
}
}

0 comments on commit deb399f

Please sign in to comment.