Unpublished content is not visible in views to users with the 'view own unpublished content' permission when used in combination with node grants

Created on 10 May 2018, over 6 years ago
Updated 9 August 2024, 5 months ago

Problem/Motivation

When Content Moderation is enabled and a user with 'view own unpublished content' creates a new piece of content and saves it in the 'draft' state they cannot see that content in either the Content Overview (Node) /admin/contentor the Managed Content (Content Moderation) admin/content/moderatedViews.

This occurs because if (a) any module implements hook_node_grants then access to the node is conditional based on if a record exists in the node_access table which (b) doesn't occur unless a node is published or another module sets access records for draft content, which Content Moderation does not do.

a) node_access_view_all_nodes docroot/core/modules/node/node.module:1014

  // If no modules implement the node access system, access is always TRUE.
  if (!\Drupal::moduleHandler()->getImplementations('node_grants')) {
    $access[$account->id()] = TRUE;
  }
  else {
    $access[$account->id()] = \Drupal::entityManager()->getAccessControlHandler('node')->checkAllGrants($account);
  }

b) \Drupal\node\NodeAccessControlHandler::acquireGrants called from \Drupal\node\Entity\Node::postSave

/**
   * {@inheritdoc}
   */
  public function acquireGrants(NodeInterface $node) {
    $grants = $this->moduleHandler->invokeAll('node_access_records', [$node]);
    // Let modules alter the grants.
    $this->moduleHandler->alter('node_access_records', $grants, $node);
    // If no grants are set and the node is published, then use the default grant.
    if (empty($grants) && $node->isPublished()) {
      $grants[] = ['realm' => 'all', 'gid' => 0, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0];
    }
    return $grants;
  }

However if a module does implement hook_node_grants, the only way the content will appear in the Content Overview View (for non-admin users) is if it published.

Steps to reproduce

  • Install Drupal 8.5.3
  • Install a module that implements hook_node_grants i.e Content Access or Permissions by Term
  • Enable Content Moderation (and it's dependency Workflows)
  • Edit 'Editorial' workflow to apply to all content types
  • Create a new use role 'Editor' with the following permissions:
  • 'access content'
    'access content overview'
    'create article content'
    'delete all revisions'
    'delete any article content'
    'delete article revisions'
    'delete own article content'
    'edit any article content'
    'edit own article content'
    'grant content access'
    'grant own content access'
    'revert all revisions'
    'revert article revisions'
    'use editorial transition archive'
    'use editorial transition archived_draft'
    'use editorial transition archived_published'
    'use editorial transition create_new_draft'
    'use editorial transition publish'
    'view all revisions'
    'view any unpublished content'
    'view article revisions'
    'view latest version'
    'view own unpublished content'
    
  • Create a new user 'editor'
  • Log in as the new user
  • Create a new 'article' with the title "[TEST] Title" with the "Save As" value "Draft" selected
  • Go to the Content Overview View (/admin/content)
    • No content is shown
  • Go to Moderated Content View (admin/content/moderated)
    • No content is shown
  • Edit the "[TEST] Title" node (/node/1)
  • Set the "Change to" field value to "Published"
  • save
  • Go to the Content Overview View (/admin/content)
  • You should see [TEST] Title with the Status Published
  • Go to Moderated Content View (admin/content/moderated)
  • You should not see [TEST] Title
  • Edit the "[TEST] Title" node (/node/1)
  • Set the "Change to" field value to "Draft"
  • Go to Moderated Content View (admin/content/moderated)
  • You should see [TEST] Title with the status

Proposed resolution

I'm not sure where the solution for this needs to occur but I feel like the implications of getting it wrong could have wide reaching consequences.

Does an extra conditional need to be added to \Drupal\node\NodeAccessControlHandler::acquireGrants to check for Content Moderation and set the same defaults, if none are set, or should Content Moderation implement hook_node_access_records?

Considering Content Moderation is now part of core I think adding a check for it and setting similar defaults as published content isn't a bad thing. Of course the 'gid' would need to be set using the users role, but would this allow other roles with more perms to access the content? This approach would also mean a test could be added in Content Moderation for the Content Overview View checking for draft visibility

I'm leaning more towards Content Moderation implementing hook_node_grants and hook_access_records - but that is where I wanted to find some validation from the community that this approach is going to be acceptable.

Remaining tasks

  • Determine the best approach for handling this.
  • Add/update tests in Content Moderation
  1. so that the Views being tested against exactly match the default views.view.moderated_content, currently none of the test Views in content_moderation_test_viewshave the same access setting as content_moderation
  2. add test coverage for draft content in Content Overview
🐛 Bug report
Status

Needs work

Version

11.0 🔥

Component
Node system 

Last updated 4 days ago

No maintainer
Created by

🇦🇺Australia GRO

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

  • Needs issue summary update

    Issue summaries save everyone time if they are kept up-to-date. See Update issue summary task instructions.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇺🇸United States shrutidkadam

    Faced the same issue in 9.4.8 #19 and #22 resolved the issue.

  • Status changed to Needs review almost 2 years ago
  • 🇮🇹Italy apaderno Brescia, 🇮🇹

    Since there are patches and this is a bug report, the status should be Needs review.

  • Status changed to Needs work almost 2 years ago
  • 🇺🇸United States smustgrave

    The last patch I see has failures in it. And no test coverage.

  • 🇨🇦Canada mahde Vancouver

    The patch fixed the issue for me!
    I faced this issue with private content module.

  • 🇭🇺Hungary mxr576 Hungary

    Opened the following issue because IMO the main part of the problem relies in a Views filter plugin that is with us since Drupal 7...

    I also read through this long comment thread, I was convinced that this can be solved because the main issue described in 🐛 The content overview Views view filters out unpublished content Active but since content_moderation DOES NOT implement hook_node_access_records() just hook_entity_access()
    - so query based filtering is not supported OOTB - therefore there could be another issue here that should be handled as part of this issue (needs issue summary update...) or in another thread with fewer comments about different topics and ideas.

  • 🇩🇪Germany Anybody Porta Westfalica
Production build 0.71.5 2024