All resources fail other than node resource when client is not authenticated as user with 'administer nodes' privilege.
this is because node.module rewrites sql with following function:
function _node_access_join_sql($node_alias = 'n', $node_access_alias = 'na') {
if (user_access('administer nodes')) {
return '';
}
return 'INNER JOIN {node_access} '. $node_access_alias .' ON '. $node_access_alias .'.nid = '. $node_alias .'.nid';
}
this join will return no results with any sql statement where primary table is not node. breaks comment_resource, file_resource, taxonomy_resource, and user_resource
the proposed solution prefixes all fields in select and where clause. open to alternate solutions. attached is an initial patch.
Comments
Comment #1
emosbaugh commentedComment #2
ygerasimov commentedSorry but I don't understand what exactly calls get broken if user is anonymous? From the patch I can see that broken calls are "index" calls. Is it correct?
Can you write the test for this bug?
Comment #3
emosbaugh commentedSorry, I tested this and you have to make sure that you have some sort of access module enable that changes the node view grants. As a result node_access_view_all_nodes() needs to return false. I've never written a simpletest. I can try to write one if you still need it. Let me know.
When you call:
$query = services_resource_build_index_query('comments', 'timestamp DESC', 0, '*');
The resulting query ends up looking something like this:
SELECT DISTINCT * FROM {comments} INNER JOIN {node_access} na ON na.nid = n.nid WHERE (na.grant_view >= 1 AND ((na.gid = 0 AND na.realm = 'all'))) ORDER BY timestamp DESC
Comment #4
emosbaugh commentedOk, digging deeper. Enable nodeaccess (http://drupal.org/project/nodeaccess) module and the resulting query when you call services_resource_build_index_query('comments', 'timestamp DESC', 0, '*'), gives an error and looks like the below.
Has nothing to do with whether or not the user is anon. Probably just cant be user 1 or have administer nodes privileged.
SELECT DISTINCT * FROM {comments} INNER JOIN {node_access} na ON na.nid = n.nid WHERE (na.grant_view >= 1 AND ((na.gid = 0 AND na.realm = 'all') OR (na.gid = 1 AND na.realm = 'nodeaccess_rid') OR (na.gid = 0 AND na.realm = 'nodeaccess_uid') OR (na.gid = 0 AND na.realm = 'nodeaccess_author'))) ORDER BY timestamp DESC
Comment #5
ygerasimov commentedYes, now I understand the problem completely and it is really critical. Thanks for this great catch.
I have ran all tests after applying patch and tests got broken.
@emosbaugh, could you please look what is wrong? I had problems in tests: "Resource Node" and "Resource Comment".
I will try to take a look at them as well in nearest few days.
Meanwhile patch has expressions like:
That should be like:
$where[] = $primary_table . '.' . $field . ' = ' . db_type_placeholder($schema['fields'][$field]['type']);(style corrections).
Comment #6
emosbaugh commentedI ran tests on both head and patched module. The test results seem to come out exactly the same except for 2 additional "fails" in node resource. See attached file. I will fix these errors and report back.
...
GET http://drupal-services/s775607IK3XufSVRg/node.php returned 200 (817 bytes). Browser ServicesWebTestCase.php 400 ServicesWebTestCase->curlExec()
Successfully received Node info NodeResource: Index ServicesResourceNodeTests.test 63 ServicesResourceNodetests->testNewEndpointResourceNodeIndex()
[01-Jun-2011 09:56:03] SELECT n.* FROM {node} AS n WHERE n.status = %d ORDER BY n.sticky DESC, n.created DESC Fatal error Unknown 0 Unknown
[01-Jun-2011 09:56:03] SELECT n.* FROM {node} AS n WHERE n.status = %d ORDER BY n.sticky DESC, n.created DESC Fatal error Unknown 0 Unknown
Starting run with db_prefix simpletest210148 System ServicesResourceNodeTests.test 35 ServicesResourceNodetests->setUp()
Endpoint successfully created Other ServicesWebTestCase.php 344 ServicesWebTestCase->saveNewEndpoint()
...
Comment #7
emosbaugh commentedforgot to include user
Comment #8
kylebrowning commentedemosbaugh, all of the test are not passing pre-patch? Are you on 5.2 or 5.3?
Comment #9
emosbaugh commentedPHP Version 5.2.17
Comment #10
emosbaugh commentedproblem is a lot of tests pass in a 'count' param and the new services 6.3 doesnt take that param. it is hardcoded to 20 results.
see services_resource_build_index_query
line 466:
$result = db_query_range($sql, $parameters, $page * 20, 20);
Comment #11
emosbaugh commentedOk, after a lot of testing I found that the 2 additional error in simpletest were error_log statements that I had inserted for testing purposes :(
So for me the results from the test cases look identical. Please verify.
I have not written a test case as of yet for the addition of node view access restrictions.
Comment #12
emosbaugh commentedAttached is a patch with corrected syntax
Comment #13
marcingy commentedQuick comment why do we have defaults for these parameters why not just pass them in for node as well as the function is only used by services and this actually confuses things by having a default that is used once.
Comment #14
emosbaugh commentedOne more time with a check to see if fields is an empty string. Not sure if this is possible but just in case...
Comment #15
emosbaugh commentedNo default params
http://drupal.org/node/1159456#comment-4549908
Comment #16
emosbaugh commentedWhat is the status of this? What can I do to get this into repo?
Comment #17
emosbaugh commentedComment #18
kylebrowning commentedIt looks good, can we get a d7 version (if needed?)
Comment #19
emosbaugh commentedI don't believe drupal 7 will have the problem with the new query builder using base_table meta data field rather than alias.
Comment #20
kylebrowning commentedComment #21
emosbaugh commentedThanks!
Comment #22
kylebrowning commented