Global principals are defined via ZCML. There are several kinds of principals that can be defined.
There are principals that can log in:
>>> zcml(""" ... <configure xmlns="http://namespaces.zope.org/zope"> ... ... <principal ... id="zope.manager" ... title="Manager" ... description="System Manager" ... login="admin" ... password_manager="SHA1" ... password="40bd001563085fc35165329ea1ff5c5ecbdbbeef" ... /> ... ... </configure> ... """)>>> import pprint >>> from zope.principalregistry.principalregistry import principalRegistry >>> [p] = principalRegistry.getPrincipals('') >>> p.id, p.title, p.description, p.getLogin(), p.validate('123') ('zope.manager', u'Manager', u'System Manager', u'admin', True)
There is the unauthenticated principal:
>>> zcml(""" ... <configure ... xmlns="http://namespaces.zope.org/zope" ... > ... ... <unauthenticatedPrincipal ... id="zope.unknown" ... title="Anonymous user" ... description="A person we don't know" ... /> ... ... </configure> ... """)>>> p = principalRegistry.unauthenticatedPrincipal() >>> p.id, p.title, p.description ('zope.unknown', u'Anonymous user', u"A person we don't know")
The unauthenticated principal will also be registered as a utility. This is to provide easy access to the data defined for the principal so that other (more featureful) principal objects can be created for the same principal.
>>> from zope import component >>> from zope.authentication import interfaces >>> p = component.getUtility(interfaces.IUnauthenticatedPrincipal) >>> p.id, p.title, p.description ('zope.unknown', u'Anonymous user', u"A person we don't know")
An unauthenticated group can also be defined in ZCML:
>>> zcml(""" ... <configure ... xmlns="http://namespaces.zope.org/zope" ... > ... ... <unauthenticatedGroup ... id="zope.unknowngroup" ... title="Anonymous users" ... description="People we don't know" ... /> ... ... </configure> ... """)
This directive creates a group and registers it as a utility providing IUnauthenticatedGroup:
>>> g = component.getUtility(interfaces.IUnauthenticatedGroup) >>> g.id, g.title, g.description ('zope.unknowngroup', u'Anonymous users', u"People we don't know")
The unauthenticatedGroup directive also updates the group of the unauthenticated principal:
>>> p = principalRegistry.unauthenticatedPrincipal() >>> g.id in p.groups True >>> p = component.getUtility(interfaces.IUnauthenticatedPrincipal) >>> g.id in p.groups True
If the unauthenticated principal is defined after the unauthenticated group, it will likewise have the group added to it:
>>> reset() >>> zcml(""" ... <configure xmlns="http://namespaces.zope.org/zope"> ... ... <unauthenticatedGroup ... id="zope.unknowngroup2" ... title="Anonymous users" ... description="People we don't know" ... /> ... <unauthenticatedPrincipal ... id="zope.unknown2" ... title="Anonymous user" ... description="A person we don't know" ... /> ... ... </configure> ... """)>>> g = component.getUtility(interfaces.IUnauthenticatedGroup) >>> g.id, g.title, g.description ('zope.unknowngroup2', u'Anonymous users', u"People we don't know") >>> p = principalRegistry.unauthenticatedPrincipal() >>> p.id, g.id in p.groups ('zope.unknown2', True) >>> p = component.getUtility(interfaces.IUnauthenticatedPrincipal) >>> p.id, g.id in p.groups ('zope.unknown2', True)
The unauthenticated group shows up as a principal in the principal registry:
>>> principalRegistry.getPrincipal(g.id) == g True>>> list(principalRegistry.getPrincipals("Anonymous")) == [g] True
There is an authenticated group:
>>> reset() >>> zcml(""" ... <configure xmlns="http://namespaces.zope.org/zope"> ... ... <unauthenticatedPrincipal ... id="zope.unknown3" ... title="Anonymous user" ... description="A person we don't know" ... /> ... <principal ... id="zope.manager2" ... title="Manager" ... description="System Manager" ... login="admin" ... password="123" ... /> ... <authenticatedGroup ... id="zope.authenticated" ... title="Authenticated users" ... description="People we know" ... /> ... <principal ... id="zope.manager3" ... title="Manager 3" ... login="admin3" ... password="123" ... /> ... ... </configure> ... """)
It defines an IAuthenticatedGroup utility:
>>> g = component.getUtility(interfaces.IAuthenticatedGroup) >>> g.id, g.title, g.description ('zope.authenticated', u'Authenticated users', u'People we know')
It also adds it self to the groups of any non-group principals already defined, and, when non-group principals are defined, they put themselves in the group if it's defined:
>>> principals = list(principalRegistry.getPrincipals('')) >>> principals.sort(lambda p1, p2: cmp(p1.id, p2.id)) >>> for p in principals: ... print p.id, p.groups == [g.id] zope.authenticated False zope.manager2 True zope.manager3 True
Excluding unauthenticated principals, of course:
>>> p = principalRegistry.unauthenticatedPrincipal() >>> p.id, g.id in p.groups ('zope.unknown3', False) >>> p = component.getUtility(interfaces.IUnauthenticatedPrincipal) >>> p.id, g.id in p.groups ('zope.unknown3', False)
Finally, there is an everybody group:
>>> reset() >>> zcml(""" ... <configure xmlns="http://namespaces.zope.org/zope"> ... ... <unauthenticatedPrincipal ... id="zope.unknown4" ... title="Anonymous user" ... description="A person we don't know" ... /> ... <principal ... id="zope.manager4" ... title="Manager" ... description="System Manager" ... login="admin" ... password="123" ... /> ... <everybodyGroup ... id="zope.everybody" ... title="Everybody" ... description="All People" ... /> ... <principal ... id="zope.manager5" ... title="Manager 5" ... login="admin5" ... password="123" ... /> ... ... </configure> ... """)
The everybodyGroup directive defines an IEveryoneGroup utility:
>>> g = component.getUtility(interfaces.IEveryoneGroup) >>> g.id, g.title, g.description ('zope.everybody', u'Everybody', u'All People')
It also adds it self to the groups of any non-group principals already defined, and, when non-group principals are defined, they put themselves in the group if it's defined:
>>> principals = list(principalRegistry.getPrincipals('')) >>> principals.sort(lambda p1, p2: cmp(p1.id, p2.id)) >>> for p in principals: ... print p.id, p.groups == [g.id] zope.everybody False zope.manager4 True zope.manager5 True
Including unauthenticated principals, of course:
>>> p = principalRegistry.unauthenticatedPrincipal() >>> p.id, g.id in p.groups ('zope.unknown4', True) >>> p = component.getUtility(interfaces.IUnauthenticatedPrincipal) >>> p.id, g.id in p.groups ('zope.unknown4', True)
Note that it is up to IAuthentication implementations to associate these groups with their principals, as appropriate.
There is also a system_user that is defined in the code. It will be returned from the getPrincipal method of the registry.
>>> import zope.security.management >>> import zope.principalregistry.principalregistry >>> auth = zope.principalregistry.principalregistry.PrincipalRegistry() >>> system_user = auth.getPrincipal(u'zope.security.management.system_user') >>> system_user is zope.security.management.system_user True
Removed zope.container dependency, as contained principals didn't make any sense, since PrincipalRegistry never provided IContainer. Also, zope.container pulls a number dependencies, that are not needed for non-persistent principal registry (like, ZCML, for example).
Set __name__ and __parent__ by hand to provide some backward-compatibility and to save a pointer to registry from principal objects.
Initial release. This package was splitted from zope.app.security as a part of the refactoring process to provide global principal registry without extra dependencies.