Problem/Motivation

A view with an EntityReference relation does not show all results when a node access module is active. Items with a referenced node are shown depending on whether the user has permissions to view the parent and child node or not. But items without a referenced node are never shown.

Basically the generated SQL looks like this:

SELECT /* columns to select */
FROM {node} node
/* Joins etc. */
WHERE
/* Views generated condition SQL */
AND
  /* node_access checks for the node table */
  EXISTS(
    SELECT na.id AS nid FROM [node_access} na
    WHERE /* conditions */
    AND (node.nid = na.nid) /* node.nid from parent query to check if user has permission for that node */
 )L
AND
  /* node_access checks for the relation table */
  EXISTS(
    SELECT na.id AS nid FROM [node_access} na
    WHERE /* conditions */
    AND (node_field_data_field_relation_name.nid = na.nid) /* node_field_data_field_relation_name.nid from parent query to check if user has permission for that node joined by the EntityReference relation */
 )

If node_field_data_field_relation_name.nid is NULL because the node does not have a relation the whole EXISTS subquery evaluates to false. And as it is combined with the Views filters using AND the whole query filters out all nodes without a relation.

How to reproduce the problem

To reproduce the problem, follow those steps:

  • Install a node access module, e. g. node_view_permissions and keep the default configuration
  • Create two content types (e. g. blog and page) and add an EntityReference field to one type allowing only nodes of the other type. (Example: the Blog type contains a reference to a page)
    • Create one page and a blog post referencing the page
    • Create a blog post without referencing a page
  • Create a view for blog posts and add a relation for the EntityReference field.

Proposed resolution

Change the node_access condition from
node_field_data_field_relation_name.nid = na.nid
to
node_field_data_field_relation_name.nid IS NULL OR node_field_data_field_relation_name.nid = na.nid
if it is not the check for the query base table to not check if the user has permission to view NULL (that does not make sense).

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mvonfrie created an issue. See original summary.

mvonfrie’s picture

Status: Active » Needs review
matt_paz’s picture

Version: 7.x-dev » 8.9.x-dev
Assigned: mvonfrie » Unassigned
FileSize
717 bytes

I think the same issue persists in Drupal 8.

Tests still to be written, but I've attached is a potential solution for anyone else that encounters this issue.

Note, in my particular case, I was experiencing this in views (that included a reference to an organization/company). About half didn't have a referenced org, folks weren't seeing expected results in the view. Therefore, it was unexpectedly restricting access to content they should have been authorized to see.

matt_paz’s picture

Title: node_access filters out items with a node relation being NULL except for admins » hook_node_access_records unexpectedly restricts access when an entity reference doesn't exist

Adjusting the title a bit to clarify use and increase visibility

mstrelan’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

I can confirm the issue as described in #4 on an existing Drupal 8.9.1 site. The patch works, but needs tests.

matt_paz’s picture

Adding a related issue that is being worked more actively than this. Need to delve more deeply, but on the surface, I suspect it might resolve the condition.

https://www.drupal.org/project/drupal/issues/1349080?page=1

matt_paz’s picture

Version: 8.9.x-dev » 9.1.x-dev

Adjusting the version that this applies to.

matt_paz’s picture

Version: 9.1.x-dev » 9.2.x-dev

Assessment of issue 1349080 is still pending, but it looks like this patch will need to be updated for 9.2

matt_paz’s picture

FileSize
720 bytes

Not sure this is needed any more but I went ahead and updated the patch for 9.2.x-dev

mstrelan’s picture

Status: Needs work » Closed (duplicate)

I have confirmed the issue is resolved by the latest patch in #1349080: node_access filters out accessible nodes when node is left joined after following the steps in the issue summary. Closing this as a duplicate.