[Zope3-checkins] CVS: Zope3/src/zope/app/security/grants - __init__.py:1.2 annotationprincipalpermissionmanager.py:1.2 annotationprincipalrolemanager.py:1.2 annotationrolepermissionmanager.py:1.2 configure.zcml:1.2 localsecuritymap.py:1.2 meta.zcml:1.2 metaconfigure.py:1.2 permissionroles.py:1.2 persistentlocalsecuritymap.py:1.2 principalpermissionmanager.py:1.2 principalrolemanager.py:1.2 rolepermissionmanager.py:1.2 rolepermissions.py:1.2

Jim Fulton jim@zope.com
Wed, 25 Dec 2002 09:13:48 -0500


Update of /cvs-repository/Zope3/src/zope/app/security/grants
In directory cvs.zope.org:/tmp/cvs-serv15352/src/zope/app/security/grants

Added Files:
	__init__.py annotationprincipalpermissionmanager.py 
	annotationprincipalrolemanager.py 
	annotationrolepermissionmanager.py configure.zcml 
	localsecuritymap.py meta.zcml metaconfigure.py 
	permissionroles.py persistentlocalsecuritymap.py 
	principalpermissionmanager.py principalrolemanager.py 
	rolepermissionmanager.py rolepermissions.py 
Log Message:
Grand renaming:

- Renamed most files (especially python modules) to lower case.

- Moved views and interfaces into separate hierarchies within each
  project, where each top-level directory under the zope package
  is a separate project.

- Moved everything to src from lib/python.

  lib/python will eventually go away. I need access to the cvs
  repository to make this happen, however.

There are probably some bits that are broken. All tests pass
and zope runs, but I haven't tried everything. There are a number
of cleanups I'll work on tomorrow.



=== Zope3/src/zope/app/security/grants/__init__.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/grants/__init__.py	Wed Dec 25 09:13:16 2002
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.


=== Zope3/src/zope/app/security/grants/annotationprincipalpermissionmanager.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/grants/annotationprincipalpermissionmanager.py	Wed Dec 25 09:13:16 2002
@@ -0,0 +1,98 @@
+##############################################################################
+#
+# 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.app.interfaces.annotation import IAnnotations
+from zope.app.interfaces.security \
+     import IPrincipalPermissionManager
+from zope.app.security.grants.localsecuritymap import LocalSecurityMap
+from zope.app.security.settings import Allow, Deny, Unset
+
+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.introspection import removeAllProxies
+        context = removeAllProxies(self._context)
+        annotations = getAdapter(context, IAnnotations)
+        try:
+            return annotations[annotation_key]
+        except KeyError:
+            if create:
+                rp = annotations[annotation_key] = LocalSecurityMap()
+                return rp
+        return None


=== Zope3/src/zope/app/security/grants/annotationprincipalrolemanager.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/grants/annotationprincipalrolemanager.py	Wed Dec 25 09:13:16 2002
@@ -0,0 +1,91 @@
+##############################################################################
+#
+# 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.app.interfaces.annotation import IAnnotations
+from zope.app.interfaces.security \
+     import IPrincipalRoleManager
+from zope.app.security.grants.persistentlocalsecuritymap import \
+     PersistentLocalSecurityMap
+from zope.app.security.settings import Allow, Deny, Unset
+
+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:
+            return annotations[annotation_key]
+        except KeyError:
+            if create:
+                rp = annotations[annotation_key] = PersistentLocalSecurityMap()
+                return rp
+        return None


=== Zope3/src/zope/app/security/grants/annotationrolepermissionmanager.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/grants/annotationrolepermissionmanager.py	Wed Dec 25 09:13:16 2002
@@ -0,0 +1,112 @@
+##############################################################################
+#
+# 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.app.interfaces.annotation import IAnnotations
+from zope.app.interfaces.security import IRolePermissionManager
+from zope.app.interfaces.security import IRolePermissionMap
+from zope.app.security.grants.persistentlocalsecuritymap import \
+     PersistentLocalSecurityMap
+from zope.app.security.settings import Allow, Deny, Unset
+
+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.introspection import removeAllProxies
+        context = removeAllProxies(self._context)
+        annotations = getAdapter(context, IAnnotations)
+        try:
+            return annotations[annotation_key]
+        except KeyError:
+            if create:
+                rp = annotations[annotation_key] = PersistentLocalSecurityMap()
+                return rp
+        return None


=== Zope3/src/zope/app/security/grants/configure.zcml 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/grants/configure.zcml	Wed Dec 25 09:13:16 2002
@@ -0,0 +1,34 @@
+<zopeConfigure
+   xmlns='http://namespaces.zope.org/zope'
+   xmlns:browser='http://namespaces.zope.org/browser'
+   package="zope.app.security"
+>
+
+  <content class="zope.app.security.grants.permissionroles.PermissionRoles">
+    <require
+        permission="zope.Security"
+        attributes="roles rolesInfo"
+        interface="zope.app.interfaces.security.IRegisteredObject" />
+  </content>
+
+  <content class="zope.app.security.grants.rolepermissions.RolePermissions">
+    <require
+        permission="zope.Security"
+        attributes="permissions permissionsInfo"
+        interface="zope.app.interfaces.security.IRegisteredObject" />
+  </content>
+
+  <adapter factory="zope.app.security.grants.annotationrolepermissionmanager.AnnotationRolePermissionManager"
+           provides="zope.app.interfaces.security.IRolePermissionManager"
+           for="zope.app.interfaces.annotation.IAnnotatable" />
+
+  <adapter factory="zope.app.security.grants.annotationprincipalrolemanager.AnnotationPrincipalRoleManager"
+           provides="zope.app.interfaces.security.IPrincipalRoleManager"
+           for="zope.app.interfaces.annotation.IAnnotatable" />
+
+  <adapter factory="zope.app.security.grants.annotationprincipalpermissionmanager.AnnotationPrincipalPermissionManager"
+           provides="zope.app.interfaces.security.IPrincipalPermissionManager"
+           for="zope.app.interfaces.annotation.IAnnotatable" />
+
+</zopeConfigure>
+


=== Zope3/src/zope/app/security/grants/localsecuritymap.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/grants/localsecuritymap.py	Wed Dec 25 09:13:16 2002
@@ -0,0 +1,73 @@
+##############################################################################
+#
+# 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 zope.app.interfaces.security.grants.localsecuritymap import ILocalSecurityMap
+
+class LocalSecurityMap(object):
+
+    __implements__ = ILocalSecurityMap
+
+    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


=== Zope3/src/zope/app/security/grants/meta.zcml 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/grants/meta.zcml	Wed Dec 25 09:13:16 2002
@@ -0,0 +1,10 @@
+<zopeConfigure xmlns='http://namespaces.zope.org/zope'>
+
+  <directives namespace="http://namespaces.zope.org/zope">
+
+    <directive name="grant" attributes="principal permission role"
+       handler="zope.app.security.grants.metaconfigure.grant" />
+
+  </directives>
+
+</zopeConfigure>


=== Zope3/src/zope/app/security/grants/metaconfigure.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/grants/metaconfigure.py	Wed Dec 25 09:13:16 2002
@@ -0,0 +1,63 @@
+##############################################################################
+#
+# 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.app.security.grants.rolepermissionmanager \
+     import rolePermissionManager as role_perm_mgr
+from zope.app.security.grants.principalpermissionmanager \
+     import principalPermissionManager as principal_perm_mgr
+from zope.app.security.grants.principalrolemanager \
+     import principalRoleManager as principal_role_mgr
+from zope.configuration.action import Action
+from zope.configuration.exceptions import ConfigurationError
+
+
+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:
+            return [
+                Action(
+                discriminator = ('grantRoleToPrincipal', role, principal),
+                callable = principal_role_mgr.assignRoleToPrincipal,
+                args = (role, principal),
+                )
+                ]
+        if permission:
+            return [
+                Action(
+                discriminator = ('grantPermissionToPrincipal',
+                                 permission,
+                                 principal),
+                callable = principal_perm_mgr.grantPermissionToPrincipal,
+                args = (permission, principal),
+                )
+                ]
+    else:
+        return [
+            Action(
+            discriminator = ('grantPermissionToRole', permission, role),
+            callable = role_perm_mgr.grantPermissionToRole,
+            args = (permission, role),
+            )
+            ]


=== Zope3/src/zope/app/security/grants/permissionroles.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:48 2002
+++ Zope3/src/zope/app/security/grants/permissionroles.py	Wed Dec 25 09:13:16 2002
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# 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.app.interfaces.security import IRolePermissionManager
+from zope.app.interfaces.security import IPermission
+from zope.app.security.settings import Unset, Allow, Deny
+
+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/app/security/grants/persistentlocalsecuritymap.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:48 2002
+++ Zope3/src/zope/app/security/grants/persistentlocalsecuritymap.py	Wed Dec 25 09:13:16 2002
@@ -0,0 +1,30 @@
+##############################################################################
+#
+# 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.app.interfaces.security.grants.localsecuritymap import ILocalSecurityMap
+from zope.app.security.grants.localsecuritymap import LocalSecurityMap
+
+class PersistentLocalSecurityMap(LocalSecurityMap, Persistent):
+
+    __implements__ = ILocalSecurityMap
+
+    def _clear(self):
+        self._byrow = PersistentDict()
+        self._bycol = PersistentDict()
+
+    def _empty_mapping(self):
+        return PersistentDict()


=== Zope3/src/zope/app/security/grants/principalpermissionmanager.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:48 2002
+++ Zope3/src/zope/app/security/grants/principalpermissionmanager.py	Wed Dec 25 09:13:16 2002
@@ -0,0 +1,63 @@
+##############################################################################
+#
+# 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."""
+
+from zope.app.interfaces.security \
+     import IPrincipalPermissionManager
+from zope.app.security.grants.localsecuritymap import LocalSecurityMap
+from zope.app.security.settings import Allow, Deny, Unset
+
+
+class PrincipalPermissionManager(LocalSecurityMap):
+    """Mappings between principals and permissions."""
+
+    __implements__ = IPrincipalPermissionManager
+
+    def grantPermissionToPrincipal( self, permission_id, principal_id ):
+        ''' See the interface IPrincipalPermissionManager '''
+        self.addCell( permission_id, principal_id, Allow )
+
+    def denyPermissionToPrincipal( self, permission_id, principal_id ):
+        ''' See the interface IPrincipalPermissionManager '''
+        self.addCell( permission_id, principal_id, Deny )
+
+    def unsetPermissionForPrincipal( self, permission_id, principal_id ):
+        ''' See the interface IPrincipalPermissionManager '''
+        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/app/security/grants/principalrolemanager.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:48 2002
+++ Zope3/src/zope/app/security/grants/principalrolemanager.py	Wed Dec 25 09:13:16 2002
@@ -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.
+#
+##############################################################################
+"""Mappings between principals and roles."""
+
+from zope.app.security.grants.localsecuritymap import LocalSecurityMap
+from zope.app.security.settings import Allow, Deny, Unset
+from zope.app.interfaces.security import IPrincipalRoleManager
+from zope.app.interfaces.security import IPrincipalRoleMap
+
+
+
+class PrincipalRoleManager(LocalSecurityMap):
+    """Mappings between principals and roles."""
+
+    __implements__ = ( IPrincipalRoleManager, IPrincipalRoleMap )
+
+    def assignRoleToPrincipal( self, role_id, principal_id ):
+        ''' See the interface IPrincipalRoleManager '''
+        self.addCell( role_id, principal_id, Allow )
+
+    def removeRoleFromPrincipal( self, role_id, principal_id ):
+        ''' See the interface IPrincipalRoleManager '''
+        self.addCell( role_id, principal_id, Deny )
+
+    def unsetRoleForPrincipal( self, role_id, principal_id ):
+        ''' See the interface IPrincipalRoleManager '''
+        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/app/security/grants/rolepermissionmanager.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:48 2002
+++ Zope3/src/zope/app/security/grants/rolepermissionmanager.py	Wed Dec 25 09:13:16 2002
@@ -0,0 +1,60 @@
+##############################################################################
+#
+# 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 roles and permissions."""
+
+from zope.app.security.grants.localsecuritymap import LocalSecurityMap
+from zope.app.security.settings import Allow, Deny
+from zope.app.interfaces.security import IRolePermissionManager
+
+
+class RolePermissionManager(LocalSecurityMap):
+    """Mappings between roles and permissions."""
+
+    __implements__ = IRolePermissionManager
+
+    def grantPermissionToRole( self, permission_id, role_id ):
+        '''See interface IRolePermissionMap'''
+        self.addCell( permission_id, role_id, Allow )
+
+    def denyPermissionToRole( self, permission_id, role_id ):
+        '''See interface IRolePermissionMap'''
+        self.addCell( permission_id, role_id, Deny )
+
+    def unsetPermissionFromRole( self, permission_id, role_id ):
+        '''See interface IRolePermissionMap'''
+        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/app/security/grants/rolepermissions.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:48 2002
+++ Zope3/src/zope/app/security/grants/rolepermissions.py	Wed Dec 25 09:13:16 2002
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# 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.app.interfaces.security import IRolePermissionManager
+from zope.app.interfaces.security import IRole
+from zope.app.security.settings import Unset
+
+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]