We’ve been trying to get this to work for quite some time now, but so far no progress. As soon as we enable a node access control module (Content Access, Node Access, Simple Access), where we limit Anonymous access to several nodes, we can’t request www.example.com/node.json anymore as anonymous. The result is a 403 header, where we would expect to get the list of nodes without the ones we are not allowed to see.
I’ve traced this back to the restws_entity_node_access function, where, if no specific node is requested this code is ran.
// No node is provided. Check for access to all nodes.
if (user_access('bypass node access', $account)) {
return TRUE;
}
if (!user_access('access content', $account)) {
return FALSE;
}
if ($op == 'view' && node_access_view_all_nodes($account)) {
return TRUE;
}
In particular the node_access_view_all_nodes
function causes this as it says:
Checks to see whether any module grants global 'view' access to a user account; global 'view' access is encoded in the {node_access} table as a grant with nid=0. If no node access modules are enabled, node.module defines such a global 'view' access grant. https://api.drupal.org/api/drupal/modules!node!node.module/function/node...
Since there is a content access module, this functions returns FALSE and restws returns a 403.
While further investigating that function I've found that the phpDoc comments above the function say:
@todo Remove this once https://drupal.org/node/1780646 is fixed.
Which has been fixed in the latest dev release of Entity API. So I was wondering if there was anything in the works to remove this function and / or implement a check for individual node access callbacks?
Comment | File | Size | Author |
---|---|---|---|
#18 | Screen Shot 2016-03-11 at 3.47.34 PM.png | 40.16 KB | cloudbull |
#8 | restws-fixing-anon-node-access-2169363-8.patch | 1.05 KB | aschmoe |
#7 | restws-anonymous-query-access-2169363-7.patch | 709 bytes | mollux |
Comments
Comment #1
dolcaer CreditAttribution: dolcaer commentedI've been thinking of this node_access_view_all_nodes part, and wonder if it is really necessary. According to the documentation on the node_access_view_all_nodes function page:
So if no node access modules are enabled, the node module provides a global 'view' grant and returns TRUE. If there however IS a node access modules enabled, that module would be responsible for the filtering of restricted nodes. Thus users should still not be able to see nodes they don't have access to.
We've just tried the following code (with content access, I don't know about the others), and it works as expected. Returning all nodes the anonymous user has access to, and stripping the ones he doesn't.
This should always work, because it is open in the case there is no content access module (node module defines the global 'view') it would have returned TRUE anyway. If there is a content access module, it is up to the module to handle the filtering.
Comment #2
timlie CreditAttribution: timlie commentedCan confirm that this solved the issue.
Nodes are shown in the listing respecting the node access permissions they have.
Comment #3
Neograph734I agree with above comments and have added a patch.
Comment #4
Grayside CreditAttribution: Grayside commentedThis seems deprecated by #2237879: Remove custom restws_entity_node_access() hack.
Comment #5
Neograph734As of now this is still an issue. The custom hack is gone but the code now checks the access using the entity API's entity_metadata_no_hook_node_access access callback. Which in turn (correctly) returns false when the access to ALL nodes is requested.
In certain use cases where a site has internal and external content where the external content should be accessible by anonymous users this will always fail as these users will never have access to all nodes or permissions to bypass node access. Making RestWS a useless module in these cases.
In my opinion this module should attempt to gain access to all nodes and when it fails, it could perhaps attempt to get view access to some nodes. I've altered the restws_handle_request function to do this below.
Comment #6
pmackay CreditAttribution: pmackay commentedI'm experiencing this issue as well. The above change enables downloading lists of nodes. Would it make sense to roll it into a patch?
Comment #7
mollux CreditAttribution: mollux as a volunteer commentedI made a patch of the above code to allow querying of entities by anonymous users.
Comment #8
aschmoe CreditAttribution: aschmoe commentedHere is #5 in a patch.
Comment #9
aschmoe CreditAttribution: aschmoe commentedMoving to needs review for testing.
Comment #14
aschmoe CreditAttribution: aschmoe commentedNot sure why the patch in #8 is failing... everything applies cleanly for me. Someone want to give it another shot?
Comment #15
Media Crumb CreditAttribution: Media Crumb commentedI found one bug with this patch. If im using any filters the url request gets redirected to node.json without the filters attached. For instance my filters are set as:
http://www.site.com/node?full=0&limit=10&type=blog
but anonymous users actually get:
http://www.site.com/node
Comment #16
Media Crumb CreditAttribution: Media Crumb commentedMore info on the bug.
It seems to only happen for people using the none json url structure. For instance
http://www.site.com/node?full=0&limit=10&type=blog
BREAKShttp://www.site.com/node.json?full=0&limit=10&type=blog
WORKSThis is a problem for people who are using http://www.site.com/node/ID however so we would need a way to fix that before considering it a working patch.
Comment #17
Derek Devnich CreditAttribution: Derek Devnich commentedI've tested both of the patches above, and they seem to succeed or fail in similar situations. For example, we have a "People" content type that we use for directory entries. The following anonymous request succeeds:
mysite.com/node.json?type=people&limit=10
mysite.com/node.xml?type=people&limit=10
Sorting by the built-in node title also works:
mysite.com/node.json?type=people&limit=10&sort=title
mysite.com/node.xml?type=people&limit=10&sort=title
However, attempting to sort by a user-defined database field fails:
mysite.com/node.json?type=people&limit=10&sort=field_people_last_name
mysite.com/node.xml?type=people&limit=10&sort=field_people_last_name
...even though these work fine for an authenticated user. The PDOException is:
PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'field_data_field_people_last_name0.nid' in 'where clause' in /var/www/drupal7-prod/htdocs/includes/database/database.inc on line 2171
I don't know enough about how restws handles permissions to know what's going on here. If it's helpful, the permissions-modifying module we're using on this site is the "View Unpublished" module.
Comment #18
cloudbull CreditAttribution: cloudbull commentedhaving same thing here,
access denied even content type and restws permission set.
test url http://test1-bangkok.coconuts.co/node.json?type=event&field_price=420.13
any help is appreciated.
thanks
Keith
Comment #19
djouuuuh CreditAttribution: djouuuuh commentedI'm having the same issue.
I have Content Access enabled and all the users that are not with "bypass content access control" permission cannot request the data.
I'm very interested in the solution.