Skip to content
Snippets Groups Projects
Commit 90baffa4 authored by catch's avatar catch
Browse files

Issue #3452426 by mxr576, kristiaanvandeneynde: Insufficient cacheability...

Issue #3452426 by mxr576, kristiaanvandeneynde: Insufficient cacheability information bubbled up by UserAccessControlHandler

(cherry picked from commit 9fc1bc9a)
parent a47b4177
No related branches found
No related tags found
16 merge requests!12212Issue #3445525 by alexpott, japerry, catch, mglaman, longwave: Add BC layer...,!10602Issue #3438769 by vinmayiswamy, antonnavi, michelle, amateescu: Sub workspace does not clear,!10301Issue #3469309 by mstrelan, smustgrave, moshe weitzman: Use one-time login...,!10187Issue #3487488 by dakwamine: ExtensionMimeTypeGuesser::guessMimeType must support file names with "0" (zero) like foo.0.zip,!9929Issue #3445469 by pooja_sharma, smustgrave: Add additional test coverage for...,!9787Resolve issue 3479427 - bootstrap barrio issue under Windows,!9742Issue #3463908 by catch, quietone: Split OptionsFieldUiTest into two,!9526Issue #3458177 by mondrake, catch, quietone, godotislate, longwave, larowlan,...,!8949Backport .gitlabci.yml changes.,!8738Issue #3424162 by camilledavis, dineshkumarbollu, smustgrave: Claro...,!8704Make greek characters available in ckeditor5,!8533Issue #3446962 by kim.pepper: Remove incorrectly added...,!8517Issue #3443748 by NexusNovaz, smustgrave: Testcase creates false positive,!6502Draft: Resolve #2938524 "Plach testing issue",!38582585169-10.1.x,!3226Issue #2987537: Custom menu link entity type should not declare "bundle" entity key
Pipeline #196929 passed with warnings
Pipeline: drupal

#196976

    Pipeline: drupal

    #196969

      Pipeline: drupal

      #196964

        +6
        ...@@ -175,7 +175,7 @@ protected function getExpectedDocument() { ...@@ -175,7 +175,7 @@ protected function getExpectedDocument() {
        */ */
        protected function getExpectedCacheContexts(?array $sparse_fieldset = NULL) { protected function getExpectedCacheContexts(?array $sparse_fieldset = NULL) {
        $cache_contexts = parent::getExpectedCacheContexts($sparse_fieldset); $cache_contexts = parent::getExpectedCacheContexts($sparse_fieldset);
        if ($sparse_fieldset === NULL || in_array('mail', $sparse_fieldset)) { if ($sparse_fieldset === NULL || !empty(array_intersect(['mail', 'display_name'], $sparse_fieldset))) {
        $cache_contexts = Cache::mergeContexts($cache_contexts, ['user']); $cache_contexts = Cache::mergeContexts($cache_contexts, ['user']);
        } }
        return $cache_contexts; return $cache_contexts;
        ......
        ...@@ -436,6 +436,9 @@ public function testGet() { ...@@ -436,6 +436,9 @@ public function testGet() {
        // @see \Drupal\Core\EventSubscriber\AnonymousUserResponseSubscriber::onRespond() // @see \Drupal\Core\EventSubscriber\AnonymousUserResponseSubscriber::onRespond()
        ->addCacheTags(['config:user.role.anonymous']); ->addCacheTags(['config:user.role.anonymous']);
        $expected_cacheability->addCacheableDependency($this->getExpectedUnauthorizedEntityAccessCacheability(FALSE)); $expected_cacheability->addCacheableDependency($this->getExpectedUnauthorizedEntityAccessCacheability(FALSE));
        // Mitigate https://www.drupal.org/project/drupal/issues/3451483 until
        // it gets resolved.
        $response = $response->withoutHeader('X-Drupal-Dynamic-Cache');
        $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('GET'), $response, $expected_cacheability->getCacheTags(), $expected_cacheability->getCacheContexts(), 'MISS', FALSE); $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('GET'), $response, $expected_cacheability->getCacheTags(), $expected_cacheability->getCacheContexts(), 'MISS', FALSE);
        } }
        else { else {
        ...@@ -448,6 +451,9 @@ public function testGet() { ...@@ -448,6 +451,9 @@ public function testGet() {
        // response. // response.
        if (static::$auth) { if (static::$auth) {
        $response = $this->request('GET', $url, $request_options); $response = $this->request('GET', $url, $request_options);
        // Mitigate https://www.drupal.org/project/drupal/issues/3451483 until
        // it gets resolved.
        $response = $response->withoutHeader('X-Drupal-Dynamic-Cache');
        $this->assertResponseWhenMissingAuthentication('GET', $response); $this->assertResponseWhenMissingAuthentication('GET', $response);
        } }
        ...@@ -485,6 +491,9 @@ public function testGet() { ...@@ -485,6 +491,9 @@ public function testGet() {
        // DX: 403 because unauthorized. // DX: 403 because unauthorized.
        $url->setOption('query', ['_format' => static::$format]); $url->setOption('query', ['_format' => static::$format]);
        $response = $this->request('GET', $url, $request_options); $response = $this->request('GET', $url, $request_options);
        // Mitigate https://www.drupal.org/project/drupal/issues/3451483 until
        // it gets resolved.
        $response = $response->withoutHeader('X-Drupal-Dynamic-Cache');
        $this->assertResourceErrorResponse(403, FALSE, $response, $expected_403_cacheability->getCacheTags(), $expected_403_cacheability->getCacheContexts(), static::$auth ? FALSE : 'MISS', FALSE); $this->assertResourceErrorResponse(403, FALSE, $response, $expected_403_cacheability->getCacheTags(), $expected_403_cacheability->getCacheContexts(), static::$auth ? FALSE : 'MISS', FALSE);
        // Then, what we'll use for the remainder of the test: multiple formats. // Then, what we'll use for the remainder of the test: multiple formats.
        ...@@ -505,6 +514,9 @@ public function testGet() { ...@@ -505,6 +514,9 @@ public function testGet() {
        // DX: 403 because unauthorized. // DX: 403 because unauthorized.
        $url->setOption('query', ['_format' => static::$format]); $url->setOption('query', ['_format' => static::$format]);
        $response = $this->request('GET', $url, $request_options); $response = $this->request('GET', $url, $request_options);
        // Mitigate https://www.drupal.org/project/drupal/issues/3451483 until
        // it gets resolved.
        $response = $response->withoutHeader('X-Drupal-Dynamic-Cache');
        $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('GET'), $response, $expected_403_cacheability->getCacheTags(), $expected_403_cacheability->getCacheContexts(), static::$auth ? FALSE : 'MISS', FALSE); $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('GET'), $response, $expected_403_cacheability->getCacheTags(), $expected_403_cacheability->getCacheContexts(), static::$auth ? FALSE : 'MISS', FALSE);
        $this->assertArrayNotHasKey('Link', $response->getHeaders()); $this->assertArrayNotHasKey('Link', $response->getHeaders());
        ......
        ...@@ -406,7 +406,8 @@ protected function assertResourceResponse($expected_status_code, $expected_body, ...@@ -406,7 +406,8 @@ protected function assertResourceResponse($expected_status_code, $expected_body,
        // Expected cache contexts: X-Drupal-Cache-Contexts header. // Expected cache contexts: X-Drupal-Cache-Contexts header.
        $this->assertSame($expected_cache_contexts !== FALSE, $response->hasHeader('X-Drupal-Cache-Contexts')); $this->assertSame($expected_cache_contexts !== FALSE, $response->hasHeader('X-Drupal-Cache-Contexts'));
        if (is_array($expected_cache_contexts)) { if (is_array($expected_cache_contexts)) {
        $this->assertEqualsCanonicalizing($expected_cache_contexts, explode(' ', $response->getHeader('X-Drupal-Cache-Contexts')[0])); $optimized_expected_cache_contexts = \Drupal::service('cache_contexts_manager')->optimizeTokens($expected_cache_contexts);
        $this->assertEqualsCanonicalizing($optimized_expected_cache_contexts, explode(' ', $response->getHeader('X-Drupal-Cache-Contexts')[0]));
        } }
        // Expected Page Cache header value: X-Drupal-Cache header. // Expected Page Cache header value: X-Drupal-Cache header.
        ......
        ...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
        namespace Drupal\user; namespace Drupal\user;
        use Drupal\Core\Access\AccessResult; use Drupal\Core\Access\AccessResult;
        use Drupal\Core\Access\AccessResultNeutral;
        use Drupal\Core\Access\AccessResultReasonInterface; use Drupal\Core\Access\AccessResultReasonInterface;
        use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityInterface;
        use Drupal\Core\Entity\EntityAccessControlHandler; use Drupal\Core\Entity\EntityAccessControlHandler;
        ...@@ -51,17 +50,24 @@ protected function checkAccess(EntityInterface $entity, $operation, AccountInter ...@@ -51,17 +50,24 @@ protected function checkAccess(EntityInterface $entity, $operation, AccountInter
        switch ($operation) { switch ($operation) {
        case 'view': case 'view':
        // Only allow view access if the account is active. // Only allow view access if the account is active.
        if ($account->hasPermission('access user profiles') && $entity->isActive()) { $result = AccessResult::allowedIfHasPermission($account, 'access user profiles');
        return AccessResult::allowed()->cachePerPermissions()->addCacheableDependency($entity);
        if ($result->isAllowed()) {
        $result = $result->andIf(
        AccessResult::allowedIf($entity->isActive())->addCacheableDependency($entity)
        );
        if ($result instanceof AccessResultReasonInterface) {
        $result->setReason("The 'access user profiles' permission is required and the user must be active.");
        }
        if ($result->isAllowed()) {
        return $result;
        }
        } }
        // Users can view own profiles at all times. // Users can view own profiles at all times.
        elseif ($account->id() == $entity->id()) { return $result->orIf(AccessResult::allowedIf($account->id() == $entity->id())->addCacheContexts(['user']));
        return AccessResult::allowed()->cachePerUser();
        }
        else {
        return AccessResultNeutral::neutral("The 'access user profiles' permission is required and the user must be active.")->cachePerPermissions()->addCacheableDependency($entity);
        }
        break;
        case 'update': case 'update':
        // Users can always edit their own account. // Users can always edit their own account.
        ......
        ...@@ -309,7 +309,7 @@ public function testPatchSecurityOtherUser() { ...@@ -309,7 +309,7 @@ public function testPatchSecurityOtherUser() {
        protected function getExpectedUnauthorizedAccessMessage($method) { protected function getExpectedUnauthorizedAccessMessage($method) {
        switch ($method) { switch ($method) {
        case 'GET': case 'GET':
        return "The 'access user profiles' permission is required and the user must be active."; return "The 'access user profiles' permission is required.";
        case 'PATCH': case 'PATCH':
        return "Users can only update their own account, unless they have the 'administer users' permission."; return "Users can only update their own account, unless they have the 'administer users' permission.";
        ...@@ -327,8 +327,13 @@ protected function getExpectedUnauthorizedAccessMessage($method) { ...@@ -327,8 +327,13 @@ protected function getExpectedUnauthorizedAccessMessage($method) {
        */ */
        protected function getExpectedUnauthorizedEntityAccessCacheability($is_authenticated) { protected function getExpectedUnauthorizedEntityAccessCacheability($is_authenticated) {
        // @see \Drupal\user\UserAccessControlHandler::checkAccess() // @see \Drupal\user\UserAccessControlHandler::checkAccess()
        return parent::getExpectedUnauthorizedEntityAccessCacheability($is_authenticated) $result = parent::getExpectedUnauthorizedEntityAccessCacheability($is_authenticated);
        ->addCacheTags(['user:3']);
        if (!\Drupal::currentUser()->hasPermission('access user profiles')) {
        $result->addCacheContexts(['user']);
        }
        return $result;
        } }
        /** /**
        ......
        0% Loading or .
        You are about to add 0 people to the discussion. Proceed with caution.
        Please register or to comment