From 99aa535dc9ffd6c0edb6b763d4df0ea799548e13 Mon Sep 17 00:00:00 2001
From: Nathaniel Catchpole <catch@35733.no-reply.drupal.org>
Date: Tue, 14 Jul 2015 15:08:37 +0100
Subject: [PATCH] Issue #2493033 by Berdir, Wim Leers, lauriii, Fabianx,
 effulgentsia, dawehner, catch, msonnabaum, Crell, webchick: Make
 'user.permissions' a required cache context

---
 core/core.services.yml                        |  2 +-
 .../block/src/Tests/BlockCacheTest.php        | 11 ++++++---
 core/modules/block/src/Tests/BlockTest.php    | 11 ++++++---
 .../block/src/Tests/BlockViewBuilderTest.php  |  8 +++----
 .../src/Tests/BlockContentCacheTagsTest.php   |  2 +-
 .../src/Tests/CommentCacheTagsTest.php        |  6 +----
 .../src/Tests/Views/ViewsIntegrationTest.php  |  2 +-
 ...enuLinkContentCacheabilityBubblingTest.php |  2 +-
 .../menu_ui/src/Tests/MenuCacheTagsTest.php   |  2 +-
 .../node/src/Tests/NodeListBuilderTest.php    |  2 +-
 .../page_cache/src/Tests/PageCacheTest.php    |  1 +
 .../AssertPageCacheContextsAndTagsTrait.php   | 23 +++++++++++++++++--
 .../system/src/Tests/Common/UrlTest.php       |  2 +-
 .../Tests/Entity/EntityCacheTagsTestBase.php  | 17 ++++++++++----
 .../Tests/Entity/EntityListBuilderTest.php    |  2 +-
 .../Tests/Entity/EntityViewBuilderTest.php    |  6 ++---
 .../Entity/EntityWithUriCacheTagsTestBase.php |  2 +-
 .../system/src/Tests/Routing/RouterTest.php   |  8 +++----
 .../tour/src/Tests/TourCacheTagsTest.php      |  2 ++
 .../src/Plugin/views/argument/RolesRid.php    |  2 +-
 .../views/src/Tests/ViewUnitTestBase.php      |  2 +-
 sites/default/default.services.yml            |  4 ++--
 22 files changed, 78 insertions(+), 41 deletions(-)

diff --git a/core/core.services.yml b/core/core.services.yml
index ba67e2e2fe3a..bf21661d8bce 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -2,7 +2,7 @@ parameters:
   session.storage.options: {}
   twig.config: {}
   renderer.config:
-    required_cache_contexts: ['languages:language_interface', 'theme']
+    required_cache_contexts: ['languages:language_interface', 'theme', 'user.permissions']
   factory.keyvalue:
     default: keyvalue.database
   factory.keyvalue.expirable:
diff --git a/core/modules/block/src/Tests/BlockCacheTest.php b/core/modules/block/src/Tests/BlockCacheTest.php
index 78ccd04b02b9..b118e8410f7e 100644
--- a/core/modules/block/src/Tests/BlockCacheTest.php
+++ b/core/modules/block/src/Tests/BlockCacheTest.php
@@ -119,9 +119,11 @@ function testCachePerRole() {
   }
 
   /**
-   * Test a cacheable block without any cache context.
+   * Test a cacheable block without any additional cache context.
    */
-  function testCacheGlobal() {
+  function testCachePermissions() {
+    // user.permissions is a required context, so a user with different
+    // permissions will see a different version of the block.
     \Drupal::state()->set('block_test.cache_contexts', []);
 
     $current_content = $this->randomMachineName();
@@ -134,9 +136,12 @@ function testCacheGlobal() {
     $current_content = $this->randomMachineName();
     \Drupal::state()->set('block_test.content', $current_content);
 
-    $this->drupalLogout();
     $this->drupalGet('user');
     $this->assertText($old_content, 'Block content served from cache.');
+
+    $this->drupalLogout();
+    $this->drupalGet('user');
+    $this->assertText($current_content, 'Block content not served from cache.');
   }
 
   /**
diff --git a/core/modules/block/src/Tests/BlockTest.php b/core/modules/block/src/Tests/BlockTest.php
index 8c65bc3033df..5ab46e13c30c 100644
--- a/core/modules/block/src/Tests/BlockTest.php
+++ b/core/modules/block/src/Tests/BlockTest.php
@@ -334,11 +334,13 @@ public function testBlockCacheTags() {
       'config:block_list',
       'block_view',
       'config:block.block.powered',
+      'config:user.role.anonymous',
       'rendered',
     );
     sort($expected_cache_tags);
+    $keys = \Drupal::service('cache_contexts_manager')->convertTokensToKeys(['languages:language_interface', 'theme', 'user.permissions'])->getKeys();
     $this->assertIdentical($cache_entry->tags, $expected_cache_tags);
-    $cache_entry = \Drupal::cache('render')->get('entity_view:block:powered:en:classy');
+    $cache_entry = \Drupal::cache('render')->get('entity_view:block:powered:' . implode(':', $keys));
     $expected_cache_tags = array(
       'block_view',
       'config:block.block.powered',
@@ -373,6 +375,7 @@ public function testBlockCacheTags() {
       'block_view',
       'config:block.block.powered',
       'config:block.block.powered-2',
+      'config:user.role.anonymous',
       'rendered',
     );
     sort($expected_cache_tags);
@@ -383,7 +386,8 @@ public function testBlockCacheTags() {
       'rendered',
     );
     sort($expected_cache_tags);
-    $cache_entry = \Drupal::cache('render')->get('entity_view:block:powered:en:classy');
+    $keys = \Drupal::service('cache_contexts_manager')->convertTokensToKeys(['languages:language_interface', 'theme', 'user.permissions'])->getKeys();
+    $cache_entry = \Drupal::cache('render')->get('entity_view:block:powered:' . implode(':', $keys));
     $this->assertIdentical($cache_entry->tags, $expected_cache_tags);
     $expected_cache_tags = array(
       'block_view',
@@ -391,7 +395,8 @@ public function testBlockCacheTags() {
       'rendered',
     );
     sort($expected_cache_tags);
-    $cache_entry = \Drupal::cache('render')->get('entity_view:block:powered-2:en:classy');
+    $keys = \Drupal::service('cache_contexts_manager')->convertTokensToKeys(['languages:language_interface', 'theme', 'user.permissions'])->getKeys();
+    $cache_entry = \Drupal::cache('render')->get('entity_view:block:powered-2:' . implode(':', $keys));
     $this->assertIdentical($cache_entry->tags, $expected_cache_tags);
 
     // Now we should have a cache hit again.
diff --git a/core/modules/block/src/Tests/BlockViewBuilderTest.php b/core/modules/block/src/Tests/BlockViewBuilderTest.php
index b3e5ee186866..2dd2f402e19c 100644
--- a/core/modules/block/src/Tests/BlockViewBuilderTest.php
+++ b/core/modules/block/src/Tests/BlockViewBuilderTest.php
@@ -9,7 +9,7 @@
 
 use Drupal\Component\Utility\Html;
 use Drupal\Core\Cache\Cache;
-use Drupal\Core\Cache\Context\UrlCacheContext;
+use Drupal\Core\Language\LanguageInterface;
 use Drupal\simpletest\KernelTestBase;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\RequestStack;
@@ -27,7 +27,7 @@ class BlockViewBuilderTest extends KernelTestBase {
    *
    * @var array
    */
-  public static $modules = array('block', 'block_test', 'system');
+  public static $modules = array('block', 'block_test', 'system', 'user');
 
   /**
    * The block being tested.
@@ -160,7 +160,7 @@ protected function verifyRenderCacheHandling() {
 
     // Test that a cache entry is created.
     $build = $this->getBlockRenderArray();
-    $cid = 'entity_view:block:test_block:en:core';
+    $cid = 'entity_view:block:test_block:' . implode(':', \Drupal::service('cache_contexts_manager')->convertTokensToKeys(['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'])->getKeys());
     $this->renderer->renderRoot($build);
     $this->assertTrue($this->container->get('cache.render')->get($cid), 'The block render element has been cached.');
 
@@ -214,7 +214,7 @@ public function testBlockViewBuilderAlter() {
     // Advanced: cached block, but an alter hook adds an additional cache key.
     $alter_add_key = $this->randomMachineName();
     \Drupal::state()->set('block_test_view_alter_cache_key', $alter_add_key);
-    $cid = 'entity_view:block:test_block:' . $alter_add_key . ':en:core';
+    $cid = 'entity_view:block:test_block:' . $alter_add_key . ':' . implode(':', \Drupal::service('cache_contexts_manager')->convertTokensToKeys(['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'])->getKeys());
     $expected_keys = array_merge($default_keys, array($alter_add_key));
     $build = $this->getBlockRenderArray();
     $this->assertIdentical($expected_keys, $build['#cache']['keys'], 'An altered cacheable block has the expected cache keys.');
diff --git a/core/modules/block_content/src/Tests/BlockContentCacheTagsTest.php b/core/modules/block_content/src/Tests/BlockContentCacheTagsTest.php
index fe2c789ba491..a02a274e4df4 100644
--- a/core/modules/block_content/src/Tests/BlockContentCacheTagsTest.php
+++ b/core/modules/block_content/src/Tests/BlockContentCacheTagsTest.php
@@ -90,7 +90,7 @@ public function testBlock() {
     // Expected keys, contexts, and tags for the block.
     // @see \Drupal\block\BlockViewBuilder::viewMultiple()
     $expected_block_cache_keys = ['entity_view', 'block', $block->id()];
-    $expected_block_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme'];
+    $expected_block_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'];
     $expected_block_cache_tags = Cache::mergeTags(['block_view', 'rendered'], $block->getCacheTags(), $block->getPlugin()->getCacheTags());
 
     // Expected contexts and tags for the BlockContent entity.
diff --git a/core/modules/comment/src/Tests/CommentCacheTagsTest.php b/core/modules/comment/src/Tests/CommentCacheTagsTest.php
index 52264340fd71..2393d96abe47 100644
--- a/core/modules/comment/src/Tests/CommentCacheTagsTest.php
+++ b/core/modules/comment/src/Tests/CommentCacheTagsTest.php
@@ -86,11 +86,7 @@ protected function createEntity() {
    * {@inheritdoc}
    */
   protected function getAdditionalCacheContextsForEntity(EntityInterface $entity) {
-    return [
-      // Field access for the user picture rendered as part of the node that
-      // this comment is created on.
-      'user.permissions',
-    ];
+    return [];
   }
 
   /**
diff --git a/core/modules/dblog/src/Tests/Views/ViewsIntegrationTest.php b/core/modules/dblog/src/Tests/Views/ViewsIntegrationTest.php
index c7f37975d4e2..063ce2550913 100644
--- a/core/modules/dblog/src/Tests/Views/ViewsIntegrationTest.php
+++ b/core/modules/dblog/src/Tests/Views/ViewsIntegrationTest.php
@@ -34,7 +34,7 @@ class ViewsIntegrationTest extends ViewUnitTestBase {
    *
    * @var array
    */
-  public static $modules = array('dblog', 'dblog_test_views');
+  public static $modules = array('dblog', 'dblog_test_views', 'user');
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/menu_link_content/src/Tests/MenuLinkContentCacheabilityBubblingTest.php b/core/modules/menu_link_content/src/Tests/MenuLinkContentCacheabilityBubblingTest.php
index 7980c77202d9..80ab0503bbee 100644
--- a/core/modules/menu_link_content/src/Tests/MenuLinkContentCacheabilityBubblingTest.php
+++ b/core/modules/menu_link_content/src/Tests/MenuLinkContentCacheabilityBubblingTest.php
@@ -69,7 +69,7 @@ public function testOutboundPathAndRouteProcessing() {
     $default_menu_cacheability = (new CacheableMetadata())
       ->setCacheMaxAge(Cache::PERMANENT)
       ->setCacheTags(['config:system.menu.tools'])
-      ->setCacheContexts(['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme']);
+      ->setCacheContexts(['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions']);
 
     User::create(['uid' => 1, 'name' => $this->randomString()])->save();
     User::create(['uid' => 2, 'name' => $this->randomString()])->save();
diff --git a/core/modules/menu_ui/src/Tests/MenuCacheTagsTest.php b/core/modules/menu_ui/src/Tests/MenuCacheTagsTest.php
index adff9a033b5b..520627ed797e 100644
--- a/core/modules/menu_ui/src/Tests/MenuCacheTagsTest.php
+++ b/core/modules/menu_ui/src/Tests/MenuCacheTagsTest.php
@@ -110,7 +110,7 @@ public function testMenuBlock() {
     $this->verifyPageCache($url, 'MISS');
 
     // Verify a cache hit.
-    $this->verifyPageCache($url, 'HIT', ['config:block_list', 'rendered']);
+    $this->verifyPageCache($url, 'HIT', ['config:block_list', 'config:user.role.anonymous', 'rendered']);
   }
 
 }
diff --git a/core/modules/node/src/Tests/NodeListBuilderTest.php b/core/modules/node/src/Tests/NodeListBuilderTest.php
index 798a0566dcf1..2d23604b6600 100644
--- a/core/modules/node/src/Tests/NodeListBuilderTest.php
+++ b/core/modules/node/src/Tests/NodeListBuilderTest.php
@@ -39,7 +39,7 @@ public function testCacheContexts() {
     $build = $list_builder->render();
     $this->container->get('renderer')->renderRoot($build);
 
-    $this->assertEqual(['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'url.query_args.pagers:0', 'user.node_grants:view'], $build['#cache']['contexts']);
+    $this->assertEqual(['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'url.query_args.pagers:0', 'user.node_grants:view', 'user.permissions'], $build['#cache']['contexts']);
   }
 
 }
diff --git a/core/modules/page_cache/src/Tests/PageCacheTest.php b/core/modules/page_cache/src/Tests/PageCacheTest.php
index 4880b2e38e36..e97a1b4f5dad 100644
--- a/core/modules/page_cache/src/Tests/PageCacheTest.php
+++ b/core/modules/page_cache/src/Tests/PageCacheTest.php
@@ -67,6 +67,7 @@ function testPageCacheTags() {
     $cache_entry = \Drupal::cache('render')->get($cid);
     sort($cache_entry->tags);
     $expected_tags = array(
+      'config:user.role.anonymous',
       'pre_render',
       'rendered',
       'system_test_cache_tags_page',
diff --git a/core/modules/system/src/Tests/Cache/AssertPageCacheContextsAndTagsTrait.php b/core/modules/system/src/Tests/Cache/AssertPageCacheContextsAndTagsTrait.php
index f8ce45432ef6..ff914f3bfab1 100644
--- a/core/modules/system/src/Tests/Cache/AssertPageCacheContextsAndTagsTrait.php
+++ b/core/modules/system/src/Tests/Cache/AssertPageCacheContextsAndTagsTrait.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\system\Tests\Cache;
 
+use Drupal\Core\Cache\Cache;
 use Drupal\Core\Url;
 
 /**
@@ -99,8 +100,14 @@ protected function debugCacheTags(array $actual_tags, array $expected_tags) {
    *
    * @param string[] $expected_tags
    *   The expected tags.
+   * @param bool $include_default_tags
+   *   (optional) Whether the default cache tags should be included.
    */
-  protected function assertCacheTags(array $expected_tags) {
+  protected function assertCacheTags(array $expected_tags, $include_default_tags = TRUE) {
+    // The anonymous role cache tag is only added if the user is anonymous.
+    if ($include_default_tags && \Drupal::currentUser()->isAnonymous()) {
+      $expected_tags = Cache::mergeTags($expected_tags, ['config:user.role.anonymous']);
+    }
     $actual_tags = $this->getCacheHeaderValues('X-Drupal-Cache-Tags');
     sort($expected_tags);
     sort($actual_tags);
@@ -115,11 +122,23 @@ protected function assertCacheTags(array $expected_tags) {
    *   The expected cache contexts.
    * @param string $message
    *   (optional) A verbose message to output.
+   * @param bool $include_default_contexts
+   *   (optional) Whether the default contexts should automatically be included.
    *
    * @return
    *   TRUE if the assertion succeeded, FALSE otherwise.
    */
-  protected function assertCacheContexts(array $expected_contexts, $message = NULL) {
+  protected function assertCacheContexts(array $expected_contexts, $message = NULL, $include_default_contexts = TRUE) {
+    if ($include_default_contexts) {
+      $default_contexts = ['languages:language_interface', 'theme'];
+      // Add the user.permission context to the list of default contexts except
+      // when user is already there.
+      if (!in_array('user', $expected_contexts)) {
+        $default_contexts[] = 'user.permissions';
+      }
+      $expected_contexts = Cache::mergeContexts($expected_contexts, $default_contexts);
+    }
+
     $actual_contexts = $this->getCacheHeaderValues('X-Drupal-Cache-Contexts');
     sort($expected_contexts);
     sort($actual_contexts);
diff --git a/core/modules/system/src/Tests/Common/UrlTest.php b/core/modules/system/src/Tests/Common/UrlTest.php
index 1a26232e5c84..f823bfa34622 100644
--- a/core/modules/system/src/Tests/Common/UrlTest.php
+++ b/core/modules/system/src/Tests/Common/UrlTest.php
@@ -58,7 +58,7 @@ function testLinkCacheability() {
 
     foreach ($cases as $case) {
       list($title, $uri, $options, $expected_cacheability) = $case;
-      $expected_cacheability['contexts'] = Cache::mergeContexts($expected_cacheability['contexts'], ['languages:language_interface', 'theme']);
+      $expected_cacheability['contexts'] = Cache::mergeContexts($expected_cacheability['contexts'], ['languages:language_interface', 'theme', 'user.permissions']);
       $link = [
         '#type' => 'link',
         '#title' => $title,
diff --git a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php
index 06e01e504500..dc0f965eef86 100644
--- a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php
+++ b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php
@@ -132,6 +132,8 @@ abstract protected function createEntity();
   /**
    * Returns the access cache contexts for the tested entity.
    *
+   * Only list cache contexts that aren't part of the required cache contexts.
+   *
    * @param \Drupal\Core\Entity\EntityInterface $entity
    *   The entity to be tested, as created by createEntity().
    *
@@ -141,12 +143,14 @@ abstract protected function createEntity();
    * @see \Drupal\Core\Entity\EntityAccessControlHandlerInterface
    */
   protected function getAccessCacheContextsForEntity(EntityInterface $entity) {
-    return ['user.permissions'];
+    return [];
   }
 
   /**
    * Returns the additional (non-standard) cache contexts for the tested entity.
    *
+   * Only list cache contexts that aren't part of the required cache contexts.
+   *
    * @param \Drupal\Core\Entity\EntityInterface $entity
    *   The entity to be tested, as created by createEntity().
    *
@@ -331,12 +335,16 @@ public function testReferencedEntity() {
     $nonempty_entity_listing_url = Url::fromRoute('entity.entity_test.collection_labels_alphabetically', ['entity_type_id' => $entity_type]);
 
     // The default cache contexts for rendered entities.
-    $default_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme'];
+    $default_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'];
     $entity_cache_contexts = $default_cache_contexts;
 
     // Cache tags present on every rendered page.
     $page_cache_tags = Cache::mergeTags(
       ['rendered'],
+      // 'user.permissions' is a required cache context, and responses that vary
+      // by this cache context when requested by anonymous users automatically
+      // also get this cache tag, to ensure correct invalidation.
+      ['config:user.role.anonymous'],
       // If the block module is used, the Block page display variant is used,
       // which adds the block config entity type's list cache tags.
       \Drupal::moduleHandler()->moduleExists('block') ? ['config:block_list']: []
@@ -391,9 +399,10 @@ public function testReferencedEntity() {
     $cache_keys = ['entity_view', 'entity_test', $this->referencingEntity->id(), 'full'];
     $cid = $this->createCacheId($cache_keys, $entity_cache_contexts);
     $access_cache_contexts = $this->getAccessCacheContextsForEntity($this->entity);
+    $additional_cache_contexts = $this->getAdditionalCacheContextsForEntity($this->referencingEntity);
     $redirected_cid = NULL;
-    if (count($access_cache_contexts)) {
-      $cache_contexts = Cache::mergeContexts($entity_cache_contexts, $this->getAdditionalCacheContextsForEntity($this->referencingEntity), $access_cache_contexts);
+    if (count($access_cache_contexts) || count($additional_cache_contexts)) {
+      $cache_contexts = Cache::mergeContexts($entity_cache_contexts, $additional_cache_contexts, $access_cache_contexts);
       $redirected_cid = $this->createCacheId($cache_keys, $cache_contexts);
       $context_metadata = \Drupal::service('cache_contexts_manager')->convertTokensToKeys($cache_contexts);
       $referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, $context_metadata->getCacheTags());
diff --git a/core/modules/system/src/Tests/Entity/EntityListBuilderTest.php b/core/modules/system/src/Tests/Entity/EntityListBuilderTest.php
index 485e72c209a0..e32b689ba94b 100644
--- a/core/modules/system/src/Tests/Entity/EntityListBuilderTest.php
+++ b/core/modules/system/src/Tests/Entity/EntityListBuilderTest.php
@@ -67,7 +67,7 @@ public function testCacheContexts() {
     $build = $list_builder->render();
     $this->container->get('renderer')->renderRoot($build);
 
-    $this->assertEqual(['entity_test_view_grants', 'languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'url.query_args.pagers:0'], $build['#cache']['contexts']);
+    $this->assertEqual(['entity_test_view_grants', 'languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'url.query_args.pagers:0', 'user.permissions'], $build['#cache']['contexts']);
   }
 
 }
diff --git a/core/modules/system/src/Tests/Entity/EntityViewBuilderTest.php b/core/modules/system/src/Tests/Entity/EntityViewBuilderTest.php
index b160081382df..169af5f2fbc2 100644
--- a/core/modules/system/src/Tests/Entity/EntityViewBuilderTest.php
+++ b/core/modules/system/src/Tests/Entity/EntityViewBuilderTest.php
@@ -65,7 +65,7 @@ public function testEntityViewBuilderCache() {
     // Get a fully built entity view render array.
     $entity_test->save();
     $build = $this->container->get('entity.manager')->getViewBuilder('entity_test')->view($entity_test, 'full');
-    $cid_parts = array_merge($build['#cache']['keys'], $cache_contexts_manager->convertTokensToKeys(['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme'])->getKeys());
+    $cid_parts = array_merge($build['#cache']['keys'], $cache_contexts_manager->convertTokensToKeys(['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'])->getKeys());
     $cid = implode(':', $cid_parts);
     $bin = $build['#cache']['bin'];
 
@@ -117,7 +117,7 @@ public function testEntityViewBuilderCacheWithReferences() {
 
     // Get a fully built entity view render array for the referenced entity.
     $build = $this->container->get('entity.manager')->getViewBuilder('entity_test')->view($entity_test_reference, 'full');
-    $cid_parts = array_merge($build['#cache']['keys'], $cache_contexts_manager->convertTokensToKeys(['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme'])->getKeys());
+    $cid_parts = array_merge($build['#cache']['keys'], $cache_contexts_manager->convertTokensToKeys(['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'])->getKeys());
     $cid_reference = implode(':', $cid_parts);
     $bin_reference = $build['#cache']['bin'];
 
@@ -136,7 +136,7 @@ public function testEntityViewBuilderCacheWithReferences() {
 
     // Get a fully built entity view render array.
     $build = $this->container->get('entity.manager')->getViewBuilder('entity_test')->view($entity_test, 'full');
-    $cid_parts = array_merge($build['#cache']['keys'], $cache_contexts_manager->convertTokensToKeys(['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme'])->getKeys());
+    $cid_parts = array_merge($build['#cache']['keys'], $cache_contexts_manager->convertTokensToKeys(['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'])->getKeys());
     $cid = implode(':', $cid_parts);
     $bin = $build['#cache']['bin'];
 
diff --git a/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php b/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php
index 6d3852e39f14..7a3f24a7fef8 100644
--- a/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php
+++ b/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php
@@ -32,7 +32,7 @@ public function testEntityUri() {
     $view_mode = $this->selectViewMode($entity_type);
 
     // The default cache contexts for rendered entities.
-    $entity_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme'];
+    $entity_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'];
 
     // Generate the standardized entity cache tags.
     $cache_tag = $this->entity->getCacheTags();
diff --git a/core/modules/system/src/Tests/Routing/RouterTest.php b/core/modules/system/src/Tests/Routing/RouterTest.php
index 8fbc3f0a5fcd..f79cc5f891a2 100644
--- a/core/modules/system/src/Tests/Routing/RouterTest.php
+++ b/core/modules/system/src/Tests/Routing/RouterTest.php
@@ -30,7 +30,7 @@ class RouterTest extends WebTestBase {
    * Confirms that our FinishResponseSubscriber logic works properly.
    */
   public function testFinishResponseSubscriber() {
-    $renderer_required_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme'];
+    $renderer_required_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'];
 
     // Confirm that the router can get to a controller.
     $this->drupalGet('router_test/test1');
@@ -47,7 +47,7 @@ public function testFinishResponseSubscriber() {
     // Check expected headers from FinishResponseSubscriber.
     $headers = $this->drupalGetHeaders();
     $this->assertEqual($headers['x-drupal-cache-contexts'], implode(' ', $renderer_required_cache_contexts));
-    $this->assertEqual($headers['x-drupal-cache-tags'], 'rendered');
+    $this->assertEqual($headers['x-drupal-cache-tags'], 'config:user.role.anonymous rendered');
     // Confirm that the page wrapping is being added, so we're not getting a
     // raw body returned.
     $this->assertRaw('</html>', 'Page markup was found.');
@@ -62,12 +62,12 @@ public function testFinishResponseSubscriber() {
     $this->drupalGet('router_test/test18');
     $headers = $this->drupalGetHeaders();
     $this->assertEqual($headers['x-drupal-cache-contexts'], implode(' ', Cache::mergeContexts($renderer_required_cache_contexts, ['url'])));
-    $this->assertEqual($headers['x-drupal-cache-tags'], 'foo rendered');
+    $this->assertEqual($headers['x-drupal-cache-tags'], 'config:user.role.anonymous foo rendered');
     // 2. controller result: render array, per-role cacheable route access.
     $this->drupalGet('router_test/test19');
     $headers = $this->drupalGetHeaders();
     $this->assertEqual($headers['x-drupal-cache-contexts'], implode(' ', Cache::mergeContexts($renderer_required_cache_contexts, ['url', 'user.roles'])));
-    $this->assertEqual($headers['x-drupal-cache-tags'], 'foo rendered');
+    $this->assertEqual($headers['x-drupal-cache-tags'], 'config:user.role.anonymous foo rendered');
     // 3. controller result: Response object, globally cacheable route access.
     $this->drupalGet('router_test/test1');
     $headers = $this->drupalGetHeaders();
diff --git a/core/modules/tour/src/Tests/TourCacheTagsTest.php b/core/modules/tour/src/Tests/TourCacheTagsTest.php
index 1c4c3234517b..8d2814ff9e01 100644
--- a/core/modules/tour/src/Tests/TourCacheTagsTest.php
+++ b/core/modules/tour/src/Tests/TourCacheTagsTest.php
@@ -52,6 +52,7 @@ public function testRenderedTour() {
     // Verify a cache hit, but also the presence of the correct cache tags.
     $expected_tags = [
       'config:tour.tour.tour-test',
+      'config:user.role.anonymous',
       'rendered',
     ];
     $this->verifyPageCache($url, 'HIT', $expected_tags);
@@ -71,6 +72,7 @@ public function testRenderedTour() {
 
     // Verify a cache hit.
     $expected_tags = [
+      'config:user.role.anonymous',
       'rendered',
     ];
     $this->verifyPageCache($url, 'HIT', $expected_tags);
diff --git a/core/modules/user/src/Plugin/views/argument/RolesRid.php b/core/modules/user/src/Plugin/views/argument/RolesRid.php
index 75fff0cdfd52..7fd209dbeb7b 100644
--- a/core/modules/user/src/Plugin/views/argument/RolesRid.php
+++ b/core/modules/user/src/Plugin/views/argument/RolesRid.php
@@ -50,7 +50,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return parent::create($container, $configuration, $plugin_id, $plugin_definition, $container->get('entity.manager'));
+    return new static($configuration, $plugin_id, $plugin_definition, $container->get('entity.manager'));
   }
 
   /**
diff --git a/core/modules/views/src/Tests/ViewUnitTestBase.php b/core/modules/views/src/Tests/ViewUnitTestBase.php
index 3aba1f556f7a..b5dfc4220630 100644
--- a/core/modules/views/src/Tests/ViewUnitTestBase.php
+++ b/core/modules/views/src/Tests/ViewUnitTestBase.php
@@ -31,7 +31,7 @@ abstract class ViewUnitTestBase extends KernelTestBase {
    *
    * @var array
    */
-  public static $modules = array('system', 'views', 'views_test_config', 'views_test_data');
+  public static $modules = array('system', 'views', 'views_test_config', 'views_test_data', 'user');
 
   /**
    * {@inheritdoc}
diff --git a/sites/default/default.services.yml b/sites/default/default.services.yml
index ecb1c43b2d5d..e20002d9228f 100644
--- a/sites/default/default.services.yml
+++ b/sites/default/default.services.yml
@@ -82,8 +82,8 @@ parameters:
     # The Renderer will automatically associate these cache contexts with every
     # render array, hence varying every render array by these cache contexts.
     #
-    # @default ['languages:language_interface', 'theme']
-    required_cache_contexts: ['languages:language_interface', 'theme']
+    # @default ['languages:language_interface', 'theme', 'user.permissions']
+    required_cache_contexts: ['languages:language_interface', 'theme', 'user.permissions']
   factory.keyvalue:
     {}
     # Default key/value storage service to use.
-- 
GitLab