[Zope-Checkins] CVS: Zope/lib/python/Products/Sessions - SessionDataManager.py:1.14.4.2

Chris McDonough chrism@zope.com
Thu, 28 Mar 2002 20:26:52 -0500


Update of /cvs-repository/Zope/lib/python/Products/Sessions
In directory cvs.zope.org:/tmp/cvs-serv18369

Modified Files:
      Tag: Zope-2_5-branch
	SessionDataManager.py 
Log Message:
The SessionDataManagerTraverser code was storing a reference to the
session data manager, wrapped in a strange acquisition context.  This could
cause erratic problems when users attempted to acquire methods from the session
data manager wrapping a transient object when the transient object was obtained
via REQUEST.SESSION. 

Instead of storing a reference to the session data manager, we now
just store a reference to its name and look it up via getattr, which
wraps it in a good acquisition context and prevents the erratic
errors.

Thanks to Andrew for pointing this out.

Also changed the add form to replace some sample text.



=== Zope/lib/python/Products/Sessions/SessionDataManager.py 1.14.4.1 => 1.14.4.2 ===
 import SessionInterfaces
 from SessionPermissions import *
+from types import StringType
 from common import DEBUG
 from ZPublisher.BeforeTraverse import registerBeforeTraverse, \
     unregisterBeforeTraverse
@@ -229,24 +230,33 @@
             self._requestSessionName = None
 
         if requestSessionName:
-            hook = SessionDataManagerTraverser(requestSessionName, self)
+            hook = SessionDataManagerTraverser(requestSessionName, self.id)
             registerBeforeTraverse(parent, hook, 'SessionDataManager', 50)
             self._hasTraversalHook = 1
             self._requestSessionName = requestSessionName
 
 class SessionDataManagerTraverser(Persistent):
-    def __init__(self, requestSessionName, sdm):
+    def __init__(self, requestSessionName, sessionDataManagerName):
         self._requestSessionName = requestSessionName
-        self._sessionDataManager = sdm
+        self._sessionDataManager = sessionDataManagerName
 
-    def __call__(self, container, request):
+    def __call__(self, container, request, StringType=StringType):
         try:
-            sdm = self._sessionDataManager.__of__(container)
-            session = sdm.getSessionData
+            sdmName = self._sessionDataManager
+            if not isinstance(sdmName, StringType):
+                # Zopes v2.5.0 - 2.5.1b1 stuck the actual session data
+                # manager object in _sessionDataManager in order to use
+                # its getSessionData method.  We don't actually want to
+                # do this, because it's safer to use getattr to get the
+                # data manager object by name.  Using getattr also puts
+                # the sdm in the right context automatically.  Here we
+                # pay the penance for backwards compatibility:
+                sdmName = sdmName.id
+            sdm = getattr(container, sdmName)
+            getSessionData = sdm.getSessionData
         except:
             msg = 'Session automatic traversal failed to get session data'
             LOG('Session Tracking', WARNING, msg, error=sys.exc_info())
             return
         if self._requestSessionName is not None:
-            request.set_lazy(self._requestSessionName, session)
-
+            request.set_lazy(self._requestSessionName, getSessionData)