Access Unpublished check being called twice

Created on 14 February 2024, about 1 year ago

Problem/Motivation

The implementation of decoration of access_check.latest_revision service has a small mistake that causes the Access Unpublished check src/Access/LatestRevisionCheck::access() to be called twice in row.

  • Once with all other services decorating the access_check.latest_revision. It might be called together with:
  • Second separately as access_unpublished.access_check.latest_revision service alone.

As a result, you might experience the following Access Denied Warning:
Path: /node/1/latest. Drupal\Core\Http\Exception\CacheableAccessDeniedHttpException: The following permissions are required: 'view latest version' AND 'view any unpublished content'. in Drupal\Core\Routing\AccessAwareRouter->checkAccess() (line 115 of /app/web/core/lib/Drupal/Core/Routing/AccessAwareRouter.php).

The definition of the Service access_unpublished.access_check.latest_revision adds the following Tag to the definition:
->addTag('access_check', ['applies_to' => ‘_content_moderation_latest_version']);
which is WRONG as it already decorated the Service access_check.latest_revision and thus it does NOT need to be called as a separate “Content moderation latest version Access Check” AGAIN.

The Tag is added in src/AccessUnpublishedServiceProvider.php:

$container->register('access_unpublished.access_check.latest_revision', LatestRevisionCheck::class)
  ->setDecoratedService('access_check.latest_revision')
  ->addArgument(new Reference('access_unpublished.access_check.latest_revision.inner'))
  ->addTag('access_check', ['applies_to' => '_content_moderation_latest_version']);

The Service access_check.latest_revision defined in the core/modules/content_moderation/content_moderation.services.yml contains tag definition with values: { name: access_check, applies_to: _content_moderation_latest_version } so when decorating there's no reason to define the same values for the service that decorates it.

 access_check.latest_revision:
    class: Drupal\content_moderation\Access\LatestRevisionCheck
    arguments: ['@content_moderation.moderation_information']
    tags:
      - { name: access_check, applies_to: _content_moderation_latest_version }

Steps to reproduce

The check is being called twice all the time.

  • If you debug core/lib/Drupal/Core/Access/AccessManager::checkRequest() which calls core/lib/Drupal/Core/Access/AccessManager::check()
  • And you review the result of the line $checks = $route->getOption('_access_checks') ?: [];
  • You should see both checks in:
    access_check.latest_revision and
    access_unpublished.access_check.latest_revision

Or more complicated situation: Use the following contribs together

Proposed resolution

Remove the service Tag mentioned above.

Remaining tasks

User interface changes

API changes

Data model changes

🐛 Bug report
Status

Needs review

Version

1.0

Component

Code

Created by

🇦🇺Australia dabbor

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.71.5 2024