From 2dad9ec01909f8c1df0a9e0e91353d4fb6f92785 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Tue, 9 May 2017 18:01:08 +0100
Subject: [PATCH] Issue #2821716 by flocondetoile, anish.a, amateescu, Thew:
 Fatal error when viewing node with content moderation enabled if a module
 which implements hook_node_grants() is enabled

---
 .../EntityRevisionConverter.php               |  2 +-
 .../ModerationStateConstraintValidator.php    |  4 +-
 .../tests/src/Functional/NodeAccessTest.php   | 58 +++++++++++++++++--
 3 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/core/modules/content_moderation/src/ParamConverter/EntityRevisionConverter.php b/core/modules/content_moderation/src/ParamConverter/EntityRevisionConverter.php
index 94f10e9f00ea..eac1913fcae5 100644
--- a/core/modules/content_moderation/src/ParamConverter/EntityRevisionConverter.php
+++ b/core/modules/content_moderation/src/ParamConverter/EntityRevisionConverter.php
@@ -98,7 +98,7 @@ public function convert($value, $definition, $name, array $defaults) {
         $latest_revision = $this->entityManager->getTranslationFromContext($latest_revision, NULL, ['operation' => 'entity_upcast']);
       }
 
-      if ($latest_revision->isRevisionTranslationAffected()) {
+      if ($latest_revision instanceof EntityInterface && $latest_revision->isRevisionTranslationAffected()) {
         $entity = $latest_revision;
       }
     }
diff --git a/core/modules/content_moderation/src/Plugin/Validation/Constraint/ModerationStateConstraintValidator.php b/core/modules/content_moderation/src/Plugin/Validation/Constraint/ModerationStateConstraintValidator.php
index d9308e8a1149..b664c65d2590 100644
--- a/core/modules/content_moderation/src/Plugin/Validation/Constraint/ModerationStateConstraintValidator.php
+++ b/core/modules/content_moderation/src/Plugin/Validation/Constraint/ModerationStateConstraintValidator.php
@@ -117,7 +117,9 @@ public function validate($value, Constraint $constraint) {
   protected function isFirstTimeModeration(EntityInterface $entity) {
     $original_entity = $this->moderationInformation->getLatestRevision($entity->getEntityTypeId(), $entity->id());
 
-    $original_id = $original_entity->moderation_state;
+    if ($original_entity) {
+      $original_id = $original_entity->moderation_state;
+    }
 
     return !($entity->moderation_state && $original_entity && $original_id);
   }
diff --git a/core/modules/content_moderation/tests/src/Functional/NodeAccessTest.php b/core/modules/content_moderation/tests/src/Functional/NodeAccessTest.php
index 2d5242142200..f3c27146d48e 100644
--- a/core/modules/content_moderation/tests/src/Functional/NodeAccessTest.php
+++ b/core/modules/content_moderation/tests/src/Functional/NodeAccessTest.php
@@ -9,6 +9,37 @@
  */
 class NodeAccessTest extends ModerationStateTestBase {
 
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'content_moderation',
+    'block',
+    'block_content',
+    'node',
+    'node_access_test_empty',
+  ];
+
+  /**
+   * Permissions to grant admin user.
+   *
+   * @var array
+   */
+  protected $permissions = [
+    'administer content moderation',
+    'access administration pages',
+    'administer content types',
+    'administer nodes',
+    'view latest version',
+    'view any unpublished content',
+    'access content overview',
+    'use editorial transition create_new_draft',
+    'use editorial transition publish',
+    'bypass node access',
+  ];
+
   /**
    * {@inheritdoc}
    */
@@ -17,6 +48,10 @@ protected function setUp() {
     $this->drupalLogin($this->adminUser);
     $this->createContentTypeFromUi('Moderated content', 'moderated_content', TRUE);
     $this->grantUserPermissionToCreateContentOfType($this->adminUser, 'moderated_content');
+
+    // Rebuild permissions because hook_node_grants() is implemented by the
+    // node_access_test_empty module.
+    node_access_rebuild();
   }
 
   /**
@@ -38,7 +73,24 @@ public function testPageAccess() {
     $edit_path = 'node/' . $node->id() . '/edit';
     $latest_path = 'node/' . $node->id() . '/latest';
 
+    // Now make a new user and verify that the new user's access is correct.
+    $user = $this->createUser([
+      'use editorial transition create_new_draft',
+      'view latest version',
+      'view any unpublished content',
+    ]);
+    $this->drupalLogin($user);
+
+    $this->drupalGet($edit_path);
+    $this->assertResponse(403);
+
+    $this->drupalGet($latest_path);
+    $this->assertResponse(403);
+    $this->drupalGet($view_path);
+    $this->assertResponse(200);
+
     // Publish the node.
+    $this->drupalLogin($this->adminUser);
     $this->drupalPostForm($edit_path, [], t('Save and Publish'));
 
     // Ensure access works correctly for anonymous users.
@@ -58,12 +110,6 @@ public function testPageAccess() {
       'title[0][value]' => 'moderated content revised',
     ], t('Save and Create New Draft'));
 
-    // Now make a new user and verify that the new user's access is correct.
-    $user = $this->createUser([
-      'use editorial transition create_new_draft',
-      'view latest version',
-      'view any unpublished content',
-    ]);
     $this->drupalLogin($user);
 
     $this->drupalGet($edit_path);
-- 
GitLab