[Zope3-checkins] CVS: Zope3/src/zope/products/securitypolicy -
__init__.py:1.2 browser.zcml:1.2 configure.zcml:1.2
interfaces.py:1.2 meta.zcml:1.2 metaconfigure.py:1.2
metadirectives.py:1.2 permissionroles.py:1.2
principalpermission.py:1.2 principalrole.py:1.2 role.py:1.2
rolepermission.py:1.2 roleregistry.py:1.2 securitymap.py:1.2
zopepolicy.py:1.2
Chris McDonough
chrism at plope.com
Wed Jan 14 17:56:03 EST 2004
Update of /cvs-repository/Zope3/src/zope/products/securitypolicy
In directory cvs.zope.org:/tmp/cvs-serv5558/src/zope/products/securitypolicy
Added Files:
__init__.py browser.zcml configure.zcml interfaces.py
meta.zcml metaconfigure.py metadirectives.py
permissionroles.py principalpermission.py principalrole.py
role.py rolepermission.py roleregistry.py securitymap.py
zopepolicy.py
Log Message:
Merge security policy refactoring:
- Moved all role- and grant-related functionality into
zope.products.securitypolicy (and out of zope.app.security.grant).
The zope.products.securitypolicy implementation is exactly
the same as the old implementation; no changes were made
to the actual mechanics of role-permission or principal-permission
grants. The only real difference is that all functionality
that is the purview of what we want a security policy to have
control of is now in that one place.
- Created new modulealias directive which can be used to provide
aliases to older modules (to not break existing ZODBs when
module locations change).
- Added minor feature: "make debug" launches a debug session in the
spirit of Zope 2's "zopectl debug".
=== Zope3/src/zope/products/securitypolicy/__init__.py 1.1 => 1.2 ===
--- /dev/null Wed Jan 14 17:56:03 2004
+++ Zope3/src/zope/products/securitypolicy/__init__.py Wed Jan 14 17:55:32 2004
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.
=== Zope3/src/zope/products/securitypolicy/browser.zcml 1.1 => 1.2 ===
--- /dev/null Wed Jan 14 17:56:03 2004
+++ Zope3/src/zope/products/securitypolicy/browser.zcml Wed Jan 14 17:55:32 2004
@@ -0,0 +1,40 @@
+<zope:configure
+ xmlns:zope="http://namespaces.zope.org/zope"
+ xmlns="http://namespaces.zope.org/browser">
+
+<!-- Role Service -->
+
+ <menuItem
+ menu="add_service"
+ for="zope.app.interfaces.container.IAdding"
+ action="RoleService"
+ title="Role Service" />
+
+ <icon
+ name="zmi_icon"
+ for=".role.ILocalRoleService"
+ file="role_service.gif" />
+
+ <pages
+ permission="zope.ManageServices"
+ for=".role.IRoleService"
+ class=".browser.Contents">
+
+ <page name="index.html" attribute="contents"
+ menu="zmi_views" title="Contents" />
+ <page name="removeObjects.html" attribute="removeObjects" />
+
+ </pages>
+
+ <pages
+ permission="zope.ManageServices"
+ for=".role.IRoleService"
+ class=".browser.Add">
+
+ <page name="+" template="addrole.pt"
+ menu="zmi_actions" title="Add" />
+ <page name="action.html" attribute="action" />
+
+ </pages>
+
+</zope:configure>
=== Zope3/src/zope/products/securitypolicy/configure.zcml 1.1 => 1.2 ===
--- /dev/null Wed Jan 14 17:56:03 2004
+++ Zope3/src/zope/products/securitypolicy/configure.zcml Wed Jan 14 17:55:32 2004
@@ -0,0 +1,88 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+ <include file="meta.zcml"/>
+
+ <content class=".permissionroles.PermissionRoles">
+ <require
+ permission="zope.Security"
+ attributes="roles rolesInfo"
+ interface=".interfaces.IRegisteredObject" />
+ </content>
+
+ <content class=".rolepermission.RolePermissions">
+ <require
+ permission="zope.Security"
+ attributes="permissions permissionsInfo"
+ interface=".interfaces.IRegisteredObject" />
+ </content>
+
+ <adapter
+ factory=".rolepermission.AnnotationRolePermissionManager"
+ provides=".interfaces.IRolePermissionManager"
+ for="zope.app.interfaces.annotation.IAnnotatable" />
+
+ <adapter
+ factory=".principalrole.AnnotationPrincipalRoleManager"
+ provides=".interfaces.IPrincipalRoleManager"
+ for="zope.app.interfaces.annotation.IAnnotatable" />
+
+ <adapter
+ factory=".principalpermission.AnnotationPrincipalPermissionManager"
+ provides=".interfaces.IPrincipalPermissionManager"
+ for="zope.app.interfaces.annotation.IAnnotatable" />
+
+ <serviceType
+ id="Roles"
+ interface=".interfaces.IRoleService" />
+
+ <service
+ serviceType="Roles"
+ component=".roleregistry.roleRegistry" />
+
+ <!-- protect Roles and Permissions -->
+ <content class=".roleregistry.Role">
+ <allow interface=".interfaces.IRegisteredObject" />
+ </content>
+
+<!-- XXX (this came out of services/configure.zcml) Role Templates -->
+
+<content class=".role.RoleService">
+ <factory
+ id="RoleService"
+ permission="zope.ManageServices"
+ />
+ <require
+ permission="zope.Security"
+ interface=".interfaces.IRoleService"
+ />
+ <require
+ permission="zope.ManageServices"
+ interface="zope.app.interfaces.container.IContainer"
+ />
+</content>
+
+<content class=".role.Role">
+ <factory />
+ <require
+ permission="zope.Security"
+ interface=".interfaces.IRole"
+ />
+</content>
+
+<!-- create module aliases for users of persistent objects moved
+ during the course of refactoring -->
+
+<modulealias module=".securitymap"
+ alias="zope.app.security.grants.securitymap"/>
+
+<modulealias module=".role"
+ alias="zope.app.services.role" />
+
+<securityPolicy
+ component=".zopepolicy.zopeSecurityPolicy"
+ />
+
+<include package=".browser"/>
+
+</configure>
+
=== Zope3/src/zope/products/securitypolicy/interfaces.py 1.1 => 1.2 ===
--- /dev/null Wed Jan 14 17:56:03 2004
+++ Zope3/src/zope/products/securitypolicy/interfaces.py Wed Jan 14 17:55:32 2004
@@ -0,0 +1,229 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Security map to hold matrix-like relationships."""
+
+from zope.interface import Interface
+from zope.app.interfaces.security import IRegisteredObject
+
+class ISecurityMap(Interface):
+ """Security map to hold matrix-like relationships."""
+
+ def addCell(rowentry, colentry, value):
+ " add a cell "
+
+ def delCell(rowentry, colentry):
+ " delete a cell "
+
+ # XXX queryCell / getCell ?
+ def getCell(rowentry, colentry, default=None):
+ " return the value of a cell by row, entry "
+
+ def getRow(rowentry):
+ " return a list of (colentry, value) tuples from a row "
+
+ def getCol(colentry):
+ " return a list of (rowentry, value) tuples from a col "
+
+ def getAllCells():
+ " return a list of (rowentry, colentry, value) "
+
+class IRole(IRegisteredObject):
+ """A role object."""
+
+class IRoleService(Interface):
+ """Define roles
+
+ 'IRoleService' objects are used to implement role-definition
+ services. Because they implement services, they are expected to
+ collaborate with services in other contexts. Client code doesn't
+ sarch a context and call multiple services. Instead, client code
+ will call the most specific service in a place and rely on the
+ service to delegate to other services as necessary.
+
+ The interface doesn't include methods for data
+ management. Services may use external data and not allow
+ management in Zope. Simularly, the data to be managed may vary
+ with different implementations of a service.
+ """
+
+ def getRole(rid):
+ """Return an 'IRole' object for the given role id."""
+
+
+ def getRoles():
+ """Return a sequence of the roles (IRole objects)
+ defined in the place containing the service."""
+
+
+
+
+class IPrincipalRoleMap(Interface):
+ """Mappings between principals and roles."""
+
+ def getPrincipalsForRole(role_id):
+ """Get the principals that have been granted a role.
+
+ Return the list of (principal id, setting) who have been assigned or
+ removed from a role.
+
+ If no principals have been assigned this role,
+ then the empty list is returned.
+ """
+
+ def getRolesForPrincipal(principal_id):
+ """Get the roles granted to a principal.
+
+ Return the list of (role id, setting) assigned or removed from
+ this principal.
+
+ If no roles have been assigned to
+ this principal, then the empty list is returned.
+ """
+
+ def getSetting(role_id, principal_id):
+ """Return the setting for this principal, role combination
+ """
+
+ def getPrincipalsAndRoles():
+ """Get all settings.
+
+ Return all the principal/role combinations along with the
+ setting for each combination as a sequence of tuples with the
+ role id, principal id, and setting, in that order.
+ """
+
+
+class IPrincipalRoleManager(IPrincipalRoleMap):
+ """Management interface for mappings between principals and roles."""
+
+ def assignRoleToPrincipal(role_id, principal_id):
+ """Assign the role to the principal."""
+
+ def removeRoleFromPrincipal(role_id, principal_id):
+ """Remove a role from the principal."""
+
+ def unsetRoleForPrincipal(role_id, principal_id):
+ """Unset the role for the principal."""
+
+
+class IRolePermissionMap(Interface):
+ """Mappings between roles and permissions."""
+
+ def getPermissionsForRole(role_id):
+ """Get the premissions granted to a role.
+
+ Return a sequence of (permission id, setting) tuples for the given
+ role.
+
+ If no permissions have been granted to this
+ role, then the empty list is returned.
+ """
+
+ def getRolesForPermission(permission_id):
+ """Get the roles that have a permission.
+
+ Return a sequence of (role id, setting) tuples for the given
+ permission.
+
+ If no roles have been granted this permission, then the empty list is
+ returned.
+ """
+
+ def getSetting(permission_id, role_id):
+ """Return the setting for the given permission id and role id
+
+ If there is no setting, Unset is returned
+ """
+
+ def getRolesAndPermissions():
+ """Return a sequence of (permission_id, role_id, setting) here.
+
+ The settings are returned as a sequence of permission, role,
+ setting tuples.
+
+ If no principal/role assertions have been made here, then the empty
+ list is returned.
+ """
+
+
+class IRolePermissionManager(IRolePermissionMap):
+ """Management interface for mappings between roles and permissions."""
+
+ def grantPermissionToRole(permission_id, role_id):
+ """Bind the permission to the role.
+ """
+
+ def denyPermissionToRole(permission_id, role_id):
+ """Deny the permission to the role
+ """
+
+ def unsetPermissionFromRole(permission_id, role_id):
+ """Clear the setting of the permission to the role.
+ """
+
+
+class IPrincipalPermissionMap(Interface):
+ """Mappings between principals and permissions."""
+
+ def getPrincipalsForPermission(permission_id):
+ """Get the principas that have a permission.
+
+ Return the list of (principal_id, setting) tuples that describe
+ security assertions for this permission.
+
+ If no principals have been set for this permission, then the empty
+ list is returned.
+ """
+
+ def getPermissionsForPrincipal(principal_id):
+ """Get the permissions granted to a principal.
+
+ Return the list of (permission, setting) tuples that describe
+ security assertions for this principal.
+
+ If no permissions have been set for this principal, then the empty
+ list is returned.
+ """
+
+ def getSetting(permission_id, principal_id):
+ """Get the setting for a permission and principal.
+
+ Get the setting (Allow/Deny/Unset) for a given permission and
+ principal.
+ """
+
+ def getPrincipalsAndPermissions():
+ """Get all principal permission settings.
+
+ Get the principal security assertions here in the form
+ of a list of three tuple containing
+ (permission id, principal id, setting)
+ """
+
+
+class IPrincipalPermissionManager(IPrincipalPermissionMap):
+ """Management interface for mappings between principals and permissions."""
+
+ def grantPermissionToPrincipal(permission_id, principal_id):
+ """Assert that the permission is allowed for the principal.
+ """
+
+ def denyPermissionToPrincipal(permission_id, principal_id):
+ """Assert that the permission is denied to the principal.
+ """
+
+ def unsetPermissionForPrincipal(permission_id, principal_id):
+ """Remove the permission (either denied or allowed) from the
+ principal.
+ """
=== Zope3/src/zope/products/securitypolicy/meta.zcml 1.1 => 1.2 ===
--- /dev/null Wed Jan 14 17:56:03 2004
+++ Zope3/src/zope/products/securitypolicy/meta.zcml Wed Jan 14 17:55:32 2004
@@ -0,0 +1,17 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:meta="http://namespaces.zope.org/meta">
+
+ <meta:directive
+ namespace="http://namespaces.zope.org/zope"
+ name="grant"
+ schema=".metadirectives.IGrantDirective"
+ handler=".metaconfigure.grant" />
+
+ <meta:directive
+ namespace="http://namespaces.zope.org/zope"
+ name="role"
+ schema=".metadirectives.IDefineRoleDirective"
+ handler=".metaconfigure.defineRole" />
+
+</configure>
=== Zope3/src/zope/products/securitypolicy/metaconfigure.py 1.1 => 1.2 ===
--- /dev/null Wed Jan 14 17:56:03 2004
+++ Zope3/src/zope/products/securitypolicy/metaconfigure.py Wed Jan 14 17:55:32 2004
@@ -0,0 +1,62 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" Register security related configuration directives.
+
+$Id$
+"""
+from zope.products.securitypolicy.rolepermission \
+ import rolePermissionManager as role_perm_mgr
+from zope.products.securitypolicy.principalpermission \
+ import principalPermissionManager as principal_perm_mgr
+from zope.products.securitypolicy.principalrole \
+ import principalRoleManager as principal_role_mgr
+from zope.configuration.exceptions import ConfigurationError
+from zope.products.securitypolicy.roleregistry import roleRegistry as role_reg
+
+
+def grant(_context, principal=None, role=None, permission=None):
+ if ( (principal is not None)
+ + (role is not None)
+ + (permission is not None)
+ ) != 2:
+ raise ConfigurationError(
+ "Exactly two of the principal, role, and permission attributes "
+ "must be specified")
+
+ if principal:
+ if role:
+ _context.action(
+ discriminator = ('grantRoleToPrincipal', role, principal),
+ callable = principal_role_mgr.assignRoleToPrincipal,
+ args = (role, principal) )
+
+ if permission:
+ _context.action(
+ discriminator = ('grantPermissionToPrincipal',
+ permission,
+ principal),
+ callable = principal_perm_mgr.grantPermissionToPrincipal,
+ args = (permission, principal) )
+ else:
+ _context.action(
+ discriminator = ('grantPermissionToRole', permission, role),
+ callable = role_perm_mgr.grantPermissionToRole,
+ args = (permission, role) )
+
+def defineRole(_context, id, title, description=''):
+ _context.action(
+ discriminator = ('defineRole', id),
+ callable = role_reg.defineRole,
+ args = (id, title, description) )
+
=== Zope3/src/zope/products/securitypolicy/metadirectives.py 1.1 => 1.2 ===
--- /dev/null Wed Jan 14 17:56:03 2004
+++ Zope3/src/zope/products/securitypolicy/metadirectives.py Wed Jan 14 17:55:32 2004
@@ -0,0 +1,42 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Grant Directive Schema
+
+$Id$
+"""
+from zope.interface import Interface
+from zope.schema import Id
+from zope.app.security.registries.metadirectives import IBaseDefineDirective
+
+class IGrantDirective(Interface):
+ """Grant Permissions to roles and principals and roles to principals."""
+
+ principal = Id(
+ title=u"Principal",
+ description=u"Specifies the Principal to be mapped.",
+ required=False)
+
+ permission = Id(
+ title=u"Permission",
+ description=u"Specifies the Permission to be mapped.",
+ required=False)
+
+ role = Id(
+ title=u"Role",
+ description=u"Specifies the Role to be mapped.",
+ required=False)
+
+class IDefineRoleDirective(IBaseDefineDirective):
+ """Define a new role."""
+
=== Zope3/src/zope/products/securitypolicy/permissionroles.py 1.1 => 1.2 ===
--- /dev/null Wed Jan 14 17:56:03 2004
+++ Zope3/src/zope/products/securitypolicy/permissionroles.py Wed Jan 14 17:55:32 2004
@@ -0,0 +1,53 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+
+from zope.component import getAdapter
+from zope.products.securitypolicy.interfaces import IRolePermissionManager
+from zope.app.interfaces.security import IPermission
+from zope.app.security.settings import Unset
+from zope.interface import implements
+
+class PermissionRoles:
+
+ implements(IPermission)
+
+ def __init__(self, permission, context, roles):
+ self._permission = permission
+ self._context = context
+ self._roles = roles
+
+ def getId(self):
+ return self._permission.getId()
+
+ def getTitle(self):
+ return self._permission.getTitle()
+
+ def getDescription(self):
+ return self._permission.getDescription()
+
+ def roleSettings(self):
+ """
+ Returns the list of setting names of each role for this permission.
+ """
+ prm = getAdapter(self._context, IRolePermissionManager)
+ proles = prm.getRolesForPermission(self._permission.getId())
+ settings = {}
+ for role, setting in proles:
+ settings[role] = setting.getName()
+ nosetting = Unset.getName()
+ return [settings.get(role.getId(), nosetting) for role in self._roles]
=== Zope3/src/zope/products/securitypolicy/principalpermission.py 1.1 => 1.2 ===
--- /dev/null Wed Jan 14 17:56:03 2004
+++ Zope3/src/zope/products/securitypolicy/principalpermission.py Wed Jan 14 17:55:32 2004
@@ -0,0 +1,163 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Mappings between principals and permissions, stored in an object locally."""
+
+from zope.component import getAdapter
+
+from zope.interface import implements
+from zope.app.interfaces.annotation import IAnnotations
+from zope.products.securitypolicy.interfaces import IPrincipalPermissionManager
+
+from zope.app.security.settings import Allow, Deny, Unset
+from zope.app.security.principal import checkPrincipal
+from zope.app.security.permission import checkPermission
+
+from zope.products.securitypolicy.securitymap import SecurityMap
+
+annotation_key = 'zopel.app.security.AnnotationPrincipalPermissionManager'
+
+class AnnotationPrincipalPermissionManager:
+ """Mappings between principals and permissions."""
+
+ implements(IPrincipalPermissionManager)
+
+ def __init__(self, context):
+ self._context = context
+
+ def grantPermissionToPrincipal(self, permission_id, principal_id):
+ ''' See the interface IPrincipalPermissionManager '''
+ pp = self._getPrincipalPermissions(create=1)
+ pp.addCell(permission_id, principal_id, Allow)
+ self._context._p_changed = 1
+
+ def denyPermissionToPrincipal(self, permission_id, principal_id):
+ ''' See the interface IPrincipalPermissionManager '''
+ pp = self._getPrincipalPermissions(create=1)
+ pp.addCell(permission_id, principal_id, Deny)
+ self._context._p_changed = 1
+
+ def unsetPermissionForPrincipal(self, permission_id, principal_id):
+ ''' See the interface IPrincipalPermissionManager '''
+ pp = self._getPrincipalPermissions()
+ # Only unset if there is a security map, otherwise, we're done
+ if pp:
+ pp.delCell(permission_id, principal_id)
+ self._context._p_changed = 1
+
+ def getPrincipalsForPermission(self, permission_id):
+ ''' See the interface IPrincipalPermissionManager '''
+ pp = self._getPrincipalPermissions()
+ if pp:
+ return pp.getRow(permission_id)
+ return []
+
+ def getPermissionsForPrincipal(self, principal_id):
+ ''' See the interface IPrincipalPermissionManager '''
+ pp = self._getPrincipalPermissions()
+ if pp:
+ return pp.getCol(principal_id)
+ return []
+
+ def getSetting(self, permission_id, principal_id):
+ ''' See the interface IPrincipalPermissionManager '''
+ pp = self._getPrincipalPermissions()
+ if pp:
+ return pp.getCell(permission_id, principal_id, default=Unset)
+ return []
+
+ def getPrincipalsAndPermissions(self):
+ ''' See the interface IPrincipalPermissionManager '''
+ pp = self._getPrincipalPermissions()
+ if pp:
+ return pp.getAllCells()
+ return []
+
+ # Implementation helpers
+
+ def _getPrincipalPermissions(self, create=0):
+ """ Get the principal permission map stored in the context, optionally
+ creating one if necessary """
+ # need to remove security proxies here, otherwise we enter
+ # an infinite loop, becuase checking security depends on
+ # getting PrincipalPermissions.
+ from zope.proxy import removeAllProxies
+ context = removeAllProxies(self._context)
+ annotations = getAdapter(context, IAnnotations)
+ try:
+ return annotations[annotation_key]
+ except KeyError:
+ if create:
+ rp = annotations[annotation_key] = SecurityMap()
+ return rp
+ return None
+
+
+class PrincipalPermissionManager(SecurityMap):
+ """Mappings between principals and permissions."""
+
+ implements(IPrincipalPermissionManager)
+
+ def grantPermissionToPrincipal(self, permission_id, principal_id,
+ check=True):
+ ''' See the interface IPrincipalPermissionManager '''
+
+ if check:
+ checkPermission(None, permission_id)
+ checkPrincipal(None, principal_id)
+
+ self.addCell(permission_id, principal_id, Allow)
+
+ def denyPermissionToPrincipal(self, permission_id, principal_id,
+ check=True):
+ ''' See the interface IPrincipalPermissionManager '''
+
+ if check:
+ checkPermission(None, permission_id)
+ checkPrincipal(None, principal_id)
+
+ self.addCell(permission_id, principal_id, Deny)
+
+ def unsetPermissionForPrincipal(self, permission_id, principal_id):
+ ''' See the interface IPrincipalPermissionManager '''
+
+ # Don't check validity intentionally.
+ # After all, we certianly want to unset invalid ids.
+
+ self.delCell(permission_id, principal_id)
+
+ def getPrincipalsForPermission(self, permission_id):
+ ''' See the interface IPrincipalPermissionManager '''
+ return self.getRow(permission_id)
+
+ def getPermissionsForPrincipal(self, principal_id):
+ ''' See the interface IPrincipalPermissionManager '''
+ return self.getCol(principal_id)
+
+ def getSetting(self, permission_id, principal_id):
+ ''' See the interface IPrincipalPermissionManager '''
+ return self.getCell(permission_id, principal_id, default=Unset)
+
+ def getPrincipalsAndPermissions(self):
+ ''' See the interface IPrincipalPermissionManager '''
+ return self.getAllCells()
+
+
+# Permissions are our rows, and principals are our columns
+principalPermissionManager = PrincipalPermissionManager()
+
+
+# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
+from zope.testing.cleanup import addCleanUp
+addCleanUp(principalPermissionManager._clear)
+del addCleanUp
=== Zope3/src/zope/products/securitypolicy/principalrole.py 1.1 => 1.2 ===
--- /dev/null Wed Jan 14 17:56:03 2004
+++ Zope3/src/zope/products/securitypolicy/principalrole.py Wed Jan 14 17:55:32 2004
@@ -0,0 +1,157 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Mappings between principals and roles, stored in an object locally."""
+
+from zope.component import getAdapter
+from zope.interface import implements
+
+from zope.security.proxy import trustedRemoveSecurityProxy
+
+from zope.app.interfaces.annotation import IAnnotations
+from zope.products.securitypolicy.interfaces import IPrincipalRoleManager
+from zope.products.securitypolicy.interfaces import IPrincipalRoleMap
+
+from zope.app.security.settings import Allow, Deny, Unset
+from zope.products.securitypolicy.securitymap import SecurityMap
+from zope.products.securitypolicy.securitymap import PersistentSecurityMap
+
+from zope.app.security.principal import checkPrincipal
+from zope.products.securitypolicy.role import checkRole
+
+annotation_key = 'zope.app.security.AnnotationPrincipalRoleManager'
+
+class AnnotationPrincipalRoleManager:
+ """Mappings between principals and roles."""
+
+ implements(IPrincipalRoleManager)
+
+ def __init__(self, context):
+ self._context = context
+
+ def assignRoleToPrincipal(self, role_id, principal_id):
+ ''' See the interface IPrincipalRoleManager '''
+ pp = self._getPrincipalRoles(create=1)
+ pp.addCell(role_id, principal_id, Allow)
+
+ def removeRoleFromPrincipal(self, role_id, principal_id):
+ ''' See the interface IPrincipalRoleManager '''
+ pp = self._getPrincipalRoles(create=1)
+ pp.addCell(role_id, principal_id, Deny)
+
+ def unsetRoleForPrincipal(self, role_id, principal_id):
+ ''' See the interface IPrincipalRoleManager '''
+ pp = self._getPrincipalRoles()
+ # Only unset if there is a security map, otherwise, we're done
+ if pp:
+ pp.delCell(role_id, principal_id)
+
+ def getPrincipalsForRole(self, role_id):
+ ''' See the interface IPrincipalRoleManager '''
+ pp = self._getPrincipalRoles()
+ if pp:
+ return pp.getRow(role_id)
+ return []
+
+ def getRolesForPrincipal(self, principal_id):
+ ''' See the interface IPrincipalRoleManager '''
+ pp = self._getPrincipalRoles()
+ if pp:
+ return pp.getCol(principal_id)
+ return []
+
+ def getSetting(self, role_id, principal_id):
+ ''' See the interface IPrincipalRoleManager '''
+ pp = self._getPrincipalRoles()
+ if pp:
+ return pp.getCell(role_id, principal_id, default=Unset)
+ return Unset
+
+ def getPrincipalsAndRoles(self):
+ ''' See the interface IPrincipalRoleManager '''
+ pp = self._getPrincipalRoles()
+ if pp:
+ return pp.getAllCells()
+ return []
+
+ # Implementation helpers
+
+ def _getPrincipalRoles(self, create=0):
+ """ Get the principal role map stored in the context, optionally
+ creating one if necessary """
+ annotations = getAdapter(self._context, IAnnotations)
+ try:
+ # there's a chance that annotations is security proxied -
+ # remove proxy to avoid authentication failure on role lookup
+ return trustedRemoveSecurityProxy(annotations)[annotation_key]
+ except KeyError:
+ if create:
+ rp = annotations[annotation_key] = PersistentSecurityMap()
+ return rp
+ return None
+
+
+class PrincipalRoleManager(SecurityMap):
+ """Mappings between principals and roles."""
+
+ implements(IPrincipalRoleManager, IPrincipalRoleMap)
+
+ def assignRoleToPrincipal(self, role_id, principal_id, check=True):
+ ''' See the interface IPrincipalRoleManager '''
+
+ if check:
+ checkPrincipal(None, principal_id)
+ checkRole(None, role_id)
+
+ self.addCell(role_id, principal_id, Allow)
+
+ def removeRoleFromPrincipal(self, role_id, principal_id, check=True):
+ ''' See the interface IPrincipalRoleManager '''
+
+ if check:
+ checkPrincipal(None, principal_id)
+ checkRole(None, role_id)
+
+ self.addCell(role_id, principal_id, Deny)
+
+ def unsetRoleForPrincipal(self, role_id, principal_id):
+ ''' See the interface IPrincipalRoleManager '''
+
+ # Don't check validity intentionally.
+ # After all, we certianly want to unset invalid ids.
+
+ self.delCell(role_id, principal_id)
+
+ def getPrincipalsForRole(self, role_id):
+ ''' See the interface IPrincipalRoleMap '''
+ return self.getRow(role_id)
+
+ def getRolesForPrincipal(self, principal_id):
+ ''' See the interface IPrincipalRoleMap '''
+ return self.getCol(principal_id)
+
+ def getSetting(self, role_id, principal_id):
+ ''' See the interface IPrincipalRoleMap '''
+ return self.getCell(role_id, principal_id, default=Unset)
+
+ def getPrincipalsAndRoles(self):
+ ''' See the interface IPrincipalRoleMap '''
+ return self.getAllCells()
+
+# Roles are our rows, and principals are our columns
+principalRoleManager = PrincipalRoleManager()
+
+# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
+from zope.testing.cleanup import addCleanUp
+addCleanUp(principalRoleManager._clear)
+del addCleanUp
=== Zope3/src/zope/products/securitypolicy/role.py 1.1 => 1.2 ===
--- /dev/null Wed Jan 14 17:56:03 2004
+++ Zope3/src/zope/products/securitypolicy/role.py Wed Jan 14 17:55:32 2004
@@ -0,0 +1,61 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from persistence import Persistent
+from zope.products.securitypolicy.roleregistry import Role
+from zope.app.container.btree import BTreeContainer
+from zope.products.securitypolicy.interfaces import IRoleService
+from zope.app.interfaces.container import IContainer
+from zope.app.component.nextservice import getNextService
+from zope.app.interfaces.services.service import ISimpleService
+from zope.interface import implements
+from zope.component import getService
+
+class Role(Role, Persistent):
+ "Persistent Role"
+
+class ILocalRoleService(IRoleService, IContainer):
+ """TTW manageable role service"""
+
+class RoleService(BTreeContainer):
+
+ implements(ILocalRoleService, ISimpleService)
+
+ def getRole(wrapped_self, rid):
+ '''See interface IRoleService'''
+ try:
+ return wrapped_self[rid]
+ except KeyError:
+ # We failed locally: delegate to a higher-level service.
+ sv = getNextService(wrapped_self, 'Roles')
+ if sv:
+ return sv.getRole(rid)
+ raise # will be original Key Error
+
+ def getRoles(wrapped_self):
+ '''See interface IRoleService'''
+ roles = list(wrapped_self.values())
+ roleserv = getNextService(wrapped_self, 'Roles')
+ if roleserv:
+ roles.extend(roleserv.getRoles())
+ return roles
+
+def checkRole(context, role_id):
+ if not getService(context, 'Roles').getRole(role_id):
+ raise ValueError("Undefined role id", role_id)
=== Zope3/src/zope/products/securitypolicy/rolepermission.py 1.1 => 1.2 ===
--- /dev/null Wed Jan 14 17:56:03 2004
+++ Zope3/src/zope/products/securitypolicy/rolepermission.py Wed Jan 14 17:55:32 2004
@@ -0,0 +1,206 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+from zope.component import getAdapter
+from zope.interface import implements
+
+from zope.app.interfaces.annotation import IAnnotations
+
+from zope.app.security.settings import Allow, Deny, Unset
+from zope.products.securitypolicy.role import checkRole
+from zope.app.security.permission import checkPermission
+
+from zope.products.securitypolicy.interfaces import IRolePermissionManager
+from zope.products.securitypolicy.interfaces import IRole
+from zope.products.securitypolicy.interfaces import IRolePermissionMap
+from zope.products.securitypolicy.securitymap import PersistentSecurityMap
+from zope.products.securitypolicy.securitymap import SecurityMap
+
+# the annotation_key is a holdover from this module's old location, but cannot
+# change without breaking existing databases
+annotation_key = 'zope.app.security.AnnotationRolePermissionManager'
+
+class AnnotationRolePermissionManager:
+ """
+ provide adapter that manages role permission data in an object attribute
+ """
+
+ implements(IRolePermissionManager, IRolePermissionMap)
+
+ def __init__(self, context):
+ self._context = context
+
+ def grantPermissionToRole(self, permission_id, role_id):
+ ''' See the interface IRolePermissionManager '''
+ rp = self._getRolePermissions(create=1)
+ rp.addCell(permission_id, role_id, Allow)
+ # probably not needed, as annotations should manage
+ # their own persistence
+ #self._context._p_changed = 1
+
+ def denyPermissionToRole(self, permission_id, role_id):
+ ''' See the interface IRolePermissionManager '''
+ rp = self._getRolePermissions(create=1)
+ rp.addCell(permission_id, role_id, Deny)
+ # probably not needed, as annotations should manage
+ # their own persistence
+ #self._context._p_changed = 1
+
+ def unsetPermissionFromRole(self, permission_id, role_id):
+ ''' See the interface IRolePermissionManager '''
+ rp = self._getRolePermissions()
+ # Only unset if there is a security map, otherwise, we're done
+ if rp:
+ rp.delCell(permission_id, role_id)
+ # probably not needed, as annotations should manage
+ # their own persistence
+ #self._context._p_changed = 1
+
+ def getRolesForPermission(self, permission_id):
+ '''See interface IRolePermissionMap'''
+ rp = self._getRolePermissions()
+ if rp:
+ return rp.getRow(permission_id)
+ else:
+ return []
+
+ def getPermissionsForRole(self, role_id):
+ '''See interface IRolePermissionMap'''
+ rp = self._getRolePermissions()
+ if rp:
+ return rp.getCol(role_id)
+ else:
+ return []
+
+ def getRolesAndPermissions(self):
+ '''See interface IRolePermissionMap'''
+ rp = self._getRolePermissions()
+ if rp:
+ return rp.getAllCells()
+ else:
+ return []
+
+ def getSetting(self, permission_id, role_id):
+ '''See interface IRolePermissionMap'''
+ rp = self._getRolePermissions()
+ if rp:
+ return rp.getCell(permission_id, role_id)
+ else:
+ return Unset
+
+ def _getRolePermissions(self, create=0):
+ """Get the role permission map stored in the context, optionally
+ creating one if necessary"""
+ # need to remove security proxies here, otherwise we enter
+ # an infinite loop, becuase checking security depends on
+ # getting RolePermissions.
+ from zope.proxy import removeAllProxies
+ context = removeAllProxies(self._context)
+ annotations = getAdapter(context, IAnnotations)
+ try:
+ return annotations[annotation_key]
+ except KeyError:
+ if create:
+ rp = annotations[annotation_key] = PersistentSecurityMap()
+ return rp
+ return None
+
+class RolePermissions:
+
+ implements(IRole)
+
+ def __init__(self, role, context, permissions):
+ self._role = role
+ self._context = context
+ self._permissions = permissions
+
+ def getId(self):
+ return self._role.getId()
+
+ def getTitle(self):
+ return self._role.getTitle()
+
+ def getDescription(self):
+ return self._role.getDescription()
+
+ def permissionsInfo(self):
+ prm = getAdapter(self._context, IRolePermissionManager)
+ rperms = prm.getPermissionsForRole(self._role.getId())
+ settings = {}
+ for permission, setting in rperms:
+ settings[permission] = setting.getName()
+ nosetting = Unset.getName()
+ return [{'id': permission.getId(),
+ 'title': permission.getTitle(),
+ 'setting': settings.get(permission.getId(), nosetting)}
+ for permission in self._permissions]
+
+
+class RolePermissionManager(SecurityMap):
+ """Mappings between roles and permissions."""
+
+ implements(IRolePermissionManager)
+
+ def grantPermissionToRole(self, permission_id, role_id, check=True):
+ '''See interface IRolePermissionMap'''
+
+ if check:
+ checkRole(None, role_id)
+ checkPermission(None, permission_id)
+
+ self.addCell(permission_id, role_id, Allow)
+
+ def denyPermissionToRole(self, permission_id, role_id, check=True):
+ '''See interface IRolePermissionMap'''
+
+ if check:
+ checkRole(None, role_id)
+ checkPermission(None, permission_id)
+
+ self.addCell(permission_id, role_id, Deny)
+
+ def unsetPermissionFromRole(self, permission_id, role_id):
+ '''See interface IRolePermissionMap'''
+
+ # Don't check validity intentionally.
+ # After all, we certianly want to unset invalid ids.
+
+ self.delCell(permission_id, role_id)
+
+ def getRolesForPermission(self, permission_id):
+ '''See interface IRolePermissionMap'''
+ return self.getRow(permission_id)
+
+ def getPermissionsForRole(self, role_id):
+ '''See interface IRolePermissionMap'''
+ return self.getCol(role_id)
+
+ def getSetting(self, permission_id, role_id):
+ '''See interface IRolePermissionMap'''
+ return self.getCell(permission_id, role_id)
+
+ def getRolesAndPermissions(self):
+ '''See interface IRolePermissionMap'''
+ return self.getAllCells()
+
+# Permissions are our rows, and roles are our columns
+rolePermissionManager = RolePermissionManager()
+
+# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
+from zope.testing.cleanup import addCleanUp
+addCleanUp(rolePermissionManager._clear)
+del addCleanUp
=== Zope3/src/zope/products/securitypolicy/roleregistry.py 1.1 => 1.2 ===
--- /dev/null Wed Jan 14 17:56:03 2004
+++ Zope3/src/zope/products/securitypolicy/roleregistry.py Wed Jan 14 17:55:32 2004
@@ -0,0 +1,82 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Global role registry."""
+
+PREFIX = 'Global Role'
+
+from zope.app.security.registries.registeredobject import RegisteredObject
+from zope.app.security.registries.registry import Registry
+from zope.products.securitypolicy.interfaces import IRole
+from zope.products.securitypolicy.interfaces import IRoleService
+from zope.app.interfaces.services.service import ISimpleService
+from zope.interface import implements
+
+class Role(RegisteredObject):
+ implements(IRole)
+
+
+class RoleRegistry(Registry):
+ implements(IRoleService, ISimpleService)
+
+ def __init__(self, prefix=PREFIX):
+ Registry.__init__(self, Role)
+ self._prefix = prefix
+
+ def _make_global_id(self, suffix):
+ return self._prefix + '.' + suffix
+
+ def defineRole(self, role, title, description=None):
+ """Define a new role object, register, and return it.
+
+ role is the role name.
+
+ title is the role title, human readable.
+
+ description (optional) is human readable
+ """
+ if description is None:
+ description = ''
+ id = role
+ return self.register(id, title, description)
+
+ def definedRole(self, id):
+ """Return true if named role is registered, otherwise return false
+ """
+ return self.is_registered(id)
+
+ def getRole(self, id):
+ """Return role object registered as name.
+
+ If no named role is registered KeyError is raised.
+ """
+ return self.getRegisteredObject(id)
+
+ def getRoles(self):
+ """Return all registered role objects.
+ """
+ return self.getRegisteredObjects()
+
+ def _clear(self):
+ # Standard roles
+ Registry._clear(self)
+ self.register("zope.Anonymous", "Everybody",
+ "All users have this role implicitly")
+
+roleRegistry = RoleRegistry()
+
+
+# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
+from zope.testing.cleanup import addCleanUp
+addCleanUp(roleRegistry._clear)
+del addCleanUp
=== Zope3/src/zope/products/securitypolicy/securitymap.py 1.1 => 1.2 ===
--- /dev/null Wed Jan 14 17:56:03 2004
+++ Zope3/src/zope/products/securitypolicy/securitymap.py Wed Jan 14 17:55:32 2004
@@ -0,0 +1,88 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" Generic two-dimensional array type """
+
+from persistence import Persistent
+from persistence.dict import PersistentDict
+from zope.interface import implements
+from zope.products.securitypolicy.interfaces import ISecurityMap
+
+class SecurityMap(object):
+
+ implements(ISecurityMap)
+
+ def __init__(self):
+ self._clear()
+
+ def _clear(self):
+ self._byrow = {}
+ self._bycol = {}
+
+ def _empty_mapping(self):
+ return {}
+
+ def addCell(self, rowentry, colentry, value):
+ # setdefault may get expensive if an empty mapping is
+ # expensive to create, for PersistentDict for instance.
+ row = self._byrow.setdefault(rowentry, self._empty_mapping())
+ row[colentry] = value
+
+ col = self._bycol.setdefault(colentry, self._empty_mapping())
+ col[rowentry] = value
+
+ def delCell(self, rowentry, colentry):
+ row = self._byrow.get(rowentry)
+ if row and (colentry in row):
+ del self._byrow[rowentry][colentry]
+ del self._bycol[colentry][rowentry]
+
+ def getCell(self, rowentry, colentry, default=None):
+ " return the value of a cell by row, entry "
+ row = self._byrow.get(rowentry)
+ if row: return row.get(colentry, default)
+ else: return default
+
+ def getRow(self, rowentry):
+ " return a list of (colentry, value) tuples from a row "
+ row = self._byrow.get(rowentry)
+ if row:
+ return row.items()
+ else: return []
+
+ def getCol(self, colentry):
+ " return a list of (rowentry, value) tuples from a col "
+ col = self._bycol.get(colentry)
+ if col:
+ return col.items()
+ else: return []
+
+ def getAllCells(self):
+ " return a list of (rowentry, colentry, value) "
+ res = []
+ for r in self._byrow.keys():
+ for c in self._byrow[r].items():
+ res.append((r,) + c)
+ return res
+
+
+class PersistentSecurityMap(SecurityMap, Persistent):
+
+ implements(ISecurityMap)
+
+ def _clear(self):
+ self._byrow = PersistentDict()
+ self._bycol = PersistentDict()
+
+ def _empty_mapping(self):
+ return PersistentDict()
=== Zope3/src/zope/products/securitypolicy/zopepolicy.py 1.1 => 1.2 ===
--- /dev/null Wed Jan 14 17:56:03 2004
+++ Zope3/src/zope/products/securitypolicy/zopepolicy.py Wed Jan 14 17:55:32 2004
@@ -0,0 +1,291 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" Define Zope\'s default security policy
+
+$Id$
+"""
+__version__='$Revision$'[11:-2]
+
+from zope.component import queryAdapter
+from zope.app.location import LocationIterator
+
+from zope.security.interfaces import ISecurityPolicy
+from zope.security.management import system_user
+
+from zope.products.securitypolicy.interfaces import \
+ IRolePermissionMap, IPrincipalPermissionMap, IPrincipalRoleMap
+from zope.products.securitypolicy.principalpermission \
+ import principalPermissionManager
+from zope.products.securitypolicy.rolepermission import rolePermissionManager
+from zope.products.securitypolicy.principalrole import principalRoleManager
+from zope.app.security.settings import Allow, Deny
+from zope.interface import implements
+
+getPermissionsForPrincipal = \
+ principalPermissionManager.getPermissionsForPrincipal
+getPermissionsForRole = rolePermissionManager.getPermissionsForRole
+getRolesForPrincipal = principalRoleManager.getRolesForPrincipal
+
+globalContext = object()
+
+
+class ZopeSecurityPolicy:
+
+ implements(ISecurityPolicy)
+
+ def __init__(self, ownerous=True, authenticated=True):
+ """
+ Two optional keyword arguments may be provided:
+
+ ownerous -- Untrusted users can create code
+ (e.g. Python scripts or templates),
+ so check that code owners can access resources.
+ The argument must have a truth value.
+ The default is true.
+
+ authenticated -- Allow access to resources based on the
+ privileges of the authenticated user.
+ The argument must have a truth value.
+ The default is true.
+
+ This (somewhat experimental) option can be set
+ to false on sites that allow only public
+ (unauthenticated) access. An anticipated
+ scenario is a ZEO configuration in which some
+ clients allow only public access and other
+ clients allow full management.
+ """
+
+ self._ownerous = ownerous
+ self._authenticated = authenticated
+
+ def checkPermission(self, permission, object, context):
+ # XXX We aren't really handling multiple principals yet
+
+ # mapping from principal to set of roles
+ user = context.user
+ if user is system_user:
+ return True
+
+ roledict = {'zope.Anonymous': Allow}
+ principals = {user.getId() : roledict}
+
+ role_permissions = {}
+ remove = {}
+
+ # Look for placeless grants first.
+
+ # get placeless principal permissions
+ for principal in principals:
+ for principal_permission, setting in (
+ getPermissionsForPrincipal(principal)):
+ if principal_permission == permission:
+ if setting is Deny:
+ return False
+ assert setting is Allow
+ remove[principal] = True
+
+ # Clean out removed principals
+ if remove:
+ for principal in remove:
+ del principals[principal]
+ if principals:
+ # not done yet
+ remove.clear()
+ else:
+ # we've eliminated all the principals
+ return True
+
+ # get placeless principal roles
+ for principal in principals:
+ roles = principals[principal]
+ for role, setting in getRolesForPrincipal(principal):
+ assert setting in (Allow, Deny)
+ if role not in roles:
+ roles[role] = setting
+
+ for perm, role, setting in (
+ rolePermissionManager.getRolesAndPermissions()):
+ assert setting in (Allow, Deny)
+ if role not in role_permissions:
+ role_permissions[role] = {perm: setting}
+ else:
+ if perm not in role_permissions[role]:
+ role_permissions[role][perm] = setting
+
+ # Get principal permissions based on roles
+ for principal in principals:
+ roles = principals[principal]
+ for role, role_setting in roles.items():
+ if role_setting is Deny:
+ return False
+ if role in role_permissions:
+ if permission in role_permissions[role]:
+ setting = role_permissions[role][permission]
+ if setting is Deny:
+ return False
+ remove[principal] = True
+
+
+ # Clean out removed principals
+ if remove:
+ for principal in remove:
+ del principals[principal]
+ if principals:
+ # not done yet
+ remove.clear()
+ else:
+ # we've eliminated all the principals
+ return True
+
+ # Look for placeful grants
+ for place in LocationIterator(object):
+
+ # Copy specific principal permissions
+ prinper = queryAdapter(place, IPrincipalPermissionMap)
+ if prinper is not None:
+ for principal in principals:
+ for principal_permission, setting in (
+ prinper.getPermissionsForPrincipal(principal)):
+ if principal_permission == permission:
+ if setting is Deny:
+ return False
+
+ assert setting is Allow
+ remove[principal] = True
+
+ # Clean out removed principals
+ if remove:
+ for principal in remove:
+ del principals[principal]
+ if principals:
+ # not done yet
+ remove.clear()
+ else:
+ # we've eliminated all the principals
+ return True
+
+ # Collect principal roles
+ prinrole = queryAdapter(place, IPrincipalRoleMap)
+ if prinrole is not None:
+ for principal in principals:
+ roles = principals[principal]
+ for role, setting in (
+ prinrole.getRolesForPrincipal(principal)):
+ assert setting in (Allow, Deny)
+ if role not in roles:
+ roles[role] = setting
+
+ # Collect role permissions
+ roleper = queryAdapter(place, IRolePermissionMap)
+ if roleper is not None:
+ for perm, role, setting in roleper.getRolesAndPermissions():
+ assert setting in (Allow, Deny)
+ if role not in role_permissions:
+ role_permissions[role] = {perm: setting}
+ else:
+ if perm not in role_permissions[role]:
+ role_permissions[role][perm] = setting
+
+ # Get principal permissions based on roles
+ for principal in principals:
+ roles = principals[principal]
+ for role, role_setting in roles.items():
+ if role_setting is Deny:
+ return False
+ if role in role_permissions:
+ if permission in role_permissions[role]:
+ setting = role_permissions[role][permission]
+ if setting is Deny:
+ return False
+ remove[principal] = True
+
+ # Clean out removed principals
+ if remove:
+ for principal in remove:
+ del principals[principal]
+ if principals:
+ # not done yet
+ remove.clear()
+ else:
+ # we've eliminated all the principals
+ return True
+
+ return False # deny by default
+
+
+def permissionsOfPrincipal(principal, object):
+ permissions = {}
+
+ roles = {'zope.Anonymous': Allow}
+ principalid = principal.getId()
+
+ # Make two passes.
+
+ # First, collect what we know about the principal:
+
+
+ # get placeless principal permissions
+ for permission, setting in getPermissionsForPrincipal(principalid):
+ if permission not in permissions:
+ permissions[permission] = setting
+
+ # get placeless principal roles
+ for role, setting in getRolesForPrincipal(principalid):
+ if role not in roles:
+ roles[role] = setting
+
+ # get placeful principal permissions and roles
+ for place in LocationIterator(object):
+
+ # Copy specific principal permissions
+ prinper = queryAdapter(place, IPrincipalPermissionMap)
+ if prinper is not None:
+ for permission, setting in prinper.getPermissionsForPrincipal(
+ principalid):
+ if permission not in permissions:
+ permissions[permission] = setting
+
+ # Collect principal roles
+ prinrole = queryAdapter(place, IPrincipalRoleMap)
+ if prinrole is not None:
+ for role, setting in prinrole.getRolesForPrincipal(principalid):
+ if role not in roles:
+ roles[role] = setting
+
+ # Second, update permissions using principal
+
+ for perm, role, setting in (
+ rolePermissionManager.getRolesAndPermissions()):
+ if role in roles and perm not in permissions:
+ permissions[perm] = setting
+
+ for place in LocationIterator(object):
+
+ # Collect role permissions
+ roleper = queryAdapter(place, IRolePermissionMap)
+ if roleper is not None:
+ for perm, role, setting in roleper.getRolesAndPermissions():
+ if role in roles and perm not in permissions:
+ permissions[perm] = setting
+
+
+
+ result = [permission
+ for permission in permissions
+ if permissions[permission] is Allow]
+
+ return result
+
+zopeSecurityPolicy=ZopeSecurityPolicy()
More information about the Zope3-Checkins
mailing list