How to install z3ext.security
- Download and install ActivePython
- Open Command Prompt
- Type
pypm install z3ext.security
Depended by
- z3ext.banner
- z3ext.blogger
- z3ext.catalog
- z3ext.company
- z3ext.content.browser
- z3ext.content.discussion
- z3ext.content.documents
- z3ext.content.draft
- z3ext.content.featured
- z3ext.content.forms
- z3ext.content.permissions
- z3ext.content.revision
- z3ext.content.schema
- z3ext.content.sorting
- z3ext.content.space
- z3ext.content.tagging
- z3ext.content.type
- z3ext.content.urlmapper
- z3ext.content.workflow
- z3ext.contenttype.event
- z3ext.contenttype.page
- z3ext.contenttypes
- z3ext.controlpanel
- z3ext.formulator
- z3ext.forum
- z3ext.groups
- z3ext.homefolder
- z3ext.layoutform
- z3ext.mailin
- z3ext.members
- z3ext.ownership
- z3ext.permissionsmap
- z3ext.persistent.fields
- z3ext.personal.blogger
- z3ext.personal.content
- z3ext.personal.favorites
- z3ext.personal.messages
- z3ext.personal.profile
- z3ext.personal.space
- z3ext.portal
- z3ext.principal.ban
- z3ext.principal.groups
- z3ext.principal.profile
- z3ext.principal.roles
- z3ext.principal.users
- z3ext.principalfolder
- z3ext.project
- z3ext.rating
- z3ext.site
- z3ext.skintool
- z3ext.subscription
- z3ext.teamfolder
- z3ext.topcontributors
- z3ext.ui.publicwidgets
- z3ext.ui.searching
- z3ext.widget.dropdowndate
- z3ext.widget.extjsdate
- z3ext.widget.extjseditor
- z3ext.wiki
Lastest release
z3ext.security
This package provides security related features
- Extended Security Policy: securitypolicy.txt
- Extended Grant Information: grantinfo.txt
- Principal Groups infomration: groups.txt
Extended Zope Security Policy
This package implements a extended version of zope.securitypolicy. Main difference:
- for permissions to roles mapping we use IRolePermissionManager interface
- for roles to permissions mapping we try find all IPrincipalRoleMap
adapters, including named adapters, extended security policy allow dynmiclly calculate roles for principal
Everything else is standard zope3 implementation. For standard security policy documentation check zope/securitypolicy/zopepolicy.txt file. Most of this code from zopepolicy.txt file because in general this security policy only extended version of standard version.
>>> import zope.interface >>> from zope.annotation.interfaces import IAttributeAnnotatable
>>> class IMyObject(zope.interface.Interface): ... pass
>>> class Ob: ... __parent__ = None ... zope.interface.implements(IAttributeAnnotatable, IMyObject)
>>> ob = Ob()
>>> class Principal: ... def __init__(self, id): ... self.id = id ... self.groups = []
>>> principal = Principal('bob')
>>> class Participation: ... interaction = None
>>> from z3ext.security.securitypolicy import SecurityPolicy
>>> import zope.security.management >>> oldpolicy = zope.security.management.setSecurityPolicy(SecurityPolicy)
Let's create interaction:
>>> participation = Participation() >>> participation.principal = principal >>> zope.security.management.endInteraction() >>> zope.security.management.newInteraction(participation) >>> interaction = zope.security.management.getInteraction()
>>> interaction.checkPermission('P1', ob) False
Let's work with roles
>>> from zope.securitypolicy import interfaces
>>> interaction.checkPermission('P1', ob) False
We will use 'content.Owner' role, we need give permission to role:
>>> roleper = interfaces.IRolePermissionManager(ob) >>> roleper.grantPermissionToRole('P1', 'content.Owner')
Right now 'bob' principal doesn't have 'content.Owner' role on 'ob' object with standard policy we should use IPrincipalRoleManager adapter to give ''content.Owner' role to principal. With extended version we can define named adapter. Here example that implemen owner roles that doesn't depends on object annotations:
Let's use 'ob' object attribute to define owner of object:
>>> ob.owner = 'bob'
Now we need custom IPrincipalRoleMap:
>>> from zope.app.security.settings import Allow, Deny
>>> class OwnerRolesMap(object): ... zope.interface.implements(interfaces.IPrincipalRoleMap) ... ... def __init__(self, context): ... self.context = context ... ... def getRolesForPrincipal(self, principal_id): ... if getattr(self.context, 'owner', '') == principal_id: ... return (('content.Owner', Allow),) ... return (('content.Owner', Deny),)
For testing implemented only getRolesForPrincipal method, but in many cases we need implement all methods.
Now we need register named adapter
>>> from zope.component import provideAdapter >>> provideAdapter(OwnerRolesMap, (IMyObject,), \ ... interfaces.IPrincipalRoleMap, name='ownership') >>> interaction.invalidate_cache()
So 'bob' principal should get 'content.Owner' role on 'ob'
>>> interaction.checkPermission('P1', ob) True
For better 'Ownership' implementation check z3ext.ownership package.
For futher testing remove permission from role:
>>> roleper.unsetPermissionFromRole('P1', 'content.Owner')
>>> interaction.checkPermission('P1', ob) False
With extended security policy we can supply custom IRolePermissionManager implementation for object:
>>> class RolePermissionMap(object): ... zope.interface.implements(interfaces.IRolePermissionMap) ... ... def __init__(self, context): ... self.context = context ... ... def getRolesForPermission(self, permission_id): ... if permission_id == 'P2': ... return (('content.Owner', Allow), ('content.Owner1', Deny)) ... elif permission_id == 'P3': ... return (('content.Owner1', Allow), ('content.Owner', Deny)) ... return ()
>>> provideAdapter(RolePermissionMap, (IMyObject,), \ ... interfaces.IRolePermissionMap, name='custom') >>> interaction.invalidate_cache()
>>> interaction.checkPermission('P2', ob) True
>>> interaction.checkPermission('P3', ob) False
>>> prinrole = interfaces.IPrincipalRoleManager(ob) >>> prinrole.assignRoleToPrincipal('content.Owner1', 'bob')
>>> interaction.checkPermission('P3', ob) True
IExtendedGrantInfo
IExtendedGrantInfo interface is extended version of IGrantInfo from zope/securitypolicy but it runs for each parent and uses all available IRolePermissionMap and IPrincipalRoleMap adapters for object.
initialization:
>>> from zope import interface >>> from zope.component import provideAdapter >>> from zope.securitypolicy import interfaces >>> from z3ext.security.grantinfo import ExtendedGrantInfo >>> from z3ext.security.interfaces import IExtendedGrantInfo
>>> provideAdapter(ExtendedGrantInfo, (interface.Interface,), IExtendedGrantInfo)
>>> import zope.interface >>> from zope.annotation.interfaces import IAttributeAnnotatable
>>> class IMyObject(zope.interface.Interface): ... pass
>>> class Ob: ... __name__ = u'' ... __parent__ = None ... zope.interface.implements(IAttributeAnnotatable, IMyObject) ... ... def __init__(self, name): ... self.__name__ = name ... def __repr__(self): ... return '<Ob "%s">'%self.__name__
>>> ob1 = Ob('ob1') >>> ob2 = Ob('ob2') >>> ob3 = Ob('ob3') >>> ob4 = Ob('ob4')
Let's build parents dependencies: ob1->ob2->ob3, ob1->ob4
>>> ob2.__parent__ = ob1 >>> ob3.__parent__ = ob2 >>> ob4.__parent__ = ob1
>>> grantinfo = IExtendedGrantInfo(ob3) >>> IExtendedGrantInfo.providedBy(grantinfo) True
>>> grantinfo.getRolesForPermission('P1') []
getRolesForPermission
This is standard behaviour:
>>> roleper = interfaces.IRolePermissionManager(ob3) >>> roleper.grantPermissionToRole('P1', 'role1')
>>> grantinfo.getRolesForPermission('P1') [('role1', PermissionSetting: Allow)]
Now let's set permission in parent:
>>> roleper = interfaces.IRolePermissionManager(ob2) >>> roleper.grantPermissionToRole('P1', 'role2')
>>> grantinfo.getRolesForPermission('P1') [('role1', PermissionSetting: Allow), ('role2', PermissionSetting: Allow)]
>>> roleper = interfaces.IRolePermissionManager(ob1) >>> roleper.grantPermissionToRole('P1', 'role3')
>>> grantinfo.getRolesForPermission('P1') [('role1', PermissionSetting: Allow), ('role3', PermissionSetting: Allow), ('role2', PermissionSetting: Allow)]
>>> roleper.denyPermissionToRole('P1', 'role3')
>>> grantinfo.getRolesForPermission('P1') [('role1', PermissionSetting: Allow), ('role3', PermissionSetting: Deny), ('role2', PermissionSetting: Allow)]
But lower object permissions/role has more weight, now we have role3 denied for P1 permission on ob1, we can allow permission on ob2 so ob3 should have allow for P1 permission on role role3
>>> roleper = interfaces.IRolePermissionManager(ob2) >>> roleper.grantPermissionToRole('P1', 'role3')
>>> grantinfo.getRolesForPermission('P1') [('role1', PermissionSetting: Allow), ('role3', PermissionSetting: Allow), ('role2', PermissionSetting: Allow)]
>>> grantinfo = IExtendedGrantInfo(ob4) >>> grantinfo.getRolesForPermission('P1') [('role3', PermissionSetting: Deny)]
global RolesForPermission
>>> from zope.securitypolicy.rolepermission import rolePermissionManager >>> rolePermissionManager.grantPermissionToRole('P1', 'role4', False)
>>> grantinfo.getRolesForPermission('P1') [('role4', PermissionSetting: Allow), ('role3', PermissionSetting: Deny)]
getRolesForPrincipal
>>> from zope.securitypolicy.principalrole import principalRoleManager >>> principalRoleManager.assignRoleToPrincipal('role10', 'bob', False)
>>> grantinfo = IExtendedGrantInfo(ob3) >>> grantinfo.getRolesForPrincipal('bob') [('role10', PermissionSetting: Allow)]
>>> prinrole = interfaces.IPrincipalRoleManager(ob3) >>> prinrole.assignRoleToPrincipal('role1', 'bob')
>>> grantinfo.getRolesForPrincipal('bob') [('role1', PermissionSetting: Allow), ('role10', PermissionSetting: Allow)]
>>> prinrole = interfaces.IPrincipalRoleManager(ob2) >>> prinrole.assignRoleToPrincipal('role2', 'bob')
>>> grantinfo.getRolesForPrincipal('bob') [('role1', PermissionSetting: Allow), ('role10', PermissionSetting: Allow), ('role2', PermissionSetting: Allow)]
>>> prinrole = interfaces.IPrincipalRoleManager(ob1) >>> prinrole.assignRoleToPrincipal('role3', 'bob')
>>> grantinfo.getRolesForPrincipal('bob') [('role1', PermissionSetting: Allow), ('role10', PermissionSetting: Allow), ('role3', PermissionSetting: Allow), ('role2', PermissionSetting: Allow)]
role3 role allowed for principal 'bob' on ob1, we can deny this role on object ob2 and on ob3 role3 should be denied
>>> prinrole = interfaces.IPrincipalRoleManager(ob2) >>> prinrole.removeRoleFromPrincipal('role3', 'bob')
>>> grantinfo.getRolesForPrincipal('bob') [('role1', PermissionSetting: Allow), ('role10', PermissionSetting: Allow), ('role3', PermissionSetting: Deny), ('role2', PermissionSetting: Allow)]
getPrincipalsForRole
>>> principalRoleManager.assignRoleToPrincipal('role1', 'bob2', False)
This is new method in extended version, it usefull when we need get all principals that have role, for example for cataloging.
>>> grantinfo = IExtendedGrantInfo(ob3) >>> grantinfo.getPrincipalsForRole('role1') [('bob', PermissionSetting: Allow), ('bob2', PermissionSetting: Allow)]
We can get info about other principals with same role
>>> prinrole = interfaces.IPrincipalRoleManager(ob1) >>> prinrole.assignRoleToPrincipal('role1', 'bob1')
>>> grantinfo.getPrincipalsForRole('role1') [('bob', PermissionSetting: Allow), ('bob2', PermissionSetting: Allow), ('bob1', PermissionSetting: Allow)]
getPrincipalsForPermission
>>> from zope.securitypolicy.interfaces import IPrincipalPermissionManager >>> from zope.securitypolicy.principalpermission import principalPermissionManager
>>> principalPermissionManager.grantPermissionToPrincipal('perm1', 'user1', False)
>>> grantinfo = IExtendedGrantInfo(ob3) >>> grantinfo.getPrincipalsForPermission('perm1') [('user1', PermissionSetting: Allow)]
>>> IPrincipalPermissionManager(ob2).denyPermissionToPrincipal('perm1', 'user1') >>> grantinfo.getPrincipalsForPermission('perm1') [('user1', PermissionSetting: Deny)]
CHANGES
1.3.0 (2009-05-29)
- Added 'z3ext:role' and 'z3ext:permission' directives
1.2.6 (2009-03-25)
- Added 'checkPermissionForPrincipal' helper function
1.2.5 (2009-03-15)
- Check IPrincipalRoleMap adapter last
1.2.4 (2009-03-12)
- Fixed permissions/roles calculation in IExtendedGrantInfo
1.2.3 (2009-01-19)
- Added 'getPrincipalsForPermission' to IExtendedGrantInfo interface
1.2.2 (2009-01-09)
- Query all IPrincipalPermissionMap adapter for context
1.2.1 (2008-09-02)
- Fixed bug in extended grant info
1.2.0 (2008-03-21)
- Code cleanup
- Move code to svn.zope.org
1.1.1 (2008-02-16)
- Performance (Profiling)
1.1.0 (2008-02-01)
- Code cleanup
- Removed unused code
1.0.0 (2007-12-08)
- Initial release.