[Checkins] SVN: zope.security/trunk/src/zope/security/ Moved the "protectclass" module, a slender collection of three

Brandon Rhodes brandon at rhodesmill.org
Wed Jan 28 08:03:16 EST 2009


Log message for revision 95308:
  Moved the "protectclass" module, a slender collection of three
  commonly-used utility functions, into "zope.security" so that the Zope
  modules that use it can stop depending on the much larger (and ZMI-
  supporting) "zope.app.security" if they do not need to.
  

Changed:
  A   zope.security/trunk/src/zope/security/protectclass.py
  A   zope.security/trunk/src/zope/security/tests/module.py
  A   zope.security/trunk/src/zope/security/tests/modulehookup.py
  A   zope.security/trunk/src/zope/security/tests/test_protectclass.py
  A   zope.security/trunk/src/zope/security/tests/test_protectsubclass.py

-=-
Copied: zope.security/trunk/src/zope/security/protectclass.py (from rev 95302, zope.app.security/trunk/src/zope/app/security/protectclass.py)
===================================================================
--- zope.security/trunk/src/zope/security/protectclass.py	                        (rev 0)
+++ zope.security/trunk/src/zope/security/protectclass.py	2009-01-28 13:03:16 UTC (rev 95308)
@@ -0,0 +1,89 @@
+##############################################################################
+#
+# 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.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.
+#
+##############################################################################
+"""Make assertions about permissions needed to access class instances
+attributes
+
+$Id$
+"""
+from zope.security.checker import defineChecker, getCheckerForInstancesOf
+from zope.security.checker import Checker, CheckerPublic
+
+
+def protectName(class_, name, permission):
+    """Set a permission on a particular name."""
+
+    checker = getCheckerForInstancesOf(class_)
+    if checker is None:
+        checker = Checker({}, {})
+        defineChecker(class_, checker)
+
+    if permission == 'zope.Public':
+        # Translate public permission to CheckerPublic
+        permission = CheckerPublic
+
+    # We know a dictionary was used because we set it
+    protections = checker.get_permissions
+    protections[name] = permission
+
+def protectSetAttribute(class_, name, permission):
+    """Set a permission on a particular name."""
+
+    checker = getCheckerForInstancesOf(class_)
+    if checker is None:
+        checker = Checker({}, {})
+        defineChecker(class_, checker)
+
+    if permission == 'zope.Public':
+        # Translate public permission to CheckerPublic
+        permission = CheckerPublic
+
+    # We know a dictionary was used because we set it
+    # Note however, that if a checker was created manually
+    # and the caller used say NamesChecker or MultiChecker,
+    # then set_permissions may be None here as Checker
+    # defaults a missing set_permissions parameter to None.
+    # Jim says this doensn't happens with the C version of the
+    # checkers because they use a 'shared dummy dict'.
+    protections = checker.set_permissions
+    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 dictionary was used because we set it
+    # Note however, that if a checker was created manually
+    # and the caller used say NamesChecker or MultiChecker,
+    # then set_permissions may be None here as Checker
+    # defaults a missing set_permissions parameter to None.
+    # Jim says this doensn't happens with the C version of the
+    # checkers because they use a 'shared dummy dict'.
+    unto_get_protections = unto_checker.get_permissions
+    unto_set_protections = unto_checker.set_permissions
+
+    checker = getCheckerForInstancesOf(class_)
+    if checker is None:
+        checker = Checker({}, {})
+        defineChecker(class_, checker)
+
+    get_protections = checker.get_permissions
+    for name in unto_get_protections:
+        get_protections[name] = unto_get_protections[name]
+
+    set_protections = checker.set_permissions
+    for name in unto_set_protections:
+        set_protections[name] = unto_set_protections[name]


Property changes on: zope.security/trunk/src/zope/security/protectclass.py
___________________________________________________________________
Added: cvs2svn:cvs-rev
   + 1.4
Added: svn:keywords
   + Id
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native

Copied: zope.security/trunk/src/zope/security/tests/module.py (from rev 95302, zope.app.security/trunk/src/zope/app/security/tests/module.py)
===================================================================
--- zope.security/trunk/src/zope/security/tests/module.py	                        (rev 0)
+++ zope.security/trunk/src/zope/security/tests/module.py	2009-01-28 13:03:16 UTC (rev 95308)
@@ -0,0 +1,20 @@
+##############################################################################
+#
+# 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.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.
+#
+##############################################################################
+"""This empty module is for containing objects used in the course of tests.
+
+(There is a problem with the way the unit tests interact with the modules
+being tests, so the objects can't be expected to show up in place.)
+
+$Id$
+"""


Property changes on: zope.security/trunk/src/zope/security/tests/module.py
___________________________________________________________________
Added: cvs2svn:cvs-rev
   + 1.2
Added: svn:keywords
   + Id
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native

Copied: zope.security/trunk/src/zope/security/tests/modulehookup.py (from rev 95302, zope.app.security/trunk/src/zope/app/security/tests/modulehookup.py)
===================================================================
--- zope.security/trunk/src/zope/security/tests/modulehookup.py	                        (rev 0)
+++ zope.security/trunk/src/zope/security/tests/modulehookup.py	2009-01-28 13:03:16 UTC (rev 95308)
@@ -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.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.
+#
+##############################################################################
+"""Preliminaries to hookup a test suite with the external TestModule.
+
+This is necessary because the test framework interferes with seeing changes in
+the running modules via the module namespace.  This enables having some
+subject classes, instances, permissions, etc, that don't live in the test
+modules, themselves.
+
+$Id$
+"""
+from zope.interface import Interface
+
+from zope.security.tests import module as TestModule
+
+class I(Interface):
+    def m1():
+        pass
+    def m2():
+        pass
+


Property changes on: zope.security/trunk/src/zope/security/tests/modulehookup.py
___________________________________________________________________
Added: cvs2svn:cvs-rev
   + 1.3
Added: svn:keywords
   + Id
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native

Copied: zope.security/trunk/src/zope/security/tests/test_protectclass.py (from rev 95302, zope.app.security/trunk/src/zope/app/security/tests/test_protectclass.py)
===================================================================
--- zope.security/trunk/src/zope/security/tests/test_protectclass.py	                        (rev 0)
+++ zope.security/trunk/src/zope/security/tests/test_protectclass.py	2009-01-28 13:03:16 UTC (rev 95308)
@@ -0,0 +1,128 @@
+##############################################################################
+#
+# 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.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.
+#
+##############################################################################
+"""Test handler for 'protectClass' directive
+
+$Id$
+"""
+import unittest
+from zope.interface import implements
+from zope.security.checker import selectChecker
+from zope.security.permission import Permission
+from zope import component
+from zope.component.testing import PlacelessSetup
+
+from zope.security.interfaces import IPermission
+from zope.security.protectclass import protectName, protectLikeUnto
+from zope.security.protectclass import protectSetAttribute
+from zope.security.tests.modulehookup import TestModule, I
+
+NOTSET = []
+
+P1 = "extravagant"
+P2 = "paltry"
+
+class Test(PlacelessSetup, unittest.TestCase):
+
+    def setUp(self):
+        super(Test, self).setUp()
+
+        component.provideUtility(Permission(P1), IPermission, P1)
+        component.provideUtility(Permission(P2), IPermission, P2)
+
+        class B(object):
+            def m1(self):
+                return "m1"
+            def m2(self):
+                return "m2"
+
+        class C(B):
+            implements(I)
+            def m3(self):
+                return "m3"
+            def m4(self):
+                return "m4"
+
+        TestModule.test_base = B
+        TestModule.test_class = C
+        TestModule.test_instance = C()
+        self.assertState()
+
+    def tearDown(self):
+        super(Test, self).tearDown()
+        TestModule.test_class = None
+
+    def assertState(self, m1P=NOTSET, m2P=NOTSET, m3P=NOTSET):
+        "Verify that class, instance, and methods have expected permissions."
+        checker = selectChecker(TestModule.test_instance)
+        self.assertEqual(checker.permission_id('m1'), (m1P or None))
+        self.assertEqual(checker.permission_id('m2'), (m2P or None))
+        self.assertEqual(checker.permission_id('m3'), (m3P or None))
+
+    def assertSetattrState(self, m1P=NOTSET, m2P=NOTSET, m3P=NOTSET):
+        "Verify that class, instance, and methods have expected permissions."
+        checker = selectChecker(TestModule.test_instance)
+        self.assertEqual(checker.setattr_permission_id('m1'), (m1P or None))
+        self.assertEqual(checker.setattr_permission_id('m2'), (m2P or None))
+        self.assertEqual(checker.setattr_permission_id('m3'), (m3P or None))
+
+    # "testSimple*" exercises tags that do NOT have children.  This mode
+    # inherently sets the instances as well as the class attributes.
+
+    def testSimpleMethodsPlural(self):
+        protectName(TestModule.test_class, 'm1', P1)
+        protectName(TestModule.test_class, 'm3', P1)
+        self.assertState(m1P=P1, m3P=P1)
+
+    def testLikeUntoOnly(self):
+        protectName(TestModule.test_base, 'm1', P1)
+        protectName(TestModule.test_base, 'm2', P1)
+        protectSetAttribute(TestModule.test_base, 'm1', P1)
+        protectSetAttribute(TestModule.test_base, 'm2', P1)
+        protectLikeUnto(TestModule.test_class, TestModule.test_base)
+        # m1 and m2 are in the interface, so should be set, and m3 should not:
+        self.assertState(m1P=P1, m2P=P1)
+        self.assertSetattrState(m1P=P1, m2P=P1)
+
+    def assertSetattrState(self, m1P=NOTSET, m2P=NOTSET, m3P=NOTSET):
+        "Verify that class, instance, and methods have expected permissions."
+        checker = selectChecker(TestModule.test_instance)
+        self.assertEqual(checker.setattr_permission_id('m1'), (m1P or None))
+        self.assertEqual(checker.setattr_permission_id('m2'), (m2P or None))
+        self.assertEqual(checker.setattr_permission_id("m3"), (m3P or None))
+
+    def testSetattr(self):
+        protectSetAttribute(TestModule.test_class, 'm1', P1)
+        protectSetAttribute(TestModule.test_class, 'm3', P1)
+        self.assertSetattrState(m1P=P1, m3P=P1)
+
+    def testLikeUntoAsDefault(self):
+        protectName(TestModule.test_base, 'm1', P1)
+        protectName(TestModule.test_base, 'm2', P1)
+        protectSetAttribute(TestModule.test_base, 'm1', P1)
+        protectSetAttribute(TestModule.test_base, 'm2', P1)
+        protectLikeUnto(TestModule.test_class, TestModule.test_base)
+        protectName(TestModule.test_class, 'm2', P2)
+        protectName(TestModule.test_class, 'm3', P2)
+        protectSetAttribute(TestModule.test_class, 'm2', P2)
+        protectSetAttribute(TestModule.test_class, 'm3', P2)
+        # m1 and m2 are in the interface, so should be set, and m3 should not:
+        self.assertState(m1P=P1, m2P=P2, m3P=P2)
+        self.assertSetattrState(m1P=P1, m2P=P2, m3P=P2)
+
+def test_suite():
+    loader=unittest.TestLoader()
+    return loader.loadTestsFromTestCase(Test)
+
+if __name__=='__main__':
+    unittest.TextTestRunner().run(test_suite())


Property changes on: zope.security/trunk/src/zope/security/tests/test_protectclass.py
___________________________________________________________________
Added: cvs2svn:cvs-rev
   + 1.6
Added: svn:keywords
   + Id
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native

Copied: zope.security/trunk/src/zope/security/tests/test_protectsubclass.py (from rev 95302, zope.app.security/trunk/src/zope/app/security/tests/test_protectsubclass.py)
===================================================================
--- zope.security/trunk/src/zope/security/tests/test_protectsubclass.py	                        (rev 0)
+++ zope.security/trunk/src/zope/security/tests/test_protectsubclass.py	2009-01-28 13:03:16 UTC (rev 95308)
@@ -0,0 +1,59 @@
+##############################################################################
+#
+# 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.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.
+#
+##############################################################################
+"""Test proper protection of inherited methods
+
+$Id$
+"""
+import unittest
+from zope.security.checker import selectChecker
+from zope.security.permission import Permission
+from zope import component
+from zope.component.testing import PlacelessSetup
+
+from zope.security.interfaces import IPermission
+from zope.security.protectclass import protectName
+
+class Test(PlacelessSetup, unittest.TestCase):
+
+    def testInherited(self):
+
+        class B1(object):
+            def g(self): return 'B1.g'
+
+        class B2(object):
+            def h(self): return 'B2.h'
+
+        class S(B1, B2):
+            pass
+
+        component.provideUtility(Permission('B1', ''), IPermission, 'B1')
+        component.provideUtility(Permission('S', ''), IPermission, 'S')
+        protectName(B1, 'g', 'B1')
+        protectName(S, 'g', 'S')
+        protectName(S, 'h', 'S')
+
+        self.assertEqual(selectChecker(B1()).permission_id('g'), 'B1')
+        self.assertEqual(selectChecker(B2()).permission_id('h'), None)
+        self.assertEqual(selectChecker(S()).permission_id('g'), 'S')
+        self.assertEqual(selectChecker(S()).permission_id('h'), 'S')
+
+        self.assertEqual(S().g(), 'B1.g')
+        self.assertEqual(S().h(), 'B2.h')
+
+
+def test_suite():
+    return unittest.makeSuite(Test)
+
+if __name__=='__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: zope.security/trunk/src/zope/security/tests/test_protectsubclass.py
___________________________________________________________________
Added: cvs2svn:cvs-rev
   + 1.4
Added: svn:keywords
   + Id
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native



More information about the Checkins mailing list