[Zope3-checkins] CVS: Zope3/src/zope/security - checker.py:1.9

Jim Fulton jim@zope.com
Fri, 7 Mar 2003 16:13:35 -0500


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

Modified Files:
	checker.py 
Log Message:
Modified CheckerPublic so that it can be pickled and unpickled without
loss of identity. This is necessary so that it can be stored and used
in persistent objects.


=== Zope3/src/zope/security/checker.py 1.8 => 1.9 ===
--- Zope3/src/zope/security/checker.py:1.8	Fri Mar  7 13:39:41 2003
+++ Zope3/src/zope/security/checker.py	Fri Mar  7 16:13:02 2003
@@ -15,21 +15,6 @@
     WATCH_CHECKERS = 0
 
 
-# Marker for public attributes
-
-class Global(object):
-
-    def __init__(self, name, module=None):
-        if module is None:
-            module = sys._getframe(1).f_locals['__name__']
-            
-        self.__name__ = name
-        self.__module__ = module
-
-    def __reduce__(self):
-        return self.__name__
-
-CheckerPublic = Global('CheckerPublic')
 
 def ProxyFactory(object, checker=None):
     """Factory function that creates a proxy for an object
@@ -176,6 +161,36 @@
                 return value
 
         return Proxy(value, checker)
+
+# Marker for public attributes
+
+# We want this to behave as a global, meaning it's pickled
+# by name, rather than value. We need to arrange that it has a suitable
+# __reduce__. 
+class Global(object):
+
+    def __init__(self, name, module=None):
+        if module is None:
+            module = sys._getframe(1).f_locals['__name__']
+            
+        self.__name__ = name
+        self.__module__ = module
+
+    def __reduce__(self):
+        return self.__name__
+
+CheckerPublic = Global('CheckerPublic')
+
+# Now we wrap it in a security proxy so that it retains it's
+# identity when it needs to be security proxied.  
+d={}
+CheckerPublic = Proxy(CheckerPublic, Checker(d))
+d['__reduce__'] = CheckerPublic
+del d
+
+# XXX It's a bit scary above that we can pickle a proxy if access is
+# granted to __reduce__. We might want to bother to prevent this in
+# general and only allow it in this specific case.
 
 def NamesChecker(names=(), permission_id=CheckerPublic, **__kw__):
     """Return a checker that grants access to a set of names.