[Zope3-checkins] CVS: Zope3/src/zope/app/security - __init__.py:1.2 _protections.py:1.2 basicauthadapter.py:1.2 basicvfsauthadapter.py:1.2 configure.zcml:1.2 exceptions.py:1.2 loginpassword.py:1.2 meta.zcml:1.2 metaconfigure.py:1.2 permissionfield.py:1.2 protectclass.py:1.2 settings.py:1.2 zopesecuritypolicy.py:1.2

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


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

Added Files:
	__init__.py _protections.py basicauthadapter.py 
	basicvfsauthadapter.py configure.zcml exceptions.py 
	loginpassword.py meta.zcml metaconfigure.py permissionfield.py 
	protectclass.py settings.py zopesecuritypolicy.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/__init__.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:46 2002
+++ Zope3/src/zope/app/security/__init__.py	Wed Dec 25 09:13:15 2002
@@ -0,0 +1,18 @@
+##############################################################################
+#
+# Copyright (c) 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 some standard types
+import _protections
+_protections.protect()
+del _protections


=== Zope3/src/zope/app/security/_protections.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:46 2002
+++ Zope3/src/zope/app/security/_protections.py	Wed Dec 25 09:13:15 2002
@@ -0,0 +1,110 @@
+##############################################################################
+#
+# 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 protection information for some standard low-level types
+
+Revision information:
+$Id$
+"""
+
+def protect():
+    from zope.security.checker import defineChecker, NamesChecker, NoProxy
+
+
+    # excluding _check, _bucket_type, _firstbucket, and write operations
+    _btreeChecker = NamesChecker(['__str__', '__repr__', '__contains__',
+                                  '__getitem__', '__iter__', '__len__',
+                                  'byValue', 'get', 'has_key', 'items',
+                                  'iteritems', 'iterkeys', 'itervalues',
+                                  'keys', 'maxKey', 'minKey', 'values'])
+
+    # excluding _next
+    _btreeBucketChecker = NamesChecker([
+            '__contains__', '__getitem__', '__iter__', '__len__', '__repr__',
+            '__str__', 'byValue', 'get', 'has_key', 'items', 'iteritems',
+            'iterkeys', 'itervalues', 'keys', 'maxKey','minKey', 'values'])
+
+    _btreeSetChecker = NamesChecker([
+            '__contains__', '__getitem__', '__iter__', '__len__', '__repr__',
+            '__str__', 'has_key', 'insert', 'keys', 'maxKey', 'minKey'])
+
+    # excluding _bucket_type, _check
+    _btreeTreeSetChecker = NamesChecker([
+            '__contains__', '__iter__', '__len__', '__repr__',
+            '__str__', 'has_key', 'insert', 'keys', 'maxKey', 'minKey'])
+
+    _btreeItemsChecker = NamesChecker([
+            '__iter__', '__repr__', '__str__', '__getitem__', '__len__',
+            '__contains__'])
+
+    _iteratorChecker = NamesChecker(['next'])
+
+    from zodb.btrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet
+    from zodb.btrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet
+    from zodb.btrees.OIBTree import OIBTree, OIBucket, OISet, OITreeSet
+    from zodb.btrees.OOBTree import OOBTree, OOBucket, OOSet, OOTreeSet
+
+    _btree_checkers = {
+        IIBTree: _btreeChecker,
+        IOBTree: _btreeChecker,
+        OIBTree: _btreeChecker,
+        OOBTree: _btreeChecker,
+        IIBucket: _btreeBucketChecker,
+        IOBucket: _btreeBucketChecker,
+        OIBucket: _btreeBucketChecker,
+        OOBucket: _btreeBucketChecker,
+        IISet: _btreeSetChecker,
+        IOSet: _btreeSetChecker,
+        OISet: _btreeSetChecker,
+        OOSet: _btreeSetChecker,
+        IITreeSet: _btreeTreeSetChecker,
+        IOTreeSet: _btreeTreeSetChecker,
+        OITreeSet: _btreeTreeSetChecker,
+        OOTreeSet: _btreeTreeSetChecker,
+        type(iter(IIBTree())): NoProxy, # II-iterator is a rock
+        type(iter(IOBTree())): _iteratorChecker, # IO-iterator
+        type(iter(OIBTree())): _iteratorChecker, # OI-iterator
+        type(iter(OOBTree())): _iteratorChecker, # OO-iterator
+        type(IIBTree().keys()): NoProxy, # IIBTreeItems is a rock
+        type(IOBTree().keys()): _btreeItemsChecker, # IOBTreeItems
+        type(OIBTree().keys()): _btreeItemsChecker, # OIBTreeItems
+        type(OOBTree().keys()): _btreeItemsChecker, # OOBTreeItems
+    }
+    for which_type, checker in _btree_checkers.iteritems():
+        defineChecker(which_type, checker)
+
+    from persistence.list import PersistentList
+
+    defineChecker(PersistentList,
+                  NamesChecker(
+                     ['__getitem__', '__getslice__', '__len__', '__iter__',
+                      '__contains__', 'index', 'count'])
+                  )
+
+    from persistence.dict import PersistentDict
+
+    defineChecker(PersistentDict,
+                  NamesChecker(['__getitem__', '__len__', '__iter__',
+                        'get', 'has_key', '__copy__',
+                        'keys', 'values', 'items',
+                        'iterkeys', 'iteritems', 'itervalues', '__contains__',
+                        ]
+                     )
+                  )
+
+    # In Python 2.3 and up, PersistentMetaClass is just type.
+    # It causes an error to define a new checker for type.
+    from persistence import PersistentMetaClass
+    if PersistentMetaClass != type:
+        from zope.security.checker import _typeChecker
+        defineChecker(PersistentMetaClass, _typeChecker)


=== Zope3/src/zope/app/security/basicauthadapter.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:46 2002
+++ Zope3/src/zope/app/security/basicauthadapter.py	Wed Dec 25 09:13:15 2002
@@ -0,0 +1,36 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+# HTTP Basic Authentication adapter
+
+from zope.publisher.interfaces.http import IHTTPCredentials
+from zope.app.security.loginpassword import LoginPassword
+
+class BasicAuthAdapter(LoginPassword):
+
+    __used_for__ = IHTTPCredentials
+
+    __request = None
+
+    def __init__(self, request):
+        self.__request = request
+        # XXX base64 decoding should be done here, not in request
+        lpw = request._authUserPW()
+        if lpw is None:
+            login, password = None, None
+        else:
+            login, password = lpw
+        LoginPassword.__init__(self, login, password)
+
+    def needLogin(self, realm):
+        self.__request.unauthorized("basic realm=%s" % realm)


=== Zope3/src/zope/app/security/basicvfsauthadapter.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/basicvfsauthadapter.py	Wed Dec 25 09:13:15 2002
@@ -0,0 +1,36 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+# HTTP Basic Authentication adapter
+
+from zope.publisher.interfaces.vfs import IVFSCredentials
+from zope.app.security.loginpassword import LoginPassword
+
+class BasicVFSAuthAdapter(LoginPassword):
+
+    __used_for__ = IVFSCredentials
+
+    __request = None
+
+    def __init__(self, request):
+        self.__request = request
+        # XXX base64 decoding should be done here, not in request
+        lpw = request._authUserPW()
+        if lpw is None:
+            login, password = None, None
+        else:
+            login, password = lpw
+        LoginPassword.__init__(self, login, password)
+
+    def needLogin(self, realm):
+        self.__request.unauthorized("Did not work")


=== Zope3/src/zope/app/security/configure.zcml 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/configure.zcml	Wed Dec 25 09:13:15 2002
@@ -0,0 +1,60 @@
+<zopeConfigure
+   xmlns='http://namespaces.zope.org/zope'
+   xmlns:browser='http://namespaces.zope.org/browser'
+   >
+
+  <include package=".registries" />
+
+  <!-- Standard Permissions -->
+
+  <permission id="zope.View"
+                       title="View"
+                       />
+
+  <permission id="zope.Security"
+                       title="Change security settings"
+                       />
+
+  <permission id="zope.ManageContent" 
+                       title="Manage Content"
+                       />
+
+  <permission id="zope.ManageBindings" 
+                       title="Manage Service Bindings"
+                       />
+
+  <permission id="zope.ManageCode" 
+                       title="Manage Code"
+                       description="Manage executable code, including
+                                    Python, SQL, ZPT, etc."
+                        />
+
+  <permission id="zope.ManageServices" 
+                       title="Manage Services"
+                        />
+
+  <!-- XXX What is this for? -->
+  <permission id="zope.ManageApplication" 
+                       title="Manage Application"
+                       />
+
+  <!-- XXX What is this for? -->
+  <permission id="zope.I18n" 
+                       title="Use Internationalization (?XXX)"
+                       />
+
+  <include package=".grants" />
+
+  <securityPolicy 
+      name="zope.app.security.zopesecuritypolicy.zopeSecurityPolicy" />
+
+  <adapter factory="zope.app.security.basicauthadapter.BasicAuthAdapter"
+           provides="zope.app.interfaces.security.ILoginPassword"
+           for="zope.publisher.interfaces.http.IHTTPCredentials" />
+
+  <adapter factory="zope.app.security.basicvfsauthadapter.BasicVFSAuthAdapter"
+           provides="zope.app.interfaces.security.ILoginPassword"
+           for="zope.publisher.interfaces.vfs.IVFSCredentials" />
+
+</zopeConfigure>
+


=== Zope3/src/zope/app/security/exceptions.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/exceptions.py	Wed Dec 25 09:13:15 2002
@@ -0,0 +1,22 @@
+##############################################################################
+#
+# 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$
+"""
+
+class UndefinedPermissionError(Exception):
+    """Somebody tried to use a permission before it was defined.
+    """


=== Zope3/src/zope/app/security/loginpassword.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/loginpassword.py	Wed Dec 25 09:13:15 2002
@@ -0,0 +1,34 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+from zope.app.interfaces.security import ILoginPassword
+
+class LoginPassword:
+
+    __implements__ = ILoginPassword
+
+    def __init__(self, login, password):
+        self.__login = login
+        if login is None:
+            self.__password = None
+        else:
+            self.__password = password or ""
+
+    def getLogin(self):
+        return self.__login
+
+    def getPassword(self):
+        return self.__password
+
+    def needLogin(self, realm):
+        pass


=== Zope3/src/zope/app/security/meta.zcml 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/meta.zcml	Wed Dec 25 09:13:15 2002
@@ -0,0 +1,11 @@
+<zopeConfigure xmlns='http://namespaces.zope.org/zope'>
+
+  <include package=".registries" file="meta.zcml" />
+  <include package=".grants" file="meta.zcml" />
+
+  <directives namespace="http://namespaces.zope.org/zope">
+    <directive name="securityPolicy" attributes="name"
+       handler="zope.app.security.metaconfigure.securityPolicy" />
+  </directives>
+
+</zopeConfigure>


=== Zope3/src/zope/app/security/metaconfigure.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/metaconfigure.py	Wed Dec 25 09:13:15 2002
@@ -0,0 +1,32 @@
+##############################################################################
+#
+# 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.configuration.action import Action
+from zope.security.securitymanager import setSecurityPolicy
+
+def securityPolicy(_context, name):
+    policy = _context.resolve(name)
+    if callable(policy):
+        policy = policy()
+    return [
+        Action(
+            discriminator = 'defaultPolicy',
+            callable = setSecurityPolicy,
+            args = (policy,),
+            )
+        ]


=== Zope3/src/zope/app/security/permissionfield.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/permissionfield.py	Wed Dec 25 09:13:15 2002
@@ -0,0 +1,32 @@
+##############################################################################
+#
+# Copyright (c) 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.
+#
+##############################################################################
+"""These are the interfaces for the common fields.
+
+$Id$
+"""
+
+from zope.schema import ValueSet
+from zope.schema.interfaces import ValidationError
+from zope.component import getService
+from zope.app.interfaces.security import IPermissionField
+
+class PermissionField(ValueSet):
+    __doc__ = IPermissionField.__doc__
+    __implements__ = IPermissionField
+
+    def _validate(self, value):
+        super(PermissionField, self)._validate(value)
+        service = getService(self.context, 'Permissions')
+        if service.getPermission(value.getId()) is None:
+            raise ValidationError("Unknown permission", value)


=== Zope3/src/zope/app/security/protectclass.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/protectclass.py	Wed Dec 25 09:13:15 2002
@@ -0,0 +1,84 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Make assertions about permissions needed to access class instances attributes
+"""
+
+from zope.app.security.exceptions import UndefinedPermissionError
+from zope.app.security.registries.permissionregistry import permissionRegistry
+
+from zope.security.checker import defineChecker, getCheckerForInstancesOf
+from zope.security.checker import Checker, CheckerPublic
+
+def checkPermission(permission):
+    """Check to make sure that the permission is valid.
+    """
+    if not permissionRegistry.definedPermission(permission):
+        raise UndefinedPermissionError(permission)
+
+def protectName(class_, name, permission):
+    "Set a permission on a particular name."
+
+    checkPermission(permission)
+
+    checker = getCheckerForInstancesOf(class_)
+    if checker is None:
+        checker = Checker({}.get, {}.get)
+        defineChecker(class_, checker)
+
+    if permission == 'zope.Public':
+        # Translate public permission to CheckerPublic
+        permission = CheckerPublic
+
+    # We know a dictionart get method was used because we set it
+    protections = checker.getPermission_func().__self__
+    protections[name] = permission
+
+def protectSetAttribute(class_, name, permission):
+    "Set a permission on a particular name."
+
+    checkPermission(permission)
+
+    checker = getCheckerForInstancesOf(class_)
+    if checker is None:
+        checker = Checker({}.get, {}.get)
+        defineChecker(class_, checker)
+
+    if permission == 'zope.Public':
+        # Translate public permission to CheckerPublic
+        permission = CheckerPublic
+
+    # We know a dictionart get method was used because we set it
+    protections = checker.getSetattrPermission_func().__self__
+    protections[name] = permission
+
+def protectLikeUnto(class_, like_unto):
+    """Use the protections from like_unto for class_
+    """
+
+    unto_checker = getCheckerForInstancesOf(like_unto)
+    if unto_checker is None:
+        return
+
+    # We know a dictionart get method was used because we set it
+    unto_protections = unto_checker.getPermission_func().__self__
+
+    checker = getCheckerForInstancesOf(class_)
+    if checker is None:
+        checker = Checker({}.get)
+        defineChecker(class_, checker)
+
+    # OK, so it's a hack.
+    protections = checker.getPermission_func().__self__
+    for name in unto_protections:
+        protections[name] = unto_protections[name]


=== Zope3/src/zope/app/security/settings.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/settings.py	Wed Dec 25 09:13:16 2002
@@ -0,0 +1,66 @@
+##############################################################################
+#
+# 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 setting constants """
+
+
+class PermissionSetting(object):
+    """PermissionSettings should be considered as immutable.
+    They can be compared by identity. They are identified by
+    their name.
+    """
+
+    def __new__(cls, name, description=None):
+        """Keep a dict of PermissionSetting instances, indexed by
+        name. If the name already exists in the dict, return that
+        instance rather than creating a new one.
+        """
+        instances = cls.__dict__.get('__instances__')
+        if instances is None:
+            cls.__instances__ = instances = {}
+        it = instances.get(name)
+        if it is None:
+            instances[name] = it = object.__new__(cls)
+            it._init(name, description)
+        return it
+
+    def _init(self, name, description):
+        self.__name = name
+        self.__description = description
+
+    def getDescription(self):
+        return self.__description
+
+    def getName(self):
+        return self.__name
+
+    def __str__(self):
+        return "PermissionSetting: %s" % self.__name
+
+# register PermissionSettings to be symbolic constants by identity,
+# even when pickled and unpickled.
+import copy_reg
+copy_reg.constructor(PermissionSetting)
+copy_reg.pickle(PermissionSetting,
+                PermissionSetting.getName,
+                PermissionSetting)
+
+
+Allow = PermissionSetting('Allow',
+    'Explicit allow setting for permissions')
+
+Deny = PermissionSetting('Deny',
+    'Explicit deny setting for permissions')
+
+Unset = PermissionSetting('Unset',
+    'Unset constant that denotes no setting for permission and role')


=== Zope3/src/zope/app/security/zopesecuritypolicy.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/security/zopesecuritypolicy.py	Wed Dec 25 09:13:16 2002
@@ -0,0 +1,299 @@
+##############################################################################
+#
+# 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.proxy.context import ContainmentIterator
+
+from zope.exceptions import Unauthorized, Forbidden
+
+from zope.security.interfaces import ISecurityPolicy
+from zope.security.securitymanagement import system_user
+
+from zope.app.interfaces.security \
+     import IRolePermissionManager, IRolePermissionMap
+from zope.app.interfaces.security \
+    import IPrincipalPermissionManager, IPrincipalPermissionMap
+from zope.app.interfaces.security \
+    import IPrincipalRoleManager, IPrincipalRoleMap
+from zope.app.interfaces.security import IRolePermissionManager
+from zope.app.security.registries.permissionregistry import permissionRegistry
+from zope.app.security.registries.principalregistry import principalRegistry
+from zope.app.security.registries.roleregistry import roleRegistry
+from zope.app.security.grants.principalpermissionmanager \
+     import principalPermissionManager
+from zope.app.security.grants.rolepermissionmanager \
+     import rolePermissionManager
+from zope.app.security.grants.principalrolemanager \
+     import principalRoleManager
+from zope.app.security.settings import Allow, Deny
+
+getPermissionsForPrincipal = \
+                principalPermissionManager.getPermissionsForPrincipal
+getPermissionsForRole = rolePermissionManager.getPermissionsForRole
+getRolesForPrincipal = principalRoleManager.getRolesForPrincipal
+
+globalContext = object()
+
+class ZopeSecurityPolicy:
+
+    __implements__ = ISecurityPolicy
+
+    def __init__(self, ownerous=1, authenticated=1):
+        """
+            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
+                privaledges 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 1
+
+        principals = {user : {'Anonymous': Allow}}
+
+        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 0
+                    assert setting is Allow
+                    remove[principal] = 1
+
+        # 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 1
+
+
+        # 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 in roles:
+                if role in role_permissions:
+                    if permission in role_permissions[role]:
+                        setting = role_permissions[role][permission]
+                        if setting is Deny:
+                            return 0
+                        remove[principal] = 1
+
+
+        # 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 1
+
+        # Look for placeful grants
+        for place in ContainmentIterator(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 0
+
+                            assert setting is Allow
+                            remove[principal] = 1
+
+            # 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 1
+
+            # 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 in roles:
+                    if role in role_permissions:
+                        if permission in role_permissions[role]:
+                            setting = role_permissions[role][permission]
+                            if setting is Deny:
+                                return 0
+                            remove[principal] = 1
+
+            # 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 1
+
+        return 0 # deny by default
+
+
+def permissionsOfPrincipal(principal, object):
+    permissions = {}
+    roles = {'Anonymous': Allow} # Everyone has anonymous
+    role_permissions = {}
+
+    # Make two passes.
+
+    # First, collect what we know about the principal:
+
+
+    # get placeless principal permissions
+    for permission, setting in getPermissionsForPrincipal(principal):
+        if permission not in permissions:
+            permissions[permission] = setting
+
+    # get placeless principal roles
+    for role, setting in getRolesForPrincipal(principal):
+        if role not in roles:
+            roles[role] = setting
+
+    # get placeful principal permissions and roles
+    for place in ContainmentIterator(object):
+
+        # Copy specific principal permissions
+        prinper = queryAdapter(place, IPrincipalPermissionMap)
+        if prinper is not None:
+            for permission, setting in prinper.getPermissionsForPrincipal(
+                principal):
+                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(principal):
+                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 ContainmentIterator(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()