This module controls access to referenced data by checking access of the entity being referenced.

With #1909436: Access denied: Entity Reference should also allow on node edit permission, this module grants 'view' access on the basis of 'update' access to the referenced entity.

        // Check whether the user has access to the referenced entity.
        $has_view_access = (entity_access('view', $field['settings']['target_type'], $target_entities[$item['target_id']]) !== FALSE);
        $has_update_access = (entity_access('update', $field['settings']['target_type'], $target_entities[$item['target_id']]) !== FALSE);
        $items[$id][$delta]['access'] = ($has_view_access || $has_update_access);

There are a group of people who prefer this behaviour - see the comments on the related issue.

However this behaviour is counter-intuitive and it creates problems for other people.

  • As per this comment, a site may have removed 'view' permissions so that editors can see the site as a normal user would.
  • Check both permissions hurts performance. On my site, it crippled performance because 'update' access was controlled by a custom hook and much more expensive to calculate. This could be mitigated to a degree by only checking 'update' permission if 'view' permission failed.
  • Withholding 'view' permission should really mean exactly that. This is a borderline security issue, but I didn't raise it as one because it is pretty obscure. Suppose that on my site ordinary editor EE can edit content type CC. I use module field_permissions so that EE can't edit field XX (and hence can't see the existing value when editing) as XX contains data that needs to remain confidential whilst a node is unpublished. I carefully check that EE has no permission to view unpublished content of type CC. However my view VV will show field XX by means of an entity reference as soon as the entity is published. EE can now see the confidential field XX by means of view VV.

This behaviour needs to be a configurable option.

We can debate the details. I tend to feel that it should be off for new sites, but of course if so, it needs to be on as a migration step.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

AdamPS’s picture

I came across the same situation as a performance problem. This is creating an extra call to hook_node_access 'update' for every row in a view, which generates unnecessary SQL queries and slows the site down. In my case, hook_node_access 'view' does nothing, so the difference is significant.

The documentation for hook_node_access does not make any mention that when checking to display content the 'update' permission should also be checked, and I've not come across that concept in other modules.

The situation where someone has deliberately set 'update' access but not 'view' isn't easy to imagine. Such a user can presumably see the existing values on the edit page so these permissions don't achieve much. So a developer may have decided that it's harmless to add the extra check. However the performance impact isn't harmless.

Possibly this code came about as a workaround for some module that sets 'update' access but accidentally forgets to set 'view' access?? If so, I would think it is better to fix that code. If anyone knows of such code, please add a comment.

The attached patch removes the unnecessary check.

AdamPS’s picture

Status: Active » Needs review
AdamPS’s picture

Request that this one is in the next release please.

joachim’s picture

> This design decision seems weird! ;)

I agree! But maybe there's a reason we're not aware of.

Have you tried using git blame to find the issue that introduced this access check? Maybe that would give us some background on this.

MustangGB’s picture

geek-merlin’s picture

Title: field formatter checks access to referenced entities with 'update' op » Make "update access implies view access" optional
Status: Needs review » Needs work
Related issues: +#1909436: Access denied: Entity Reference should also allow on node edit permission

Yes this was intentionally done in #1909436: Access denied: Entity Reference should also allow on node edit permission. I totally second Dave Reid who said in #1909436-17: Access denied: Entity Reference should also allow on node edit permission:

I really wish this was an optional behavior. I don't like this change since when I view a node that might refer to unpublished, but future-scheduled nodes in an entity reference field, this means I can see them now and doesn't match the expectation of what a normal user would see.

So as some gals need that and others don't this should be the way to go. Updating title accordingly.

AdamPS’s picture

Issue summary: View changes
AdamPS’s picture

Thanks everyone - I should have thought of checking git blame. I have updated the issue summary.

I would welcome any opinions on the last para - what should the default behaviour be for "update access implies view access"?

A) Default to ON. This is simplest.
B) Default to OFF. Turn on as a migration step for existing sites.
C) As B, but also as a migration step turn on a warning inviting people to turn the setting off if they don't need it. Warning goes away when settings are saved for first time.

joachim’s picture

> Default to ON

This is good for existing sites, but not ideal for new sites, as it's not the default we want to encourage.

> Default to OFF

This is good for new installations, as it helps performance.

However, it means it breaks existing sites. At least it breaks them in the direction of hiding things that should be visible, rather than exposing things that should be hidden. But it's still a pain to sites that rely on this.

I would suggest default to OFF, and a hook_update_N() which automatically sets existing fields to ON to preserve the existing behaviour (and has an explanation of why it's doing that).

MustangGB’s picture

I'd say B is enough (default off + hook_update_N() + documentation), no need to go the extra step of forcing/encouraging people to switch.

AdamPS’s picture

Assigned: Unassigned » AdamPS

OK, thanks, that's two votes for B, so I'll make a new patch based on that option.

geek-merlin’s picture

Thanks a lot Adam PS!

AdamPS’s picture

Status: Needs work » Needs review
FileSize
5.31 KB

OK, ready for review please.

geek-merlin’s picture

The code looks straightforward and solid to me. Did not test though.
(I wish that more code be so well-commented and readable ;-)!

scotwith1t’s picture

While well-formatted and well-commented, "entityreference" is spelled "entityreferece" in many places...can't imagine that's intended...

AdamPS’s picture

Thanks - done a search and replace of many entityreferece with entityreference

Status: Needs review » Needs work

The last submitted patch, 16: entityreference.access.2292451-16.patch, failed testing.

AdamPS’s picture

Status: Needs work » Needs review

Baffled as to why the trivial search and replace has caused the tests to fail. Advice welcome! Setting back to needs review to give the tests another try in case it was a temporary glitch.

Status: Needs review » Needs work

The last submitted patch, 16: entityreference.access.2292451-16.patch, failed testing.

geek-merlin’s picture

@AsanPS:
note that the branch tests are very old and the failing tests migh come from the module itself, not your patch. (note that the number of tests changed, and the last branch test is from 2015)
i did not find how to re-trigger the branch test as non-maintainer, but in any case, you can upload an empty (trivial, comment-only) patch here to check the branch test integrity.

if that does not uncover the cause, please make and upload an interdiff.

MustangGB’s picture

Looks like branch tests are passing as of August 24th (https://www.drupal.org/pift-ci-job/431579), so I tried queuing a re-test.

MustangGB’s picture

Status: Needs work » Needs review

Looks like it passes fine now.

Chris Matthews’s picture

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

The 2 year old patch in #16 does not apply to the latest 7.x-1.x-dev and if still relevant needs a reroll.

pokurek’s picture

MustangGB’s picture

Status: Needs work » Needs review

Lets trigger some tests then.

pokurek’s picture

MustangGB’s picture

Did you do a find and replace?
Because $items['entityreference/autocomplete/single/%/%/%'] turned into $items['autocomplete/single/%/%/%'].

Also perhaps entityreference_update_7003() should be entityreference_update_7101() now?

MustangGB’s picture

Status: Needs review » Needs work
pokurek’s picture

You are right. I miss that. Hope this will be better one.

pokurek’s picture

Status: Needs work » Needs review
rpayanm’s picture

Issue tags: -Needs reroll