[Zope3-checkins] CVS: Zope3/src/zope/security - __init__.py:1.2.26.1 _proxy.c:1.3.22.1 checker.py:1.22.4.1 context.py:1.3.10.1 interfaces.py:1.6.18.1 management.py:1.3.12.1 manager.py:1.3.16.1 proxy.py:1.5.2.1 simplepolicies.py:1.4.10.1
Grégoire Weber
zope@i-con.ch
Sun, 22 Jun 2003 10:24:28 -0400
Update of /cvs-repository/Zope3/src/zope/security
In directory cvs.zope.org:/tmp/cvs-serv24874/src/zope/security
Modified Files:
Tag: cw-mail-branch
__init__.py _proxy.c checker.py context.py interfaces.py
management.py manager.py proxy.py simplepolicies.py
Log Message:
Synced up with HEAD
=== Zope3/src/zope/security/__init__.py 1.2 => 1.2.26.1 ===
--- Zope3/src/zope/security/__init__.py:1.2 Wed Dec 25 09:15:21 2002
+++ Zope3/src/zope/security/__init__.py Sun Jun 22 10:23:53 2003
@@ -1,2 +1,7 @@
#
# This file is necessary to make this directory a package.
+
+
+# XXX There's a circular import problem with the proxy package.
+# The proxy framework needs some refactoring, but not today.
+import zope.proxy
=== Zope3/src/zope/security/_proxy.c 1.3 => 1.3.22.1 ===
--- Zope3/src/zope/security/_proxy.c:1.3 Fri Feb 7 15:16:35 2003
+++ Zope3/src/zope/security/_proxy.c Sun Jun 22 10:23:53 2003
@@ -852,21 +852,6 @@
};
static PyObject *
-module_getObject(PyObject *self, PyObject *arg)
-{
- PyObject *result;
-
- if (!Proxy_Check(arg)) {
- PyErr_SetString(PyExc_TypeError,
- "getObject argument must be a _Proxy");
- return NULL;
- }
- result = Proxy_GetObject(arg);
- Py_INCREF(result);
- return result;
-}
-
-static PyObject *
module_getChecker(PyObject *self, PyObject *arg)
{
PyObject *result;
@@ -883,7 +868,6 @@
static PyMethodDef
module_functions[] = {
- {"getObject", module_getObject, METH_O, "get object from proxy"},
{"getChecker", module_getChecker, METH_O, "get checker from proxy"},
{NULL}
};
@@ -911,7 +895,7 @@
SecurityProxyType.ob_type = &PyType_Type;
SecurityProxyType.tp_alloc = PyType_GenericAlloc;
SecurityProxyType.tp_free = _PyObject_GC_Del;
- SecurityProxyType.tp_base = ProxyType;
+ SecurityProxyType.tp_base = &ProxyType;
if (PyType_Ready(&SecurityProxyType) < 0)
return;
=== Zope3/src/zope/security/checker.py 1.22 => 1.22.4.1 ===
--- Zope3/src/zope/security/checker.py:1.22 Sat May 3 12:38:17 2003
+++ Zope3/src/zope/security/checker.py Sun Jun 22 10:23:53 2003
@@ -13,6 +13,13 @@
##############################################################################
"""
$Id$
+
+You can set the environment variable ZOPE_WATCH_CHECKERS to get additional
+security checker debugging output on the standard error.
+
+Setting ZOPE_WATCH_CHECKERS to 1 will display messages about unauthorized or
+forbidden attribute access. Setting it to a larger number will also display
+messages about granted attribute access.
"""
import os
@@ -20,24 +27,28 @@
import types
import datetime
-from zope.interface import directlyProvides, Interface
+from zope.interface import directlyProvides, Interface, implements
from zope.interface.interfaces import IInterface, IInterfaceSpecification
from zope.interface.declarations import ObjectSpecification
from zope.interface.declarations import ProvidesSpecification
-from zope.interface.declarations import OnlyImplementsSpecification
+from zope.interface.declarations import ImplementsOnlySpecification
from zope.interface.declarations import ImplementsSpecification
from zope.interface.declarations import InterfaceSpecification
-from zope.security.interfaces import IChecker
+from zope.security.interfaces import IChecker, INameBasedChecker
from zope.security.interfaces import ISecurityProxyFactory
from zope.security.management import getSecurityManager
-from zope.security._proxy import _Proxy as Proxy
-from zope.exceptions \
- import Unauthorized, ForbiddenAttribute, DuplicationError
+from zope.security._proxy import _Proxy as Proxy, getChecker
+from zope.exceptions import Unauthorized, ForbiddenAttribute, DuplicationError
+
+__metaclass__ = type
if os.environ.get('ZOPE_WATCH_CHECKERS'):
- WATCH_CHECKERS = True
+ try:
+ WATCH_CHECKERS = int(os.environ.get('ZOPE_WATCH_CHECKERS'))
+ except ValueError:
+ WATCH_CHECKERS = 1
else:
- WATCH_CHECKERS = False
+ WATCH_CHECKERS = 0
def ProxyFactory(object, checker=None):
@@ -45,29 +56,43 @@
The proxy checker is looked up if not provided.
"""
-
+ if type(object) is Proxy:
+ if checker is None or checker is getChecker(object):
+ return object
+ else:
+ # We have a proxy, but someone asked us to change its checker.
+ # Let's raise an exception.
+ #
+ # Other reasonable actions would be to either keep the existing
+ # proxy, or to create a new one with the given checker.
+ # The latter might be a security hole though, if untrusted code
+ # can call ProxyFactory.
+ raise TypeError("Tried to use ProxyFactory to change a Proxy's"
+ " checker.")
if checker is None:
checker = getattr(object, '__Security_checker__', None)
- if checker is None:
-
- checker = selectChecker(object)
if checker is None:
- return object
-
+ checker = selectChecker(object)
+ if checker is None:
+ return object
else:
- # Maybe someone passed us a proxy and a checker
- if type(object) is Proxy:
- # XXX should we keep the existing proxy or create a new one.
- return object
-
+ c = getattr(object, '__Security_checker__', None)
+ if c is not None:
+ pass
+ # XXX This is odd. We're being asked to use a checker that is
+ # not the "natural" one for this object.
return Proxy(object, checker)
directlyProvides(ProxyFactory, ISecurityProxyFactory)
-class Checker:
- __implements__ = IChecker
+class TrustedCheckerBase:
+ """Marker type used by zope.security.proxy.trustedRemoveSecurityProxy"""
+
+
+class Checker(TrustedCheckerBase):
+ implements(INameBasedChecker)
def __init__(self, permission_func,
setattr_permission_func=lambda name: None
@@ -93,7 +118,6 @@
setattr_permission_func = setattr_permission_func.get
self._setattr_permission_func = setattr_permission_func
-
def getPermission_func(self):
return self._permission_func
@@ -101,13 +125,11 @@
return self._setattr_permission_func
def permission_id(self, name):
- """Return the result of calling the permission func
- """
+ 'See INameBasedChecker'
return self._permission_func(name)
def setattr_permission_id(self, name):
- """Return the result of calling the permission func
- """
+ 'See INameBasedChecker'
return self._setattr_permission_func(name)
def check_getattr(self, object, name):
@@ -116,72 +138,216 @@
def check_setattr(self, object, name):
'See IChecker'
-
- if WATCH_CHECKERS:
- print >> sys.stderr, ('Checking %r.%s:' % (object, name)),
-
- # We have the information we need already
permission = self._setattr_permission_func(name)
- if permission:
+ if permission is not None:
if permission is CheckerPublic:
- if WATCH_CHECKERS:
- print >> sys.stderr, 'Public.'
return # Public
manager = getSecurityManager()
if manager.checkPermission(permission, object):
- if WATCH_CHECKERS:
- print >> sys.stderr, 'Granted.'
return
else:
- if WATCH_CHECKERS:
- print >> sys.stderr, 'Unauthorized.'
__traceback_supplement__ = (TracebackSupplement, object)
- raise Unauthorized(name=name)
+ raise Unauthorized, name
+
+ __traceback_supplement__ = (TracebackSupplement, object)
+ raise ForbiddenAttribute, name
- if WATCH_CHECKERS:
- print >> sys.stderr, 'Forbidden.'
+ def check(self, object, name):
+ 'See IChecker'
+ permission = self._permission_func(name)
+ if permission is not None:
+ if permission is CheckerPublic:
+ return # Public
+ manager = getSecurityManager()
+ if manager.checkPermission(permission, object):
+ return
+ else:
+ __traceback_supplement__ = (TracebackSupplement, object)
+ raise Unauthorized, name
+ elif name in _always_available:
+ return
__traceback_supplement__ = (TracebackSupplement, object)
- raise ForbiddenAttribute(name)
+ raise ForbiddenAttribute, name
+
+ def proxy(self, value):
+ 'See IChecker'
+ checker = getattr(value, '__Security_checker__', None)
+ if checker is None:
+ checker = selectChecker(value)
+ if checker is None:
+ return value
+
+ return Proxy(value, checker)
+
+
+class CombinedChecker(TrustedCheckerBase):
+ """A checker that combines two other checkers in a logical-or fashion.
+
+ The following table describes the result of a combined checker in detail.
+
+ checker1 checker2 CombinedChecker(checker1, checker2)
+ ------------------ ------------------ -----------------------------------
+ ok anything ok (checker2 is never called)
+ Unauthorized ok ok
+ Unauthorized Unauthorized Unauthorized
+ Unauthorized ForbiddenAttribute Unauthorized
+ ForbiddenAttribute ok ok
+ ForbiddenAttribute Unauthorized Unauthorized
+ ForbiddenAttribute ForbiddenAttribute ForbiddenAttribute
+ ------------------ ------------------ -----------------------------------
+ """
+ implements(IChecker)
+
+ def __init__(self, checker1, checker2):
+ """Create a combined checker."""
+ self._checker1 = checker1
+ self._checker2 = checker2
def check(self, object, name):
'See IChecker'
+ try:
+ self._checker1.check(object, name)
+ except ForbiddenAttribute:
+ self._checker2.check(object, name)
+ except Unauthorized, unauthorized_exception:
+ try: self._checker2.check(object, name)
+ except ForbiddenAttribute:
+ raise unauthorized_exception
+
+ def check_getattr(self, object, name):
+ 'See IChecker'
+ try:
+ self._checker1.check_getattr(object, name)
+ except ForbiddenAttribute:
+ self._checker2.check_getattr(object, name)
+ except Unauthorized, unauthorized_exception:
+ try: self._checker2.check_getattr(object, name)
+ except ForbiddenAttribute:
+ raise unauthorized_exception
+
+ def check_setattr(self, object, name):
+ 'See IChecker'
+ try:
+ self._checker1.check_setattr(object, name)
+ except ForbiddenAttribute:
+ self._checker2.check_setattr(object, name)
+ except Unauthorized, unauthorized_exception:
+ try: self._checker2.check_setattr(object, name)
+ except ForbiddenAttribute:
+ raise unauthorized_exception
+
+ def proxy(self, value):
+ 'See IChecker'
+ checker = getattr(value, '__Security_checker__', None)
+ if checker is None:
+ checker = selectChecker(value)
+ if checker is None:
+ return value
+
+ return Proxy(value, checker)
+
+
+class DecoratedChecker(TrustedCheckerBase):
+ """A checker using further permissions relative to an original checker.
+ """
+ implements(IChecker)
- if WATCH_CHECKERS:
- print >> sys.stderr, ('Checking %r.%s:' % (object, name)),
+ def __init__(self, original_checker, permission_func,
+ setattr_permission_func=lambda name: None
+ ):
+ """Create a decorated checker
+
+ A dictionary or a callable must be provided for computing permissions
+ for names. The callable will be called with attribute names and must
+ return a permission id, None, or the special marker, CheckerPublic. If
+ None is returned, then access to the name is decided by
+ original_checker. If CheckerPublic is returned, then access will be
+ granted without checking a permission.
+
+ An optional setattr permission function or dictionary may be
+ provided for checking set attribute access.
+ """
+ self._original_checker = original_checker
- # We have the information we need already
+ if type(permission_func) is dict:
+ permission_func = permission_func.get
+ self._permission_func = permission_func
+
+ if type(setattr_permission_func) is dict:
+ setattr_permission_func = setattr_permission_func.get
+ self._setattr_permission_func = setattr_permission_func
+
+ if INameBasedChecker.isImplementedBy(original_checker):
+ directlyProvides(self, INameBasedChecker)
+
+ def permission_id(self, name):
+ 'See INameBasedChecker'
permission = self._permission_func(name)
- if permission:
+ if permission is None:
+ permission = self._original_checker.permission_id(name)
+ return permission
+
+ def setattr_permission_id(self, name):
+ 'See INameBasedChecker'
+ permission = self._setattr_permission_func(name)
+ if permission is None:
+ permission = self._original_checker.setattr_permission_id(name)
+ return permission
+
+ def check(self, object, name):
+ 'See IChecker'
+ permission = self._permission_func(name)
+ if permission is not None:
if permission is CheckerPublic:
- if WATCH_CHECKERS:
- print >> sys.stderr, 'Public.'
return # Public
manager = getSecurityManager()
if manager.checkPermission(permission, object):
- if WATCH_CHECKERS:
- print >> sys.stderr, 'Granted.'
return
else:
- if WATCH_CHECKERS:
- print >> sys.stderr, 'Unauthorized.'
__traceback_supplement__ = (TracebackSupplement, object)
- raise Unauthorized(name=name)
- elif name in _always_available:
- if WATCH_CHECKERS:
- print >> sys.stderr, 'Always available.'
+ raise Unauthorized, name
+ else:
+ # let the original checker decide
+ self._original_checker.check(object, name)
return
- if WATCH_CHECKERS:
- print >> sys.stderr, 'Forbidden.'
+ def check_getattr(self, object, name):
+ 'See IChecker'
+ permission = self._permission_func(name)
+ if permission is not None:
+ if permission is CheckerPublic:
+ return # Public
+ manager = getSecurityManager()
+ if manager.checkPermission(permission, object):
+ return
+ else:
+ __traceback_supplement__ = (TracebackSupplement, object)
+ raise Unauthorized, name
+ else:
+ # let the original checker decide
+ self._original_checker.check_getattr(object, name)
+ return
- __traceback_supplement__ = (TracebackSupplement, object)
- raise ForbiddenAttribute(name)
+ def check_setattr(self, object, name):
+ 'See IChecker'
+ permission = self._setattr_permission_func(name)
+ if permission is not None:
+ if permission is CheckerPublic:
+ return # Public
+ manager = getSecurityManager()
+ if manager.checkPermission(permission, object):
+ return
+ else:
+ __traceback_supplement__ = (TracebackSupplement, object)
+ raise Unauthorized, name
+ else:
+ # let the original checker decide
+ self._original_checker.check_setattr(object, name)
+ return
def proxy(self, value):
'See IChecker'
- # Now we need to create a proxy
-
checker = getattr(value, '__Security_checker__', None)
if checker is None:
checker = selectChecker(value)
@@ -190,6 +356,84 @@
return Proxy(value, checker)
+
+class CheckerLoggingMixin:
+ """Debugging mixin for checkers.
+
+ Prints verbose debugging information about every performed check to
+ sys.stderr.
+
+ If verbosity is set to 1, only displays Unauthorized and Forbidden messages.
+ If verbosity is set to a larger number, displays all messages.
+ """
+
+ verbosity = 1
+
+ def check(self, object, name):
+ try:
+ super(CheckerLoggingMixin, self).check(object, name)
+ if self.verbosity > 1:
+ if name in _always_available:
+ print >> sys.stderr, (
+ '[CHK] + Always available: %s on %r' % (name, object))
+ else:
+ print >> sys.stderr, (
+ '[CHK] + Granted: %s on %r' % (name, object))
+ except Unauthorized:
+ print >> sys.stderr, (
+ '[CHK] - Unauthorized: %s on %r' % (name, object))
+ raise
+ except ForbiddenAttribute:
+ print >> sys.stderr, (
+ '[CHK] - Forbidden: %s on %r' % (name, object))
+ raise
+
+ def check_getattr(self, object, name):
+ try:
+ super(CheckerLoggingMixin, self).check(object, name)
+ if self.verbosity > 1:
+ if name in _always_available:
+ print >> sys.stderr, (
+ '[CHK] + Always available getattr: %s on %r'
+ % (name, object))
+ else:
+ print >> sys.stderr, (
+ '[CHK] + Granted getattr: %s on %r'
+ % (name, object))
+ except Unauthorized:
+ print >> sys.stderr, (
+ '[CHK] - Unauthorized getattr: %s on %r' % (name, object))
+ raise
+ except ForbiddenAttribute:
+ print >> sys.stderr, (
+ '[CHK] - Forbidden getattr: %s on %r' % (name, object))
+ raise
+
+ def check_setattr(self, object, name):
+ try:
+ super(CheckerLoggingMixin, self).check_setattr(object, name)
+ if self.verbosity > 1:
+ print >> sys.stderr, (
+ '[CHK] + Granted setattr: %s on %r' % (name, object))
+ except Unauthorized:
+ print >> sys.stderr, (
+ '[CHK] - Unauthorized setattr: %s on %r' % (name, object))
+ raise
+ except ForbiddenAttribute:
+ print >> sys.stderr, (
+ '[CHK] - Forbidden setattr: %s on %r' % (name, object))
+ raise
+
+
+if WATCH_CHECKERS:
+ class Checker(CheckerLoggingMixin, Checker):
+ verbosity = WATCH_CHECKERS
+ class CombinedChecker(CheckerLoggingMixin, CombinedChecker):
+ verbosity = WATCH_CHECKERS
+ class DecoratedChecker(CheckerLoggingMixin, DecoratedChecker):
+ verbosity = WATCH_CHECKERS
+
+
# Helper class for __traceback_supplement__
class TracebackSupplement:
@@ -328,12 +572,14 @@
# XXX we really need formal proxy introspection
- if type(object) is Proxy:
- # Is this already a security proxy?
- return None
+ #if type(object) is Proxy:
+ # # Is this already a security proxy?
+ # return None
- checker = _getChecker(getattr(object, '__class__', type(object)),
- _defaultChecker)
+ checker = _getChecker(type(object), _defaultChecker)
+
+ #checker = _getChecker(getattr(object, '__class__', type(object)),
+ # _defaultChecker)
if checker is NoProxy:
return None
@@ -397,7 +643,9 @@
return _checkers.get(module, _typeChecker)
-
+# The variable '_always_available' should really be called
+# '_available_by_default', as that would better reflect its meaning.
+# XXX: Fix the name.
_always_available = ['__lt__', '__le__', '__eq__',
'__gt__', '__ge__', '__ne__',
'__hash__', '__nonzero__',
@@ -426,6 +674,23 @@
datetime.date: NoProxy,
datetime.time: NoProxy,
}
+# Available for tests. Located here so it can be kept in sync with BasicTypes.
+BasicTypes_examples = {
+ object: object(),
+ int: 65536,
+ float: -1.4142,
+ long: 65536l,
+ complex: -1.4142j,
+ types.NoneType: None,
+ str: 'abc',
+ unicode: u'uabc',
+ type(True): True,
+ datetime.timedelta: datetime.timedelta(3),
+ datetime.datetime: datetime.datetime(2003, 1, 1),
+ datetime.date: datetime.date(2003, 1, 1),
+ datetime.time: datetime.time(23, 58)
+}
+
class _Sequence(object):
def __len__(self): return 0
@@ -435,15 +700,16 @@
_default_checkers = {
dict: NamesChecker(['__getitem__', '__len__', '__iter__',
- 'get', 'has_key', '__copy__', '__str__', 'keys',
+ 'get', 'has_key', 'copy', '__str__', 'keys',
'values', 'items', 'iterkeys', 'iteritems',
'itervalues', '__contains__']),
list: NamesChecker(['__getitem__', '__getslice__', '__len__', '__iter__',
- '__contains__', 'index', 'count', '__str__']),
+ '__contains__', 'index', 'count', '__str__',
+ '__add__', '__radd__', ]),
# YAGNI: () a rock
- tuple: NamesChecker(['__getitem__', '__getslice__', '__add__',
- '__contains__', '__len__', '__iter__', '__iadd__',
+ tuple: NamesChecker(['__getitem__', '__getslice__', '__add__', '__radd__',
+ '__contains__', '__len__', '__iter__',
'__str__']),
types.InstanceType: _instanceChecker,
Proxy: NoProxy,
@@ -452,16 +718,18 @@
types.MethodType: _callableChecker,
types.BuiltinFunctionType: _callableChecker,
types.BuiltinMethodType: _callableChecker,
+ type(().__getslice__): _callableChecker, # slot description
type: _typeChecker,
types.ModuleType: _moduleChecker,
type(iter([])): _iteratorChecker, # Same types in Python 2.2.1,
type(iter(())): _iteratorChecker, # different in Python 2.3.
+ type(iter({})): _iteratorChecker,
type(iter(_Sequence())): _iteratorChecker,
type(Interface): InterfaceChecker(IInterface, __str__=CheckerPublic),
ObjectSpecification: _InterfaceSpecification_checker,
ProvidesSpecification: _InterfaceSpecification_checker,
ImplementsSpecification: _InterfaceSpecification_checker,
- OnlyImplementsSpecification: _InterfaceSpecification_checker,
+ ImplementsOnlySpecification: _InterfaceSpecification_checker,
InterfaceSpecification: _InterfaceSpecification_checker,
}
=== Zope3/src/zope/security/context.py 1.3 => 1.3.10.1 ===
--- Zope3/src/zope/security/context.py:1.3 Thu May 1 15:35:47 2003
+++ Zope3/src/zope/security/context.py Sun Jun 22 10:23:53 2003
@@ -11,29 +11,27 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-""" Default ISecurityContext impl """
+"""Default ISecurityContext implementation."""
from zope.security.interfaces import ISecurityContext
+from zope.interface import implements
class SecurityContext:
- """
- Capture transient request-specific security information.
-
- Attribute( 'stack'
- , 'A stack of elements, each either be an ExecutableObject'
- 'or a tuple consisting of an ExecutableObject and a'
- 'custom SecurityPolicy.'
- )
+ """Capture transient request-specific security information.
- Attribute( 'user'
- , 'The AUTHENTICATED_USER for the request.'
- )
+ Attribute('stack',
+ 'A stack of elements, each either be an ExecutableObject or a'
+ ' tuple consisting of an ExecutableObject and a custom'
+ ' SecurityPolicy.'
+ )
+
+ Attribute('user',
+ 'The AUTHENTICATED_USER for the request.'
+ )
"""
+ implements(ISecurityContext)
- __implements__ = ISecurityContext
-
def __init__(self, user):
-
self.stack = []
self.user = user
self.objectCache = {}
=== Zope3/src/zope/security/interfaces.py 1.6 => 1.6.18.1 ===
--- Zope3/src/zope/security/interfaces.py:1.6 Thu Mar 13 11:28:14 2003
+++ Zope3/src/zope/security/interfaces.py Sun Jun 22 10:23:53 2003
@@ -150,6 +150,22 @@
"""Return a security proxy for the value."""
+class INameBasedChecker(IChecker):
+ """Security checker that uses permissions to check attribute access."""
+
+ def permission_id(name):
+ """Return the permission used to check attribute access on name.
+
+ This permission is used by both check and check_getattr.
+ """
+
+ def setattr_permission_id(name):
+ """Return the permission used to check attribute assignment on name.
+
+ This permission is used by check_setattr.
+ """
+
+
class ISecurityPolicy(Interface):
def checkPermission(permission, object, context):
=== Zope3/src/zope/security/management.py 1.3 => 1.3.12.1 ===
--- Zope3/src/zope/security/management.py:1.3 Fri Apr 18 18:12:34 2003
+++ Zope3/src/zope/security/management.py Sun Jun 22 10:23:53 2003
@@ -22,7 +22,8 @@
system_user = object()
from zope.interface import moduleProvides
-from zope.security.interfaces import ISecurityManagement, ISecurityManagementSetup
+from zope.security.interfaces import ISecurityManagement
+from zope.security.interfaces import ISecurityManagementSetup
from zope.security.manager import SecurityManager
from zope.security.manager import setSecurityPolicy as _setSecurityPolicy
from zope.security.context import SecurityContext
=== Zope3/src/zope/security/manager.py 1.3 => 1.3.16.1 ===
--- Zope3/src/zope/security/manager.py:1.3 Thu Mar 13 13:49:16 2003
+++ Zope3/src/zope/security/manager.py Sun Jun 22 10:23:53 2003
@@ -15,7 +15,7 @@
$Id$
"""
-
+from zope.interface import implements
from zope.security.simplepolicies import ParanoidSecurityPolicy
MAX_STACK_SIZE = 100
@@ -31,11 +31,10 @@
def setSecurityPolicy(aSecurityPolicy):
- """
- Set the system default security policy.
+ """Set the system default security policy.
- This method should only be caused by system startup code. It should
- never, for example, be called during a web request.
+ This method should only be caused by system startup code. It should never,
+ for example, be called during a web request.
"""
global _defaultPolicy
@@ -46,19 +45,17 @@
from zope.security.interfaces import ISecurityManager
class SecurityManager:
+ """A security manager provides methods for checking access and managing
+ executable context and policies.
"""
- A security manager provides methods for checking access and managing
- executable context and policies.
- """
- __implements__ = ISecurityManager
+ implements(ISecurityManager)
def __init__(self, context):
self._context = context
self._policy = None
def _getPolicy(self):
- """
- Find current policy, or default.
+ """Find current policy, or default.
"""
policy = self._policy
if policy is None:
@@ -69,37 +66,34 @@
# ISecurityManager implementation
#
def getPrincipal(self):
- """
- Return the authenticated user.
+ """Return the authenticated user.
- This is equivalent to something like::
+ This is equivalent to something like::
- REQUEST['AUTHENTICATED_USER']
+ REQUEST['AUTHENTICATED_USER']
- but is a bit cleaner, especially if 'REQUEST' isn't handy.
+ but is a bit cleaner, especially if 'REQUEST' isn't handy.
"""
return self._context.user
def checkPermission(self, permission, object):
- """
- Check whether the security context allows the given
- permission on the given object. Return a boolean value.
+ """Check whether the security context allows the given
+ permission on the given object. Return a boolean value.
- Arguments:
+ Arguments:
permission -- A permission name
object -- The object being accessed according to the permission
"""
- return self._getPolicy().checkPermission(permission, object
- , self._context)
+ return self._getPolicy().checkPermission(permission, object,
+ self._context)
def pushExecutable(self, anExecutableObject):
+ """Push an ExecutableObject onto the manager's stack, and
+ activate its custom security policy, if any.
"""
- Push an ExecutableObject onto the manager's stack, and
- activate its custom security policy, if any.
- """
- stack=self._context.stack
+ stack = self._context.stack
if len(stack) >= MAX_STACK_SIZE:
raise SystemError, 'Excessive recursion'
@@ -113,11 +107,10 @@
self._policy = p
def popExecutable(self, anExecutableObject):
+ """Pop the topmost ExecutableObject from the stack, deactivating
+ any custom security policy it might have installed.
"""
- Pop the topmost ExecutableObject from the stack, deactivating
- any custom security policy it might have installed.
- """
- stack=self._context.stack
+ stack = self._context.stack
if not stack:
return
@@ -130,7 +123,7 @@
indexes = range(len(stack))
indexes.reverse()
for i in indexes:
- top=stack[i]
+ top = stack[i]
if top is anExecutableObject:
del stack[i:]
break
@@ -138,24 +131,21 @@
return
if stack:
-
top = stack[-1]
p = getattr(top, '_customSecurityPolicy', None)
if p is not None:
- p=p()
- self._policy=p
-
+ p = p()
+ self._policy = p
else:
- self._policy=None
+ self._policy = None
def calledByExecutable(self):
- """
- Return a boolean indicating whether the current request has
- invoked any IExecutableObjects.
+ """Return a boolean indicating whether the current request has
+ invoked any IExecutableObjects.
- This can be used to determine if an object was called
- (more or less) directly from a URL, or if it was called by
- through-the-web provided code.
+ This can be used to determine if an object was called (more or less)
+ directly from a URL, or if it was called by through-the-web provided
+ code.
"""
return len(self._context.stack)
=== Zope3/src/zope/security/proxy.py 1.5 => 1.5.2.1 ===
--- Zope3/src/zope/security/proxy.py:1.5 Tue May 20 16:28:50 2003
+++ Zope3/src/zope/security/proxy.py Sun Jun 22 10:23:53 2003
@@ -16,30 +16,29 @@
$Id$
"""
-from zope.security._proxy import getObject, getChecker
+from zope.proxy import getProxiedObject
+from zope.security._proxy import getChecker
from zope.security._proxy import _Proxy as Proxy
-from zope.security.checker import Checker as _trustedChecker
+from zope.security.checker import TrustedCheckerBase
# This import represents part of the API for this module
from zope.security.checker import ProxyFactory
def trustedRemoveSecurityProxy(object):
- """Remove a security proxy if the proxy's checker came from a trusted source.
+ """Remove a security proxy if its checker came from a trusted source.
- The rational is that it's OK to do this since the caller is
- trusted and the proxy can always be recreated by callingt the
+ The rationale is that it is OK to do this since the caller is
+ trusted and the proxy can always be recreated by calling the
proxy factory and getting back a proxy with the same checker.
XXX More thought needs to be given to assuring this contact.
-
"""
if ((type(object) is Proxy) and
- isinstance(getChecker(object), _trustedChecker)
+ isinstance(getChecker(object), TrustedCheckerBase)
):
- return getObject(object)
+ return getProxiedObject(object)
return object
-
def getTestProxyItems(proxy):
"""Try to get checker names and permissions for testing
=== Zope3/src/zope/security/simplepolicies.py 1.4 => 1.4.10.1 ===
--- Zope3/src/zope/security/simplepolicies.py:1.4 Thu May 1 15:35:47 2003
+++ Zope3/src/zope/security/simplepolicies.py Sun Jun 22 10:23:53 2003
@@ -11,33 +11,30 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-""" Simple ISecurityPolicy implementations."""
+"""Simple ISecurityPolicy implementations."""
from zope.security.interfaces import ISecurityPolicy
from zope.security.management import system_user
import zope.security.checker
+from zope.interface import implements
class ParanoidSecurityPolicy:
- """
- Deny all access.
- """
- __implements__ = ISecurityPolicy
+ """Deny all access."""
+ implements(ISecurityPolicy)
def checkPermission(self, permission, object, context):
if permission is zope.security.checker.CheckerPublic:
- return 1
+ return True
if (context.user is system_user # no user
and not context.stack # no untrusted code
):
- return 1 # Nobody not to trust!
+ return True # Nobody not to trust!
- return 0
+ return False
class PermissiveSecurityPolicy:
- """
- Allow all access
- """
- __implements__ = ISecurityPolicy
+ """Allow all access."""
+ implements(ISecurityPolicy)
def checkPermission(self, permission, object, context):
- return 1
+ return True