I have a list of articles, some of them are published and others are not published.
If I do an anonymous request to:
GET /api/node/article/1234?_format=api_json
And node 1234 is not published I got:
{"errors":[{"title":"Forbidden","status":403,"detail":"The current user is not allowed to GET the selected resource.","links":{"info":"http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html#sec10.4.4"},"code":0}]}
Which makes sense.
But, when I do:
GET /api/node/article?_format=api_json
The article 1234 is listed on the results. The permissions to see published content are not respected.
My understanding is this is not applicable to all entities (not all entities have status to restrict access), but this is valid at least for nodes.
| Comment | File | Size | Author |
|---|---|---|---|
| #22 | 2778627--interdiff--17-22.txt | 878 bytes | e0ipso |
| #22 | 2778627--individual-entity-access--22.patch | 26.19 KB | e0ipso |
Comments
Comment #2
e0ipsoComment #3
e0ipsoAgain, thanks for reporting this. You are killing it @dagmar!
Comment #4
Anonymous (not verified) commentedI can confirm the same issue.
I've found that the node access is checked when requesting a single one but, in the other hand,
when requesting a list of resources the access isn't checked.
Perhaps a filter by status can be added when the query is formed, isntead iterating by all the results checking the access individually.
Comment #5
e0ipsoAdded a test that proves the error.
Comment #6
e0ipsoMaking the testbot execute the tests and seeing them fail.
Comment #9
e0ipsoSince the access handlers are not executed during the entity queries, we need to manually check for the errors in the collection.
Then we need to treat the errors as if they were includes and bubble them up to the top level. That way we can effectively have something like:
Comment #10
e0ipsoIt turns out that for it to be valid JSON API we need something like:
We'll need an extension to document the opinionated stance towards errored entities in collections.
Comment #11
e0ipsoThis one was tricky.
Comment #12
e0ipsoAdded a new extension for this: https://gist.github.com/e0ipso/732712c3e573a6af1d83b25b9f0269c8
Comment #17
e0ipsoComment #18
dawehnerI totally love how this patch encodes more things in pure return objects than other potential solutions, like setting some data somewhere.
This is just lovely. For better readability I would have separated access related stuff with new lines.
Comment #19
wim leers#777578: Add an entity query access API and deprecate hook_query_ENTITY_TYPE_access_alter() would help with this a lot; then you wouldn't need to call
access()on every individual entity anymore.Which makes me wonder whether this should actually avoid calling
$entity->access()if$entity instanceof NodeInterface? Listings are always per entity type, so if the entity type is'node', then JSON API should rely on that instead of this?Comment #20
wim leersComment #21
David Hernández commentedI'm not sure but this might be the same issue as #2807185: [BUGFIX] Handle relationships when target resource is not accessible or at least related with it.
Comment #22
e0ipsoAddressed the feedback provided by @dawehner.
@Wim Leers afaik the logic in
\Drupal\Node\NodeAccessControlHandler::accessis not checked during the EntityQuery. If that is the case then this check is indeed needed and additional to the grants system. I may be wrong though, I'm a bit fuzzy on this area.Comment #24
e0ipsoThere is a question still open for @Wim Leers, but this code will still be needed atm regardless of the answer.