[Zope-Checkins] CVS: Zope/lib/python/Products/Sessions - BrowserIdManager.py:1.15 SessionDataManager.py:1.22 SessionInterfaces.py:1.12
Chris McDonough
chrism@zope.com
Mon, 19 Aug 2002 15:50:47 -0400
Update of /cvs-repository/Zope/lib/python/Products/Sessions
In directory cvs.zope.org:/tmp/cvs-serv24326
Modified Files:
BrowserIdManager.py SessionDataManager.py SessionInterfaces.py
Log Message:
Added the capability for browser ids to be encoded in URLs.
When a set of knobs is set on the browser_id_manager "settings" screen,
("look for browser id name in..." and 'automatically encode browser ids..."),
a traversal hook is installed in the browser id manager's container which
causes a) the request to be searched for a browser id name and a browser
id as the first two elements of the URL path and b) for Zope-generated URLs
to contain these path elements.
Various documentation and interface updates. No interface methods
were harmed in the filming of this checkin, but a few were added or extended
with defaults.
=== Zope/lib/python/Products/Sessions/BrowserIdManager.py 1.14 => 1.15 === (456/556 lines abridged)
--- Zope/lib/python/Products/Sessions/BrowserIdManager.py:1.14 Wed Aug 14 18:25:09 2002
+++ Zope/lib/python/Products/Sessions/BrowserIdManager.py Mon Aug 19 15:50:17 2002
@@ -1,5 +1,5 @@
############################################################################
-#
+#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -15,7 +15,7 @@
import Globals
from Persistence import Persistent
from ZODB import TimeStamp
-from Acquisition import Implicit
+from Acquisition import Implicit, aq_base, aq_parent, aq_inner
from AccessControl.Owned import Owned
from AccessControl.Role import RoleManager
from App.Management import Tabs
@@ -27,6 +27,11 @@
from common import DEBUG
import os, time, random, string, binascii, sys, re
from cgi import escape
+from urllib import quote
+from urlparse import urlparse, urlunparse
+from ZPublisher.BeforeTraverse import registerBeforeTraverse, \
+ unregisterBeforeTraverse, queryBeforeTraverse
+import zLOG
b64_trans = string.maketrans('+/', '-.')
b64_untrans = string.maketrans('-.', '+/')
@@ -39,23 +44,27 @@
constructBrowserIdManagerForm = Globals.DTMLFile('dtml/addIdManager',globals())
+BROWSERID_MANAGER_NAME = 'browser_id_manager'# imported by SessionDataManager
+ALLOWED_BID_NAMESPACES = ('form', 'cookies', 'url')
ADD_BROWSER_ID_MANAGER_PERM="Add Browser Id Manager"
+TRAVERSAL_APPHANDLE = 'BrowserIdManager'
def constructBrowserIdManager(
- self, id, title='', idname='_ZopeId', location='cookiethenform',
- cookiepath='/', cookiedomain='', cookielifedays=0, cookiesecure=0,
- REQUEST=None
+ self, id=BROWSERID_MANAGER_NAME, title='', idname='_ZopeId',
+ location=('cookies', 'url', 'form'), cookiepath='/', cookiedomain='',
+ cookielifedays=0, cookiesecure=0, auto_url_encoding=0, REQUEST=None
):
""" """
ob = BrowserIdManager(id, title, idname, location, cookiepath,
- cookiedomain, cookielifedays, cookiesecure)
[-=- -=- -=- 456 lines omitted -=- -=- -=-]
+ TimeStamp=TimeStamp.TimeStamp, translate=string.translate
+ ):
+ t=time()
+ ts=split(b2a(`apply(TimeStamp,(gmtime(t)[:5]+(t%60,)))`)[:-1],'=')[0]
+ return translate(ts, b64_trans)
+
+def getB64TStampToInt(
+ ts, TimeStamp=TimeStamp.TimeStamp, b64_untrans=b64_untrans,
+ a2b=binascii.a2b_base64, translate=string.translate
+ ):
+ return TimeStamp(a2b(translate(ts+'=',b64_untrans))).timeTime()
+
+def getBrowserIdPieces(bid):
+ """ returns browser id parts in a tuple consisting of rand_id,
+ timestamp
+ """
+ return (bid[:8], bid[8:19])
+
+
+def isAWellFormedBrowserId(bid, binerr=binascii.Error,
+ timestamperr=TimeStamp.error):
+ try:
+ rnd, ts = getBrowserIdPieces(bid)
+ int(rnd)
+ getB64TStampToInt(ts)
+ return bid
+ except (TypeError, ValueError, AttributeError, IndexError, binerr,
+ timestamperr):
+ return None
+
+
+def getNewBrowserId(randint=random.randint, maxint=99999999):
+ """ Returns 19-character string browser id
+ 'AAAAAAAABBBBBBBB'
+ where:
+
+ A == leading-0-padded 8-char string-rep'd random integer
+ B == modified base64-encoded 11-char timestamp
+
+ To be URL-compatible, base64 encoding is modified as follows:
+ '=' end-padding is stripped off
+ '+' is translated to '-'
+ '/' is translated to '.'
+
+ An example is: 89972317A0C3EHnUi90w
+ """
+ return '%08i%s' % (randint(0, maxint-1), getB64TStamp())
Globals.InitializeClass(BrowserIdManager)
=== Zope/lib/python/Products/Sessions/SessionDataManager.py 1.21 => 1.22 ===
--- Zope/lib/python/Products/Sessions/SessionDataManager.py:1.21 Wed Aug 14 18:25:09 2002
+++ Zope/lib/python/Products/Sessions/SessionDataManager.py Mon Aug 19 15:50:17 2002
@@ -1,5 +1,5 @@
############################################################################
-#
+#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -25,11 +25,11 @@
from SessionPermissions import *
from types import StringType
from common import DEBUG
+from BrowserIdManager import isAWellFormedBrowserId, getNewBrowserId,\
+ BROWSERID_MANAGER_NAME
from ZPublisher.BeforeTraverse import registerBeforeTraverse, \
unregisterBeforeTraverse
-BID_MGR_NAME = 'browser_id_manager'
-
bad_path_chars_in=re.compile('[^a-zA-Z0-9-_~\,\. \/]').search
class SessionDataManagerErr(Exception): pass
@@ -103,19 +103,20 @@
security.declareProtected(ARBITRARY_SESSIONDATA_PERM,'getSessionDataByKey')
def getSessionDataByKey(self, key):
return self._getSessionDataObjectByKey(key)
-
+
security.declareProtected(ACCESS_CONTENTS_PERM, 'getBrowserIdManager')
def getBrowserIdManager(self):
""" """
- mgr = getattr(self, BID_MGR_NAME, None)
+ mgr = getattr(self, BROWSERID_MANAGER_NAME, None)
if mgr is None:
raise SessionDataManagerErr,(
- 'No browser id manager named %s could be found.' % BID_MGR_NAME
+ 'No browser id manager named %s could be found.' %
+ BROWSERID_MANAGER_NAME
)
return mgr
# END INTERFACE METHODS
-
+
def __init__(self, id, path=None, title='', requestName=None):
self.id = id
self.setContainerPath(path)
@@ -160,14 +161,14 @@
self.obpath = list(path) # sequence
else:
raise SessionDataManagerErr, ('Bad path value %s' % path)
-
+
security.declareProtected(MGMT_SCREEN_PERM, 'getContainerPath')
def getContainerPath(self):
""" """
if self.obpath is not None:
return string.join(self.obpath, '/')
return '' # blank string represents undefined state
-
+
def _hasSessionDataObject(self, key):
""" """
c = self._getSessionDataContainer()
@@ -251,6 +252,12 @@
self._sessionDataManager = sessionDataManagerName
def __call__(self, container, request, StringType=StringType):
+ """
+ This method places a session data object reference in
+ the request. It is called on each and every request to Zope in
+ Zopes after 2.5.0 when there is a session data manager installed
+ in the root.
+ """
try:
sdmName = self._sessionDataManager
if not isinstance(sdmName, StringType):
@@ -268,7 +275,10 @@
msg = 'Session automatic traversal failed to get session data'
LOG('Session Tracking', WARNING, msg, error=sys.exc_info())
return
+
+ # set the getSessionData method in the "lazy" namespace
if self._requestSessionName is not None:
request.set_lazy(self._requestSessionName, getSessionData)
+
Globals.InitializeClass(SessionDataManager)
=== Zope/lib/python/Products/Sessions/SessionInterfaces.py 1.11 => 1.12 ===
--- Zope/lib/python/Products/Sessions/SessionInterfaces.py:1.11 Wed Aug 14 18:25:09 2002
+++ Zope/lib/python/Products/Sessions/SessionInterfaces.py Mon Aug 19 15:50:17 2002
@@ -12,7 +12,7 @@
############################################################################
"""
-Sessioning-related Object APIs
+Session APIs
See Also
@@ -32,12 +32,24 @@
visitors, and for servicing requests from Session Data Managers
related to the browser id.
"""
- def encodeUrl(url):
+ def encodeUrl(url, style='querystring'):
"""
Encodes a provided URL with the current request's browser id
- and returns the result. For example, the call
- encodeUrl('http://foo.com/amethod') might return
- 'http://foo.com/amethod?_ZopeId=as9dfu0adfu0ad'.
+ and returns the result. Two forms of URL-encoding are supported:
+ 'querystring' and 'inline'. 'querystring' is the default.
+
+ If the 'querystring' form is used, the browser id name/value pair
+ are postfixed onto the URL as a query string. If the 'inline'
+ form is used, the browser id name/value pair are prefixed onto
+ the URL as the first two path segment elements.
+
+ For example:
+
+ The call encodeUrl('http://foo.com/amethod', style='querystring')
+ might return 'http://foo.com/amethod?_ZopeId=as9dfu0adfu0ad'.
+
+ The call encodeUrl('http://foo.com/amethod, style='inline')
+ might return 'http://foo.com/_ZopeId/as9dfu0adfu0ad/amethod'.
Permission required: Access contents information