[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