If you refer to any entity with an entity reference field right now, access to that entity is not enforced when the entity is displayed through the formatter.
The attached patch adds an access check by invoking entity_access() in entityreference_field_formatter_prepare_view(), since that is where the entities are loaded, and non-existing entities are removed there as well. This was an easy fix, but you might want to handle this in the handler instead?
| Comment | File | Size | Author |
|---|---|---|---|
| #19 | 1412572.19.entityreference.formatter-access-check-preserve-data.patch | 2.55 KB | joachim |
| #8 | entity-access-1412572-8.patch | 1.11 KB | fabsor |
| #2 | no-access-check-1412572-2.patch | 1.18 KB | fabsor |
| no-access-check-1.patch | 1.5 KB | fabsor |
Comments
Comment #1
amitaibu> This was an easy fix, but you might want to handle this in the handler instead?
Indeed, I think maybe we should use
$valid_ids = entityreference_get_selection_handler($field, $instance)->validateReferencableEntities(array_keys($ids));, instead of just entity_acces() (For example once we get this, OG will not need to declare its own formatter, which sounds great).Comment #2
fabsor commentedAlright, here is a version that uses the handler instead. Another upside of this is that there already are tests for this.
Comment #3
amitaibuIf there are no valid-ids, maybe we can return early.
Comment #4
fabsor commentedWe still need to loop through the items array and unset inapplicable items even if we didn't get any results, the formatter_view expects to be able to render each row in items, so it will try to render them and it will result in warnings. We could go through the items array if we don't have any results and unset them in our own loop and then return, but that seems like doing double work since we have the proper logic in place anyway.
Comment #5
amitaibuAfter testing the patch, and thinking some more I think that maybe entity_access() (i.e. the first path) is the correct approach. As a user might be able to select limited nodes but they are still allowed to view other nodes, so validateReferencableEntities will be too strict.
Comment #7
amitaibu@fabsor, can you re-roll please?
Comment #8
fabsor commentedHere is a reroll of the entity access patch, since that's the one that was most interesting.
Comment #9
amitaibuCommitted, thanks.
Comment #11
firebird commentedThis patch is causing a slight problem for me.
For referred entities that do not define an access callback, the entityreference field is not shown. This is because entity_access() returns NULL, which gets evaluated as FALSE in:
if (isset($target_entities[$item['target_id']]) && entity_access('view', $field['settings']['target_type'], $target_entities[$item['target_id']])) {Elsewhere, for example in hook_node_access, a returned NULL value means "I don't care", whereas a FALSE means "No access".
Shouldn't the if-clause here do a strict comparison to FALSE, instead of evaluating NULL as FALSE?
Comment #12
firebird commentedRelated issues:
http://drupal.org/node/976360
http://drupal.org/node/1526198
Comment #13
Alumei commentedI have also noticed, that when using entity-reference to link a user, the value is only show, if the viewing user has the 'View user profiles' permission.
This result is resonable from the point, that entity_access obviously should check for that permission.
But in my usecase i want to reference a user account so that only users with the 'View user profiles' get a link to the profile page and all other users simply get the referenced account name shown.
Comment #14
joachim commentedThis patch also has a serious problem in that it *removes data* from the entity.
For example, suppose I have node A that has a reference field to node B, and node B is unpublished.
In the node template, I would expect the $node object to be the same in all circumstances: it's the loaded, raw data from the database.
However, this patch has changed that: the $node object in the template has its field value *unset* when a user who does not have access to node B looks at node A.
Comment #15
amitaibu> This patch also has a serious problem in that it *removes data* from the entity.
I see, so you are actually recommending to move this to the formatter itself?
Comment #16
joachim commentedYes, definitely. Entity objects should not have their data removed.
Comment #17
amitaibu@joachim, any chance for a patch :) ?
Comment #18
amitaibuAdding tags
Comment #19
joachim commentedHere's a patch on RC5 which is currently identical to HEAD :)
I'm keeping the access check in entityreference_field_formatter_prepare_view(). There would be no performance change in moving it to entityreference_field_formatter_view(), but the code we'd repeat would be more complex to read, so that's one reason to keep it where it is. Also, I figure the earlier the access data gets in, the better for any alter hooks or theme preprocessing.
Comment #20
amitaibuWe should add tests for it. joachim, got time for this?
Comment #21
twardnw commentedPatch in #19 applies clean and access to entities is working correctly for me. My test was that an anon user cannot see unpublished node from reference on a published node.
Comment #22
amitaibuI've edited a bit the patch, and committed. thanks.
This code is already in the 8.x patch.