[Zope3-checkins] CVS: Zope3/src/zope/security/tests - test_checker.py:1.14.46.1 test_proxy.py:1.6.48.1

Marius Gedminas marius at pov.lt
Mon Feb 23 14:18:08 EST 2004


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

Modified Files:
      Tag: mgedmin-events2-branch
	test_checker.py test_proxy.py 
Log Message:
Added interaction to security proxies.  Added interaction arguments to security
checkers.  Added a lot of XXX comments in places where proxies are created but
no interaction is (yet) available.

Added an initial draft of IInteraction to zope.security.interfaces.  This might
move to zope.interaction.interfaces as suggested by Steve.

Fixed a buglet in CheckerLoggingMixin: check_getattr delegated the check to
super(...).check instead of super(...).check_getattr.  Added full unit tests
for CheckerLoggingMixin.



=== Zope3/src/zope/security/tests/test_checker.py 1.14 => 1.14.46.1 ===
--- Zope3/src/zope/security/tests/test_checker.py:1.14	Thu Jun  5 07:45:03 2003
+++ Zope3/src/zope/security/tests/test_checker.py	Mon Feb 23 14:18:07 2004
@@ -18,6 +18,7 @@
 """
 
 from unittest import TestCase, TestSuite, main, makeSuite
+from StringIO import StringIO
 from zope.interface import implements
 from zope.interface.verify import verifyObject
 from zope.security.checker import Checker, NamesChecker, CheckerPublic
@@ -26,7 +27,7 @@
 from zope.exceptions import Forbidden, Unauthorized, ForbiddenAttribute
 from zope.security.management import setSecurityPolicy
 from zope.proxy import getProxiedObject
-from zope.security.proxy import getChecker
+from zope.security.proxy import getChecker, getInteraction
 from zope.security.checker import defineChecker, ProxyFactory
 from zope.security.proxy import Proxy
 import types, pickle
@@ -134,41 +135,59 @@
         newinst = NewInst()
         newinst.d = NewInst()
 
+        interaction = object()
+
         for inst in oldinst, newinst:
             checker = NamesChecker(['a', 'b', 'c', '__getitem__'], 'perm')
 
-            self.assertRaises(Unauthorized, checker.check_getattr, inst, 'a')
-            self.assertRaises(Unauthorized, checker.check_getattr, inst, 'b')
-            self.assertRaises(Unauthorized, checker.check_getattr, inst, 'c')
-            self.assertRaises(Unauthorized, checker.check, inst, '__getitem__')
-            self.assertRaises(Forbidden, checker.check, inst, '__setitem__')
-            self.assertRaises(Forbidden, checker.check_getattr, inst, 'd')
-            self.assertRaises(Forbidden, checker.check_getattr, inst, 'e')
-            self.assertRaises(Forbidden, checker.check_getattr, inst, 'f')
+            self.assertRaises(Unauthorized,
+                              checker.check_getattr, inst, 'a', interaction)
+            self.assertRaises(Unauthorized,
+                              checker.check_getattr, inst, 'b', interaction)
+            self.assertRaises(Unauthorized,
+                              checker.check_getattr, inst, 'c', interaction)
+            self.assertRaises(Unauthorized,
+                              checker.check, inst, '__getitem__', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check, inst, '__setitem__', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_getattr, inst, 'd', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_getattr, inst, 'e', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_getattr, inst, 'f', interaction)
 
             checker = NamesChecker(['a', 'b', 'c', '__getitem__'],
                                    'test_allowed')
 
-            checker.check_getattr(inst, 'a')
-            checker.check_getattr(inst, 'b')
-            checker.check_getattr(inst, 'c')
-            checker.check(inst, '__getitem__')
-            self.assertRaises(Forbidden, checker.check, inst, '__setitem__')
-            self.assertRaises(Forbidden, checker.check_getattr, inst, 'd')
-            self.assertRaises(Forbidden, checker.check_getattr, inst, 'e')
-            self.assertRaises(Forbidden, checker.check_getattr, inst, 'f')
+            checker.check_getattr(inst, 'a', interaction)
+            checker.check_getattr(inst, 'b', interaction)
+            checker.check_getattr(inst, 'c', interaction)
+            checker.check(inst, '__getitem__', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check, inst, '__setitem__', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_getattr, inst, 'd', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_getattr, inst, 'e', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_getattr, inst, 'f', interaction)
 
             checker = NamesChecker(['a', 'b', 'c', '__getitem__'],
                                    CheckerPublic)
 
-            checker.check_getattr(inst, 'a')
-            checker.check_getattr(inst, 'b')
-            checker.check_getattr(inst, 'c')
-            checker.check(inst, '__getitem__')
-            self.assertRaises(Forbidden, checker.check, inst, '__setitem__')
-            self.assertRaises(Forbidden, checker.check_getattr, inst, 'd')
-            self.assertRaises(Forbidden, checker.check_getattr, inst, 'e')
-            self.assertRaises(Forbidden, checker.check_getattr, inst, 'f')
+            checker.check_getattr(inst, 'a', interaction)
+            checker.check_getattr(inst, 'b', interaction)
+            checker.check_getattr(inst, 'c', interaction)
+            checker.check(inst, '__getitem__', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check, inst, '__setitem__', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_getattr, inst, 'd', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_getattr, inst, 'e', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_getattr, inst, 'f', interaction)
 
     def test_check_setattr(self):
 
@@ -178,48 +197,64 @@
         newinst = NewInst()
         newinst.d = NewInst()
 
+        interaction = object()
+
         for inst in oldinst, newinst:
             checker = Checker({}, {'a': 'perm', 'z': 'perm'})
 
-            self.assertRaises(Unauthorized, checker.check_setattr, inst, 'a')
-            self.assertRaises(Unauthorized, checker.check_setattr, inst, 'z')
-            self.assertRaises(Forbidden, checker.check_setattr, inst, 'c')
-            self.assertRaises(Forbidden, checker.check_setattr, inst, 'd')
-            self.assertRaises(Forbidden, checker.check_setattr, inst, 'e')
-            self.assertRaises(Forbidden, checker.check_setattr, inst, 'f')
+            self.assertRaises(Unauthorized,
+                              checker.check_setattr, inst, 'a', interaction)
+            self.assertRaises(Unauthorized,
+                              checker.check_setattr, inst, 'z', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_setattr, inst, 'c', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_setattr, inst, 'd', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_setattr, inst, 'e', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_setattr, inst, 'f', interaction)
 
             checker = Checker({}, {'a': 'test_allowed', 'z': 'test_allowed'})
 
-            checker.check_setattr(inst, 'a')
-            checker.check_setattr(inst, 'z')
-            self.assertRaises(Forbidden, checker.check_setattr, inst, 'd')
-            self.assertRaises(Forbidden, checker.check_setattr, inst, 'e')
-            self.assertRaises(Forbidden, checker.check_setattr, inst, 'f')
+            checker.check_setattr(inst, 'a', interaction)
+            checker.check_setattr(inst, 'z', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_setattr, inst, 'd', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_setattr, inst, 'e', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_setattr, inst, 'f', interaction)
 
             checker = Checker({}, {'a': CheckerPublic, 'z': CheckerPublic})
 
-            checker.check_setattr(inst, 'a')
-            checker.check_setattr(inst, 'z')
-            self.assertRaises(Forbidden, checker.check_setattr, inst, 'd')
-            self.assertRaises(Forbidden, checker.check_setattr, inst, 'e')
-            self.assertRaises(Forbidden, checker.check_setattr, inst, 'f')
+            checker.check_setattr(inst, 'a', interaction)
+            checker.check_setattr(inst, 'z', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_setattr, inst, 'd', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_setattr, inst, 'e', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_setattr, inst, 'f', interaction)
 
     def test_proxy(self):
         checker = NamesChecker(())
+        interaction = object()
 
         from zope.security.checker import BasicTypes_examples
         rocks = tuple(BasicTypes_examples.values())
         rocks += (AttributeError(), AttributeError)
         for rock in rocks:
-            proxy = checker.proxy(rock)
+            proxy = checker.proxy(rock, interaction)
             self.failUnless(proxy is rock, (rock, type(proxy)))
 
         for class_ in OldInst, NewInst:
             inst = class_()
 
             for ob in inst, class_:
-                proxy = checker.proxy(ob)
+                proxy = checker.proxy(ob, interaction)
                 self.failUnless(getProxiedObject(proxy) is ob)
+                self.failUnless(getInteraction(proxy) is interaction)
                 checker = getChecker(proxy)
                 if ob is inst:
                     self.assertEqual(checker.permission_id('__str__'),
@@ -235,14 +270,14 @@
             #defineChecker(class_, special)
             #
             #for ob in inst, TransparentProxy(inst):
-            #    proxy = checker.proxy(ob)
+            #    proxy = checker.proxy(ob, interaction)
             #    self.failUnless(getProxiedObject(proxy) is ob)
             #
             #    checker = getChecker(proxy)
             #    self.failUnless(checker is special,
             #                    checker.getPermission_func().__self__)
             #
-            #    proxy2 = checker.proxy(proxy)
+            #    proxy2 = checker.proxy(proxy, interaction)
             #    self.failUnless(proxy2 is proxy, [proxy, proxy2])
 
     def testMultiChecker(self):
@@ -300,25 +335,29 @@
     def testAlwaysAvailable(self):
         from zope.security.checker import NamesChecker
         checker = NamesChecker(())
+        interaction = object()
         class C: pass
-        self.assertEqual(checker.check(C, '__hash__'), None)
-        self.assertEqual(checker.check(C, '__nonzero__'), None)
-        self.assertEqual(checker.check(C, '__class__'), None)
-        self.assertEqual(checker.check(C, '__implements__'), None)
-        self.assertEqual(checker.check(C, '__lt__'), None)
-        self.assertEqual(checker.check(C, '__le__'), None)
-        self.assertEqual(checker.check(C, '__gt__'), None)
-        self.assertEqual(checker.check(C, '__ge__'), None)
-        self.assertEqual(checker.check(C, '__eq__'), None)
-        self.assertEqual(checker.check(C, '__ne__'), None)
+        self.assertEqual(checker.check(C, '__hash__',interaction), None)
+        self.assertEqual(checker.check(C, '__nonzero__',interaction), None)
+        self.assertEqual(checker.check(C, '__class__',interaction), None)
+        self.assertEqual(checker.check(C, '__implements__',interaction), None)
+        self.assertEqual(checker.check(C, '__lt__',interaction), None)
+        self.assertEqual(checker.check(C, '__le__',interaction), None)
+        self.assertEqual(checker.check(C, '__gt__',interaction), None)
+        self.assertEqual(checker.check(C, '__ge__',interaction), None)
+        self.assertEqual(checker.check(C, '__eq__',interaction), None)
+        self.assertEqual(checker.check(C, '__ne__',interaction), None)
 
     def test_setattr(self):
         checker = NamesChecker(['a', 'b', 'c', '__getitem__'],
                                'test_allowed')
+        interaction = object()
 
         for inst in NewInst(), OldInst():
-            self.assertRaises(Forbidden, checker.check_setattr, inst, 'a')
-            self.assertRaises(Forbidden, checker.check_setattr, inst, 'z')
+            self.assertRaises(Forbidden,
+                              checker.check_setattr, inst, 'a', interaction)
+            self.assertRaises(Forbidden,
+                              checker.check_setattr, inst, 'z', interaction)
 
     # XXX write a test to see that
     # Checker.check/check_setattr handle permission
@@ -373,6 +412,14 @@
         proxy2 = ProxyFactory(proxy1, checker)
         self.assert_(proxy1 is proxy2)
 
+    def test_ProxyFactory_interaction(self):
+        class SomeClass:
+            pass
+        obj = SomeClass()
+        interaction = object()
+        proxy = ProxyFactory(obj, interaction=interaction)
+        self.assert_(getInteraction(proxy) is interaction)
+
 
 class TestCheckerPublic(TestCase):
 
@@ -397,26 +444,27 @@
 
     def check_checking_impl(self, checker):
         o = self.obj
-        checker.check_getattr(o, 'both_get_set')
+        interaction = object()
+        checker.check_getattr(o, 'both_get_set', interaction)
         self.assert_(self.policy.checkChecked(['dc_get_permission']))
-        checker.check_getattr(o, 'c_only')
+        checker.check_getattr(o, 'c_only', interaction)
         self.assert_(self.policy.checkChecked(['get_permission']))
-        checker.check_getattr(o, 'd_only')
+        checker.check_getattr(o, 'd_only', interaction)
         self.assert_(self.policy.checkChecked(['dc_get_permission']))
         self.assertRaises(ForbiddenAttribute,
                           checker.check_getattr, o,
-                          'completely_different_attr')
+                          'completely_different_attr', interaction)
         self.assert_(self.policy.checkChecked([]))
-        checker.check(o, '__str__')
+        checker.check(o, '__str__', interaction)
         self.assert_(self.policy.checkChecked(['get_permission']))
 
-        checker.check_setattr(o, 'both_get_set')
+        checker.check_setattr(o, 'both_get_set', interaction)
         self.assert_(self.policy.checkChecked(['dc_set_permission']))
         self.assertRaises(ForbiddenAttribute,
-                          checker.check_setattr, o, 'c_only')
+                          checker.check_setattr, o, 'c_only', interaction)
         self.assert_(self.policy.checkChecked([]))
         self.assertRaises(ForbiddenAttribute,
-                          checker.check_setattr, o, 'd_only')
+                          checker.check_setattr, o, 'd_only', interaction)
         self.assert_(self.policy.checkChecked([]))
 
     originalChecker = NamesChecker(['both_get_set', 'c_only', '__str__'],
@@ -429,6 +477,7 @@
 
     overridingChecker = Checker(decorationGetMap, decorationSetMap)
 
+
 class TestDecoratedChecker(TestMixinDecoratedChecker, TestCase):
 
     def setUp(self):
@@ -470,16 +519,19 @@
         # When a permission is not authorized by the security policy,
         # the policy is queried twice per check_getattr -- once for each
         # checker.
+        interaction = object()
         self.policy.permissions['dc_get_permission'] = False
-        cc.check_getattr(self.obj, 'both_get_set')
+        cc.check_getattr(self.obj, 'both_get_set', interaction)
         self.assert_(
             self.policy.checkChecked(['dc_get_permission', 'get_permission'])
             )
 
         # This should raise Unauthorized instead of ForbiddenAttribute, since
         # access can be granted if you e.g. login with different credentials.
-        self.assertRaises(Unauthorized, cc.check_getattr, self.obj, 'd_only')
-        self.assertRaises(Unauthorized, cc.check, self.obj, 'd_only')
+        self.assertRaises(Unauthorized,
+                          cc.check_getattr, self.obj, 'd_only', interaction)
+        self.assertRaises(Unauthorized,
+                          cc.check, self.obj, 'd_only', interaction)
 
     def test_interface(self):
         from zope.security.checker import CombinedChecker
@@ -487,12 +539,127 @@
         dc = CombinedChecker(self.overridingChecker, self.originalChecker)
         verifyObject(IChecker, dc)
 
+
+class TestCheckerLoggingMixin(TestCase):
+
+    object = '<object>'
+    name = '<name>'
+    interaction = '<interaction>'
+
+    def newChecker(self, check_raises=AssertionError,
+                   check_setattr_raises=AssertionError,
+                   check_getattr_raises=AssertionError,
+                   verbosity=1):
+
+        from zope.security.checker import CheckerLoggingMixin
+
+        class CheckerStub:
+
+            def check(self, object, name, interaction):
+                if check_raises is not None:
+                    raise check_raises
+
+            def check_getattr(self, object, name, interaction):
+                if check_getattr_raises is not None:
+                    raise check_getattr_raises
+
+            def check_setattr(self, object, name, interaction):
+                if check_setattr_raises is not None:
+                    raise check_setattr_raises
+
+        buf = StringIO()
+        v = verbosity
+
+        class CheckerLoggingStub(CheckerLoggingMixin, CheckerStub):
+            stderr = buf
+            verbosity = v
+
+        return CheckerLoggingStub(), buf
+
+    def test_check(self):
+        c, s = self.newChecker(check_raises=None)
+        c.check(self.object, self.name, self.interaction)
+        self.assertEquals(s.getvalue(), '')
+
+        c, s = self.newChecker(check_raises=None, verbosity=2)
+        c.check(self.object, self.name, self.interaction)
+        self.assertEquals(s.getvalue(),
+                "[CHK] + Granted: <name> on '<object>'\n")
+
+        c, s = self.newChecker(check_raises=None, verbosity=2)
+        c.check(self.object, '__repr__', self.interaction)
+        self.assertEquals(s.getvalue(),
+                "[CHK] + Always available: __repr__ on '<object>'\n")
+
+        c, s = self.newChecker(check_raises=Unauthorized)
+        self.assertRaises(Unauthorized, c.check, self.object, self.name,
+                          self.interaction)
+        self.assertEquals(s.getvalue(),
+                "[CHK] - Unauthorized: <name> on '<object>'\n")
+
+        c, s = self.newChecker(check_raises=ForbiddenAttribute)
+        self.assertRaises(ForbiddenAttribute, c.check, self.object, self.name,
+                          self.interaction)
+        self.assertEquals(s.getvalue(),
+                "[CHK] - Forbidden: <name> on '<object>'\n")
+
+    def test_check_getattr(self):
+        c, s = self.newChecker(check_getattr_raises=None)
+        c.check_getattr(self.object, self.name, self.interaction)
+        self.assertEquals(s.getvalue(), '')
+
+        c, s = self.newChecker(check_getattr_raises=None, verbosity=2)
+        c.check_getattr(self.object, self.name, self.interaction)
+        self.assertEquals(s.getvalue(),
+                "[CHK] + Granted getattr: <name> on '<object>'\n")
+
+        c, s = self.newChecker(check_getattr_raises=None, verbosity=2)
+        c.check_getattr(self.object, '__repr__', self.interaction)
+        self.assertEquals(s.getvalue(),
+                "[CHK] + Always available getattr: __repr__ on '<object>'\n")
+
+        c, s = self.newChecker(check_getattr_raises=Unauthorized)
+        self.assertRaises(Unauthorized, c.check_getattr, self.object,
+                          self.name, self.interaction)
+        self.assertEquals(s.getvalue(),
+                "[CHK] - Unauthorized getattr: <name> on '<object>'\n")
+
+        c, s = self.newChecker(check_getattr_raises=ForbiddenAttribute)
+        self.assertRaises(ForbiddenAttribute, c.check_getattr, self.object,
+                          self.name, self.interaction)
+        self.assertEquals(s.getvalue(),
+                "[CHK] - Forbidden getattr: <name> on '<object>'\n")
+
+    def test_check_setattr(self):
+        c, s = self.newChecker(check_setattr_raises=None)
+        c.check_setattr(self.object, self.name, self.interaction)
+        self.assertEquals(s.getvalue(), '')
+
+        c, s = self.newChecker(check_setattr_raises=None, verbosity=2)
+        c.check_setattr(self.object, self.name, self.interaction)
+        self.assertEquals(s.getvalue(),
+                "[CHK] + Granted setattr: <name> on '<object>'\n")
+
+        c, s = self.newChecker(check_setattr_raises=Unauthorized)
+        self.assertRaises(Unauthorized, c.check_setattr, self.object,
+                          self.name, self.interaction)
+        self.assertEquals(s.getvalue(),
+                "[CHK] - Unauthorized setattr: <name> on '<object>'\n")
+
+        c, s = self.newChecker(check_setattr_raises=ForbiddenAttribute)
+        self.assertRaises(ForbiddenAttribute, c.check_setattr, self.object,
+                          self.name, self.interaction)
+        self.assertEquals(s.getvalue(),
+                "[CHK] - Forbidden setattr: <name> on '<object>'\n")
+
+
 def test_suite():
     return TestSuite((
         makeSuite(Test),
         makeSuite(TestCheckerPublic),
         makeSuite(TestDecoratedChecker),
         makeSuite(TestCombinedChecker),
+        makeSuite(TestCheckerLoggingMixin),
         ))
 
 if __name__=='__main__':


=== Zope3/src/zope/security/tests/test_proxy.py 1.6 => 1.6.48.1 ===
--- Zope3/src/zope/security/tests/test_proxy.py:1.6	Wed May 28 13:19:24 2003
+++ Zope3/src/zope/security/tests/test_proxy.py	Mon Feb 23 14:18:07 2004
@@ -19,22 +19,22 @@
 
     ok = 1
 
-    def check_getattr(self, object, name):
+    def check_getattr(self, object, name, interaction):
         if name not in ("foo", "next", "__class__", "__name__", "__module__"):
             raise RuntimeError
 
-    def check_setattr(self, object, name):
+    def check_setattr(self, object, name, interaction):
         if name != "foo":
             raise RuntimeError
 
-    def check(self, object, opname):
+    def check(self, object, opname, interaction):
         if not self.ok:
             raise RuntimeError
 
-    def proxy(self, value):
+    def proxy(self, value, interaction):
         if type(value) is str:
             return value
-        return ProxyFactory(value, self)
+        return ProxyFactory(value, self, interaction)
 
 
 class Something:
@@ -242,7 +242,8 @@
         ]
 
     def test_unops(self):
-        P = self.c.proxy
+        interaction = object()
+        P = lambda v: self.c.proxy(v, interaction)
         for expr in self.unops:
             x = 1
             y = eval(expr)
@@ -254,7 +255,8 @@
 
     def test_odd_unops(self):
         # unops that don't return a proxy
-        P = self.c.proxy
+        interaction = object()
+        P = lambda v: self.c.proxy(v, interaction)
         for func in hex, oct, lambda x: not x:
             self.assertEqual(func(P(100)), func(100))
             self.shouldFail(func, P(100))
@@ -265,7 +267,8 @@
         ]
 
     def test_binops(self):
-        P = self.c.proxy
+        interaction = object()
+        P = lambda v: self.c.proxy(v, interaction)
         for expr in self.binops:
             first = 1
             for x in [1, P(1)]:
@@ -280,7 +283,8 @@
 
     def test_inplace(self):
         # XXX should test all inplace operators...
-        P = self.c.proxy
+        interaction = object()
+        P = lambda v: self.c.proxy(v, interaction)
 
         pa = P(1)
         pa += 2
@@ -307,7 +311,8 @@
         self.shouldFail(doit)
 
     def test_coerce(self):
-        P = self.c.proxy
+        interaction = object()
+        P = lambda v: self.c.proxy(v, interaction)
 
         # Before 2.3, coerce() of two proxies returns them unchanged
         import sys




More information about the Zope3-Checkins mailing list