From 97a4389997676ebf22db6bea89417caeb79fd426 Mon Sep 17 00:00:00 2001
From: xjm <xjm@65776.no-reply.drupal.org>
Date: Tue, 6 Feb 2018 21:47:47 -0500
Subject: [PATCH] Issue #2942600 by tim.plunkett:
 SectionComponent::toRenderArray() runs access checks even when not needed

---
 .../layout_builder/src/SectionComponent.php   | 16 +++++--
 .../src/Functional/LayoutSectionTest.php      |  1 -
 .../tests/src/Unit/SectionRenderTest.php      | 47 +++++++++++++++++++
 3 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/core/modules/layout_builder/src/SectionComponent.php b/core/modules/layout_builder/src/SectionComponent.php
index 7af03af132b2..6c08fb3aeb7d 100644
--- a/core/modules/layout_builder/src/SectionComponent.php
+++ b/core/modules/layout_builder/src/SectionComponent.php
@@ -3,6 +3,7 @@
 namespace Drupal\layout_builder;
 
 use Drupal\Component\Plugin\Exception\PluginException;
+use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Block\BlockPluginInterface;
 use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\Core\Plugin\ContextAwarePluginInterface;
@@ -103,11 +104,18 @@ public function toRenderArray(array $contexts = [], $in_preview = FALSE) {
     // @todo Figure out the best way to unify fields and blocks and components
     //   in https://www.drupal.org/node/1875974.
     if ($plugin instanceof BlockPluginInterface) {
-      $access = $plugin->access($this->currentUser(), TRUE);
-      $cacheability = CacheableMetadata::createFromObject($access);
+      $cacheability = CacheableMetadata::createFromObject($plugin);
 
-      if ($in_preview || $access->isAllowed()) {
-        $cacheability->addCacheableDependency($plugin);
+      // Only check access if the component is not being previewed.
+      if ($in_preview) {
+        $access = AccessResult::allowed()->setCacheMaxAge(0);
+      }
+      else {
+        $access = $plugin->access($this->currentUser(), TRUE);
+      }
+
+      $cacheability->addCacheableDependency($access);
+      if ($access->isAllowed()) {
         // @todo Move this to BlockBase in https://www.drupal.org/node/2931040.
         $output = [
           '#theme' => 'block',
diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutSectionTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutSectionTest.php
index 0437c1ca8538..d5e0c7523c89 100644
--- a/core/modules/layout_builder/tests/src/Functional/LayoutSectionTest.php
+++ b/core/modules/layout_builder/tests/src/Functional/LayoutSectionTest.php
@@ -76,7 +76,6 @@ public function providerTestLayoutSectionFormatter() {
       ],
       [
         'foobar',
-        'User context found',
       ],
       'user',
       'user:2',
diff --git a/core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php b/core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php
index 6dade754977d..ed7dfd202f9f 100644
--- a/core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php
+++ b/core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php
@@ -136,6 +136,9 @@ public function testToRenderArrayAccessDenied() {
     $access_result = AccessResult::forbidden();
     $block->access($this->account->reveal(), TRUE)->willReturn($access_result);
     $block->build()->shouldNotBeCalled();
+    $block->getCacheContexts()->willReturn([]);
+    $block->getCacheTags()->willReturn([]);
+    $block->getCacheMaxAge()->willReturn(Cache::PERMANENT);
 
     $section = [
       new SectionComponent('some_uuid', 'content', ['id' => 'block_plugin_id']),
@@ -155,6 +158,50 @@ public function testToRenderArrayAccessDenied() {
     $this->assertEquals($expected, $result);
   }
 
+  /**
+   * @covers ::toRenderArray
+   */
+  public function testToRenderArrayPreview() {
+    $block_content = ['#markup' => 'The block content.'];
+    $render_array = [
+      '#theme' => 'block',
+      '#weight' => 0,
+      '#configuration' => [],
+      '#plugin_id' => 'block_plugin_id',
+      '#base_plugin_id' => 'block_plugin_id',
+      '#derivative_plugin_id' => NULL,
+      'content' => $block_content,
+      '#cache' => [
+        'contexts' => [],
+        'tags' => [],
+        'max-age' => 0,
+      ],
+    ];
+    $block = $this->prophesize(BlockPluginInterface::class);
+    $this->blockManager->createInstance('block_plugin_id', ['id' => 'block_plugin_id'])->willReturn($block->reveal());
+
+    $block->access($this->account->reveal(), TRUE)->shouldNotBeCalled();
+    $block->build()->willReturn($block_content);
+    $block->getCacheContexts()->willReturn([]);
+    $block->getCacheTags()->willReturn([]);
+    $block->getCacheMaxAge()->willReturn(Cache::PERMANENT);
+    $block->getConfiguration()->willReturn([]);
+    $block->getPluginId()->willReturn('block_plugin_id');
+    $block->getBaseId()->willReturn('block_plugin_id');
+    $block->getDerivativeId()->willReturn(NULL);
+
+    $section = [
+      new SectionComponent('some_uuid', 'content', ['id' => 'block_plugin_id']),
+    ];
+    $expected = [
+      'content' => [
+        'some_uuid' => $render_array,
+      ],
+    ];
+    $result = (new Section('layout_onecol', [], $section))->toRenderArray([], TRUE);
+    $this->assertEquals($expected, $result);
+  }
+
   /**
    * @covers ::toRenderArray
    */
-- 
GitLab