Unverified Commit 07829ec0 authored by acbramley's avatar acbramley Committed by larowlan

Issue #2852717 by acbramley: Limit access to moderation form based on edit access

parent 94e3e2b5
......@@ -7,6 +7,7 @@ use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\TypedData\TranslatableInterface;
use Drupal\workbench_moderation\Event\WorkbenchModerationEvents;
use Drupal\workbench_moderation\Event\WorkbenchModerationTransitionEvent;
......@@ -45,6 +46,13 @@ class EntityOperations {
*/
protected $tracker;
/**
* The current user service.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;
/**
* Constructs a new EntityOperations object.
*
......@@ -58,13 +66,16 @@ class EntityOperations {
* The event dispatcher.
* @param \Drupal\workbench_moderation\RevisionTrackerInterface $tracker
* The revision tracker.
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user service.
*/
public function __construct(ModerationInformationInterface $moderation_info, EntityTypeManagerInterface $entity_type_manager, FormBuilderInterface $form_builder, EventDispatcherInterface $event_dispatcher, RevisionTrackerInterface $tracker) {
public function __construct(ModerationInformationInterface $moderation_info, EntityTypeManagerInterface $entity_type_manager, FormBuilderInterface $form_builder, EventDispatcherInterface $event_dispatcher, RevisionTrackerInterface $tracker, AccountInterface $current_user) {
$this->moderationInfo = $moderation_info;
$this->entityTypeManager = $entity_type_manager;
$this->eventDispatcher = $event_dispatcher;
$this->formBuilder = $form_builder;
$this->tracker = $tracker;
$this->currentUser = $current_user;
}
/**
......@@ -229,6 +240,7 @@ class EntityOperations {
if ($component) {
$build['workbench_moderation_control'] = $this->formBuilder->getForm(EntityModerationForm::class, $entity);
$build['workbench_moderation_control']['#weight'] = $component['weight'];
$build['workbench_moderation_control']['#access'] = $this->currentUser->hasPermission('moderate entities that cannot edit') || $entity->access('update');
}
}
......
<?php
namespace Drupal\Tests\workbench_moderation\Functional;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\workbench_moderation\WorkbenchModerationTestTrait;
/**
* Tests access to the moderation form.
*
* @group workbench_moderation
*/
class ModerationFormAccessTest extends BrowserTestBase {
use WorkbenchModerationTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = [
'workbench_moderation',
'node',
'options',
'user',
'system',
];
/**
* Tests user access to the moderation form.
*/
public function testModerationFormAccess() {
$page = $this->getSession()->getPage();
$base_permissions = [
'access content',
'view all revisions',
'view moderation states',
'view latest version',
'view any unpublished content',
'use draft_needs_review transition',
];
$node_type = $this->createNodeType('Test', 'test');
$entity_display = EntityViewDisplay::load('node.test.default');
$entity_display->setComponent('workbench_moderation_control');
$entity_display->save();
// Create a node with a forward revision for the form to display on.
$node = $this->createNode(['type' => $node_type->id(), 'moderation_state' => 'published']);
$node->moderation_state->target_id = 'draft';
$node->save();
// Page doesn't have form if user can't edit or bypass edit access.
$this->drupalLogin($this->drupalCreateUser($base_permissions));
$this->drupalGet($node->toUrl('latest-version'));
$this->assertFalse($page->hasSelect('Moderate'));
// Page has moderation form for user that can edit.
$this->drupalLogin($this->drupalCreateUser(array_merge($base_permissions, ['edit any test content'])));
$this->drupalGet($node->toUrl('latest-version'));
$this->assertTrue($page->hasSelect('Moderate'));
// Page has moderation form for user that has edit bypass permission.
$this->drupalLogin($this->drupalCreateUser(array_merge($base_permissions, ['moderate entities that cannot edit'])));
$this->drupalGet($node->toUrl('latest-version'));
$this->assertTrue($page->hasSelect('Moderate'));
}
}
......@@ -7,8 +7,8 @@
namespace Drupal\Tests\workbench_moderation\Functional;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\simpletest\BrowserTestBase;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\workbench_moderation\WorkbenchModerationTestTrait;
/**
* Tests the view access control handler for moderation state entities.
......@@ -21,6 +21,8 @@ use Drupal\simpletest\BrowserTestBase;
*/
class ModerationStateAccessTest extends BrowserTestBase {
use WorkbenchModerationTestTrait;
/**
* {@inheritdoc}
*/
......@@ -107,27 +109,4 @@ class ModerationStateAccessTest extends BrowserTestBase {
$this->assertFalse($page->hasLink('Published'));
}
/**
* Creates a new node type.
*
* @param string $label
* The human-readable label of the type to create.
* @param string $machine_name
* The machine name of the type to create.
*
* @return NodeType
* The node type just created.
*/
protected function createNodeType($label, $machine_name) {
/** @var NodeType $node_type */
$node_type = NodeType::create([
'type' => $machine_name,
'label' => $label,
]);
$node_type->setThirdPartySetting('workbench_moderation', 'enabled', TRUE);
$node_type->save();
return $node_type;
}
}
<?php
namespace Drupal\Tests\workbench_moderation;
/**
* Defines a trait for common testing methods for workbench moderation.
*/
trait WorkbenchModerationTestTrait {
/**
* Creates a new node type.
*
* @param string $label
* The human-readable label of the type to create.
* @param string $machine_name
* The machine name of the type to create.
*
* @return \Drupal\node\Entity\NodeType
* The node type just created.
*/
protected function createNodeType($label, $machine_name) {
/** @var \Drupal\node\Entity\NodeType $node_type */
$node_type = $this->createContentType(['name' => $label, 'type' => $machine_name]);
$node_type->setThirdPartySetting('workbench_moderation', 'enabled', TRUE);
$node_type->setThirdPartySetting('workbench_moderation', 'allowed_moderation_states', [
'draft',
'needs_review',
'published',
]);
$node_type->save();
return $node_type;
}
}
......@@ -20,5 +20,9 @@ view latest version:
title: View the latest version
description: View the latest version of an entity. (Also requires "View any unpublished content" permission)
moderate entities that cannot edit:
title: Moderate without edit access
description: Allows a user to bypass edit access checks when displaying the moderation form.
permission_callbacks:
- \Drupal\workbench_moderation\Permissions::transitionPermissions
......@@ -15,7 +15,7 @@ services:
arguments: ['@string_translation', '@workbench_moderation.moderation_information', '@entity_type.manager']
workbench_moderation.entity_operations:
class: Drupal\workbench_moderation\EntityOperations
arguments: ['@workbench_moderation.moderation_information', '@entity_type.manager', '@form_builder', '@event_dispatcher', '@workbench_moderation.revision_tracker']
arguments: ['@workbench_moderation.moderation_information', '@entity_type.manager', '@form_builder', '@event_dispatcher', '@workbench_moderation.revision_tracker', '@current_user']
workbench_moderation.inline_editing_disabler:
class: \Drupal\workbench_moderation\InlineEditingDisabler
arguments: ['@workbench_moderation.moderation_information']
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment