Skip to content. | Skip to navigation

Personal tools

Navigation

You are here: Home / Members / jhb / research notes / membrane, groups and roles

membrane, groups and roles

by Jörg Baach last modified Apr 12, 2010 04:03 PM
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?

  • In prefs_groups_overviews.cpt in Plone/Products/CMFPlone/skin/plone_prefs a @@pas_search is called to get info on groups
  • this pas_search is defined in Products.PlonePAS/browser/search.py (searchGroups)
  • in there: enumerators = plugins.listPlugins( IGroupEnumerationPlugin )
  • then enumerateGroups in Products.membrane/Products/membrane/plugins/groupmanager.py is called (this implements IGroupEnumerationPlugin)
  • this adapts to IGroup, group = IGroup(obj), to Products.membrane.interfaces.group.IGroup to be precise
  • which then only fills in the uninteresting bits. I missed something -
  • back in   it does "group python:acl_users.getGroupById(group_info['groupid'])", and later group.getRoles(). So the real question is:

What is the getGroupById doing?

  • One level up from where we are a self.getGroupById.im_func.func_code tells me that this function is defined in Products.PlonePAS/Products/PlonePAS/pas.py :226
  • which calls Products.PlonePAS/Products/PlonePAS/tools/groups.py(213)getGroupById()
  • Products.PlonePAS/Products/PlonePAS/pas.py(200)getGroup()
  • "introspectors = self.plugins.listPlugins(IGroupIntrospection)"
  • ok, the first introspector hits: <GroupManager at /westapedia/acl_users/source_groups>
  • This is not really as expected - I would have hoped that the membrane tool somehow would do it.

Idea:

  1. Why does the GroupManager give the wrong results?
    1. Products.PlonePAS-3.12-py2.4.egg/Products/PlonePAS/plugins/group.py(103)getGroupById()
    2. Products.PlonePAS-3.12-py2.4.egg/Products/PlonePAS/plugins/group.py(227)_verifyGroup()
    3. which then calls enumerators = plugins.listPlugins(IGroupEnumerationPlugin) - oh oh
    4. anyhow, we now know its really a group
    5. Products.PlonePAS-3.12-py2.4.egg/Products/PlonePAS/plugins/group.py(178)_findGroup()
    6. Products.PlonePAS-3.12-py2.4.egg/Products/PlonePAS/plugins/group.py(159)_createGroup()
    7. 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."
    8. further up, Products.PlonePAS-3.12-py2.4.egg/Products/PlonePAS/plugins/group.py(197)_findGroup() : propfinders = plugins.listPlugins(IPropertiesPlugin)
    9. rolemakers = plugins.listPlugins(IRolesPlugin) - there is a <MembraneRoleManager at /westapedia/acl_users/membrane_roles>, coming last
    10. Products.membrane-1.1b5-py2.4.egg/Products/membrane/plugins/rolemanager.py(52)getRolesForPrincipal()
    11. this calls unrestrictedSearchResults on <MembraneTool at /westapedia/membrane_tool used for /westapedia/acl_users/membrane_roles>
    12. uSR(exact_getUserId=principal.getId(),object_implements=IMembraneUserRoles.__identifier__) doesn't return anything. ???
    13. Ok, so why don't we have a IMembraneUserRoles, and what would be that?
      1. it is "Used for objects that can provide user roles."
      2. 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...
      3. I think this is another rabbit hole, and think that maybe reordering might be enough (back to 1)
      4. 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.
  2. 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.

 

  1. prefs_groups_modify.cpy in Plone/Products/CMFPlone/skin/plone_prefs gets called
  2. this calls editGroup on portal_groups (Products.PlonePAS.tools.groups)
  3. this calls self.setRolesForGroup
  4. this selects rolemanagers(IRoleAssignerPlugin) and calls rmanager.assignRolesToPrincipal(roles, group_id). There is no membrane rolemanger
    1. 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
    2. 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.

 

Filed under:
Add comment

You can add a comment by filling out the form below. Plain text formatting.

Question: What is 6 times 7?
Your answer: