Access Unpublished check being called twice

Created on 14 February 2024, 4 months 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.69.0 2024