Welcome, guest | Sign In | My Account | Store | Cart

Notice! PyPM is being replaced with the ActiveState Platform, which enhances PyPM’s build and deploy capabilities. Create your free Platform account to download ActivePython or customize Python with the packages you require and get automatic updates.

Download
ActivePython
INSTALL>
pypm install z3ext.security

How to install z3ext.security

  1. Download and install ActivePython
  2. Open Command Prompt
  3. Type pypm install z3ext.security
 Python 2.7Python 3.2Python 3.3
Windows (32-bit)
1.3.0 Available View build log
Windows (64-bit)
1.3.0 Available View build log
Mac OS X (10.5+)
1.3.0 Available View build log
Linux (32-bit)
1.3.0 Available View build log
Linux (64-bit)
1.3.0 Available View build log
Web
 
Author
License
ZPL 2.1
Imports
Lastest release
version 1.3.0 on Jan 5th, 2011

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

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

Bullet list ends without a blank line; unexpected unindent.

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.

Subscribe to package updates

Last updated Jan 5th, 2011

Download Stats

Last month:1

What does the lock icon mean?

Builds marked with a lock icon are only available via PyPM to users with a current ActivePython Business Edition subscription.

Need custom builds or support?

ActivePython Enterprise Edition guarantees priority access to technical support, indemnification, expert consulting and quality-assured language builds.

Plan on re-distributing ActivePython?

Get re-distribution rights and eliminate legal risks with ActivePython OEM Edition.