[Checkins]
SVN: zope.security/branches/mgedmin-cleanup/src/zope/security/
Extract the bits defined in the C module into an equivalent
Python module.
Marius Gedminas
marius at pov.lt
Mon Jul 28 12:55:41 EDT 2008
Log message for revision 88879:
Extract the bits defined in the C module into an equivalent Python module.
I'm looking for symmetry here, but this fails: CheckerPublic needs Checker
already defined, but the module that defines Checker needs CheckerPublic
to be defined...
Changed:
A zope.security/branches/mgedmin-cleanup/src/zope/security/_checker.py
U zope.security/branches/mgedmin-cleanup/src/zope/security/checker.py
-=-
Copied: zope.security/branches/mgedmin-cleanup/src/zope/security/_checker.py (from rev 88876, zope.security/branches/mgedmin-cleanup/src/zope/security/checker.py)
===================================================================
--- zope.security/branches/mgedmin-cleanup/src/zope/security/_checker.py (rev 0)
+++ zope.security/branches/mgedmin-cleanup/src/zope/security/_checker.py 2008-07-28 16:55:40 UTC (rev 88879)
@@ -0,0 +1,193 @@
+##############################################################################
+#
+# Copyright (c) 2003-2008 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (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.
+#
+##############################################################################
+"""Python version of _zope_security_checker.c
+
+$Id$
+"""
+
+from zope.interface import implements
+from zope.security.interfaces import INameBasedChecker
+from zope.security.interfaces import Unauthorized, ForbiddenAttribute
+from zope.security._definitions import thread_local
+from zope.security._proxy import _Proxy as Proxy
+from zope.security.checker import CheckerPublic
+
+
+class Checker(object):
+ implements(INameBasedChecker)
+
+ def __init__(self, get_permissions, set_permissions=None):
+ """Create a checker
+
+ A dictionary must be provided for computing permissions for
+ names. The dictionary get 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
+ forbidden. If CheckerPublic is returned, then access will be
+ granted without checking a permission.
+
+ An optional setattr dictionary may be provided for checking
+ set attribute access.
+
+ """
+ assert isinstance(get_permissions, dict)
+ self.get_permissions = get_permissions
+ if set_permissions is not None:
+ assert isinstance(set_permissions, dict)
+ self.set_permissions = set_permissions
+
+ def permission_id(self, name):
+ 'See INameBasedChecker'
+ return self.get_permissions.get(name)
+
+ def setattr_permission_id(self, name):
+ 'See INameBasedChecker'
+ if self.set_permissions:
+ return self.set_permissions.get(name)
+
+ def check_getattr(self, object, name):
+ 'See IChecker'
+ self.check(object, name)
+
+ def check_setattr(self, object, name):
+ 'See IChecker'
+ if self.set_permissions:
+ permission = self.set_permissions.get(name)
+ else:
+ permission = None
+
+ if permission is not None:
+ if permission is CheckerPublic:
+ return # Public
+ if thread_local.interaction.checkPermission(permission, object):
+ return # allowed
+ else:
+ __traceback_supplement__ = (TracebackSupplement, object)
+ raise Unauthorized(object, name, permission)
+
+ __traceback_supplement__ = (TracebackSupplement, object)
+ raise ForbiddenAttribute(name, object)
+
+ def check(self, object, name):
+ 'See IChecker'
+ permission = self.get_permissions.get(name)
+ if permission is not None:
+ if permission is CheckerPublic:
+ return # Public
+ if thread_local.interaction.checkPermission(permission, object):
+ return
+ else:
+ __traceback_supplement__ = (TracebackSupplement, object)
+ raise Unauthorized(object, name, permission)
+ elif name in _available_by_default:
+ return
+
+ if name != '__iter__' or hasattr(object, name):
+ __traceback_supplement__ = (TracebackSupplement, object)
+ raise ForbiddenAttribute(name, object)
+
+ def proxy(self, value):
+ 'See IChecker'
+ if type(value) is Proxy:
+ return value
+ checker = getattr(value, '__Security_checker__', None)
+ if checker is None:
+ checker = selectChecker(value)
+ if checker is None:
+ return value
+
+ return Proxy(value, checker)
+
+
+# Helper class for __traceback_supplement__
+class TracebackSupplement(object):
+
+ def __init__(self, obj):
+ self.obj = obj
+
+ def getInfo(self):
+ result = []
+ try:
+ cls = self.obj.__class__
+ if hasattr(cls, "__module__"):
+ s = "%s.%s" % (cls.__module__, cls.__name__)
+ else:
+ s = str(cls.__name__)
+ result.append(" - class: " + s)
+ except:
+ pass
+ try:
+ cls = type(self.obj)
+ if hasattr(cls, "__module__"):
+ s = "%s.%s" % (cls.__module__, cls.__name__)
+ else:
+ s = str(cls.__name__)
+ result.append(" - type: " + s)
+ except:
+ pass
+ return "\n".join(result)
+
+
+
+def selectChecker(object):
+ """Get a checker for the given object
+
+ The appropriate checker is returned or None is returned. If the
+ return value is None, then object should not be wrapped in a proxy.
+ """
+
+ # We need to be careful here. We might have a proxy, in which case
+ # we can't use the type. OTOH, we might not be able to use the
+ # __class__ either, since not everything has one.
+
+ # TODO: we really need formal proxy introspection
+
+ #if type(object) is Proxy:
+ # # Is this already a security proxy?
+ # return None
+
+ checker = _getChecker(type(object), _defaultChecker)
+
+ #checker = _getChecker(getattr(object, '__class__', type(object)),
+ # _defaultChecker)
+
+ if checker is NoProxy:
+ return None
+
+ while not isinstance(checker, Checker):
+ checker = checker(object)
+ if checker is NoProxy or checker is None:
+ return None
+
+ return checker
+
+
+NoProxy = object()
+
+# _checkers is a mapping.
+#
+# - Keys are types
+#
+# - Values are
+#
+# o None => rock
+# o a Checker
+# o a function returning None or a Checker
+#
+_checkers = {}
+
+_defaultChecker = Checker({})
+_available_by_default = []
+
+_getChecker = _checkers.get
Modified: zope.security/branches/mgedmin-cleanup/src/zope/security/checker.py
===================================================================
--- zope.security/branches/mgedmin-cleanup/src/zope/security/checker.py 2008-07-28 16:52:29 UTC (rev 88878)
+++ zope.security/branches/mgedmin-cleanup/src/zope/security/checker.py 2008-07-28 16:55:40 UTC (rev 88879)
@@ -44,7 +44,6 @@
from zope.security.interfaces import IChecker, INameBasedChecker
from zope.security.interfaces import ISecurityProxyFactory
from zope.security.interfaces import Unauthorized, ForbiddenAttribute
-from zope.security._definitions import thread_local
from zope.security._proxy import _Proxy as Proxy, getChecker
if os.environ.get('ZOPE_WATCH_CHECKERS'):
@@ -138,122 +137,7 @@
# indicates a programming or configuration error
return True
-class Checker(object):
- implements(INameBasedChecker)
- def __init__(self, get_permissions, set_permissions=None):
- """Create a checker
-
- A dictionary must be provided for computing permissions for
- names. The dictionary get 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
- forbidden. If CheckerPublic is returned, then access will be
- granted without checking a permission.
-
- An optional setattr dictionary may be provided for checking
- set attribute access.
-
- """
- assert isinstance(get_permissions, dict)
- self.get_permissions = get_permissions
- if set_permissions is not None:
- assert isinstance(set_permissions, dict)
- self.set_permissions = set_permissions
-
- def permission_id(self, name):
- 'See INameBasedChecker'
- return self.get_permissions.get(name)
-
- def setattr_permission_id(self, name):
- 'See INameBasedChecker'
- if self.set_permissions:
- return self.set_permissions.get(name)
-
- def check_getattr(self, object, name):
- 'See IChecker'
- self.check(object, name)
-
- def check_setattr(self, object, name):
- 'See IChecker'
- if self.set_permissions:
- permission = self.set_permissions.get(name)
- else:
- permission = None
-
- if permission is not None:
- if permission is CheckerPublic:
- return # Public
- if thread_local.interaction.checkPermission(permission, object):
- return # allowed
- else:
- __traceback_supplement__ = (TracebackSupplement, object)
- raise Unauthorized(object, name, permission)
-
- __traceback_supplement__ = (TracebackSupplement, object)
- raise ForbiddenAttribute(name, object)
-
- def check(self, object, name):
- 'See IChecker'
- permission = self.get_permissions.get(name)
- if permission is not None:
- if permission is CheckerPublic:
- return # Public
- if thread_local.interaction.checkPermission(permission, object):
- return
- else:
- __traceback_supplement__ = (TracebackSupplement, object)
- raise Unauthorized(object, name, permission)
- elif name in _available_by_default:
- return
-
- if name != '__iter__' or hasattr(object, name):
- __traceback_supplement__ = (TracebackSupplement, object)
- raise ForbiddenAttribute(name, object)
-
- def proxy(self, value):
- 'See IChecker'
- if type(value) is Proxy:
- return value
- checker = getattr(value, '__Security_checker__', None)
- if checker is None:
- checker = selectChecker(value)
- if checker is None:
- return value
-
- return Proxy(value, checker)
-
-
-
-# Helper class for __traceback_supplement__
-class TracebackSupplement(object):
-
- def __init__(self, obj):
- self.obj = obj
-
- def getInfo(self):
- result = []
- try:
- cls = self.obj.__class__
- if hasattr(cls, "__module__"):
- s = "%s.%s" % (cls.__module__, cls.__name__)
- else:
- s = str(cls.__name__)
- result.append(" - class: " + s)
- except:
- pass
- try:
- cls = type(self.obj)
- if hasattr(cls, "__module__"):
- s = "%s.%s" % (cls.__module__, cls.__name__)
- else:
- s = str(cls.__name__)
- result.append(" - type: " + s)
- except:
- pass
- return "\n".join(result)
-
-
class Global(object):
"""A global object that behaves like a string.
@@ -347,38 +231,6 @@
return Checker(data)
-def selectChecker(object):
- """Get a checker for the given object
-
- The appropriate checker is returned or None is returned. If the
- return value is None, then object should not be wrapped in a proxy.
- """
-
- # We need to be careful here. We might have a proxy, in which case
- # we can't use the type. OTOH, we might not be able to use the
- # __class__ either, since not everything has one.
-
- # TODO: we really need formal proxy introspection
-
- #if type(object) is Proxy:
- # # Is this already a security proxy?
- # return None
-
- checker = _getChecker(type(object), _defaultChecker)
-
- #checker = _getChecker(getattr(object, '__class__', type(object)),
- # _defaultChecker)
-
- if checker is NoProxy:
- return None
-
- while not isinstance(checker, Checker):
- checker = checker(object)
- if checker is NoProxy or checker is None:
- return None
-
- return checker
-
def getCheckerForInstancesOf(class_):
return _checkers.get(class_)
@@ -398,28 +250,15 @@
def undefineChecker(type_):
del _checkers[type_]
-NoProxy = object()
-# _checkers is a mapping.
-#
-# - Keys are types
-#
-# - Values are
-#
-# o None => rock
-# o a Checker
-# o a function returning None or a Checker
-#
-_checkers = {}
-
-_defaultChecker = Checker({})
-_available_by_default = []
-
-# Get optimized versions
+# Get optimized versions, if available
try:
import zope.security._zope_security_checker
except ImportError:
- pass
+ from zope.security._checker import _checkers, selectChecker
+ from zope.security._checker import NoProxy, Checker
+ from zope.security._checker import _defaultChecker
+ from zope.security._checker import _available_by_default
else:
from zope.security._zope_security_checker import _checkers, selectChecker
from zope.security._zope_security_checker import NoProxy, Checker
@@ -428,8 +267,6 @@
zope.interface.classImplements(Checker, INameBasedChecker)
-_getChecker = _checkers.get
-
class CombinedChecker(Checker):
"""A checker that combines two other checkers in a logical-or fashion.
More information about the Checkins
mailing list