I worked out a solution to assigning roles to users based upon the group ID of the node to be accessed. A group user will only have this role's permissions while in the group. The user no longer has this particular role's permissions when he leaves the group. This is not how og_roles currently works, but it should (in my humble opinion).
Right now, when og_roles assigns a role to a user, that user has that role for any group or non-group content he accesses. Effectively, I need to have a different set of roles for every group I create. For example, if I assign a user the admin role in Group A, he now has the admin role for any content he accesses throughout Drupal.
What my modification does is allow you to have one set of roles for all groups, and group users will only have access to group content based upon the role(s) they are assigned for that group. For example, if I assign a user the admin role in Group A, he only has the admin role for content he access in Group A and NO WHERE ELSE -- unless I specifically assign him the admin role in another group.
My solution required:
* modification of the og_roles.module to *really* assign roles to users by group
* creation of a new table to tie roles to group ids
* modification of the user_access function in the user.module to use my new table for permissions checks
I've got it up and working. I can have an unlimited number of groups and use only 2 roles (member, admin). Every user can have a different role in different groups (instead of the same roles in all groups).
I suppose I could have created my own module, but I'd like to see if this could be incorporated into the og suite of modules. Also, I need someone more advanced than me to figure out how to implement this module without directly modifying the user.module.
I've attached here the new module I created called og_user_groups.module.
Here is the new table I created for use in og_user_groups:
-- --------------------------------------------------------
--
-- Table structure for table `og_users_roles`
--
CREATE TABLE `og_users_roles` (
`uid` int(10) unsigned NOT NULL default '0',
`rid` int(10) unsigned NOT NULL default '0',
`gid` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`uid`,`rid`,`gid`)
) DEFAULT CHARSET=utf8;
Here is the modified user.module code:
function user_access($string, $account = NULL) {
global $user;
static $perm = array();
if (is_null($account)) {
$account = $user;
}
// User #1 has all privileges:
if ($account->uid == 1) {
return TRUE;
}
// To reduce the number of SQL queries, we cache the user's permissions
// in a static variable.
if (!isset($perm[$account->uid])) {
//
// Modified this to call user_all_roles();
// This is the only modification to user_access() function;
//
// $result = db_query("SELECT DISTINCT(p.perm) FROM {role} r INNER JOIN {permission} p ON p.rid = r.rid WHERE r.rid IN (%s)", implode(',', array_keys($account->roles)));
$result = db_query("SELECT DISTINCT(p.perm) FROM {role} r INNER JOIN {permission} p ON p.rid = r.rid WHERE r.rid IN (%s)", implode(',', user_all_roles($account)));
//
$perm[$account->uid] = '';
while ($row = db_fetch_object($result)) {
$perm[$account->uid] .= "$row->perm, ";
}
}
if (isset($perm[$account->uid])) {
return strpos($perm[$account->uid], "$string, ") !== FALSE;
}
return FALSE;
}
//
// This function takes the global $user (or $account) value and returns a list
// of group and non-group roles for this user
//
function user_all_roles($user) {
// This will be the process to get BOTH the group and non-group roles for a user
$uid = $user->uid;
$gid = 0;
$nodeID = 0;
//
// Don't want to take a chance -- want to know exactly what the url is
// before we try to determine the nodeID
//
$uri_request_id = $_SERVER['REQUEST_URI'];
$arg = explode("/", $uri_request_id);
$ogroles = array();
$x1 = 0;
//
// This will by default add the anonymous user
//
$ogroles[0] = 0;
$x1 = 1;
//
// We try to get the groupID this way first
//
$group_node = og_get_group_context();
$gid02 = $group_node->nid;
$gid = $gid02;
if ($gid02 === null) $gid = 0;
//
// If the above doesn't get the groupID, then we start trying stuff
//
if ($gid == 0) {
// http://exampls.com/node/79
if (arg(0) == 'node' && is_numeric(arg(1)) && is_null(arg(2))) {
$nodeID = (int)arg(1);
$gid = getgid($nodeID, $uid);
}
// http://example.com/node/79/edit
// http://example.com/node/79/outline
// http://example.com/node/79/track
if (arg(0) == 'node' && is_numeric(arg(1)) && (arg(2) == 'edit' || arg(2) == 'outline' || arg(2) == 'track' ) ) {
$nodeID = (int)arg(1);
$gid = getgid($nodeID, $uid);
}
// Here we get the gid directly
//
// http://example.com/og/users/72
// http://example.com/og/manage/72
if (arg(0) == 'og' && is_numeric(arg(2)) && is_null(arg(3))) {
$gid = (int)arg(2);
}
// og_calendar
//
// http://example.com/og_calendar/72
if (arg(0) == 'og_calendar' && is_numeric(arg(1)) && is_null(arg(2))) {
$gid = (int)arg(1);
}
// og_forum
// 0 1 2 3
// http://example.com/og_forum/39/72?edit[og_groups][]=72
if ($arg[1] == 'og_forum' && strpos($arg[3], 'og_groups') !== false && (!is_null($arg[3])) ) {
$subsections = explode("=", $arg[3]);
$gid = (int)$subsections[1];
}
// og create nodes
// 0 1 2 3
// http://example.com/node/add/forum?edit[og_groups][]=72
// http://example.com/node/add/simplenews?edit[og_groups][]=72
// http://example.com/node/add/webform?edit[og_groups][]=72
// http://example.com/node/add/video?edit[og_groups][]=72
// http://example.com/node/add/page?edit[og_groups][]=72
// http://example.com/node/add/blog?edit[og_groups][]=72
// http://example.com/node/add/event?edit[og_groups][]=72
// http://example.com/node/add/poll?edit[og_groups][]=72
if ($arg[1] == 'node' && strpos($arg[3], 'og_groups') !== false && (!is_null($arg[3])) ) {
$subsections = explode("=", $arg[3]);
$gid = (int)$subsections[1];
}
} // end $gid if
//
// Now, using $uid and $gid we find out what roles this user has in this group;
//
//
$results = db_query('SELECT role.rid FROM role INNER JOIN og_users_roles ON role.rid = og_users_roles.rid WHERE og_users_roles.uid = ' . $uid . ' AND og_users_roles.gid = ' . $gid );
while ( $row = db_fetch_array($results) ) {
$ogroles[$x1] = $row["rid"];
$x1++;
}
//
// First, we need to create an array of the $user->role keys.
// These are the non-group roles that this user has already.
//
$temp = implode(", ", array_keys($user->roles));
$c = array();
$c = explode(", ", $temp);
//
// Next, we add the $user->roles array to the $ogroles array
//
$d = array();
$d = array_merge($c, $ogroles);
return $d;
} // end user_all_roles()
function getgid($nodeID, $uid) {
// This will return a $gid based upon the $nodeID and $uid supplied
$gid = 0;
$result = db_query("select node_access.gid from node_access INNER JOIN og_uid ON node_access.gid = og_uid.nid WHERE node_access.nid = $nodeID AND og_uid.uid = $uid");
while($t = db_fetch_object($result)) {
$gid = $t->gid;
}
return $gid;
} // end getgid()
Thanks!
| Comment | File | Size | Author |
|---|---|---|---|
| #69 | tacScreen.gif | 21.74 KB | somebodysysop |
| #57 | og_user_roles.module.db-prefix-fix.txt | 37.29 KB | bibo |
| #56 | README_14.txt | 6.42 KB | somebodysysop |
| #18 | user.module.4.7.5.patch.txt | 10.97 KB | somebodysysop |
| #15 | user.module.patch_9.txt | 9.11 KB | somebodysysop |
Comments
Comment #1
webchickThanks!
Could you also create a patch between your version of user.module and the one you started with?
Comment #2
somebodysysop commentedYes, if someone will direct me to how I can create a patch. I haven't a clue.
Comment #3
vm commentedHOW TO: Create a patch http://drupal.org/node/323
Comment #4
somebodysysop commentedHere's the patch. Please keep in mind the following:
1. This patch is for the user.module for version 4.7
2. The permissions will work only for domains like this: www.domain.com and NOT like this: www.domain.com/folder
3. The table og_users_roles MUST already exist in your Drupal database.
4. Don't forget to that og_user_roles.module must be installed and used to assign roles to users by group. Right now, I'm not sure if it will co-exist with og_roles.module.
That's all I can think of. I'm sure something else will come up, and if so, please post. Thanks!
Comment #5
davea commentedI am trying to understand what you have done here.
The challenge that I found with og is this:
You invite a friend. They are granted access and they can do anything within the group that anyone else can! I wanted to limit the people that were *invited* to have read only access. In other works they could be part of a group but only only view what the owner of the group wanted them to view.
Do your changes address this?
If not, no problem. I am just trying to wrap my brain around Drupal and its node access system.
Comment #6
somebodysysop commentedWell, what you are describing is handled by roles. Your role in a group may be as "contrib", that is, you can enter content in the group. You could invite your friend to join, and his role in this group would be "member", that is, he can access content but cannot enter any content in this group.
og_roles works fine with this. The problem is, if you have more than one group on your site, then your role is "contrib" for every group in the site. Same is true for your "member" friend.
The module I wrote addresses this weakness by limiting the permissions granted/denied by a role to a specific group. So, now, you can be "contrib" in group A, but "member" in group B. Same for your friend who will be "member" in the first group, but perhaps "contrib" in another.
If you don't care what roles users have in your groups, then the module I wrote doesn't affect you. If it's ok that users have the same roles in all groups, then it doesn't affect you. If you are willing to create different role sets for different groups, then what I wrote doesn't affect you.
Make sense now?
Also, what I wrote is not an official contribution nor is it sactioned anywhere by anyone. I wrote it to resolve the roles issue on my site, and put it up here for feedback. It is designed for folks who understand both Drupal and og very well, and know exactly the role structure they wish to have within groups.
Comment #7
bonobo commentedHello,
I was wondering about the status of this patch/feature -- I checked the cvs messages for mention of it, and didn't see anything.
This is functionality that would, IMO, extend og role nicely --
Thanks,
Bill
Comment #8
somebodysysop commentedI haven't followed up on it. The only thing I see to do is either make it a part of og_roles module, or create a new module myself. And, the module I create would simply be the og_roles module with my enhancements. I've never created a module for public use before, so you can imagine my hesitance.
Comment #9
dwees commentedI'd like to find a way of having a new group created by a user automatically assign the creator of the group all of the roles within the group. It appears now that if you create a group, you have to take the time to assign yourself the appropriate roles, which is a bit of a barrier for a new user. I'd rather that this was automatic. Any suggestions?
Dave
Comment #10
somebodysysop commentedNeed some help.
I along with another Drupal administrator have tested this module, and for the most part it is working. We have run into one problem. Here's the scenario:
There are two roles created: publisher and member. When a user is assigned to a group, he is assigned either the publisher or member role. Only publishers can create content.
The list of content items that the publisher can create shows up perfectly on the group menu (this means my user_access() modification is working). However, when the publisher clicks on a group menu create content link, he gets "Access Denied". I looked around and could not find anything wrong with the logic in my program. So, I wrote a little debug snippet to write out to a file the value that the user_access() function (that, is, "user_access($string_value)") receives.
My debug program is showing me the "administer cac_lite" permission. I have no idea why, but when I granted all authenticated users the "administer cac_lite" permission, the access denied problem goes away for user roles in groups. It works perfectly, giving and denying access to content based upon the role(s) assigned to a user in a specific group.
As if this wasn't bad enough, the other Drupal user who was experiencing the same problem ran my debug snippet, and it is the "maintain buddy list" permission showing up in his log. When he granted all authenticated the "maintain buddy list", then the problem went away for him as well. My modification works exactly as it is supposed to, granting permissions to users based upon roles that are restricted by group.
I asssume there is something about the way I modified user_access() that causes it to hang on these particular permissions.
I know this is pretty deep, but can someone give me a clue as to what the problem might be here? Resolve this, and this program is good to go. Thanks.
-ron
Comment #11
sksmithson commentedIt would be great if we could crack this as it really makes Organic Groups secure. The problem with vanilla OG is that someone with rights to create a story can create in ANY group they are a member. I want to have a group administrator who is able to create items for the group they are administrator for but NOT for another group they are simply a viewing member of.
Would be great if this was core to OG 5.0 and could also be resolved for 4.7!
Comment #12
Andrupal commentedI'm using the contributed code above that allows group-assigned roles only have those permissions within group content, and it's a major enhancement that I think would really improve the usefulness of the module, however like others I'm not thrilled at having to hack my user module...
I'd be very supportive of a solution to this issue that avoids a user.module modification, and that perhaps includes the functionality of the promote module, so that group managers may choose to automatically promote new subscribers to a given role, limited only to that group's content.
Comment #13
somebodysysop commentedAs the author of this modified code, I wholeheartedly agree. I did not want to modify the user.module. I posted a number of messages asking questions about how permissions and roles worked, but rarely received any answers.
So, I went about the task of trying to figure out how to accomplish this goal on my own. The key, as far as I could tell, was the user_roles table. Needed another table to define what roles a user would have in each group. And, finally, needed a way to grant permissions based upon roles in this table. The only way I saw (and see) to do this was in the user_access function in the user.module. Since there was no "hook", the module had to be modified directly.
So, if we could get Drupal to implement user_access as a "hooK', our "hacking core code" problem is solved.
And, by the way, I finally solved the last problem to my modification -- the one which was causing it to incorrectly identify permissions from the cache. Essentially, all I had to do was remove the "isset" test for the cache, and simply re-create it each time. Not efficient, but it does the trick. Since a user's permission can be different depending upon the content's group, what I now need is some way to tell user_access to only update the cache if the group has changed. For another day. Right now, however, the code is working perfectly.
That modification is attached.
If someone has a better idea or approach, I'm all ears. However, my code is working now for 4.7.
Comment #14
sanduhrsThis issue is very interesting.
Could you kindly provide patches, as it is much easier to follow your modifications.
Comment #15
somebodysysop commentedOK, this is the version of the user.module I modified (version 4.7):
Attached is the patch. Please note from #4:
Comment #16
somebodysysop commentedWhen a user attempts to create a new node:
http://drupalsite.com/node/add/flexinode-3?edit[og_groups][]=71
What permission function(s) are executed?
user_access?
node_access?
og_basic_access?
And, in which modules?
My user_access function is working correctly, but apparently when the above command is executed, some other permission checking is executed. If I could find out what, I could probably solve this for good.
Thanks so much for any assistance anyone can provide.
-ron
Comment #17
somebodysysop commentedOops. I accidently changed the titled of this thread. Sorry.
Comment #18
somebodysysop commentedI've not given up. Attached is my latest patch to the user.module. It is designed to be applied to the original Drupal 4.7.5 user.module. Same requirements for og_user_roles.module as defined at the top of this thread.
My modification is more or less working. The one problem we've ran into is on node creation, you sometimes get "user access denied" error if you have logged in previously using the same browser but with a different account. The user_access function I modified actually works every time, with the exception of this potential problem, and even this is only on node creation. The problem is resolved by clearing the cache and running cron.php.
The only symptom I've been able to find is that when the "access denied" error occurs, the user_access function is unable to read the default drupal "arg" values. In other words, I created a test to output to a test file the values that are in user_access each time it is called. When the program fails on node creation, it is always unable to read the value of "arg(0)". So, my educated guess is that the user_access function is losing the group or node context under this circumstance. If it loses the group context, then it can't very well determine the user's group role(s). Maybe someone will understand why this is happening.
At any rate, I put into the patch I have attached code to write to a test file called "user_test" the values that user_access receives each time it is called. This is purely for debugging purposes. The command to create the user_test file:
Finally, I came up with a way to assure that there is never a permissions issue with node creation using my modified module. I created code for my own "node/addform" node. All I did was:
1. Create a page node (all user roles should have access to it) with the following php code:
2. Created an alias for this new node called "node/addform". In other words, if the page node I created is "node/145", I create an alias to it called "node/addform".
3. Now, when I want to create group content, instead of this command:
I use this command:
So, if for whatever wacky reason, the "user_access" function loses the group context as a result of whatever permissions checks, my program is designed to still get it and verify the user's group role access. The result is that the permissions are checked correctly every time, regardless of how many times you log in and out as various users.
The og.module automatically creates the group node creation urls. If you are able to use my og_user_roles.module without incident, then use the default menus. If not, then you'll have to create your own custom menus for group content creation.
I think that's it for now.
Comment #19
somebodysysop commentedHere is my modified 'addform' code. I forgot to mention that you may need to modify the code for node types that aren't captured by it now. I created the code this way because I primarily use flexinode content types for my groups, but needless to say, your cases may differ.
Comment #20
Sean Buscay commentedHello.
Thank you for this modification to the OG Roles functionality.
The feature you added is exactly what I was looking for.
Does anyone know, is this likely to become its own module such as og_user_roles? Or will it be merged into og_roles?
As you mentioned in your posts, you were not sure how the two modules will play together.
I don't think they would really need to, in that probably one feature set or the other is needed. Really, I would think most might want the feature you added.
If you plan to keep them as separate modules for now, and you are looking to make sure the two do not conflict then:
Upon an brief look, I had a question about two small items:
1. On line 178 of the original code you posted, does this function name "function _user_roles" have the potential to conflict with the og_roles module? If so, perhaps it could be renamed, and then the reference to it on line 130 of your code, could be updated:
2. Does the form name need to be changed from ['user_roles'] to something else, or does the scope in which it is used, not affect the og_roles module?
Thanks again. I am hoping to see this feature added soon to OG for Drupal 5.0.
Comment #21
somebodysysop commentedYou are right. og_roles module isn't used at all.
og_user_roles is the new module name. Everything that was og_roles was changed to og_user_roles.
No conflict with user_roles() or _user_roles().
Comment #22
Sean Buscay commentedYou wouldn't happen to already have a version for 5.0?
Comment #23
somebodysysop commentedVersion 5.0? I barely got it working on 4.7!
Comment #24
Sean Buscay commentedLOL. Okay. Just thought I'd ask before I attempted something myself.
Thanks for all the info your thread and code has provided.
Best Regards
Comment #25
inforeto commentedsubscribing
Comment #26
wojtha commentedHi,
I'm new maintainer of the OG Roles module.
SomebodySysop very nice improvement! I've been also thinking about that. Are you going to run it as your own project? OG Roles is very simple but nice module and merging it with your request/project(? :-) ) to one module may be little contraproductive. Some reasons in few points:
1/ There is no problem in Drupal 5.0 with merging acces rules from many modules.
2/ OG Roles doesn't need own table, your OG User Roles does
3/ Merging to one may be complicated... many settings, IFs and so on
What do you think?
Comment #27
somebodysysop commentedI think what I need to do first is see if I can get it to work in 5.0. Who knows? Maybe it will be easier. If so, then I guess I'll go ahead and try to make it a separate project. You are right: It should not co-exist with the existing OG Roles, and it is too confusing to have both anyway.
Yes, it does need it's own table because that was the simplest way to get it to work with the user_access function (although I put all the code into the user.module, there is only really one line that needs to change). Also because the module creates a new paradigm for permissions (requiring that they be determined by both Role AND Group instead of Role alone). Doing this without a new table would require massive changes to the user_access function, and I simply wanted to stay away from that.
Anyway, I'm starting to familiarize myself with 5.0 now. If I can implement this in 5.0, I will. In any event, I agree that trying to merge with existing OG Roles is not a good idea.
Thanks for the feedback.
Comment #28
wojtha commented@SomebodySysop: Ok. If you will start it as your own project and want co-maintainer don't hesitate and contact me ;-) I'll need something similar like this in my next project, I think.
Comment #29
somebodysysop commentedI'm just about ready to go with this as a 5.x module, just have one problem that continues to haunt:
Further testing shows that the function is not losing the group context. That, surprisingly, is maintained. All other variable values as well, such as permissions, roles, etc... What's disappearing are the arg() values, and that is apparently a symptom of the problem in that it only happens when access is (incorrectly) denied.
Can anyone give me a clue as to why the user_access function would lose the arg() variables? I bring back the same table $user->roles does, only with any additional group roles.
Thanks for any clues.
Comment #30
knseibert commentedHi,
i would like to help. Unfortunately i could not find a cvs version of your module? Are the sources for version 5 available somewhere?
Comment #31
somebodysysop commentedI cannot tell you how much I would appreciate the help. I tried to attach the .gz file I created, but that type is not allowed here.
For the time being, I have uploaded it here: http://ftp.scbbs.com/pub/drupal/og_user_roles/og_user_roles-5.x-1.x-dev....
The first problem I ran into when I tried to install it is that the og_users_roles table wasn't automatically created. Don't know if I didn't create the .install file correctly.
Please let me know what you think of the README.txt and everything. It's my first time doing this so I'm a complete newbie. Also, if someone could give me some advice on beginning this as a project.
Please let me know if there are any questions you have!
Thanks!
Comment #32
tannerjfco commentedI think in order to start a module on drupal.org you have to apply for a cvs account:
http://drupal.org/cvs-account
Best of luck to you with this module, I'm really looking forward to it maturing!
Comment #33
fagodo you really need a change to user_access? isn't node_access sufficient?
Modules introduce new permission, which are usually use in a context that's most times isn't associated with any group.
The need for modifying node access is obvious, but this should be able to do with the node access system or? (hook_node_grants and so on).
Comment #34
somebodysysop commentedI want to say "yes", but that would be assuming I know everything there is to know about Drupal, and that is far from the truth. I don't know how you would make it work using node_access, particularly since:
a) node_access calls user_access
b) node_acess is not used for permisisons in node listing (node_db_rewrite_sql is)
With respect to node_grants, let's take the taxonomy_access_node_grant:
This function uses $user->roles. But, how does it get the additional role(s) this user may have in this particular group? We have to now modify this function as well.
However, by adding the appropriate roles to user_access, you get the correct grants when listing/creating/updating/modifying.
Of course, if I'm wrong, I'm more than happy to know where and how.
Comment #35
fagoI've also never worked with node_access so I can't help you much there. But of course you need to write your on hook implementation instead of hacking another one. I think the grants are collected and put in the node_access table so hook_rewrite_sql for nodes will make use of it. Node lists are respecting node access correctly!
Comment #36
ray007 commentedsubscribing
Comment #37
somebodysysop commentedModifying node grants seems to make sense, but remember that my paradigm is radically different from the existing Drupal permission schema. I'm not just giving a user a role, but giving the user a role within the group context that the user is currently in. In other words, if the Drupal permission schema is curently three dimensional, I'm adding a 4th dimension (time/space). Neither the node_access or term_access tables are currently designed to accomodate this additional restriction (you have a certain role, and therfore certain permissions, if you are in a certain group at the time you execute this function)
After exchanging notes on the developer list, I figured what I really need to do is propose a hook for user_access. What I found with my user_access modification is that it works practically everywhere EXCEPT node creation.
I actually modified node_db_rewrite_sql() (as a test) to respect the additonal roles provided by og user roles. No change. Remember the node_db_rewrite_sql() hook is primarily for node listing, not node creation.
My user_access modification works for listing/updating/deleting but not creating (at least default node creation using node/add).
I am able to create nodes with it by calling the node_add function directly. I created a node which contains php code that does a user_access permission check, and if the user has the "create" permission for the content type, it then executes node_add(content_type) to create the new content.
So, if user_access is returning the permissions, the question still remains: why does the default /node/add fail? That remains the last piece of the puzzle to resolve.
FYI, the code for that "content submission" node is below. I'm only using 3 document types with og user roles, so those are the only ones the code currently processes. I give the node the url path alias "node/addform", and construct the url like this:
Comment #38
fagohttp://api.drupal.org/api/5/function/hook_node_grants
node grants are not specific to user roles or terms. Og already does node access based on groups..
Comment #39
somebodysysop commentedReally appreciate the response. Got me to hoping that perhaps it might be the solution to my problem.
Remember the problem: User is given role by og user roles that allows him to create a content type, let's say "document" here. The "create document" link appears in his group menu. When he clicks on that link, he gets "access denied". The link is node/add/document?gids[]=29
My user_access modification has granted the user the "create document" permission in this group according to his role in this group.
So, user gets "access denied" message when attempting to create content that user_access grants him permission to create. If I am understanding you correctly, you are suggesting that this problem could be resolved by adding the necessary grants using the node_grants hook.
Below is the code which invokes the node_grant hooks in node_access:
Note the key phrase here:
Since the node_grants hook is only accessed here in node_access, and NOT for a create operation, theoretically, it would have no effect this particular case, even if I did use it. Or, am I missing something?
I hope so, because I would really like to find a solution to this. And, if there is a solution, what would the grant I need to add via a node_grant hook look like?
Comment #40
ray007 commentedI think the best way is to have an own path for adding nodes, i.e. og/node/add/ with independent access control.
And of course a special edit path like og/node/edit/ ...
In the callback function use
$output = drupal_get_form($type .'_node_form', $node);to get the right node edit form.fwiw, I agree that excluding op = 'create' in the node_access() function seems quite stupid, but we got to live with that for the time being ... and maybe there are reasons I'm not yet aware of for doing that?
Comment #41
somebodysysop commentedDon't have problem with node edit, just node create. Which is why I created my own content submission node (posted above).
In og I did this:
Needless to say, I'd like to figure out why node/add fails.
Also, I want to re-interate that individual calls to node_access() and user_access() by users in og user roles for content they should have access to actually succeed. It's just the node/add process that fails.
Comment #42
ray007 commentedI guess Content Type Administration by Organic Group would be nice to take into account if active ...
Comment #43
somebodysysop commentedMore than a couple times on this list and elsewhere I have asked for someone to please help me figure out what happens in the node/add process that would prevent my modification from working. Never, not once, have I ever received a response to that question. I guess it's because everyone else knew what I didn't: There is a debug module which will show you everything that a particular command is doing.
I've found it, and I think it's going to help me resolve my problem. I just wanted to share it with those of you who may never have heard of it (like me, until recently).
Devel: http://drupal.org/project/devel
A great module for Drupal developers to have.
Comment #44
benkewell commentedhello~ it's nice to find that someone is working on such a module as i really need that on a website =)
anyway, the file on ftp posted above (og_user_roles-5.x-1.x-dev.tar.gz) is corrupted (can't be extracted)
so could someone please kindly check and update that?
also i would like to know will there be any module release on the cvs for that in the future?
thx for u all =)
Comment #45
somebodysysop commentedNo CVS yet because still have the issue of user.module modification to resolve. I'm going to propose some sort of hook to add roles provided by module to those obtained in user_roles function. That would do the trick.
The latest og_use_roles module is here:
http://ftp.scbbs.com/pub/drupal/og_user_roles/
I've tested it and it appears to be working fine.
Please let me know any comments you may have. Thanks.
Comment #46
p_palmer commentedHi,
i'm confused as to where to download the 4.7.x version of og_user_roles.module IIRC 4.7.x is where this development began.
I enabled og, og_forum, and og_user_roles on a 4.7.6 install. The 4.7.5 user.module patch applies fine with 4.7.6 (bug fix release), however, the og_user_roles is 5.x ? tried to run it anyway and get errors...
navigating to .../admin/og/og_user_roles
navigating to .../admin/settings/og_user_roles
Has anyone succesfully run this against 4.7.6??
I know there must be tweaks to this code, but unsure where, maybe the author could take a peek ;)
Many thanks in advance.
Comment #47
somebodysysop commentedFirst off, this is not an official project. The whole module depends upon a patch to core. I need to propose some sort of user_access hook for this module to work without any core modifications.
Secondly, I am not supporting the 4.7 version of this module. Yes, the original module was written in 4.7, but I was never successful in getting it to run without having to use an alternative method for creating group nodes. I have been successful in 5.x, so that's what I'm sticking with.
Sorry for the trouble.
Comment #48
chrisroditis commentedsomebodysysop, i am confident that your work in this module is of high value to people who utilize organic group structures in their websites. I was wondering how we can all help you find the user_access hook you are looking for. Perhaps raising the awareness of og devs towards your work would help?
Comment #49
somebodysysop commentedThe developer of og said he was not interested in "exotic" forms of access control like this. The current manager of og roles and I agreed that these are two totally different modules, and should not be combined. There have been offers of assistance, but the biggest help I need is in folks just using the module to find where the problems may be.
Outside of that, a little help with defining the hook proposal would be useful. Right now, the basic og user roles hook proposal is this:
a. We need a way for a module to add permissions to $perm[$account->uid] in this operation in the user_access function:
OR;
b. We need a way for a module to add roles for a user to the result of this operation anywhere it is called:
Either one of these would accomplish what we need, although I believe b. would be the most efficient way to handle it. The modification I have now actually replaces $user->roles in the user_access function.
Comment #50
somebodysysop commentedSubmitted proposal to add hook_roles feature to Drupal core here: http://drupal.org/node/143393
Comment #51
somebodysysop commentedI need some help. I have basically solved the problem of patching the core user.module for og_user_roles to work.
I was able to re-write the module to use the hook_user "load" operation to add the group roles to $user->roles when it is called in user_access. It's working. However, as I describe here: http://drupal.org/node/143393, I'm getting the same error message on group node creation that I got when I patched user_access: "Access denied".
So, what I really, really need now is to know what else, besides user_access (and $user->roles) would be used to determine a user's permissions on a group node creations such as:
http://www.mysite.com/node/add/link?gids[]=29
Something in the node.module, the og.module?
I solve this, and the module is good to go -- with no core hacking!
Comment #52
jonty_q commentedHey, sounds good!
Sorry I can't help.
Wonder how to get this question in front of those who would know the answer?? hmmm ...
Comment #53
somebodysysop commentedLooks like I've finally cracked this nut. I'll post notice when I've incorporated this modification into the distribution I've made available.
I had to do an end-around to do it, but I've finally come up with an implementation that doesn't require modifying other modules.
From the very beginning, the only circumstance in which my og user roles module failed was in node creation, specifically node/add/type?gids[]=gid. To solve this problem, I simply created code that would check the user access and call node_add directly:
This worked, but required that the user a) create a node, b) put this code in the node, c) rename the node to "addform", d) edit the og module to call "addform" instead of "node/add".
A lot to ask of a user, which is why I tried so mightily to figure out what the access problem was.
Someone on the development list once suggested using "hook_init". In seaching the Drupal site for ideas, I saw that someone had used hook_init to redirect url requests. So it hit me: Why not redirect node/add/type?gids[]=gid requests directly to my addform? But, instead of creating a separate node for addform, make it part of my module.
So, by using hook_menu to create the callback for "node/addform":
and, creating a re-direct in hook_init:
I was finally able to get "node/add" working for og user roles without patching any core modules (user.module OR node.module).
If anyone is still reading this, I have one small development question:
Since my addform code is now basically replacing node_access in this circumstance, how do I check the "create" permission on any content type (not just "node" content type) for any module without having to know them all in advance?
Thanks for all the help. Again, I'll post notice of the update once completed.
Comment #54
p_palmer commentedDoes this help?
http://api.drupal.org/api/5/function/node_content_access
Comment #55
somebodysysop commentedClose. That code checks for all "node" content types, but not all content types. However, that code is called in node_access by a module_invoke that is created from the results of node_get_types(). So, I re-worked that code to give me this:
I've got this working. So, now all I have to do is re-work the code for some other changes, run some final tests, and we're good to go.
Thanks!
Comment #56
somebodysysop commentedThe latest OG User Roles distribution is now available here: http://ftp.scbbs.com/pub/drupal/og_user_roles/
Version: 5.x-2.x-dev
README.txt is attached.
Please test out and let me know if you find any problems.
Thanks!
Comment #57
bibo commentedHi there SomebodySysop,
first of all I just wanna say: awesome work on this user roles module, it is exactly what I need for a big project that I will be working on this summer. Without this functionality I might just be crying in a corner ;) Actually, Im pretty new to drupal, but I love this system. Your dedication especially is very inspiring, hopefully you get a project site, core dev support and whatever you need up to get all up and running.
I couldnt find the official site/post for User Roles, only places like this (http://drupal.org/node/87679)
where i dl:ed the latest version (5.x-2.x-dev).. and this text apparently was too long for a private msg. So I'll just write here.... oh, uhm, to the point:
I hadn't installed any previous version, and I havent yet tried the OG/TAC-patches, just the normal OG user roles-module.
Seems like there were some bugs in the latest "og_user_roles.module"-file. I got sql-errors on most of my pages after installing it, and the reason was quite clear: its trying get/put data to/from tables that dont exist.. and seemed like my db-table prefix was missing. The install module created the tables with the correct prefix, but seems like the actual module has lots of lines where the prefix is ignored, and thus results in sql query syntax-errors.
I'm not even sure what db_query()-does, but seems that it changes all strings with {tablename} to {prefixtablename}, while doing other stuff. You must be aware of that since most of the queries had that format. However, some lines didnt, so I added the {}-to those lines... and after reinstalling the module, its fixed all my db-errors (or so it seems right now) :)
I havent tested the actual functionality just yet, but I wanted to inform you right away. This is what I changed (in "og_user_roles.module"):
Around L652:
L911
L954
L963:
These fixes are in also the attachment, where you can locate the changes by searching for "// FIXED TABLE PREFIX {} "
I might have missed something but Im not getting any errors atm. I suppose your sandbox/live site dont use table prefixes, so you never noticed these errors. Anyway, I hope this helps (if you didnt already know about this), and again thank you for this great module.
Comment #58
webchickI haven't used this module at all, but in glancing through at the code just posted:
No, no, NO!! *Never* put raw values into SQL strings. Use the escape mechanisms built into db_query:
$result = db_query("select {og_term}.nid from {og_term} INNER JOIN {og_uid} ON {og_term}.nid = {og_uid}.nid WHERE {og_term}.tid = $nodeID AND {og_uid}.uid = %d", $uid);
Otherwise, your code is vulnerable to SQL injection. See http://drupal.org/writing-secure-code.
Comment #59
bibo commentedThanks for the warning, but If you look closely, the only things I changed in the SQL was adding "{" and "}" around each tablename where they didnt exist. Afaik all it did was for drupal to check if it should put a table prefix (and maybe something else) in front of the table name. My installation produced errors because the queries didnt include my db-prefix, and just adding the tablename format to "{tablename}" for some lines fixed everything for me.
I dont see that making the code more unsecure. http://drupal.org/writing-secure-code is a good read, but in the example theyre using printf() for escaping $_GET (or $_POST/$_REQUEST-parameters), which is of course direct user input.
I'm not too familiar with drupal core code, but If I understood correctly, all the parameters like $uid have allready gone through some validation or conversion to numeric value, which poses no risk of sql-injection. Maybe some drupal expert can confirm this?.
Of course it's not a good thing to assume, but that's how all the other SQL-commands were build that I saw in the few modules I've examined. I would normally use mysql_real_escape_sting() for that. I just searched the API-site for the db_query()-function. ( http://api.drupal.org/api/5/function/db_query ). The function's doumentation also refers to securing user input, and does some other things like apparently pregreplace of {*}, and thus corrects the db prefixes, which is in the end the only difference to the other original code :p.
(Hope I don't sound too cocky..)
Comment #60
somebodysysop commentedThank you webchick and bibo. I have implemented both the table prefix and secure code changes you both recommended. I will post notice with the updated module has been uploaded. I appreciate very much your assistance in pointing out these issues!
Comment #61
somebodysysop commentedNew 5.x-2.x-dev distribution uploaded here: http://ftp.scbbs.com/pub/drupal/og_user_roles/
This has the changes discussed above, in addition to one major change: A "configure member roles" permission has been created. So, this permission must be given to any role allowed to use og user roles to give group members group roles. Before this change, you only had to be the group administrator to be able to assign group roles.
Thanks!
Comment #62
somebodysysop commentedFinally got my own project for this:
http://drupal.org/project/og_user_roles
All future distributions can be downloaded from here.
Thanks to all of you who stuck with it.
And, special thanks to the OG Roles maintainer for letting me continue this thread until I got OG User Roles working.
Comment #63
rconstantine commentedLooks like I'm late to the party. I'm the author of http://drupal.org/project/og_content_type_admin and had I found this sooner, I would have helped. In fact, this was the module I was going to write after completing one or two more modules I already have on my plate. I understand well your frustration in not getting help. I'd be willing to collaborate on any future developments.
I'll be giving this a thorough evaluation in the coming week or so. My question for you now is: are there any points to the module as it stands that you would have liked to do differently, or that you aren't quite satisfied with? If so, let me know what those points are and I'll take a particular look at them and see if I can't find a solution.
As the website I am creating will depend heavily on OG, I am creating and modifying a great number of modules to be better integrated with OG. I've found it's fairly easy to get SOMETHING to work, but it's the integration of several things that is difficult. Should your module not work with mine as they stand, you can expect to see patches from me in the near future.
Good job. Thanks for your hard work.
P.S. As you're still learning Drupal (as am I) I highly suggest going through all of the lullabot podcasts and the drupal-dojo screencasts. That's how I learned about the devel module and other aids, as well as more about the workings of Drupal. And the new book out by Matt Westgate is very good. It is well organized and covers all of the basics and more. There are some fine details missing, but is still handier to use than the drupal.org site for looking things up.
Comment #64
somebodysysop commentedThanks for the note.
For me, the next step for OG User Roles is to get TAC and OG working together without core hacks. I've got them working now, with half the access control code in OG User Roles, and the other half (mostly db_rewrite_sql mods) in patches to node, taxonomy_access and og.
Details here: http://groups.drupal.org/node/3700
The group is called "Access Control" here: http://groups.drupal.org/access-control
Any help would be highly appreciated.
Comment #65
rconstantine commentedI'm subscribing to the group. I know you've put a lot of work into this module. I'll have time to look at it over the course of the next week.
In thinking about how I would approach this problem, I actually thought about using a TAC-like approach in the first place. Let me explain (hang in there with me):
TAC (Taxonomy Access Control for viewers not familiar with the acronym) allows/denies access based on taxonomy terms. There is a CCK module that shows/hides fields based on taxonomy. This allows one node type to change based on the taxonomy terms assigned to it. You then have many content types from only creating one! I want to modify this so that as OGs are created, a vocabulary is setup which mirrors the OG names. So in effect, the 'page' content type could have dynamic fields based on which OG you're currently in. Very powerful stuff. Of course, viewing the content also would be restricted.
Likewise, this same vocabulary that is setup to mirror OG names could be used to grant/deny permissions. Do you follow what I'm saying? I think that this may somehow be a simpler approach, but that's easy to say since I'm not yet 'in the trenches'. What do you think?
Comment #66
rconstantine commentedIn rereading my post I think I was overly brief and unclear. The special OG-specific taxonomy would not be used as tags are - or would at least be invisible to the user. In terms of the access control via this taxonomy, I obviously haven't worked through all of the details, but thought that (since I'm going to use node profiles) the same terms (subscribed group names) could be assigned to users (and still hidden from them). Permissions would be listed in the taxonomy as well. These permission-terms would be assigned to the node profile and would be a secondary check after the regular roles/permissions are checked. For example:
[begin long-winded rambling]
Permissions: //regular permissions
PA, PB, PC
Roles: //regular roles
R1 = PA, PB
R2 = PA, PC
Groups: //regular groups
GA, GB
Users: //node profile-based users
U1, U2
Taxonomy: //regular vocabulary, (or one similar to cck_taxonomy?)
SW (site-wide)
GA
GA->R1
GA->R2
GB
GB->R1
GB->R2
Users are each subscribed to both groups.
Users' Site-wide Roles: //regular role assignments
U1 = R1, R2
U2 = R1, R2
You can see they both are assigned the same roles, but we want to limit them in the groups.
User Taxonomy Assignments:
U1 = GA, GA->R1, GB
U2 = GA, GA->R2, GB, GB->R1
So with this, the GA and GB term assignments can tell us that subterms are legitimate. User 1 belongs to both GA and GB. He also has the permission R1 for GA. User 2 also belongs to both GA and GB, but has R2 role in GA and R1 role in GB. Neither has site-wide (SW) use of these roles.
So rather than take the approach of finding ACCESS to a node or function in a given OG, we can first determine whether a user has access AT ALL to that kind of content, and then EXCLUDE and REDIRECT based on these secondary criteria.
But honestly, and let me repeat, I haven't had a chance to see how yours works and don't know whether my approach would work, though on the surface mine wouldn't have to modify any existing modules and would play nice with others.
[end long-winded rambling]
I think you mention elsewhere that permissions don't simply address node access, but views and other items as well and I'm not clear whether my approach would solve those problems.
Anyway, I just thought you might find this interesting and may even spark an idea or two.
See you around.
Comment #67
somebodysysop commentedI'm not sure if you realize this or not, but what you just described, particularly with respect to this:
is precisely what OG User Roles does right now. It restricts "permissions" based upon the role(s) a user has within a group. And, this is without any taxonomy vocabulary.
Now, when we add taxonomy to the mix, we can further refine access based upon "term_access" (list/view/create/update/delete), or what I refer to as "grants".
As far as I can see, your cck show/hide field mechanism should have no problem in this environment.
The problem is with access control. Currently, if you create a group node, and assign to it a vocabulary term, a user will be able to see the node if he either a) belongs to the group or b) does not belong to the group, but has access to the term. This is insane.
What we want is for the user to only have access to the node if he has BOTH a) group access and b) term access.
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.
That's what I've worked out here: http://groups.drupal.org/node/3700
What I haven't worked out is how to do it without hacking core/contribution modules.
I say all that to say that your idea still needs to address the TAC/OG issue if you intend to use taxonomy to make it work securely.
You might be able to get away with it using OG Vocab (I tried it and can't remember what the problems were), but it doesn't have near the richness of TAC. With TAC you can control not just who can see/not see a node, but you have total control of all "grant" operations.
My two cents.
Comment #68
rconstantine commentedYeah, 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:
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?
Hmm, perhaps I should copy this and move it to your actual issue queue. Respond here instead: http://drupal.org/node/149886
Comment #69
somebodysysop commentedOG User Roles doesn't use terms either.
That's a functionality I want to add so that I can have multiple layers of access within a single group. See attached.
If you look at the larger picture, it's not about what TAC does in particular, but Drupal Access Control in general. The way node_access works now, whatever your access control, it returns either a TRUE or FALSE or NULL. What we need is for the node_access to return TRUE if all access controls say (TRUE or NULL), or FALSE if just one returns FALSE. There's a very good discussion on this subject here: http://drupal.org/node/143075
That's cool. But, in my scenario, I want to give users who have higher access the ability to decide who can and cannot see the content they post within the group. For that, you need to make the taxonomy visible, or have some selection mechanism the user can use which will select the correct vocabulary term(s).
Your idea sounds good, if it will work. Are you developing this module now? I'd certainly like to see what kind of progress you can make.
Comment #70
(not verified) commented