[Zope3-checkins] SVN: Zope3/branches/jim-call-checkers/src/zope/
Implemented
Jim Fulton
jim at zope.com
Fri Oct 7 16:31:21 EDT 2005
Log message for revision 38905:
Implemented
http://dev.zope.org/Zope3/SecurityCheckersBecomeSecurityProxyFactories
in Python version.
Changed:
U Zope3/branches/jim-call-checkers/src/zope/app/decorator.py
U Zope3/branches/jim-call-checkers/src/zope/app/schema/tests/test_field.py
U Zope3/branches/jim-call-checkers/src/zope/app/schema/tests/test_schemautility.py
U Zope3/branches/jim-call-checkers/src/zope/security/checker.py
U Zope3/branches/jim-call-checkers/src/zope/security/tests/test_checker.py
U Zope3/branches/jim-call-checkers/src/zope/security/tests/test_proxy.py
-=-
Modified: Zope3/branches/jim-call-checkers/src/zope/app/decorator.py
===================================================================
--- Zope3/branches/jim-call-checkers/src/zope/app/decorator.py 2005-10-07 17:23:21 UTC (rev 38904)
+++ Zope3/branches/jim-call-checkers/src/zope/app/decorator.py 2005-10-07 20:31:20 UTC (rev 38905)
@@ -19,7 +19,8 @@
$Id$
"""
from zope.proxy import getProxiedObject, ProxyBase
-from zope.security.checker import selectChecker, CombinedChecker
+from zope.security.checker import selectChecker, CombinedChecker, queryChecker
+from zope.security.checker import defaultChecker
from zope.security.proxy import Proxy, getChecker
from zope.interface.declarations import ObjectSpecificationDescriptor
from zope.interface.declarations import getObjectSpecification
@@ -169,11 +170,8 @@
When the wrapper has a checker but the proxied object doesn't:
- >>> from zope.security.checker import NoProxy, _checkers
- >>> del _checkers[Foo]
- >>> defineChecker(Foo, NoProxy)
- >>> selectChecker(foo) is None
- True
+ >>> from zope.security.checker import undefineChecker
+ >>> undefineChecker(Foo)
>>> selectChecker(wrapper) is wrapperChecker
True
@@ -185,14 +183,8 @@
When the proxied object has a checker but the wrapper doesn't:
- >>> del _checkers[Wrapper]
- >>> defineChecker(Wrapper, NoProxy)
- >>> selectChecker(wrapper) is None
- True
- >>> del _checkers[Foo]
+ >>> undefineChecker(Wrapper)
>>> defineChecker(Foo, fooChecker)
- >>> selectChecker(foo) is fooChecker
- True
the decorator uses only the proxied object checker:
@@ -201,12 +193,7 @@
Finally, if neither the wrapper not the proxied have checkers:
- >>> del _checkers[Foo]
- >>> defineChecker(Foo, NoProxy)
- >>> selectChecker(foo) is None
- True
- >>> selectChecker(wrapper) is None
- True
+ >>> undefineChecker(Foo)
the decorator doesn't have a checker:
@@ -219,14 +206,14 @@
return self
else:
proxied_object = getProxiedObject(inst)
- if type(proxied_object) is Proxy:
+ if isinstance(proxied_object, Proxy):
checker = getChecker(proxied_object)
else:
- checker = getattr(proxied_object, '__Security_checker__', None)
- if checker is None:
- checker = selectChecker(proxied_object)
+ checker = queryChecker(proxied_object)
+
wrapper_checker = selectChecker(inst)
- if wrapper_checker is None:
+ if wrapper_checker is defaultChecker:
+ # optimization
return checker
elif checker is None:
return wrapper_checker
Modified: Zope3/branches/jim-call-checkers/src/zope/app/schema/tests/test_field.py
===================================================================
--- Zope3/branches/jim-call-checkers/src/zope/app/schema/tests/test_field.py 2005-10-07 17:23:21 UTC (rev 38904)
+++ Zope3/branches/jim-call-checkers/src/zope/app/schema/tests/test_field.py 2005-10-07 20:31:20 UTC (rev 38905)
@@ -25,7 +25,7 @@
from zope.security.management import system_user, newInteraction
from zope.app.testing import setup
from zope.app.schema.wrapper import Struct
-from zope.security.checker import getChecker, _defaultChecker
+from zope.security.checker import getChecker, defaultChecker
import zope.app.schema.tests
@@ -62,8 +62,8 @@
f2 = Struct(f2)
f2 = ProxyFactory(f2)
self.assertEquals(getChecker(f1), getChecker(f2))
- self.failIf(getChecker(f1) is _defaultChecker)
- self.failIf(getChecker(f2) is _defaultChecker)
+ self.failIf(getChecker(f1) is defaultChecker)
+ self.failIf(getChecker(f2) is defaultChecker)
def tearDown(self):
setup.placefulTearDown()
Modified: Zope3/branches/jim-call-checkers/src/zope/app/schema/tests/test_schemautility.py
===================================================================
--- Zope3/branches/jim-call-checkers/src/zope/app/schema/tests/test_schemautility.py 2005-10-07 17:23:21 UTC (rev 38904)
+++ Zope3/branches/jim-call-checkers/src/zope/app/schema/tests/test_schemautility.py 2005-10-07 20:31:20 UTC (rev 38905)
@@ -19,7 +19,7 @@
from zope.configuration import xmlconfig
from zope.schema import Text, getFieldNamesInOrder, getFieldsInOrder
-from zope.security.checker import getChecker, _defaultChecker, ProxyFactory
+from zope.security.checker import getChecker, ProxyFactory
from zope.app.schema.schema import SchemaUtility
from zope.app.testing import setup
from zope.app import zapi
Modified: Zope3/branches/jim-call-checkers/src/zope/security/checker.py
===================================================================
--- Zope3/branches/jim-call-checkers/src/zope/security/checker.py 2005-10-07 17:23:21 UTC (rev 38904)
+++ Zope3/branches/jim-call-checkers/src/zope/security/checker.py 2005-10-07 20:31:20 UTC (rev 38905)
@@ -73,18 +73,54 @@
# 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
- return Proxy(object, checker)
+ try:
+ return checker(object)
+ except TypeError:
+ import warnings
+ warnings.warn(
+ "Non-callable checkers like %s are deprecated and will not be"
+ " supported after 2006." % checker,
+ DeprecationWarning)
+ return Proxy(object, checker)
directlyProvides(ProxyFactory, ISecurityProxyFactory)
+def queryChecker(ob, default=None):
+ """Determine the checker for an object
+
+ Return None if no checker is defined.
+
+ >>> class C(object):
+ ... pass
+
+ >>> c = C()
+ >>> print queryChecker(c)
+ None
+
+ >>> checker1 = Checker({})
+ >>> defineChecker(C, checker1)
+ >>> queryChecker(c) is checker1
+ True
+ >>> checker2 = Checker({})
+ >>> c.__Security_checker__ = checker2
+ >>> queryChecker(c) is checker2
+ True
+
+ """
+ checker = getattr(ob, '__Security_checker__', None)
+
+ if checker is None:
+ checker = _getChecker(type(ob), default)
+
+ return checker
+
def canWrite(obj, name):
"""Check whether the interaction may write an attribute named name on obj.
@@ -199,13 +235,14 @@
checker = getattr(value, '__Security_checker__', None)
if checker is None:
checker = selectChecker(value)
- if checker is None:
- return value
- return Proxy(value, checker)
+ return checker(value)
+ def __call__(self, value):
+ return Proxy(value, self)
+
# Helper class for __traceback_supplement__
class TracebackSupplement(object):
@@ -335,28 +372,10 @@
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.
+ checker = _getChecker(type(object), defaultChecker)
- # 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
@@ -376,8 +395,43 @@
raise DuplicationError(type_)
_checkers[type_] = checker
-NoProxy = object()
+def undefineChecker(type_):
+ """Undefine a checker for a given type of object
+ >>> class C(object):
+ ... pass
+
+ >>> c = C()
+ >>> print queryChecker(c)
+ None
+
+ >>> checker1 = Checker({})
+ >>> defineChecker(C, checker1)
+ >>> queryChecker(c) is checker1
+ True
+
+ >>> undefineChecker(C)
+ >>> print queryChecker(c)
+ None
+
+
+ """
+ if not isinstance(type_, (type, types.ClassType, types.ModuleType)):
+ raise TypeError(
+ 'type_ must be a type, class or module, not a %s' % type_)
+ del _checkers[type_]
+
+
+class NoProxyChecker(Checker):
+
+ def check(self, object, name):
+ pass
+
+ def __call__(self, object):
+ return object
+
+NoProxy = NoProxyChecker({})
+
# _checkers is a mapping.
#
# - Keys are types
@@ -390,7 +444,8 @@
#
_checkers = {}
-_defaultChecker = Checker({})
+defaultChecker = Checker({})
+
_available_by_default = []
# Get optimized versions
@@ -401,7 +456,7 @@
else:
from zope.security._zope_security_checker import _checkers, selectChecker
from zope.security._zope_security_checker import NoProxy, Checker
- from zope.security._zope_security_checker import _defaultChecker
+ from zope.security._zope_security_checker import defaultChecker
from zope.security._zope_security_checker import _available_by_default
zope.interface.classImplements(Checker, INameBasedChecker)
@@ -463,8 +518,10 @@
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.
+ 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
@@ -532,7 +589,7 @@
verbosity = WATCH_CHECKERS
def _instanceChecker(inst):
- return _checkers.get(inst.__class__, _defaultChecker)
+ return _checkers.get(inst.__class__, defaultChecker)
def moduleChecker(module):
return _checkers.get(module)
@@ -605,7 +662,7 @@
_implied=CheckerPublic,
subscribe=CheckerPublic)
-def f():
+def generator_sample():
yield f
@@ -642,7 +699,7 @@
type({}.iterkeys()): _iteratorChecker,
type({}.itervalues()): _iteratorChecker,
type(iter(_Sequence())): _iteratorChecker,
- type(f()): _iteratorChecker,
+ type(generator_sample()): _iteratorChecker,
type(Interface): InterfaceChecker(
IInterface,
__str__=CheckerPublic, _implied=CheckerPublic, subscribe=CheckerPublic,
Modified: Zope3/branches/jim-call-checkers/src/zope/security/tests/test_checker.py
===================================================================
--- Zope3/branches/jim-call-checkers/src/zope/security/tests/test_checker.py 2005-10-07 17:23:21 UTC (rev 38904)
+++ Zope3/branches/jim-call-checkers/src/zope/security/tests/test_checker.py 2005-10-07 20:31:20 UTC (rev 38905)
@@ -32,6 +32,7 @@
from zope.security.checker import canWrite, canAccess
from zope.security.proxy import Proxy
import types, pickle
+from zope.testing import doctest
class SecurityPolicy(object):
implements(ISecurityPolicy)
@@ -349,8 +350,8 @@
proxy = ProxyFactory(obj)
self.assert_(type(proxy) is Proxy)
- from zope.security.checker import _defaultChecker
- self.assert_(getChecker(proxy) is _defaultChecker)
+ from zope.security.checker import defaultChecker
+ self.assert_(getChecker(proxy) is defaultChecker)
defineChecker(SomeClass, checker)
@@ -544,6 +545,7 @@
makeSuite(Test),
makeSuite(TestCheckerPublic),
makeSuite(TestCombinedChecker),
+ doctest.DocTestSuite('zope.security.checker')
))
if __name__=='__main__':
Modified: Zope3/branches/jim-call-checkers/src/zope/security/tests/test_proxy.py
===================================================================
--- Zope3/branches/jim-call-checkers/src/zope/security/tests/test_proxy.py 2005-10-07 17:23:21 UTC (rev 38904)
+++ Zope3/branches/jim-call-checkers/src/zope/security/tests/test_proxy.py 2005-10-07 20:31:20 UTC (rev 38905)
@@ -18,6 +18,7 @@
import unittest
from zope.security.proxy import getChecker, ProxyFactory, removeSecurityProxy
+from zope.security.proxy import Proxy
from zope.proxy import ProxyBase as proxy
class Checker(object):
@@ -43,7 +44,11 @@
return value
return ProxyFactory(value, self)
+ def __call__(self, value):
+ return Proxy(value, self)
+
+
class Something:
def __init__(self):
self.foo = [1,2,3]
@@ -388,6 +393,9 @@
... print 'check_getattr', name
... def proxy(self, object):
... return 1
+ ... def __call__(self, object):
+ ... return Proxy(object, self)
+
>>> def f():
... pass
>>> p = ProxyFactory(f, Checker())
More information about the Zope3-Checkins
mailing list