membrane, groups and roles


Research notes


I am digging around in PlonePAS.

Problem: how do I get my membrane based group to be editable in the groups management interface in configuration?

What is the getGroupById doing?


Why does the GroupManager give the wrong results?



which then calls enumerators = plugins.listPlugins(IGroupEnumerationPlugin) - oh oh

anyhow, we now know its really a group



return PloneGroup(group_id, name).__of__(self) - ok, here is where the PloneGroup gets created. Further up in the comments of the code:
"Create group object. For users, this can be done with a plugin, but I don't care to define one for that now. Just uses PloneGroup.  But, the code's still here, just commented out."

further up, Products.PlonePAS-3.12-py2.4.egg/Products/PlonePAS/plugins/group.py(197)_findGroup() : propfinders = plugins.listPlugins(IPropertiesPlugin)

rolemakers = plugins.listPlugins(IRolesPlugin) - there is a <MembraneRoleManager at /westapedia/acl_users/membrane_roles>, coming last


this calls unrestrictedSearchResults on <MembraneTool at /westapedia/membrane_tool used for /westapedia/acl_users/membrane_roles>

uSR(exact_getUserId=principal.getId(),object_implements=IMembraneUserRoles.__identifier__) doesn't return anything. ???

Ok, so why don't we have a IMembraneUserRoles, and what would be that?

it is "Used for objects that can provide user roles."

There are adapters from IRolesProvider to IMembraneUserRoles, so whats IRolesProvider?
"Marks the object as a Membrane roles provider using the default roles computation mechanism defined in the Roles adapter. Objects must also provide or adapt to IUserRoles." Seems to be more for plugins...

I think this is another rabbit hole, and think that maybe reordering might be enough (back to 1)

Resorted to implement the following interfaces. This means I put them into _implements_:

  1. IUserRelated - this has a getUserId. This needs to be set because tools.membrane.getUserId adapts to this interface.
  2. IUserRoles - getRoles. This is needed because factories.roles.getRolesForPrincipal adapts to this.

If we reorder the introspectors, we might get better results.

  1. This I have done in acl_users/plugins
  2. no difference
  3. follow down, to see if the first introspector is membrane, and what/why it doesn't deliver anything
  4. it does hit, and calls Products.membrane-1.1b5-py2.4.egg/Products/membrane/plugins/groupmanager.py(152)getGroupById()
  5. Products.membrane-1.1b5-py2.4.egg/Products/membrane/plugins/groupmanager.py(212)_findGroup()
  6. which calls _createGroup (see 1.7) - so we end up with a PloneGroup again, and all hope now rests on rolemakers = plugins.listPlugins(IRolesPlugin) (see 1.9). And we know that fails.

So, now it shows up in the prefs_groups_overviews (because of 1.13.4, see above).


Now lets make it editable.


prefs_groups_modify.cpy in Plone/Products/CMFPlone/skin/plone_prefs gets called

this calls editGroup on portal_groups (Products.PlonePAS.tools.groups)

this calls self.setRolesForGroup

this selects rolemanagers(IRoleAssignerPlugin) and calls rmanager.assignRolesToPrincipal(roles, group_id). There is no membrane rolemanger

Lets see if the normal rolemanager would work

  1. Products.PlonePAS.plugins.role.GroupAwareRoleManager.assignRolesToPrincipal gets called
  2. self._principal_roles principal_id = tuple(roles). What is _principal_roles?
  3. Its a btree. Seems to store all global roles for all prinicipals. Two ways from here - either have my custom group store the roles in portal_groups, or create a new role manager. Lets look at the rolemanager first

Why is there no membrane rolemanager available - because it doesn't exist. Only the standard PAS defines a IRoleAssignerPlugin

So either implement a plugin, or have the group object actually use the portal_groups to store the group. This would also mean to include member adding / removing capability, and group adding. For now delay doing this decision - in the end this is user interface polishing.