Closed (fixed)
Project:
Domain
Version:
5.x-1.0beta6
Component:
Code
Priority:
Normal
Category:
Feature request
Assigned:
Reporter:
Created:
12 Nov 2007 at 02:59 UTC
Updated:
1 Dec 2007 at 21:38 UTC
Jump to comment: Most recent file
Talking to merlinofchaos in IRC today, and his comments make me think that we might get better integration of this module and other node_access modules (like og) if we do not user the {node_access} table.
Instead, we would store our grants in a separate table, and use db_rewrite_sql to enforce domain access rules.
Pros and Cons to this approach:
PRO
- Greater integration flexibility
- Removal of OR based grants from node access queries.
CON
- Requires rewriting the module's main functions.
- Requires implementing and debugging hook_db_rewrite_sql().
Looking for feedback, especially code-level feedback.
| Comment | File | Size | Author |
|---|---|---|---|
| #15 | multiple_node_access.patch | 5.98 KB | agentrickard |
| #12 | node_access.patch | 6.06 KB | agentrickard |
Comments
Comment #1
agentrickardThe Nodeaccess module does something similar, I believe.
Comment #2
agentrickardHere's the problem in practice. With OG enabled, the following node_access query is run:
The domain module queries really need to be AND queries here, since the node should be viewable only if both OG and Domain Access approve the request.
The only exception to this rule is the domain_editor realm, which functions correctly:
This grant should be an OR grant, as any editor role that gives you access should be respected.
Comment #3
agentrickardTo make this happen, we would need to hijack the node_access function a little.
http://api.drupal.org/api/function/node_access/5
node_access does not use db_rewrite_sql(), and the grant OR logic is hard coded in.
However, this clause would let us rewrite the rules.
In domain_access($op, $node), we would replicate most of the lower portion of node_access, but rewrite the queries so that, if domain realms were involved, they became AND.
Alternately, we could choose to implement hook_access() just to check the DA rules. If DA returns TRUE, we might actually return NULL, which would let normal node access rules apply. If DA returned FALSE, then we would return FALSE and end the request.
Comment #4
agentrickardI think we have to move in this direction. See http://drupal.org/node/191587 for example.
And this gives us the option of configuring DA as an "AND" or "OR" check for working with other access control modules.
Note: on certain paths, the view check is always TRUE -- e.g. search, mysite/UID/view, user/UID/track -- see http://drupal.org/node/189797#comment-626343. Though this would also be configurable.
Comment #5
agentrickardMore notes:
In all cases check if the rule is AND or OR?
Comment #6
agentrickard^%$@!
This clause in node_access ONLY works for node type modules. The full clause is:
We're going to need to patch this function:
I don't like it, but there it is.
Comment #7
agentrickardAfter thinking about this and studying OG, I think this is the wrong direction.
The correct path is to patch the node access behavior in the function, rewriting this part of the node_access function:
Introduce a hook_access_logic that allows the AND and OR logic here to be specified on a per-module basis.
Then implement this hook in Domain Access and submit as a patch for Drupal 7.
Comment #8
agentrickardOf course we still have to deal with the $node_status issue mentioned in http://drupal.org/node/191587.
So I suspect we have to do two things:
- Insert a statement that allows non-node modules to rewrite access rules.
- Make the node access table query more flexible.
Comment #9
moshe weitzman commentedi agree that a core patch is needed to do what you want here. and yes, your needs are reasonable and generic. i don't really understand the hook you are proposing. if it isn't too much trouble, perhaps write the patch and submit here. and consider filing the feature request against core.
Comment #10
agentrickardThat's the plan.
hook_access_logic() will make more sense when I write the handler inside of node_access() which processes the hook.
I'll write it up and submit against 7.x
Comment #11
agentrickardWell, it turns out that this can be accomplished.....
But it requires SUBSELECT statements -- which requires MySQL 4.1+ or PgSQL 7.x+ -- and it may not work for more than two access control modules at a time....
Comment #12
agentrickardOK. I found the answer -- and the reason that Drupal < 6 doesn't work this way.
You must use subqueries to properly AND the logic together.
Attached is an experimental patch for Drupal 5. It changes the node_access logic to use AND syntax. It should work for multiple node access modules.
Some notes:
- WILL NOT WORK on MySQL < 4.1
- Should be fine on all pgSQL.
- Introduces a change to hook_node_access_grants. In addition to passing an array of grant ids, three new optional items may be included in the array:
- $grants['group'] = 'NAME_OF_GROUP';
- $grants['required'] = TRUE / FALSE;
- $grants['check'] = TRUE / FALSE; -- Allows node access checks to be run for unpublished nodes. This is a use-case specific to the Domain Access workflow.
The behavior of this patch is as follows:
IF
- No 'group' elements or 'required' elements are set, all grants are OR linked together. This is the current node access behavior.
- For each unique 'group' element present, a new subquery is AND linked to the main query, with each grant in the group linked together as an OR clause.
- For each 'required' element present, a new subquery is AND linked to the main query.
Sample queries -- with OG and Domain Access --
Next steps:
-- Port the patch to Drupal 6 and file as feature for Drupal 7.
-- Document the API changes.
-- Testing!
Comment #13
moshe weitzman commentedAt first glance, this looks like a terrific solution. I'm very curious about benchmarks. If you can do the benchmarks, I'll enhance the devel_generate module so that its generated nodes can optionally become part of groups.
Comment #14
agentrickardMoshe-
No official benchmark tests yet, but Devel module does not flag any of these queries as 'slow' (i.e. > 5 ms).
I think I'm going to pull the 'required' element out, since I think it is redundant. If developers want to make something required, it should be its own group.
Note, btw, that this can be implemented without any changes to OG.
Comment #15
agentrickardRequired has been removed as a flag. The change now is the addition of 'group' and 'check' to the hook_node_grants() array.
This version of the patch has been committed to HEAD.
Comment #16
moshe weitzman commentedi like the simplification to remove required. i do think this is core worthy. we should benchmark the subquery but since it is new functionality, there is no real comparison. also, needs to be verified to work on postgres.
thanks ken.
Comment #17
agentrickardmoshe-
The subqueries posted above have been tested on pgSQL -- but only as isolated queries, not in a Drupal context.
The other question is: how does this approach compare to http://drupal.org/node/122173
Comment #18
moshe weitzman commentedthere have been many attempts at nodeapi('access') but they ultimately fail because they do nothing to protect access for node listings. we need to use pure SQL to select al lthe nodes for the home page or group page or whatever so the pager works. and that rules out running php on each node. the solution proposed here is great, independant of what happens in that issue.
Comment #19
agentrickardI actually think we may need both. I can see additional use-cases for nodeapi('access') and started down that path before settling on this (as the above record shows).
But I think sub-selects and revamping hook_node_grants() is the best path.
Comment #20
agentrickardThis has been submitted as a core patch here: http://drupal.org/node/196922
In porting this for Drupal 7.x, I found this bug
Comment #21
agentrickardBugfix committed to HEAD.