node_access_grants() is expecting an $op parameter. The call to node_access_grants in views_handler_filter_node_access.inc appears to send in both $op and $account arguments that haven't been set.

When this filter is used in views on a site with modules like og_access enabled, you get an incorrect set of grants back, as implementations of hook_node_grants like og_access_node_grants are expecting an $op value of "view" in order to return certain grants:

  if ($op == 'view') {
    $grants['og_public'][] = 0; // everyone can see a public node
  }

Not sure if sending in blank $op and $account values was intentional, but it seems like the $op coming from Views should always be "view", and the optional $account argument should be omitted, since node_access_grants will be grabbing the global $user object in this case anyway.

The attached patch ensures that Views is asking all implementers of hook_node_grants for grants for the "view" op.

Example query (before patch):

SELECT comments.cid AS cid,
comments.timestamp AS comments_timestamp
FROM {comments} comments
INNER JOIN {node} node_comments ON comments.nid = node_comments.nid
LEFT JOIN {node_access} node_comments__node_access ON node_comments.nid = node_comments__node_access.nid
WHERE ((comments.status = 0) AND (node_comments.moderate = 0) AND (node_comments.status <> 0) AND (node_comments.nid = %d))
AND (((node_comments__node_access.gid = 0 AND node_comments__node_access.realm = 'all')) AND (node_comments__node_access.grant_view >= 1))
ORDER BY comments_timestamp DESC

Example query after patch:

SELECT comments.cid AS cid,
comments.timestamp AS comments_timestamp
FROM {comments} comments
INNER JOIN {node} node_comments ON comments.nid = node_comments.nid
LEFT JOIN {node_access} node_comments__node_access ON node_comments.nid = node_comments__node_access.nid\n WHERE ((comments.status = 0) AND (node_comments.moderate = 0) AND (node_comments.status <> 0) AND (node_comments.nid = %d))
AND (((node_comments__node_access.gid = 0 AND node_comments__node_access.realm = 'all') OR (node_comments__node_access.gid = 0 AND node_comments__node_access.realm = 'og_public')) AND (node_comments__node_access.grant_view >= 1))
ORDER BY comments_timestamp DESC

Comments

dawehner’s picture

Without testing the code, its makes sense to use view.

      'handler' => 'views_handler_filter_node_access',
      'help' => t('Filter for nodes by view access. <strong>Not necessary if you are using node as your base table.</strong>'),

So view is definitive the thing to use here.

Additonal it makes sense too, to remove $account, because here it is NULL, always.

merlinofchaos’s picture

Status: Needs review » Fixed

Makes sense. Though this, at some point, needs to be opened up so we can actually query view, update and delete.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.