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.


cristopher pierson ewing wrote:


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 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

On Thu, 15 Feb 2007, Tres Seaver wrote:

Hash: SHA1

cristopher pierson ewing wrote:


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 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

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 Seaver          +1 540-429-0999          [EMAIL PROTECTED]
Palladion Software   "Excellence by Design"
Version: GnuPG v1.4.2.2 (GNU/Linux)
Comment: Using GnuPG with Mozilla -


Zope-PAS mailing list

Reply via email to