I'm not sure if you realize this or not, ... is precisely what OG User Roles does right now.
Yeah, I was just offering a possible alternate route. The taxonomy_fields module doesn't add terms to nodes, so they aren't tags. So there isn't anything to click on for the user, and they can't do term searches for those terms. There's a disconnect from the normal taxonomy functionality that I'll be able to use in the showing/hiding of fields. The user doesn't even need to be aware that the vocabulary exists.
Where you say:
Your cck scenario would work now, but you'd need to have some way to restrict the term access to just within the group, otherwise, non-group users who somehow have access to the vocabulary term would also be able to access the nodes.
Because of the disconnect, I don't think access to the vocabulary term applies. Because of this, I think that I can apply a term to one node (not tag it) and another (still not tagging) and then compare the two to determine access to the first. All of this is behind the scenes. Users should be unaware and not have access to this taxonomy. The taxonomy should be completely generated programmatically as groups and their nodes are added/updated/deleted/etc.
In doing it this way, I'm trying to think of whether TAC would work along side, or get in the way. Let me see if I understand TAC. If a term is assigned (tagged) to a node, access is granted. This is regardless of whether access has already been denied by another module. Is this correct? Well, then, what if TAC were modified to check for both visible (tagged) terms and these cck-style taxonomy_fields terms, all in one module? It seems that TAC could easily collect permissions based on both the visible and invisible terms, AND them together and pop out a result. The only difference between these two kinds of taxonomy is the use of the term_node table. Tagging applies terms to this table. The taxonomy_fields version doesn't, but applies it to a cck table.
Is that more clear? I think I understand your problem a little better. Does this expansion of my idea present any possibilities?
Comments
Comment #1
rconstantine commentedI think I'm struggling to be clear in my description.
I presume that TAC uses the term_node table to determine access. Is that correct?
cck_taxonomy_fields (I thought it was taxonomy_fields, but got that wrong) implements an association of terms to nodes without using the term_node table. Rather, it uses a cck content type table. So in effect, these terms are hidden to TAC so far as I can tell.
So - if each node in an OG had one of these hidden associations to a term, one would simply have to check for this term to know whether to grant access to the node. And since the vocabulary could mirror the group names, it could be used to not just grant access to nodes, but to roles as well. The roles side could check the group or group context itself. The node side could check the hidden term. Or the roles side could check the hidden term instead. This would essentially be a roles-by-term situation, not a roles-by-group situation, though the effect would be the same if the vocabulary were used exclusively as group names.
So in summary, I think that in using hidden terms with groups, roles and node access can both be granted/denied, rather than using separate role and node access.
If I were to start coding today, I would probably begin modifying the TAC module to see the hidden terms. I would then use what it sees to determine the current applicable roles. Since OG already manages node access for nodes in groups, I wouldn't have to use the node access side of TAC. TAC would ignore nodes without tags, right? However, if I'm using tags for nodes, then perhaps TAC could use what it now sees about the hidden terms. Since whatever vocabulary is used for tags is presumably different from the one used in the hidden way, users can be granted access to that term or vocabulary the normal way. Then, TAC can combine the results or the visible terms (tags) and hidden terms (group names). This would result in the following combinations of access:
If a user is not a member of a group: they will not have access to the hidden group term and so it won't matter if they have access to a tagging vocabulary; TAC will deny access.
If a user is a member of a group and a node is not tagged: they will have access to the hidden term and both see the node and be able to interact with it based on the roles associated with that hidden term (using a table similar to the one you now use)
If a user is a member of a group and a node is tagged: they will have access to the hidden term, and based on their access to the tag, either be granted or denied access to a node. If granted access, the hidden term will determine available roles.
This necessitates that non-group (public) posts have a site-wide hidden term applied to them so that site-wide roles can be assigned and applied.
Hopefully this time I'm being clear. Am I forgetting a situation given the above?
Comment #2
somebodysysop commentedSo far, so good. Vocabulary terms not associated with nodes. Certainly can't use TAC for that since it's whole mission in life is to create access "grants" for nodes.
And, here's where you're going to run into trouble. node_access() is used to determine access to nodes. By NOT associating the term to the node in term_node, you've got to find another way to check the permissions and associate the term with the node. How are you going to do that? You can't use hook_access because all node content types (you're using cck, right?) are handled by node_content_access(). So, can you describe exactly what mechanism you are going to use to check access for the node (in association with the term)?
Unfortunately, you can't always rely on group context being available (another hard lesson from OG User Roles).
Assigning access to roles by term is EXACTLY what TAC is designed to do -- but you just eliminated it's functionality by removing the terms from term_node (i.e., not tagging the the nodes with the terms).
Now, I believe I understand what you mean to do: Determine the access by giving the term the same name as the group the node is in, then figuring out what access the term grants, then giving that access to the node.
But what I don't understand is how you intend to do that? Using what hook(s) or function(s).
I understand that the cck_taxonomy_fields implements this functionality to determine what fields appear on a node form, but it does NOT use this functionality to determine access to the node -- which, if I understand you, is what you wish to do.
Yes, but again, how?
This sounds great. If the hidden terms are associated with the nodes by TAC, then they are, in fact, in the term_node table. If that's the case, what you are trying to do makes a lot more sense to me. However, you will still be faced with the problem of making sure the terms are associated with only a particular group (og_vocab?) and therefore cannot be used to give access to nodes to users who are not in the group.
Anyway, making more sense. Hope to see some coding on it soon.
Comment #3
rconstantine commentedVery good direct questions! It seems I finally was able to explain most of what I'm thinking. To answer you...
To check the hidden term, I figured I would write my own function that would be called sometime in the node building process before it is presented to the user, but after node_access has approved it. I figure such a module would only have to intervene if grants/permissions/etc were given, not if they were retained. So if the node_access module rejected the node operation, then this module would never even see it. But if TAC said it was okay to use the node, then I would look to see if the hidden term also allows access. I would probably use a linking table that contained IDs for users, terms, and groups. I thought I'd also have to include roles, but if TAC takes care of roles at its level, then I wouldn't have to.
Right. There are a few things that can be done about that. I had problems related to that in og_forum that I seem to have fixed. [I'm now a maintainer, but haven't updated it yet to reflect the current state of my code. See various posts in the issue queue as to why. The maintainer may be turning that module over to me shortly as I'm very interested in maintaining it and expanding it. My version allows the use of both site-wide and group forums without making a mess. But I digress!] Mostly I was able to interject calls to og_set_context (or whatever the function is called) all over the place just to make sure. Otherwise, checking the url helped. I take it you are still having issues after doing both of those things?
Well, I didn't understand that TAC was designed to assign roles. I thought it was only for node access in a less granular way. However, I think that writing a patch to TAC that could look for the hidden terms could be done and is better than patching anything from core. In the case of groups, you would need a visible vocab for roles, and a hidden vocab for straight access. Perhaps I'm still missing some understanding here.
Right. Well, I'm not sure myself, but like I said above, I think that after SOME permissions are granted that others can be determined autonomously from the established node_access system.
Right again. I simply had not considered implementing a separate term table like cck_taxonomy_fields does. So when I found it, I thought it was a good idea and of possible use since nothing is written to term_node which 'hides' terms from users' visibility and could be used strictly by the backend.
So from your latest comments, my revised view would be this:
Begin with one site-wide vocabulary for roles. Define them however you wish - such as Group admin, Group moderator, Group editor, or whatever. Give them the TAC roles that you want. I assume that Group admin will be tagging nodes with these vocab terms. [I still am not up to speed on TAC. Sorry.] TAC operates site-wide, right?
Then you add OG to the mix:
OG has groups defined. Users should be able to only see subscribed groups and their content. Roles go across groups and don't respect their boundaries. If a tag is in a group, TAC grants access regardless of whether the user is in the group.
So:
Define a second, site-wide vocab. This would be filled with the names of the groups. Every node in a group would be given a hidden tag of that group which is kept in a cck field table. Users would not have access to this table and a helper module would generate this vocab on the fly.
If OG denies access, but TAC gives access, how do we determine the correct result?:
Either-
A) Modify TAC to see this hidden vocab. I'm not sure whether to use the hidden terms in the same way as the tags are used, or to define a simple on/off to verify the results of the tag-related permissions. I lean toward this second approach. Namely, if the hidden vocab exists, check to see if there is an associated hidden term for the node. If no term exists, continue with normal TAC operation by checking the tags of the visible vocab. If a hidden term DOES exist, use the new 'hidden term checking function' which compares the term to the user's authorized OG group names in the OG tables. If the user is not authorized to view the OG group, skip the normal TAC operation and return FALSE. If the user is in the group, continue the normal TAC operations and return the normal TAC results.
B) Make a module that looks at the hidden term AFTER TAC is done, but before the node is presented to the user. Compare the hidden term to the user's subscriptions. Either proceed, or redirect (using drupal_goto, or drupal_denied).
C) This may be able to be implemented via a new TAC hook. So changes to TAC would just include the hook call (invoke_all) and then dumping out or continuing on based on the result. Since TAC isn't core, this could be implemented quickly. You would then do a separate module to do the actual checking of the user and their subscriptions.
I'm glad. I thought I was going in circles. As for code, I don't have anything yet. I have one or two modules ahead of it in line. When I found yours, I figured I'd use it instead of write my own. However, I still need to evaluate what you've got and see if it meets all of my needs or not. Plus, this has been an enlightening exchange and you've brought up several interesting issues. I'll now have to look at TAC and see if the above description is more of what I need or not.
Comment #4
rconstantine commentedStill haven't reviewed your module or started anything myself, but I had a thought. If one were to use TAC and hidden terms which mirror the OG names, then one would not even need to enable OG access control, would one? Then both the hidden and visible terms could be handled by TAC.
Comment #5
somebodysysop commentedHaving created an interface that allows TAC and OG to work together, and having worked on OG User Roles for over 9 months, not to mention a module I just created that maintains a truly "private" (only user who creates it can list/view it) node, I do know a little something about Drupal Access Control.
I'm no expert by any means, but if you intend to do anything with Access Control in Drupal, you are going to have to use one or more of the following hooks:
hook_access
hook_nodeapi
hook_node_grants
hook_node_access_records
hook_db_rewrite_sql
My goal is not to replace existing access control systems, but to make them work together without patches -- starting with TAC and OG.
Your "hidden" taxonomy fields concept sounds intriguing, but you have yet to demonstrate that it can actually work. And, even if it did, I don't know why we would want to replace OG's access control with another access control based upon taxonomy terms that must match OG groups.
My biggest problem with making TAC and OG work together was not with "create", "view", "update" or "delete" operations. The toughest problem was with "list" operations, which are controlled by hook_node grants and hook_db_rewrite_sql.
I've gotten some insight from a recent module I've worked on and intend to focus my attention on using these hooks to get rid of the patches.
You should really start coding your idea to see if it's actually going to fly.
Comment #6
somebodysysop commented