[Zope3-checkins] SVN: Zope3/trunk/src/zope/ I think this fixes our security proxy issues. Gary, that's cool with you?

Stephan Richter srichter at cosmos.phy.tufts.edu
Wed Oct 26 22:26:47 EDT 2005


Log message for revision 39662:
  I think this fixes our security proxy issues. Gary, that's cool with you?
  
  

Changed:
  U   Zope3/trunk/src/zope/app/security/_protections.py
  U   Zope3/trunk/src/zope/security/README.txt
  U   Zope3/trunk/src/zope/security/checker.py
  U   Zope3/trunk/src/zope/security/tests/test_checker.py

-=-
Modified: Zope3/trunk/src/zope/app/security/_protections.py
===================================================================
--- Zope3/trunk/src/zope/app/security/_protections.py	2005-10-27 00:49:40 UTC (rev 39661)
+++ Zope3/trunk/src/zope/app/security/_protections.py	2005-10-27 02:26:46 UTC (rev 39662)
@@ -32,14 +32,11 @@
 
     # Make sure the message id gets never proxied
     # TODO because MessageIDs are mutable, this is a security hole.  This hole
-    # is one of the primary reasons for the development of the Message 
+    # is one of the primary reasons for the development of the Message
     # replacement.  See zope/i18nmessageid/messages.txt.
     zope.security.checker.BasicTypes[MessageID] = NoProxy
     # this, however, is not a security hole, because Messages are immutable.
     zope.security.checker.BasicTypes[Message] = NoProxy
-    zope.security.checker._clear() # XXX The BasicTypes approach requires
-    # _clear be called.  This is not a good idea.  This should be addressed
-    # before release.
 
     # add __parent__ and __name__ to always available names
     import zope.security.checker

Modified: Zope3/trunk/src/zope/security/README.txt
===================================================================
--- Zope3/trunk/src/zope/security/README.txt	2005-10-27 00:49:40 UTC (rev 39661)
+++ Zope3/trunk/src/zope/security/README.txt	2005-10-27 02:26:46 UTC (rev 39662)
@@ -226,23 +226,23 @@
 being accessed::
 
   class SimulationSecurityPolicy:
-  
+
       implements(ISecurityPolicy)
-  
+
       createInteraction = staticmethod(simpleinteraction.createInteraction)
-  
+
       def checkPermission(self, permission, object, interaction):
-  
+
           home = object.getHome()
           db = getattr(SimulationSecurityDatabase, home.getId(), None)
-  
+
           if db is None:
               return False
-  
+
           allowed = db.get('any', ())
           if permission in allowed or ALL in allowed:
               return True
-  
+
           if interaction is None:
               return False
           if not interaction.participations:
@@ -252,7 +252,7 @@
               allowed = db.get(token, ())
               if permission not in allowed:
                   return False
-  
+
           return True
 
 There are no specific requirements for the interaction class, so we can just

Modified: Zope3/trunk/src/zope/security/checker.py
===================================================================
--- Zope3/trunk/src/zope/security/checker.py	2005-10-27 00:49:40 UTC (rev 39661)
+++ Zope3/trunk/src/zope/security/checker.py	2005-10-27 02:26:46 UTC (rev 39662)
@@ -560,7 +560,28 @@
                             '__eq__', '__ne__', '__lt__', '__gt__',
                             '__le__', '__ge__'])
 
-BasicTypes = {
+class BasicTypes(dict):
+    """Basic Types Dictionary
+
+    Make sure that the checkers a really updated, when a new type is added.
+    """
+    def __setitem__(self, name, value):
+        super(BasicTypes.__class__, self).__setitem__(name, value)
+        _checkers[name] = value
+
+    def __delitem__(self, name):
+        super(BasicTypes.__class__, self).__delitem__(name)
+        del _checkers[name]
+
+    def clear(self):
+        # Make sure you cannot clear the values
+        raise NotImplementedError
+
+    def update(self, d):
+        super(BasicTypes.__class__, self).update(d)
+        _checkers.update(d)
+
+BasicTypes = BasicTypes({
     object: NoProxy,
     int: NoProxy,
     float: NoProxy,
@@ -569,14 +590,14 @@
     types.NoneType: NoProxy,
     str: NoProxy,
     unicode: NoProxy,
-    type(True): NoProxy, # Boolean, if available :)
+    bool: NoProxy,
     datetime.timedelta: NoProxy,
     datetime.datetime: NoProxy,
     datetime.date: NoProxy,
     datetime.time: NoProxy,
     datetime.tzinfo: NoProxy,
     type(pytz.UTC): NoProxy,
-}
+})
 
 # Available for tests. Located here so it can be kept in sync with BasicTypes.
 BasicTypes_examples = {
@@ -588,7 +609,7 @@
     types.NoneType: None,
     str: 'abc',
     unicode: u'uabc',
-    type(True): True,
+    bool: True,
     datetime.timedelta: datetime.timedelta(3),
     datetime.datetime: datetime.datetime(2003, 1, 1),
     datetime.date: datetime.date(2003, 1, 1),

Modified: Zope3/trunk/src/zope/security/tests/test_checker.py
===================================================================
--- Zope3/trunk/src/zope/security/tests/test_checker.py	2005-10-27 00:49:40 UTC (rev 39661)
+++ Zope3/trunk/src/zope/security/tests/test_checker.py	2005-10-27 02:26:46 UTC (rev 39662)
@@ -28,9 +28,10 @@
 from zope.security.management import endInteraction, getInteraction
 from zope.security.proxy import removeSecurityProxy
 from zope.security.proxy import getChecker
+from zope.security.proxy import Proxy
 from zope.security.checker import defineChecker, ProxyFactory
 from zope.security.checker import canWrite, canAccess
-from zope.security.proxy import Proxy
+from zope.security.checker import BasicTypes, _checkers, NoProxy, _clear
 import types, pickle
 
 class SecurityPolicy(object):
@@ -525,7 +526,8 @@
         self.interaction.permissions['dc_get_permission'] = False
         cc.check_getattr(self.obj, 'both_get_set')
         self.assert_(
-            self.interaction.checkChecked(['dc_get_permission', 'get_permission'])
+            self.interaction.checkChecked(['dc_get_permission',
+                                           'get_permission'])
             )
 
         # This should raise Unauthorized instead of ForbiddenAttribute, since
@@ -539,11 +541,62 @@
         dc = CombinedChecker(self.overridingChecker, self.originalChecker)
         verifyObject(IChecker, dc)
 
+
+class TestBasicTypes(TestCase):
+
+    def test(self):
+        class MyType(object): pass
+        class MyType2(object): pass
+
+        # When an item is added to the basic types, it should also be added to
+        # the list of checkers.
+        BasicTypes[MyType] = NoProxy
+        self.assert_(MyType in _checkers)
+
+        # If we clear the checkers, the type should still be there
+        _clear()
+        self.assert_(MyType in BasicTypes)
+        self.assert_(MyType in _checkers)
+
+        # Now delete the type from the dictionary, will also delete it from
+        # the checkers
+        del BasicTypes[MyType]
+        self.assert_(MyType not in BasicTypes)
+        self.assert_(MyType not in _checkers)
+
+        # The quick way of adding new types is using update
+        BasicTypes.update({MyType: NoProxy, MyType2: NoProxy})
+        self.assert_(MyType in BasicTypes)
+        self.assert_(MyType2 in BasicTypes)
+        self.assert_(MyType in _checkers)
+        self.assert_(MyType2 in _checkers)
+
+        # Let's remove the two new types
+        del BasicTypes[MyType]
+        del BasicTypes[MyType2]
+
+        # Of course, BasicTypes is a full dictionary. This dictionary is by
+        # default filled with several entries:
+        keys = BasicTypes.keys()
+        keys.sort()
+        self.assert_(bool in keys)
+        self.assert_(int in keys)
+        self.assert_(float in keys)
+        self.assert_(str in keys)
+        self.assert_(unicode in keys)
+        self.assert_(object in keys)
+        # ...
+
+        # Finally, the ``clear()`` method has been deactivated to avoid
+        # unwanted deletions.
+        self.assertRaises(NotImplementedError, BasicTypes.clear)
+
 def test_suite():
     return TestSuite((
         makeSuite(Test),
         makeSuite(TestCheckerPublic),
         makeSuite(TestCombinedChecker),
+        makeSuite(TestBasicTypes),
         ))
 
 if __name__=='__main__':



More information about the Zope3-Checkins mailing list