A group-aware implementation of

A principal is created with an ID:

>>> p = Principal(1)
>>> p

title and description may also be provided:

>>> p = Principal('george', 'George', 'A site member.')
>>> p
>>> p.title
>>> p.description
'A site member.'

The groups is a simple list, filled in by plugins.

>>> p.groups

The allGroups attribute is a readonly iterable of the full closure of the groups in the groups attribute--that is, if the principal is a direct member of the 'Administrators' group, and the 'Administrators' group is a member of the 'Reviewers' group, then p.groups would be ['Administrators'] and list(p.allGroups) would be ['Administrators', 'Reviewers'].

To illustrate this, we'll need to set up a dummy authentication utility, and a few principals. Our main principal will also gain some groups, as if plugins had added the groups to the list. This is all setup--skip to the next block to actually see allGroups in action.

>>> p.groups.extend(
...     ['content_administrators', 'zope_3_project',
...      'list_administrators', 'zpug'])
>>> editor = Principal('editors', 'Content Editors')
>>> creator = Principal('creators', 'Content Creators')
>>> reviewer = Principal('reviewers', 'Content Reviewers')
>>> reviewer.groups.extend(['editors', 'creators'])
>>> usermanager = Principal('user_managers', 'User Managers')
>>> contentAdmin = Principal(
...     'content_administrators', 'Content Administrators')
>>> contentAdmin.groups.extend(['reviewers', 'user_managers'])
>>> zope3Dev = Principal('zope_3_project', 'Zope 3 Developer')
>>> zope3ListAdmin = Principal(
...     'zope_3_list_admin', 'Zope 3 List Administrators')
>>> zope3ListAdmin.groups.append('zope_3_project') # duplicate, but
... # should only appear in allGroups once
>>> listAdmin = Principal('list_administrators', 'List Administrators')
>>> listAdmin.groups.append('zope_3_list_admin')
>>> zpugMember = Principal('zpug', 'ZPUG Member')
>>> martians = Principal('martians', 'Martians') # not in p's allGroups
>>> group_data = dict((, p) for p in (
...     editor, creator, reviewer, usermanager, contentAdmin,
...     zope3Dev, zope3ListAdmin, listAdmin, zpugMember, martians))
>>> class DemoAuth(object):
...     interface.implements(IAuthentication)
...     def getPrincipal(self, id):
...         return group_data[id]
>>> demoAuth = DemoAuth()
>>> component.provideUtility(demoAuth)

Now, we have a user with the following groups (lowest level are p's direct groups, and lines show membership):

editors creators
zope_3_project (duplicate)

System Message: WARNING/2 (<string>, line 77)

Block quote ends without a blank line; unexpected unindent.
reviewers user_managers |
---------/ zope_3_list_admin

System Message: WARNING/2 (<string>, line 79); backlink

Inline substitution_reference start-string without end-string.

System Message: WARNING/2 (<string>, line 80)

Definition list ends without a blank line; unexpected unindent.

content_administrators zope_3_project list_administrators zpug

The allGroups value includes all of the shown groups, and with 'zope_3_project' only appearing once.

>>> p.groups # doctest: +NORMALIZE_WHITESPACE
['content_administrators', 'zope_3_project', 'list_administrators',
>>> list(p.allGroups) # doctest: +NORMALIZE_WHITESPACE
['content_administrators', 'reviewers', 'editors', 'creators',
 'user_managers', 'zope_3_project', 'list_administrators',
 'zope_3_list_admin', 'zpug']

Base classes

Implemented Interfaces



There are no methods in this class.

Known Subclasses

There are no known subclasses.