It is my understanding that with the node access patch supplied with your module, and (I suppose) some patching to Taxonomy Access Control and Organic Group modules, we can effectively get these two modules working together on the access grants level.
That is, if a node is created that has both taxonomy and belongs to a group, a user can NOT access it unless he has grants for BOTH the taxonomy and the group. Right now, the behaviour is that a user can access the node if he has EITHER a grant for the taxonomy OR a grant for the group.
I'm writing to see if you can get me started in the right direction on this. I suppose step one is to apply the patch. But, once done, what do I need to do with TAC and OG so that they work together as I've described above?
I know you've spent a LOT of time and effort explaining this patch and how it works and why it's the best solution to this problem. I tend to agree with you, but just have not figured out specifically what needs to be done in order to do it.
Thanks for any help in this.
| Comment | File | Size | Author |
|---|---|---|---|
| #25 | new_multiple.patch | 6.22 KB | agentrickard |
| #10 | GroupMemberStoryNodeAccess.jpg | 38.87 KB | somebodysysop |
Comments
Comment #1
agentrickardOK. The key here is that we add a 'groups' element to the array returned by hook_node_grants().
For example, OG normally returns the following in response to that hook:
What happens with the patch enabled is that all elements returned by hook_node_grants() that do not have a declared 'group' will by placed into the default 'all' group. This is the behavior as it stands now. All grants assigned to a common group will be placed within the same clause and chained together using OR logic.
To enable AND logic for TAC, you would simply do the following:
This will place the TAC logic in a separate group, allowing the AND grants to function.
Doing so will give you:
IF (all OR og) AND (tac)Instead of:
IF (all OR og OR tac)If you look at the logic of http://therickards.com/api/function/domain_node_grants/Domain, you will see that there is an administrative setting to control the AND/OR behavior of DA. This is recommended.
Since DA actually writes two grants, its logic ends up like so:
IF (all OR og) AND (domain_site OR domain_id)Comment #2
somebodysysop commentedGreat. Thanks for the quick response. I think I get this. But, one dumb question: Do I need the DA module installed for this to work, or only the patch?
That is, if all I want is this node grant functionality:
IF (all OR og) AND (tac)Can I just install the patch and modify TAC_node_grants? Or, do I need to install DA and do some configurations, even if I don't need domain access?
Comment #3
agentrickardJust the patch. DA is not required.
However, if you add the 'group' element to the array _without_ the patch, it will throw an error. My advice is to wrap that group logic in a settings check.
For DA, I do two things:
-- Set the variable default to FALSE == do not include a 'group' element.
-- Check on the configuration page if multiple node_access modules are installed.
---- IF the above is TRUE, allow the AND logic to be enabled.
Then when I run hook_node_grants, I check the variable before setting the 'group' element.
Comment #4
agentrickardSee also http://drupal.org/node/241189 for a note about OG permissions and this patch. The problem would occur with TAC as well, since OG does not write its grants in some cases.
Comment #5
somebodysysop commentedOK. started with relatively clean 5.7 site.
Installed latest stable 5.x versions of OG and Taxonomy_Access.
Verified that OG and TAC were working as expected. Created a vocabulary term and assigned it to a node within a group. As expected, users can access node if they belong to role permitted by TAC, in spite of not belonging to group.
Downloaded latest Domain Access module.
Applied multiple_node_access.patch to node.module.
Modified TAC as described above:
Went to Admin->Content Management->Post Settings->Rebuild Permissions
On attempting to access the node which I assigned a term, get this error:
Comment #6
agentrickardTake that one-line IF statement out so the code is easier to read, please.
You should end up returning something like so:
The 'group' is a keyed element in the main grants array.
Comment #7
somebodysysop commentedSorry, but I'm trying to get up to speed on this whole node grants thing as I go. Is this ok?
With this, I no longer get the error, but...
I created a group. I created a node in the group and made it private to the group. I then created a vocabulary term and using TAC, made it accessible only if a user belongs to a particular role. I then gave the node in the group this term.
So, theoretically, a user who belongs to the group should NOT be able to see the node unless he belongs to the correct role. This should be the (all or og) AND (tac) logic.
What is happening is that a user who belongs to the group CAN see the node.
Any ideas?
Comment #8
somebodysysop commentedI'll try to explain this more in detail to see if it helps.
I created a group called "Test Group 02".
I created a vocabulary called "Test Access".
I created a role called "GroupMember".
Created a new Test Access term: "Group Member Access". Went to Admin->User Management->Taxonomy Access: Permissions and made sure that only GroupMember role has access to Group Member Access term. Made sure that "anonymous" and "authenticated" roles do NOT have access to Group Member Access term.
Went back to Test Group 02 and created a new node: Group Member Story. This node is:
* Private to Test Group 02 (not "Public")
* Assigned the Group Member Access term.
The behaviour that we want is that a user who is a member of Test Group 02 but does NOT have the GroupMember role should NOT see the Group Member Story (TAC and OG working together).
What is actually happening is that the user who is a member of Test Group 02 CAN see the Group Member Story node.
This is what is in my node_access table for Group Member Story (NodeID = 7):
I was assuming that I would get the AND logic with respect to the multiple_node_patch and therefore the user without the term_access grant would be denied access. As it stands, this user is granted access.
Comment #9
agentrickardThe easiest way to debug this is to install the Devel module. Turn on Devel Node Access and query logging.
You should see some node_access information and queries. We can use those to debug.
I'm on the road right now, or I would test this as well. I appreciate that you are keeping with it.
Remember, too, that users with 'administer nodes' are exempt from node access rules.
Comment #10
somebodysysop commentedOK, installed devel module. As authenticated non-admin user who does NOT have GroupMember role but belongs to Test Group 02, I accessed the Group Member Story node.
nid 4 = Test Group 02
nid 7 = Group Member Story node (that should not be seen)
rid (roleID) 3 = GroupMember (role required to see Group Member Story)
Test Access vocabulary ID = 1
Group Member Access term ID = 2
The node_access queries:
Don't see "term_access" anywhere except here:
Attached is screenshot of node_access entries.
Hope this helps.
Comment #11
agentrickardThe queries above suggest that TAC is not returning any grants or that the multiple_node_access patch is not installed.
If taxonomy_access is using its own db_rewrite_sql() hook, then the patch will not have any effect.
Comment #12
somebodysysop commentedWith respect to listing, this is true. But, with respect to "View", this would be handled by node_access.
I applied the patch to node.module version 5.7. Does this look correct?
Comment #13
agentrickardYes. That is the correct code after the patch. Let me take a look at the code.
Comment #14
agentrickardTry this:
Returns the following queries for an anonymous user:
Comment #15
somebodysysop commentedI think we're really close. I believe there may be a slight problem with your multinode_access_patch code when it comes to TAC. Perhaps you may know how to fix it, if in fact, what I am suggesting is a problem.
As I explain in the following post, I have been able to achieve most of the behaviour I'm seeking. I ran into a problem, however: In Test Group 02, I created a node that I assigned the Group Member Access term. I have a user who is a member of Test Group 02 and has the GroupMember role, which means he should be able to see this node. He cannot.
As stated earlier, this is what is in my node_access table for Group Member Story (NodeID = 7):
The user attempting to access this node has RoleIDs (rid) 3 and 4, in addition to 2 (authenticated) The node_access query I see for this user when trying to access this node (7) is:
This results in 0.
What it should say is:
This results in 1, which would be correct.
This user has 3 roles (2 = authenticated, 3 = GroupMember and 4 = Devel). However, it seems (in the case of TAC) that the multinode_access_patch is consistently creating a query for just the last role created.
What do you think?
Comment #16
somebodysysop commentedOK, I worked some more on this. Let me say, first off, that your code IS working for the most part. There is a problem I think we can fix, and I re-edited my previous post to explain it.
However, for the benefit of those who follow behind us on this, there some some VERY important things you should know.
The following assumes a site where a) TAC and OG are both in use; b) there are nodes created which belong to groups but are "public" (i.e., viewable by anonymous users); c) there are nodes created which do have taxonomy restrictions; d) the taxonomy restrictions are to be respected even when the node belongs to a group (i.e., users must have both the appropriate TAC AND OG access grants to view such nodes).
1. In Taxonomy Access: Permissions, you must set "Uncategorized nodes" to "View" for EVERY role you created.
Normally, if you set "Uncategorized nodes" to "View" for just anonymous and authenticated users, that does the trick. But, with the way the multinode_access_patch works, it is now necessary to make this setting for EVERY role on your site.
I created a role on my site called Devel so that my test user could see the results from the devel.module. Even though in TAC: Permissions I set anonymous and authenticated users to be able to view "Uncategorized nodes" this user, surprisingly, could not see any nodes. When I went back to TAC: Permissions and allowed the Devel role to see "Uncategorized nodes", my test user was now able to see what he was supposed to see -- exceot for Public access stuff, which is explained next.
2. Once the "Uncategorized nodes" are set to "View" for ALL nodes, your anonymous and authenticated users can now see OG content that is flagged "Public". However, what about TAC content that you wish to be publically available for viewing?
If you create a vocabulary for a node that has a term that should be available to ALL users, you must go into TAC: Permissions and set that term for "View" and "List" for EVERY role on your site.
Yes, I understand that you should only have to set Public access terms in the anonymous and authenticated roles. What I'm telling you is that to get the expected behaviour (everyone can see the node) then you must basically set it public for EVERY role.
Comment #17
somebodysysop commentedI have verified that either because of the way the patch is coded, or the way taxonomy_access_node_grants is coded, node_access is NOT receiving all the roleIDs of a user.
My test user had two roles outside of authenticated: RoleID 3 (GroupMember) and RoleID 4 (Devel). Every time the test user tries to access a node that he should have access to because of RoleID 3, he is denied access. In the node_access query I see:
(realm = 'term_access' AND gid = 4).I removed RoleID 4 from the user and Voila, he can now see the node. In the node_access query I see:
(realm = 'term_access' AND gid = 3).So, how do we get this code to recognize ALL the RoleIDs a user has?
Comment #18
agentrickardThe line that causes the problem is this one:
I have trouble reading that syntax. I believe that what Drupal's hook_node_access_records is expecting is:
<?php
$grants['term_access'][] == // role 1;
$grants['term_access'][] == // role 2;
$grants['term_access'][] == // role 3;
$grants['term_access']['group'] == 'tac';
?
Comment #19
somebodysysop commentedOK, I created a little test. I made this change:
Then created this test code to see what is actually returned:
This is what I got back:
When I attempted to access the node in question (still using this this test taxonomy_access_node_grants()), I got access denied. Predictably, the node access query:
Note that roleID 5 is the last roleID in the array.
I went back to the original taxonomy_access_node_grants() to see what it was returning:
I then changed taxonomy_access_node_grants() back to the code I've been using for the multinode_access_patch:
This is is using the line you say is causing the problem:
If this is NOT what hook_node_grants is supposed to return, then we need to know what it should return.
If this IS what hook_node_grants is supposed to return, then I think we need to look at how the multinode_access_patch is processing this array. I've been trying to figure that out, but just don't know enough about your code and access grants in general (apparently) to tell.
Does this help any? It looks like either the multinode_access_patch code needs to be changed to identify multiple rids from taxonomy_access, or the taxonomy_access_node_grants code needs to be changed so that the patch processes it correctly. One or the other, looks like we're thisclose to making it work.
Comment #20
agentrickardYes. This helps. I just need to look at what happens when DA returns multiple domain_id grants.
With the patch,
node_access_grants_sql()should split these into separate OR clauses within the subselect.Look at the code after the lines:
Comment #21
somebodysysop commentedOK, looked even more deeply. Our problem is here:
The $rules value contains all the taxonomy access rids for the user.
However, the resulting $grants value contains only the last one.
I actually printed out the $gid as the above code executed, and the TAC rids are there, but only the last one is inserted into the $grants table, and thus, the $grants_sql:
That makes sense since in this particular foreach clause,
$grants[$group][$realm]NEVER changes. Again, it is my lack of knowledge about the grant table that prevents me from determing how this should be changed, but hopefully you can see it immediately.Comment #22
somebodysysop commentedBy Jove, I think I've got it. Below is test code I created to simulate node_access_grants_sql().
I basically added an additional array element to $grants array so that multiple gids for the same realm can be accomodated. Please check it out. Thanks!
I have modified my node_access_grants_sql() with the changes identified above and it appears to be working as I would anticipate: Allowing TAC and OG to work together in concert.
Comment #23
agentrickardI see what you're doing. I'm really going to need to spend some time digging into this code snippet, probably this weekend.
Comment #24
somebodysysop commentedOK. Here is the code change that I'm actually testing now. So far, so good. It appears to be working for the scenarios I have earlier described. Continuing to test and will report results.
If you could test to make sure this doesn't adversely affect multinode_access with DA, that would be great.
Comment #25
agentrickardMan, credit where credit is due. That was a nice catch. In the DA world, we never pass an array of grants for a single realm, so I never tested that case.
Take a look and see if this behaves as expected.
Comment #26
somebodysysop commentedThanks for the very prompt responses. Applied patch. Appears to be working. Doing some tests. Will report back.
Again, thanks for the help in figuring this one out. I've been trying to get an elegant solution to TAC/OG cooperation for over a year, and this just might finally do it.
Comment #27
agentrickardBe sure to note that over at http://drupal.org/node/196922
Also be aware of http://drupal.org/node/241189 -- with this patch, it becomes essential that all node access modules write access rules for all nodes.
Comment #28
agentrickardAdded to 5.x.1.4 and 6.x.1.0-beta2
Comment #29
Anonymous (not verified) commentedAutomatically closed -- issue fixed for two weeks with no activity.