[development] OG User Roles: user_access / node add /$user->roles

Ron Parker sysop at scbbs.com
Sun May 27 21:11:00 UTC 2007


Looks like I've finally cracked this nut.  But, I had to do an 
end-around to do it.

 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:

function og_user_roles_addform() {
  global $user;
  $gids = $_GET['gids'];
  $typeFound = 'no';
   if ($gids) {
       $group_node = node_load($gids[0]);
       og_set_group_context($group_node);
   }
   $type = $_GET['type'];
   if ($type) { <>   if ($type == 'forum') {
        if (user_access('create forum topics')) {
            $typeFound = 'yes';
            $output = node_add('forum');
        }
    }
etc...
 }
return $output;
}

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 this 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 node.

So, by using hook_menu to create the callback for "node/addform":

$access = $user->uid; // login is required
$items[] = array('path' => 'node/addform', 'type' => MENU_CALLBACK, 
'callback' => 'og_user_roles_addform', 'access' => $access, 'title' => 
t('Create content'));

and, creating a re-direct in hook_init:

    // Looking for this format:
    http://www.mysite.com/node/add/link?gids[]=29

    function og_user_roles_init ()
    {
    if (arg(0) == 'node' && arg(1) == 'add' && isset($_REQUEST['gids'])) {
    $gids = $_GET['gids'];
    $gid = intval(current($_REQUEST['gids']));

    $type = arg(2);

    $path = 'node/addform';
    $query = 'type=' . $type . '&gids[]=' . $gid;
    drupal_goto($path, $query);
    }
    }

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 onesmall 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 to all of you who took the time to give suggestions.  I all 
helped me to finally come up with a solution. 

-ron

Ron Parker wrote:

> I uninstalled "devel" module completely, emptied cache, ran cron, and 
> I'm back to "Access denied" message.
>
> At this point, I don't think my problem is either user_access or 
> node_access.  I've put watchdogs everywhere in those two functions, as 
> well as my hook_user and hook_nodeapi, and I seem to get the same 
> output whether the node/add is successful or not.  That is to say, the 
> correct roles and correct permissions are always returned in the 
> output I see.
>
> I have three create links that are created on the Group home page as a 
> result of my modified $user->roles (hook_user and hook_init): "create 
> forum", "create link" and "create story".  The fact that they appear 
> on the group home page tells me that user_access is working. 
>
> I noted that in the Drupal main navigation menu, there is no "create" 
> link, even though the create links appear in the group menu.
>
> As a test, I gave all authenticated users the "create link" permission 
> (site-wide using normal "access control" not group limited).  Now, I 
> see "create link" link in main navigation menu.  I click on "create 
> link" link in group menu, and voila, it works.
>
> But, I noticed something else: I also now see "create forum" and 
> "create story" links in the main navigation menu. I click on those in 
> the group menu, and THEY work.  I thought two things: 1. 
> Theoretically, when I go to the group home page, I should see in both 
> the group menu AND main navigation menu create links for all nodes 
> that I have OG roles permissions to create in that group and 2. 
> Perhaps there is a relationship between not seeing the "create" link 
> in the main navigation menu and getting "Access denied" message even 
> though user->roles, user_access and node_access all give me permission 
> to create the node?
>
> So, now my question is: How does the main navigation menu determine 
> what content a user can create?   Perhaps there is some hook I've 
> overlooked that needs to tell the menu building process that this is a 
> group page.  Right now, hook_user, hook_init and h ook_nodeapi 
> apparently aren't doing it.
>
> Thanks for any assistance!
>
> -ron
>
> Ron Parker wrote:
>
>> I actually have been using a similar nodeapi patch for some time now 
>> with remarkable success on another project.  The Extensible Node 
>> Access/Authorisation Capability patch: http://drupal.org/node/122173. 
>> <http://drupal.org/node/122173:> I've documented those efforts here: 
>> http://groups.drupal.org/node/3700  However, that's a discussion for 
>> another day.
>>
>> I didn't try using this patch with OG User Roles because I was trying 
>> to get the module to run without *any* core patches.  However, 
>> prompted by your e-mail, and months of frustration, I updated my 
>> node.module with the version of the nodeapi patch I've already used.
>>
>> Initially, it didn't work.  Every watchdog I put in (hook_nodeapi, 
>> hook_user, node_access) returned the values I would expect, but I 
>> continued to get "Access denied".  I emptied the cache, logged on and 
>> off, etc...  Every time I clicked on "create link", it failed.
>>
>> So, I decided to use the default Drupal access control to give the 
>> user in question the "create link" permission (by giving the 
>> permission to all authenticated users).  Of course, when the user 
>> clicked on "create link", it brought up the node submission form.
>>
>> I didn't notice anything particularly different in the logs, so I 
>> removed the permission from authenticated users.  Deleted cache, ran 
>> cron.php, and tried to "create link" again.  It worked.  Deleted 
>> cache, etc.. again.  It still worked.
>>
>> I logged off and logged back on as a different user.  Messed around, 
>> then logged off and back on as the user I've been working with. 
>> Clicked on "create link".  It still works.
>>
>> I guess I should be happy, but I'm not because I know that whatever 
>> the problem was, it's still there.  I can neither identify what the 
>> problem is, nor explain why the /node/add is working now.
>>
>> Nor can I define why the /node/add works when the user has 
>> devel.module permissions turned on.
>>
>> -ron
>>
>> Larry Garfield wrote:
>>
>>>Ron,
>>>
>>>I have to ask.  Would this be easier for you if this patch went in: http://drupal.org/node/143075
>>>
>>>Your task sounds like exactly the sort of thing that patch would simplify.  Please correct me if I'm wrong, though.
>>>  
>>>
>> You are right, if in fact this is working.
>>
>>>On Tue, 22 May 2007 12:24:38 -0700, Ron Parker <sysop at scbbs.com> wrote:
>>>  
>>>
>>>>I created two watchdog notices: One in user_access (showing $string and
>>>>result: true/false) and one in the hook_user "load" (showing roles
>>>>returned) operation.
>>>>
>>>>I logged in as user in question, went to groups, clicked on "create
>>>>link", got "Access denied".
>>>>
>>>>One of the roles that is returned by the og modified $user->roles gives
>>>>this user the permission to "create link".  The watchdog entries verify
>>>>that for the url in question: /node/add/link?gids[]=29,  the correct
>>>>roles are returned in $user->roles and the correct access in
>>>>user_access.  Yet access is denied.
>>>>
>>>>Does the following bit of information provide a clue?:
>>>>
>>>>When I load the "devel" module, and give this user access to it (through
>>>>access control), the user does not receive "Access denied" message when
>>>>clicking on "create link".  If I go into access control, and remove
>>>>permissions for "devel" module, the user still continues to be able to
>>>>"create link".  However, if as admin I delete the cache, run cron.php,
>>>>logout and log back in as user, the "Access denied" message returns.
>>>>
>>>>It seems that if this is a cache problem, clearing the cache doesn't
>>>>appear to resolve it.
>>>>
>>>>I really appreciate any insight.  I've been working on cracking this for
>>>>8 months now.  It's driving me nuts because there must be something
>>>>somewhere, either in user_access or node_access or some other hook
>>>>that's if I only knew I could correct the problem.
>>>>
>>>>Thanks so much!
>>>>
>>>>David Metzler wrote:
>>>>
>>>>    
>>>>
>>>>>Thinking about this maybe the problem is user_access, not the roles
>>>>>themselves.  Check out the user_access function in user.module.  Note
>>>>>that is uses a static variable caching mechanism, so it may have
>>>>>already determined the results of "user_access" before you've
>>>>>modified the roles.  (It would need to in order to route the request
>>>>>and check access permissions).
>>>>>
>>>>>One way to check would be to call user_access immediately after you
>>>>>set the roles, and see if it gives you the proper result, (in your
>>>>>watchdog or debug files).
>>>>>
>>>>>The bad news is that I don't really know of a good way to solve this
>>>>>if that's the case. I'm afraid that we need a hook_user_access in
>>>>>core in order to implement this.  Either that or an added parameter
>>>>>to force user_access to ignore the cache.
>>>>>
>>>>>Here's hoping I'm wrong :).
>>>>>
>>>>>Dave
>>>>>
>>>>>
>>>>>On May 21, 2007, at 3:39 PM, Ron Parker wrote:
>>>>>
>>>>>      
>>>>>
>>>>>>Thanks so much for the reply.  Here's what I tried in hook_init:
>>>>>>
>>>>>>function og_user_roles_init ()
>>>>>>{
>>>>>>   global $user;
>>>>>>   $roles = og_user_roles_all_roles($user); // This returns normal
>>>>>>$user->roles and includes OG roles if any
>>>>>>   $user->roles = $roles;
>>>>>>   $displayRoles = implode(",", $roles);
>>>>>>   if ($user->uid) watchdog('og_user_roles', 'user roles = ' .
>>>>>>$displayRoles); // Show this in log if it hits.
>>>>>>}
>>>>>>
>>>>>>Here's what I tried in hook_user:
>>>>>>
>>>>>>   // Add the group roles to $user->roles if this is a group
>>>>>>   // This should only be effective until the next global $user call
>>>>>>   if ($op == "load") {
>>>>>>       $roles = og_user_roles_all_roles($user); // This returns
>>>>>>normal $user->roles and includes OG roles if any
>>>>>>       $user->roles = $roles;
>>>>>>   } // end $op load
>>>>>>
>>>>>>I looked at the watchdog and my own debug file, and the correct
>>>>>>roles are being returned each and every time.
>>>>>>My guess is that $user->roles is doing what it should, but there is
>>>>>>something else happening in the node/add
>>>>>>(http://www.mysite.com/ node/add/link?gids[]=29) process that
>>>>>>doesn't depend upon $user->roles that is causing the access denied
>>>>>>error.
>>>>>>
>>>>>>Again, any clues would be much appreciated.
>>>>>>
>>>>>>-ron
>>>>>>
>>>>>>David Metzler wrote:
>>>>>>
>>>>>>        
>>>>>>
>>>>>>>I've run into similar problems with using user_load to alter
>>>>>>>user_data.  User_load doesn't fire as often as you might think it
>>>>>>>does due to some caching strategies.   To prove this, place a
>>>>>>>drupal_set_message call in your user_load trap and see when it
>>>>>>>fires.  It may not be firing on the page where you're getting the
>>>>>>>access denied errors.
>>>>>>>
>>>>>>>To solve my problem I had to move user alteration into the init hook.
>>>>>>>
>>>>>>>It may be that there's core bug here, but I haven't yet tracked  it
>>>>>>>down since the init hook solved my problem.
>>>>>>>
>>>>>>>I never did find out why user_load wasn't firing.
>>>>>>>On May 15, 2007, at 11:56 AM, Ron Parker wrote:
>>>>>>>
>>>>>>>          
>>>>>>>
>>>>>>>>A few weeks back I floated my og user roles module  idea on this
>>>>>>>>list as instructed by CVS Admin.  This module (http://drupal.org/
>>>>>>>>node/87679) is designed to assign roles to OG group members that
>>>>>>>>are specific to the groups they are in.  The problem was that I
>>>>>>>>had  to patch the core user.module in order to get it to work.
>>>>>>>>
>>>>>>>>After a couple of suggestions, I decided to formulate a proposal
>>>>>>>>for a Drupal hook.  What I thought made the most sense was either
>>>>>>>>a  user_access hook or a $user->roles hook because what I wanted
>>>>>>>>to do  was add roles to the site wide roles returned by $user-
>>>>>>>>            
>>>>>>>>
>>>>>>>>>roles.   user_access (which returns permissions allowed  according
>>>>>>>>>              
>>>>>>>>>
>>>>>>>>to roles)  is called by node_access which is what  determines
>>>>>>>>access on a node/ add.
>>>>>>>>
>>>>>>>>I recently proposed a $user->roles hook (http://drupal.org/node/
>>>>>>>>143393), and someone pointed out that I could accomplish the  same
>>>>>>>>thing by using the existing hook_user "load" operation.   They
>>>>>>>>were  right.  I modified my module to add the appropriate  roles to
>>>>>>>>the  user object using hook_user "load" and in testing,  it appears
>>>>>>>>that  $user->roles now returns the OG group as well as  the site
>>>>>>>>wide  roles when a user is in a group.
>>>>>>>>
>>>>>>>>However, on a group node add, for example, http://www.mysite.com/
>>>>>>>>node/add/link?gids[]=29, my user gets an "Access denied" error.
>>>>>>>>I  wrote a little debug program that writes out the values
>>>>>>>>returned by  my hook_user "load" addition, and every time it's
>>>>>>>>called it returns  the correct values.
>>>>>>>>
>>>>>>>>node_access would be the access control for a group node add.  I
>>>>>>>>have examined the code closely, and this is the only code that
>>>>>>>>would be executed on a node "create":
>>>>>>>>
>>>>>>>> // Can't use node_invoke(), because the access hook takes the
>>>>>>>>$op  parameter
>>>>>>>> // before the $node parameter.
>>>>>>>> $module = node_get_types('module', $node);
>>>>>>>> if ($module == 'node') {
>>>>>>>>   $module = 'node_content'; // Avoid function name collisions.
>>>>>>>> }
>>>>>>>> $access = module_invoke($module, 'access', $op, $node);
>>>>>>>> if (!is_null($access)) {
>>>>>>>>   return $access;
>>>>>>>> }
>>>>>>>>
>>>>>>>>This code would then call "node_content_access" (hook_access for
>>>>>>>>node), which would use "user_access" (thus calling global $user,
>>>>>>>>thus invoking my modification) to determine access.
>>>>>>>>
>>>>>>>>So, I'm at a complete loss as to why I would get an "Access
>>>>>>>>denied"  error for a group role.  I need some help!
>>>>>>>>
>>>>>>>>The only thing I have noticed which seems to give me a clue is
>>>>>>>>that  when I load the "devel" module and give users access,
>>>>>>>>everything  works.  But, I can't figure out what the devel module
>>>>>>>>is doing that  would cause this.
>>>>>>>>
>>>>>>>>Any hint, clue or anything would be appreciated.  Thanks!
>>>>>>>>
>>>>>>>>-ron
>>>>>>>>
>>>>>>>>--
>>>>>>>>Ron Parker
>>>>>>>>Software Creations               http://www.scbbs.com
>>>>>>>>Self-Administration Web Site     http://saw.scbbs.com
>>>>>>>>SDSS Subscription Mgmt Service   http://sdss.scbbs.com
>>>>>>>>Central Ave Dance Ensemble       http://www.centralavedance.com
>>>>>>>>R & B Salsa                      http://www.randbsalsa.com
>>>>>>>>
>>>>>>>>            
>>>>>>>>
>>>>>>>__________ NOD32 2277 (20070518) Information __________
>>>>>>>
>>>>>>>This message was checked by NOD32 antivirus system.
>>>>>>>http://www.eset.com
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>          
>>>>>>>
>>>>>>--
>>>>>>Ron Parker
>>>>>>Software Creations               http://www.scbbs.com
>>>>>>Self-Administration Web Site     http://saw.scbbs.com
>>>>>>SDSS Subscription Mgmt Service   http://sdss.scbbs.com
>>>>>>Central Ave Dance Ensemble       http://www.centralavedance.com
>>>>>>R & B Salsa                      http://www.randbsalsa.com
>>>>>>
>>>>>>        
>>>>>>
>>>>>__________ NOD32 2285 (20070522) Information __________
>>>>>
>>>>>This message was checked by NOD32 antivirus system.
>>>>>http://www.eset.com
>>>>>
>>>>>
>>>>>
>>>>>      
>>>>>
>>>>--
>>>>Ron Parker
>>>>Software Creations               http://www.scbbs.com
>>>>Self-Administration Web Site     http://saw.scbbs.com
>>>>SDSS Subscription Mgmt Service   http://sdss.scbbs.com
>>>>Central Ave Dance Ensemble       http://www.centralavedance.com
>>>>R & B Salsa                      http://www.randbsalsa.com
>>>>    
>>>>
>>>
>>>
>>>__________ NOD32 2285 (20070522) Information __________
>>>
>>>This message was checked by NOD32 antivirus system.
>>>http://www.eset.com
>>>
>>>
>>>
>>>  
>>>
>>
>>
>>-- 
>>Ron Parker
>>Software Creations               http://www.scbbs.com
>>Self-Administration Web Site     http://saw.scbbs.com
>>SDSS Subscription Mgmt Service   http://sdss.scbbs.com
>>Central Ave Dance Ensemble       http://www.centralavedance.com
>>R & B Salsa                      http://www.randbsalsa.com
>>  
>>
>
>
>-- 
>Ron Parker
>Software Creations               http://www.scbbs.com
>Self-Administration Web Site     http://saw.scbbs.com
>SDSS Subscription Mgmt Service   http://sdss.scbbs.com
>Central Ave Dance Ensemble       http://www.centralavedance.com
>R & B Salsa                      http://www.randbsalsa.com
>  
>
>
>
> __________ NOD32 2292 (20070525) Information __________
>
> This message was checked by NOD32 antivirus system.
> http://www.eset.com



-- 
Ron Parker
Software Creations               http://www.scbbs.com
Self-Administration Web Site     http://saw.scbbs.com
SDSS Subscription Mgmt Service   http://sdss.scbbs.com
Central Ave Dance Ensemble       http://www.centralavedance.com
R & B Salsa                      http://www.randbsalsa.com

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.drupal.org/pipermail/development/attachments/20070527/8abd7b11/attachment-0001.htm 


More information about the development mailing list