[Zope-PAS] Re: Failure authorizing with PlonePAS and pubcookie

Michael Gilbert mdgilb at u.washington.edu
Wed Feb 28 20:10:40 EST 2007


Here's our first stab at creating a custom role manager, working almost 
entirely as it should.  It currently behaves quite similarly to the 
regular RoleManager, except that if no roles are found it will attempt 
to get them from the root.  The problem we're running into, I'm 
guessing, comes from the fact that since the user 'mdgilb' in the 
context of the /plone site is not the same as the root level 'mdgilb' I 
need to actually load the second by doing something like

   root_user = self.getPhysicalRoot().acl_users.getUser(principal.getId())

Once I get the root user, I can get the roles in the proper context by 
just doing

   roles = list( root_user.getRoles() )

This portion of the code actually seems to work, since the proper roles 
are returned.  The problem comes when after the roles are returned a 
loop seems to happen in getRolesForPrincipal.  Every time 'user = 
new_self.getPhysicalRoot().acl_users.getUser(Id)' is called 
getRolesForPrincipal goes back to the beginning, so I'm thinking the 
initial call to getUser is causing some value to be misread later on, 
which causes the loop.  Another point to note is that when the method is 
first called, my username (mdgilb) is properly listed in the principal 
value.  In successive calls another user (peggyros) is listed, which is 
just not right.

If anyone could offer any  insight into  this issue it would be greatly 
appreciated.

Thanks,
-michael

cristopher pierson ewing wrote:

> Tres,
>
> Again, thanks for the replies on this.  Your input has been invaluable 
> in working out what's going on here.
>
> We had another little debugging session the other day,  and have come 
> to a few conclusions about what is needed here and what we should do.  
> I wanted to send a quick note to you with our plans, just in case 
> anything we are thinking is so clearly stupid and dangerous that you 
> want to jump up and say 'STOP!'.  ;)
>
> We've definitely narrowed the problem down to the role manager plugin. 
> The issue is that when a user is set up in the zope acl_users PAS 
> object, and given the role of manager, that user cannot access the ZMI 
> or pages of a plone site installed in his/her zope instance as a 
> manager.  The reason for this is definitely that the acl_users PAS 
> object in the Plone site has a 'role manager' plugin available that is 
> cansulted and it only returns the roles for the user that are defined 
> in the context of that PAS object. Since the 'Zope Manager' we defined 
> above is not listed in the Plone PAS object, no roles are returned, 
> and the user is given the base role of 'Authenticated User'.
>
> We've decided that this problem is really not one that is directly 
> related to the PubcookiePAS plugin, but rather external to it.  So 
> we've decided to create a new, single plugin that provides the IRoles 
> interface, but checks upward to parent folders for valid PAS objects 
> in which to look for roles.  We figure that if we make such a plugin, 
> then adding it to the active list of role manager plugins in any plone 
> site installed in our Zope instance will allow them to find zope-level 
> manager roles for zope-level managers, and apply those roles to pages 
> within the plone site.
>
> The only reason we need to do this at all is because the folks I'm 
> working with have a setup where they are running several plone sites 
> from a single zope instance, and they want to be able to set up 
> 'global' managers from zope who will have permissions to manage all 
> the plone sites.  Since I don't need to do this, and many others may 
> not.  It seems wise to put this plugin in a product of its own, rather 
> than including it in my PubcookiePAS multi-plugin product.
>
> Any alarm bells ringing here?
>
> Thanks again for your help so far.  You've been great.
>
> Cris
>
> ********************************
> Cris Ewing
> CME and Telehealth Web Services
> Department of Radiology Web Services
> University of Washington
> School of Medicine
> Work Phone: (206) 685-9116
> Home Phone: (206) 365-3413
> E-mail: cewing at u.washington.edu
> *******************************
>
>
> On Thu, 15 Feb 2007, Tres Seaver wrote:
>
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> cristopher pierson ewing wrote:
>>
>>> Tres,
>>>
>>> I'm the poor lug who wrote the plugins in queestion.  Thanks again for
>>> helping out with this.  I've got some questions and some ideas 
>>> folded in
>>> with your response below.
>>>
>>> On Tue, 13 Feb 2007, Tres Seaver wrote:
>>>
>>>>>> Thanks for responding.
>>>>>>
>>>>>> The multi-plugin was written by Cris (cc'd above) here at UW.  The
>>>>>> plugin isn't incredibly invasive, and in fact at one point it 
>>>>>> seemed to
>>>>>> be working so I tend to assume that it may be a
>>>>>> configuration/installation/human error.  If you'd like to take a 
>>>>>> look at
>>>>>> it, I've copied a tarball and the extracted contents out to
>>>>>> http://staff.washington.edu/mdgilb/ for perusal.  We've done a fair
>>>>>> amount of debugging to the plugin and haven't found a blaring 
>>>>>> error yet,
>>>>>> but it is possible we missed something.
>>>>>>
>>>>>> The main problem that we seem to be having seems related to the 
>>>>>> context
>>>>>> of the installation - if the plugin is installed at the zope root
>>>>>> acl_users folder, only users listed in that folder with the 
>>>>>> manager role
>>>>>> will have their permission reflected on all plone sites 
>>>>>> underneath.  If
>>>>>> the plugin is installed under a plone site's acl_users folder, users
>>>>>> with the manager role in that site have the proper permissions, 
>>>>>> but root
>>>>>> level managers (ie zope admins) will have a limited set of rights 
>>>>>> - once
>>>>>> the plugin is enabled for the final plugin type, trying to view all
>>>>>> available plugin types again (/<SiteName>/acl_users/plugins) will 
>>>>>> result
>>>>>> in a list of Undo options instead of the expected Plugin Types.
>>>>>
>>>>
>>>> The plugin likely needs to check with the "parent" user folder, if 
>>>> any,
>>>> for role assignments, as well as looking in its own map.  Likewise for
>>>> group membership, if your roles are assigned to groups, rather than
>>>> directly to users.
>>>
>>> The plugins I wrote don't have any component for checking group 
>>> membership
>>> or roles (as far as I know).  There's only four plugins defined in the
>>> folder, a Challenge plugin, an authenticateCredentials plugin, an
>>> extractCredentials plugin, and a resetCredentials plugin.  As far as I
>>> have been able to tell, group membership seems to be handled by the
>>> 'source_groups' plugin in the plone acl_users and by 'groups' in the 
>>> zope
>>> acl_users.  The same goes for role acquisition.  There appears to be a
>>> role manager for the plone acl_users and another for the zope 
>>> acl_users.
>>> As far as I've been able to tell, the problem seems to be that the only
>>> acl_users that gets checked with is the one appropriate to the 
>>> context of
>>> the page request made.  So, if a page from the zope ZMI is 
>>> requested, the
>>> acl_users in the root zope folder is used for all plugins.  If the page
>>> requested comes from the plone site, then the plone acl_users is 
>>> selected,
>>> and the plugins come from there.  The problem seems to arise in that 
>>> if a
>>> principal defined in the zope acl_users and given the role of 'manager'
>>> from there attempts to access a plone site page, the role he is 
>>> granted by
>>> the zope acl_users is never found, because the role manager consulted
>>> comes from the plone acl_users, and the principal doesn't exist there.
>>
>>
>> You've got your finger on the crux, here:  the user identified by
>> pubcookie is being "recognized" by the child PAS (becuase of the
>> cookie), but is *not the same user* as the one in the root:  she just
>> happens to have the same userid as the one defined in the root.  This
>> would be the same problem if you created "traditional" user foldere and
>> defined users with the same ID in both parent and child:  any role
>> assignments made to the parent would be "shadowed" by the presence of
>> the doppelganger in the child.
>>
>> As a hack, I might try adding another method, 'getRolesForPrincipal', on
>> your plugin, and register it as an IRoles plugin.  In that method, you
>> will need to check the global roles of the user with that ID in the
>> *parent* user folder, and add them to any assigned there.
>>
>> In fact, you might be able to accomplish this via a
>> 'DelegatingMultiPlugin' (or at least steal the code from there).  Here
>> is what its 'getRolesForPrincipal' looks like::
>>
>>    def getRolesForPrincipal(self, user, request=None):
>>        """ Fullfill RolesPlugin requirements """
>>        acl = self._getUserFolder()
>>
>>        if acl is None:
>>            return ()
>>
>>        user = acl.getUserById(user.getId())
>>
>>        if user is None:
>>            return ()
>>
>>        return tuple(user.getRoles())
>>
>> In your case, the only hard part would be that first call, to
>> '_getUserFolder':  you would need to replace it with something which
>> looked at the "grandparent" of the plugin to find the containing user
>> folder:'(aq_parent(aq_parent(aq_inner(self)))'.
>>
>>> In general, I would break apart the idea of group membership, which is
>>> typically done globally (within the entire scope of the user folder),
>>> from role assignment.  Mostly, I avoid doing "global" role assignment,
>>> preferrning instead to grant roles to the groups as "local roles".
>>>
>>>> So, if I read this right, you are suggesting that a principal 
>>>> should be
>>>> granted roles solely on the basis of group memberships.  That makes 
>>>> sense
>>>> to me, it certainly cleans up the picture when trying to figure out 
>>>> which
>>>> roles to apply.
>>>
>>>
>>> I'm also pretty convinced that you don't really want or need more than
>>> one user folder, in general at the root of the Zope database:  the
>>> complexity caused by nesting user folders outweighs any benefit I've
>>> ever identified.
>>>
>>>> We haven't been nesting user folders.  The problem seems to arise 
>>>> in that
>>>> a default zope installation creates an acl_users 'folder' (really a 
>>>> PAS
>>>> object), and a default plone installation creates a second one at 
>>>> the root
>>>> of the plone site.
>>>
>>
>> Plone creates both, actually, replacing the "traditional" one in the 
>> root.
>>
>>>>  The problem seems to be that the PAS object that
>>>> exists in the context of the page request made is the only one 
>>>> asked for
>>>> information about the roles/credentials of the user making the 
>>>> request,
>>>> and so we are running into trouble.
>>>
>>>
>>>> Is it possible to just delete the acl_users PAS object from the 
>>>> root of
>>>> the plone site?  Is it advisable to do so?  If we do that, will the
>>>> request for plugins to handle authorization and authentication 
>>>> bubble up
>>>> to the zope instance of acl_users?  Perhaps this would solve all our
>>>> problems, but it's a little scary to do.
>>>
>>
>> It is certainly possible:  you would need to ensure that you recreate
>> any state in the child folder (properties, etc.).
>>
>>>> Thanks again for your help
>>>
>>
>> You're welcome.
>> ,
>>
>> Tres.
>> - --
>> ===================================================================
>> Tres Seaver          +1 540-429-0999          tseaver at palladion.com
>> Palladion Software   "Excellence by Design"    http://palladion.com
>> -----BEGIN PGP SIGNATURE-----
>> Version: GnuPG v1.4.2.2 (GNU/Linux)
>> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
>>
>> iD8DBQFF1GXX+gerLs4ltQ4RAuBVAJ9Xj8OPT7Y4Q2B/ZVziD4Wr8ENqWgCfUzNV
>> adwPxPSEarKQj0+5p1PFyvo=
>> =5b6u
>> -----END PGP SIGNATURE-----
>>



More information about the Zope-PAS mailing list