From 135c739d664cb03c6692ee9b6f259fc19df0d73d Mon Sep 17 00:00:00 2001
From: git <git@3355222.no-reply.drupal.org>
Date: Mon, 25 Apr 2016 19:09:28 +0200
Subject: [PATCH] Issue #2709483 by CTaPByK, slashrsm:
 EntityRevisionRouteAccessChecker doesn't correctly handle local tasks

---
 entity.services.yml                           |  4 +-
 .../EntityRevisionRouteAccessChecker.php      | 19 +++-
 .../entity_module_test.links.task.yml         |  9 ++
 .../entity_module_test.permissions.yml        |  4 +
 .../src/Entity/EnhancedEntity.php             |  1 +
 .../Functional/RevisionRouteAccessTest.php    | 94 +++++++++++++++++++
 6 files changed, 127 insertions(+), 4 deletions(-)
 create mode 100644 tests/modules/entity_module_test/entity_module_test.links.task.yml
 create mode 100644 tests/src/Functional/RevisionRouteAccessTest.php

diff --git a/entity.services.yml b/entity.services.yml
index 0cb872c..5d8c875 100644
--- a/entity.services.yml
+++ b/entity.services.yml
@@ -1,6 +1,6 @@
 services:
   access_checker.entity_revision:
     class: \Drupal\entity\Access\EntityRevisionRouteAccessChecker
-    arguments: ['@entity_type.manager']
+    arguments: ['@entity_type.manager', '@request_stack']
     tags:
-      - { name: access_check, applies_to: _entity_access_revision, needs_request: TRUE }
+      - { name: access_check, applies_to: _entity_access_revision }
diff --git a/src/Access/EntityRevisionRouteAccessChecker.php b/src/Access/EntityRevisionRouteAccessChecker.php
index f4f8e1d..833c2e2 100644
--- a/src/Access/EntityRevisionRouteAccessChecker.php
+++ b/src/Access/EntityRevisionRouteAccessChecker.php
@@ -14,6 +14,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Routing\Access\AccessInterface;
 use Drupal\Core\Session\AccountInterface;
 use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
 use Symfony\Component\Routing\Route;
 
 /**
@@ -33,20 +34,34 @@ class EntityRevisionRouteAccessChecker implements AccessInterface {
    */
   protected $accessCache = array();
 
+  /**
+   * The request stack.
+   *
+   * @var \Symfony\Component\HttpFoundation\RequestStack
+   */
+  protected $requestStack;
+
   /**
    * Creates a new EntityRevisionRouteAccessChecker instance.
    *
    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
    *   The entity manager.
+   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+   *   The request stack.
    */
-  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
+  public function __construct(EntityTypeManagerInterface $entity_type_manager, RequestStack $request_stack) {
     $this->entityTypeManager = $entity_type_manager;
+    $this->requestStack = $request_stack;
   }
 
   /**
    * {@inheritdoc}
    */
-  public function access(Route $route, AccountInterface $account, Request $request) {
+  public function access(Route $route, AccountInterface $account, Request $request = NULL) {
+    if (empty($request)) {
+      $request = $this->requestStack->getCurrentRequest();
+    }
+
     $operation = $route->getRequirement('_entity_access_revision');
     list(, $operation) = explode('.', $operation, 2);
 
diff --git a/tests/modules/entity_module_test/entity_module_test.links.task.yml b/tests/modules/entity_module_test/entity_module_test.links.task.yml
new file mode 100644
index 0000000..f680bb6
--- /dev/null
+++ b/tests/modules/entity_module_test/entity_module_test.links.task.yml
@@ -0,0 +1,9 @@
+entity.entity_module_test.canonical:
+  title: View
+  route_name: entity.entity_module_test.canonical
+  base_route: entity.entity_module_test.canonical
+
+entity.entity_module_test.edit_form:
+  title: Edit
+  route_name: entity.entity_module_test.edit_form
+  base_route: entity.entity_module_test.canonical
diff --git a/tests/modules/entity_module_test/entity_module_test.permissions.yml b/tests/modules/entity_module_test/entity_module_test.permissions.yml
index b41f84b..b9ff91d 100644
--- a/tests/modules/entity_module_test/entity_module_test.permissions.yml
+++ b/tests/modules/entity_module_test/entity_module_test.permissions.yml
@@ -1,3 +1,7 @@
 'administer entity_test_enhanced':
   title: 'Administer entity_test_enhanced'
   'restrict access': TRUE
+
+'view all entity_test_enhanced revisions':
+  title: 'View all entity_test_enhanced revisions'
+  'restrict access': TRUE
diff --git a/tests/modules/entity_module_test/src/Entity/EnhancedEntity.php b/tests/modules/entity_module_test/src/Entity/EnhancedEntity.php
index e0685e4..32b2bbd 100644
--- a/tests/modules/entity_module_test/src/Entity/EnhancedEntity.php
+++ b/tests/modules/entity_module_test/src/Entity/EnhancedEntity.php
@@ -47,6 +47,7 @@ use Drupal\entity\Revision\RevisionableContentEntityBase;
  *   links = {
  *     "add-page" = "/entity_test_enhanced/add",
  *     "add-form" = "/entity_test_enhanced/add/{type}",
+ *     "edit-form" = "/entity_test_enhanced/{entity_test_enhanced}/edit",
  *     "canonical" = "/entity_test_enhanced/{entity_test_enhanced}",
  *     "collection" = "/entity_test_enhanced",
  *     "delete-multiple-form" = "/entity_test_enhanced/delete",
diff --git a/tests/src/Functional/RevisionRouteAccessTest.php b/tests/src/Functional/RevisionRouteAccessTest.php
new file mode 100644
index 0000000..42c5840
--- /dev/null
+++ b/tests/src/Functional/RevisionRouteAccessTest.php
@@ -0,0 +1,94 @@
+<?php
+
+namespace Drupal\Tests\entity\Functional;
+
+use Drupal\entity_module_test\Entity\EnhancedEntity;
+use Drupal\entity_module_test\Entity\EnhancedEntityBundle;
+use Drupal\simpletest\BlockCreationTrait;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Tests the revision route access check.
+ *
+ * @group entity
+ *
+ * @runTestsInSeparateProcesses
+ *
+ * @preserveGlobalState disabled
+ */
+class RevisionRouteAccessTest extends BrowserTestBase {
+
+  use BlockCreationTrait;
+
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface;
+   */
+  protected $account;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['entity_module_test', 'user', 'entity', 'block'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    EnhancedEntityBundle::create([
+      'id' => 'default',
+      'label' => 'Default',
+    ])->save();
+
+    $this->placeBlock('local_tasks_block');
+    $this->placeBlock('system_breadcrumb_block');
+
+    $this->account = $this->drupalCreateUser([
+      'administer entity_test_enhanced',
+      'view all entity_test_enhanced revisions',
+    ]);
+
+    $this->drupalLogin($this->account);
+  }
+
+  /**
+   * Test enhanced entity revision routes access.
+   */
+  public function testRevisionRouteAccess() {
+    $entity = EnhancedEntity::create([
+      'name' => 'rev 1',
+      'type' => 'default',
+    ]);
+    $entity->save();
+
+    $revision = clone $entity;
+    $revision->name->value = 'rev 2';
+    $revision->setNewRevision(TRUE);
+    $revision->isDefaultRevision(FALSE);
+    $revision->save();
+
+    $this->drupalGet('/entity_test_enhanced/1/revisions');
+    $this->assertSession()->statusCodeEquals(200);
+    $this->assertSession()->responseContains('Revisions');
+    $collection_link = $this->getSession()->getPage()->findLink('Entity test with enhancements');
+    $collection_link->click();
+    $this->assertSession()->addressEquals('/entity_test_enhanced');
+    $this->assertSession()->responseContains('Edit');
+    $edit_link = $this->getSession()->getPage()->findLink('Edit');
+    $edit_link->click();
+    $this->assertSession()->addressEquals('/entity_test_enhanced/1/edit');
+    $this->drupalGet('/entity_test_enhanced/1/revisions/2/view');
+    $this->assertSession()->statusCodeEquals(200);
+    $this->assertSession()->responseContains('rev 2');
+    $revisions_link = $this->getSession()->getPage()->findLink('Revisions');
+    $revisions_link->click();
+    $this->assertSession()->addressEquals('/entity_test_enhanced/1/revisions');
+    $this->assertSession()->statusCodeEquals(200);
+  }
+
+}
-- 
GitLab