Commit d4c75698 authored by Chris McDonough's avatar Chris McDonough

As per suggestions by Amos, I changed the terminology used by the browser id...

As per suggestions by Amos, I changed the terminology used by the browser id manager and session data manager.  Previous to the change, browser ids were known as "tokens".  I've changed this to "browser id" in the docs as well as in all API methods that used the name "token".  Interfaces, permissions, and help have been updated with the changes.
parent 06dfed3b
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
# #
############################################################################ ############################################################################
__version__='$Revision: 1.3 $'[11:-2] __version__='$Revision: 1.4 $'[11:-2]
import Globals import Globals
from Persistence import Persistent from Persistence import Persistent
from ZODB import TimeStamp from ZODB import TimeStamp
...@@ -94,7 +94,7 @@ import os, time, random, string, binascii, sys, re ...@@ -94,7 +94,7 @@ import os, time, random, string, binascii, sys, re
b64_trans = string.maketrans('+/', '-.') b64_trans = string.maketrans('+/', '-.')
b64_untrans = string.maketrans('-.', '+/') b64_untrans = string.maketrans('-.', '+/')
badtokenkeycharsin = re.compile('[\?&;, ]').search badidnamecharsin = re.compile('[\?&;, ]').search
badcookiecharsin = re.compile('[;, ]').search badcookiecharsin = re.compile('[;, ]').search
twodotsin = re.compile('(\w*\.){2,}').search twodotsin = re.compile('(\w*\.){2,}').search
...@@ -105,16 +105,12 @@ constructBrowserIdManagerForm = Globals.DTMLFile('dtml/addIdManager',globals()) ...@@ -105,16 +105,12 @@ constructBrowserIdManagerForm = Globals.DTMLFile('dtml/addIdManager',globals())
ADD_BROWSER_ID_MANAGER_PERM="Add Browser ID Manager" ADD_BROWSER_ID_MANAGER_PERM="Add Browser ID Manager"
def constructBrowserIdManager( def constructBrowserIdManager(
self, id, title='', tokenkey='_ZopeId', cookiepri=1, formpri=2, self, id, title='', idname='_ZopeId', location='cookiethenform',
urlpri=0, cookiepath='/', cookiedomain='', cookielifedays=0, cookiepath='/', cookiedomain='', cookielifedays=0, cookiesecure=0,
cookiesecure=0, REQUEST=None REQUEST=None
): ):
""" """ """ """
# flip dictionary and take what's not 0 (god I hate HTML) ob = BrowserIdManager(id, title, idname, location, cookiepath,
d = {}
for k,v in {'url':urlpri, 'form':formpri, 'cookies':cookiepri}.items():
if v: d[v] = k
ob = BrowserIdManager(id, title, tokenkey, d, cookiepath,
cookiedomain, cookielifedays, cookiesecure) cookiedomain, cookielifedays, cookiesecure)
self._setObject(id, ob) self._setObject(id, ob)
ob = self._getOb(id) ob = self._getOb(id)
...@@ -148,152 +144,124 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs): ...@@ -148,152 +144,124 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs):
icon = 'misc_/Sessions/idmgr.gif' icon = 'misc_/Sessions/idmgr.gif'
def __init__( def __init__(self, id, title='', idname='_ZopeId',
self, id, title='', tokenkey='_ZopeId', location='cookiesthenform', cookiepath=('/'),
tokenkeynamespaces={1:'cookies',2:'form'}, cookiepath=('/'), cookiedomain='', cookielifedays=0, cookiesecure=0):
cookiedomain='', cookielifedays=0, cookiesecure=0, on=1 self.id = str(id)
): self.title = str(title)
self.setBrowserIdName(idname)
self.id = id self.setBrowserIdLocation(location)
self.title = title
self.setTokenKey(tokenkey)
self.setTokenKeyNamespaces(tokenkeynamespaces)
self.setCookiePath(cookiepath) self.setCookiePath(cookiepath)
self.setCookieDomain(cookiedomain) self.setCookieDomain(cookiedomain)
self.setCookieLifeDays(cookielifedays) self.setCookieLifeDays(cookielifedays)
self.setCookieSecure(cookiesecure) self.setCookieSecure(cookiesecure)
if on:
self.turnOn()
else:
self.turnOff()
# delegating methods follow
# don't forget to change the name of the method in
# delegation if you change a delegating method name
security.declareProtected(ACCESS_CONTENTS_PERM, 'hasToken') security.declareProtected(ACCESS_CONTENTS_PERM, 'hasBrowserId')
def hasToken(self): def hasBrowserId(self):
""" Returns true if there is a current browser token, but does """ Returns true if there is a current browser id, but does
not create a browser token for the current request if one doesn't not create a browser id for the current request if one doesn't
already exist """ already exist """
if not self.on: if self.getBrowserId(create=0): return 1
return self._delegateToParent('hasToken')
if self.getToken(create=0): return 1
security.declareProtected(ACCESS_CONTENTS_PERM, 'getToken') security.declareProtected(ACCESS_CONTENTS_PERM, 'getBrowserId')
def getToken(self, create=1): def getBrowserId(self, create=1):
""" """
Examines the request and hands back browser token value or Examines the request and hands back browser id value or
None if no token exists. If there is no browser token None if no id exists. If there is no browser id
and if 'create' is true, create one. If cookies are are and if 'create' is true, create one. If cookies are are
an allowable id key namespace and create is true, set one. Stuff an allowable id namespace and create is true, set one. Stuff
the token and the namespace it was found in into the REQUEST object the id and the namespace it was found in into the REQUEST object
for further reference during this request. Delegate this call to for further reference during this request.
a parent if we're turned off.
""" """
if not self.on:
return self._delegateToParent('getToken', create)
REQUEST = self.REQUEST REQUEST = self.REQUEST
# let's see if token has already been attached to request # let's see if bid has already been attached to request
token = getattr(REQUEST, 'browser_token_', None) bid = getattr(REQUEST, 'browser_id_', None)
if token is not None: if bid is not None:
# it's already set in this request so we can just return it # it's already set in this request so we can just return it
# if it's well-formed # if it's well-formed
if not self._isAWellFormedToken(token): if not self._isAWellFormedBrowserId(bid):
# somebody screwed with the REQUEST instance during # somebody screwed with the REQUEST instance during
# this request. # this request.
raise BrowserIdManagerErr, ( raise BrowserIdManagerErr, (
'Ill-formed token in REQUEST.browser_token_: %s' % token 'Ill-formed browserid in REQUEST.browser_id_: %s' % bid
) )
return token return bid
# fall through & ck id key namespaces if token is not in request. # fall through & ck id namespaces if bid is not in request.
tk = self.token_key tk = self.browserid_name
ns = self.token_key_namespaces ns = self.browserid_namespaces
for name in ns: for name in ns:
token = getattr(REQUEST, name).get(tk, None) bid = getattr(REQUEST, name).get(tk, None)
if token is not None: if bid is not None:
# hey, we got a token! # hey, we got a browser id!
if self._isAWellFormedToken(token): if self._isAWellFormedBrowserId(bid):
# token is not "plain old broken" # bid is not "plain old broken"
REQUEST.browser_token_ = token REQUEST.browser_id_ = bid
REQUEST.browser_token_ns_ = name REQUEST.browser_id_ns_ = name
return token return bid
# fall through if token is invalid or not in key namespaces # fall through if bid is invalid or not in namespaces
if create: if create:
# create a brand new token # create a brand new bid
token = self._getNewToken() bid = self._getNewBrowserId()
if 'cookies' in ns: if 'cookies' in ns:
self._setCookie(token, REQUEST) self._setCookie(bid, REQUEST)
REQUEST.browser_token_ = token REQUEST.browser_id_ = bid
REQUEST.browser_token_ns_ = None REQUEST.browser_id_ns_ = None
return token return bid
# implies a return of None if: # implies a return of None if:
# (not create=1) and (invalid or ((not in req) and (not in ns))) # (not create=1) and (invalid or ((not in req) and (not in ns)))
security.declareProtected(ACCESS_CONTENTS_PERM, 'flushTokenCookie') security.declareProtected(ACCESS_CONTENTS_PERM, 'flushBrowserIdCookie')
def flushTokenCookie(self): def flushBrowserIdCookie(self):
""" removes the token cookie from the client browser """ """ removes the bid cookie from the client browser """
if not self.on: if 'cookies' not in self.browserid_namespaces:
return self._delegateToParent('flushToken')
if 'cookies' not in self.token_key_namespaces:
raise BrowserIdManagerErr,('Cookies are not now being used as a ' raise BrowserIdManagerErr,('Cookies are not now being used as a '
'browser token key namespace, thus ' 'browser id namespace, thus the '
'the token cookie cannot be flushed.') 'browserid cookie cannot be flushed.')
self._setCookie('deleted', self.REQUEST, remove=1) self._setCookie('deleted', self.REQUEST, remove=1)
security.declareProtected(ACCESS_CONTENTS_PERM, 'isTokenFromCookie') security.declareProtected(ACCESS_CONTENTS_PERM, 'isBrowserIdFromCookie')
def isTokenFromCookie(self): def isBrowserIdFromCookie(self):
""" returns true if browser token is from REQUEST.cookies """ """ returns true if browser id is from REQUEST.cookies """
if not self.on: if not self.getBrowserId(): # make sure the bid is stuck on REQUEST
return self._delegateToParent('isTokenFromCookie') raise BrowserIdManagerErr, 'There is no current browser id.'
if not self.getToken(): # make sure the token is stuck on REQUEST if getattr(self.REQUEST, 'browser_id_ns_') == 'cookies':
raise BrowserIdManagerErr, 'There is no current browser token.'
if getattr(self.REQUEST, 'browser_token_ns_') == 'cookies':
return 1 return 1
security.declareProtected(ACCESS_CONTENTS_PERM, 'isTokenFromForm') security.declareProtected(ACCESS_CONTENTS_PERM, 'isBrowserIdFromForm')
def isTokenFromForm(self): def isBrowserIdFromForm(self):
""" returns true if browser token is from REQUEST.form """ """ returns true if browser id is from REQUEST.form """
if not self.on: if not self.getBrowserId(): # make sure the bid is stuck on REQUEST
return self._delegateToParent('isTokenFromForm') raise BrowserIdManagerErr, 'There is no current browser id.'
if not self.getToken(): # make sure the token is stuck on REQUEST if getattr(self.REQUEST, 'browser_id_ns_') == 'form':
raise BrowserIdManagerErr, 'There is no current browser token.'
if getattr(self.REQUEST, 'browser_token_ns_') == 'form':
return 1 return 1
security.declareProtected(ACCESS_CONTENTS_PERM, 'isTokenNew') security.declareProtected(ACCESS_CONTENTS_PERM, 'isBrowserIdNew')
def isTokenNew(self): def isBrowserIdNew(self):
""" """
returns true if browser token is 'new', meaning the token exists returns true if browser id is 'new', meaning the id exists
but it has not yet been acknowledged by the client (the client but it has not yet been acknowledged by the client (the client
hasn't sent it back to us in a cookie or in a formvar). hasn't sent it back to us in a cookie or in a formvar).
""" """
if not self.on: if not self.getBrowserId(): # make sure the id is stuck on REQUEST
return self._delegateToParent('isTokenNew') raise BrowserIdManagerErr, 'There is no current browser id.'
if not self.getToken(): # make sure the token is stuck on REQUEST
raise BrowserIdManagerErr, 'There is no current browser token.'
# ns will be None if new, negating None below returns 1, which # ns will be None if new, negating None below returns 1, which
# would indicate that it's new on this request # would indicate that it's new on this request
return not getattr(self.REQUEST, 'browser_token_ns_') return not getattr(self.REQUEST, 'browser_id_ns_')
security.declareProtected(ACCESS_CONTENTS_PERM, 'encodeUrl') security.declareProtected(ACCESS_CONTENTS_PERM, 'encodeUrl')
def encodeUrl(self, url, create=1): def encodeUrl(self, url, create=1):
""" """
encode a URL with the browser key as a postfixed query string encode a URL with the browser id as a postfixed query string
element element
""" """
if not self.on: bid = self.getBrowserId(create)
return self._delegateToParent('encodeUrl', url) if bid is None:
token = self.getToken(create) raise BrowserIdManagerErr, 'There is no current browser id.'
if token is None: name = self.getBrowserIdName()
raise BrowserIdManagerErr, 'There is no current browser token.'
key = self.getTokenKey()
if '?' in url: if '?' in url:
return '%s&%s=%s' % (url, key, token) return '%s&%s=%s' % (url, name, bid)
else: else:
return '%s?%s=%s' % (url, key, token) return '%s?%s=%s' % (url, name, bid)
# non-delegating methods follow
security.declareProtected(MGMT_SCREEN_PERM, 'manage_browseridmgr') security.declareProtected(MGMT_SCREEN_PERM, 'manage_browseridmgr')
manage_browseridmgr = Globals.DTMLFile('dtml/manageIdManager', globals()) manage_browseridmgr = Globals.DTMLFile('dtml/manageIdManager', globals())
...@@ -301,65 +269,93 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs): ...@@ -301,65 +269,93 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs):
security.declareProtected(CHANGE_IDMGR_PERM, security.declareProtected(CHANGE_IDMGR_PERM,
'manage_changeBrowserIdManager') 'manage_changeBrowserIdManager')
def manage_changeBrowserIdManager( def manage_changeBrowserIdManager(
self, title='', tokenkey='_ZopeId', cookiepri=1, formpri=2, self, title='', idname='_ZopeId', location='cookiesthenform',
cookiepath='/', cookiedomain='', cookielifedays=0, cookiesecure=0, cookiepath='/', cookiedomain='', cookielifedays=0, cookiesecure=0,
on=0, REQUEST=None REQUEST=None
): ):
""" """ """ """
d = {}
for k,v in {'cookies':cookiepri, 'form':formpri}.items():
if v: d[v] = k # I hate HTML
self.title = title self.title = title
self.setTokenKey(tokenkey) self.setBrowserIdName(idname)
self.setTokenKeyNamespaces(d)
self.setCookiePath(cookiepath) self.setCookiePath(cookiepath)
self.setCookieDomain(cookiedomain) self.setCookieDomain(cookiedomain)
self.setCookieLifeDays(cookielifedays) self.setCookieLifeDays(cookielifedays)
self.setCookieSecure(cookiesecure) self.setCookieSecure(cookiesecure)
if on: self.setBrowserIdLocation(location)
self.turnOn()
else:
self.turnOff()
if REQUEST is not None: if REQUEST is not None:
return self.manage_browseridmgr(self, REQUEST) return self.manage_browseridmgr(
self, REQUEST, manage_tabs_message = 'Changes saved.'
)
security.declareProtected(CHANGE_IDMGR_PERM, 'setTokenKey') security.declareProtected(CHANGE_IDMGR_PERM, 'setBrowserIdName')
def setTokenKey(self, k): def setBrowserIdName(self, k):
""" sets browser token key string """ """ sets browser id name string """
if not (type(k) is type('') and k and not badtokenkeycharsin(k)): if not (type(k) is type('') and k and not badidnamecharsin(k)):
raise BrowserIdManagerErr, 'Bad id key string %s' % repr(k) raise BrowserIdManagerErr, 'Bad id name string %s' % repr(k)
self.token_key = k self.browserid_name = k
security.declareProtected(ACCESS_CONTENTS_PERM, 'getTokenKey') security.declareProtected(ACCESS_CONTENTS_PERM, 'getBrowserIdName')
def getTokenKey(self): def getBrowserIdName(self):
""" """ """ """
return self.token_key return self.browserid_name
security.declareProtected(CHANGE_IDMGR_PERM, 'setTokenKeyNamespaces') security.declareProtected(CHANGE_IDMGR_PERM, 'setBrowserIdNamespaces')
def setTokenKeyNamespaces(self,namespacesd={1:'cookies',2:'form'}): def setBrowserIdNamespaces(self,namespacesd={1:'cookies',2:'form'}):
""" """
accepts dictionary e.g. {1: 'cookies', 2: 'form'} as token accepts dictionary e.g. {1: 'cookies', 2: 'form'} as browser
id key allowable namespaces and lookup ordering priority id allowable namespaces and lookup ordering priority
where key is 'priority' with 1 being highest. where key is 'priority' with 1 being highest.
""" """
allowed = self.getAllTokenKeyNamespaces() allowed = self.getAllBrowserIdNamespaces()
for name in namespacesd.values(): for name in namespacesd.values():
if name not in allowed: if name not in allowed:
raise BrowserIdManagerErr, ( raise BrowserIdManagerErr, (
'Bad id key namespace %s' % repr(name) 'Bad browser id namespace %s' % repr(name)
) )
self.token_key_namespaces = [] self.browserid_namespaces = []
nskeys = namespacesd.keys() nskeys = namespacesd.keys()
nskeys.sort() nskeys.sort()
for priority in nskeys: for priority in nskeys:
self.token_key_namespaces.append(namespacesd[priority]) self.browserid_namespaces.append(namespacesd[priority])
security.declareProtected(ACCESS_CONTENTS_PERM, 'getBrowserIdLocation')
def getBrowserIdLocation(self):
d = {}
i = 1
for name in self.browserid_namespaces:
d[name] = i
i = i + 1
if d.get('cookies') == 1:
if d.get('form'):
return 'cookiesthenform'
else:
return 'cookiesonly'
elif d.get('form') == 1:
if d.get('cookies'):
return 'formthencookies'
else:
return 'formonly'
else:
return 'cookiesthenform'
security.declareProtected(CHANGE_IDMGR_PERM, 'setBrowserIdLocation')
def setBrowserIdLocation(self, location):
""" accepts a string and turns it into a namespaces dict """
if location == 'formthencookies':
d = {1:'form', '2':'cookies'}
elif location == 'cookiesonly':
d = {1:'cookies'}
elif location == 'formonly':
d = {1:'form'}
else:
d = {1:'cookies',2:'form'}
self.setBrowserIdNamespaces(d)
security.declareProtected(ACCESS_CONTENTS_PERM, 'getTokenKeyNamespaces') security.declareProtected(ACCESS_CONTENTS_PERM, 'getBrowserIdNamespaces')
def getTokenKeyNamespaces(self): def getBrowserIdNamespaces(self):
""" """ """ """
d = {} d = {}
i = 1 i = 1
for name in self.token_key_namespaces: for name in self.browserid_namespaces:
d[i] = name d[i] = name
i = i + 1 i = i + 1
return d return d
...@@ -428,33 +424,18 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs): ...@@ -428,33 +424,18 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs):
""" """ """ """
return self.cookie_secure return self.cookie_secure
security.declareProtected(ACCESS_CONTENTS_PERM, 'getAllTokenKeyNamespaces') security.declareProtected(ACCESS_CONTENTS_PERM,'getAllBrowserIdNamespaces')
def getAllTokenKeyNamespaces(self): def getAllBrowserIdNamespaces(self):
""" """
These are the REQUEST namespaces searched when looking for an These are the REQUEST namespaces searched when looking for an
id key value. browser id.
""" """
return ('form', 'cookies') return ('form', 'cookies')
security.declareProtected(CHANGE_IDMGR_PERM, 'turnOn')
def turnOn(self):
""" """
self.on = 1
security.declareProtected(CHANGE_IDMGR_PERM, 'turnOff')
def turnOff(self):
""" """
self.on = 0
security.declareProtected(ACCESS_CONTENTS_PERM, 'isOn')
def isOn(self):
""" """
return self.on
# non-interface methods follow # non-interface methods follow
def _getNewToken(self, randint=random.randint, maxint=99999999): def _getNewBrowserId(self, randint=random.randint, maxint=99999999):
""" Returns 19-character string browser token """ Returns 19-character string browser id
'AAAAAAAABBBBBBBB' 'AAAAAAAABBBBBBBB'
where: where:
...@@ -465,21 +446,13 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs): ...@@ -465,21 +446,13 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs):
'=' end-padding is stripped off '=' end-padding is stripped off
'+' is translated to '-' '+' is translated to '-'
'/' is translated to '.' '/' is translated to '.'
An example is: 89972317A0C3EHnUi90w
""" """
return '%08i%s' % (randint(0, maxint-1), self._getB64TStamp()) return '%08i%s' % (randint(0, maxint-1), self._getB64TStamp())
def _delegateToParent(self, *arg, **kw):
fn = arg[0]
rest = arg[1:]
try:
parent_sessidmgr=getattr(self.aq_parent, self.id)
parent_fn = getattr(parent_sessidmgr, fn)
except AttributeError:
raise BrowserIdManagerErr, 'Browser id management disabled'
return apply(parent_fn, rest, kw)
def _setCookie( def _setCookie(
self, token, REQUEST, remove=0, now=time.time, strftime=time.strftime, self, bid, REQUEST, remove=0, now=time.time, strftime=time.strftime,
gmtime=time.gmtime gmtime=time.gmtime
): ):
""" """ """ """
...@@ -501,11 +474,11 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs): ...@@ -501,11 +474,11 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs):
return # should we raise an exception? return # should we raise an exception?
cookies = REQUEST.RESPONSE.cookies cookies = REQUEST.RESPONSE.cookies
cookie = cookies[self.token_key]= {} cookie = cookies[self.browserid_name]= {}
for k,v in d.items(): for k,v in d.items():
if v: if v:
cookie[k] = v #only stuff things with true values cookie[k] = v #only stuff things with true values
cookie['value'] = token cookie['value'] = bid
def _getB64TStamp( def _getB64TStamp(
self, b2a=binascii.b2a_base64,gmtime=time.gmtime, time=time.time, self, b2a=binascii.b2a_base64,gmtime=time.gmtime, time=time.time,
...@@ -522,19 +495,19 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs): ...@@ -522,19 +495,19 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs):
): ):
return TimeStamp(a2b(translate(ts+'=',b64_untrans))).timeTime() return TimeStamp(a2b(translate(ts+'=',b64_untrans))).timeTime()
def _getTokenPieces(self, token): def _getBrowserIdPieces(self, bid):
""" returns browser token parts in a tuple consisting of rand_id, """ returns browser id parts in a tuple consisting of rand_id,
timestamp timestamp
""" """
return (token[:8], token[8:19]) return (bid[:8], bid[8:19])
def _isAWellFormedToken(self, token, binerr=binascii.Error, def _isAWellFormedBrowserId(self, bid, binerr=binascii.Error,
timestamperr=TimeStamp.error): timestamperr=TimeStamp.error):
try: try:
rnd, ts = self._getTokenPieces(token) rnd, ts = self._getBrowserIdPieces(bid)
int(rnd) int(rnd)
self._getB64TStampToInt(ts) self._getB64TStampToInt(ts)
return token return bid
except (TypeError, ValueError, AttributeError, IndexError, binerr, except (TypeError, ValueError, AttributeError, IndexError, binerr,
timestamperr): timestamperr):
return None return None
......
...@@ -90,7 +90,6 @@ from SessionPermissions import * ...@@ -90,7 +90,6 @@ from SessionPermissions import *
from common import DEBUG from common import DEBUG
from ZPublisher.BeforeTraverse import registerBeforeTraverse, \ from ZPublisher.BeforeTraverse import registerBeforeTraverse, \
unregisterBeforeTraverse unregisterBeforeTraverse
import traceback
BID_MGR_NAME = 'browser_id_manager' BID_MGR_NAME = 'browser_id_manager'
...@@ -103,8 +102,8 @@ constructSessionDataManagerForm = Globals.DTMLFile('dtml/addDataManager', ...@@ -103,8 +102,8 @@ constructSessionDataManagerForm = Globals.DTMLFile('dtml/addDataManager',
ADD_SESSION_DATAMANAGER_PERM="Add Session Data Manager" ADD_SESSION_DATAMANAGER_PERM="Add Session Data Manager"
def constructSessionDataManager(self, id, title='', path=None, requestName=None, def constructSessionDataManager(self, id, title='', path=None,
REQUEST=None): requestName=None, REQUEST=None):
""" """ """ """
ob = SessionDataManager(id, path, title, requestName) ob = SessionDataManager(id, path, title, requestName)
self._setObject(id, ob) self._setObject(id, ob)
...@@ -150,7 +149,7 @@ class SessionDataManager(Item, Implicit, Persistent, RoleManager, Owned, Tabs): ...@@ -150,7 +149,7 @@ class SessionDataManager(Item, Implicit, Persistent, RoleManager, Owned, Tabs):
security.declareProtected(ACCESS_SESSIONDATA_PERM, 'getSessionData') security.declareProtected(ACCESS_SESSIONDATA_PERM, 'getSessionData')
def getSessionData(self, create=1): def getSessionData(self, create=1):
""" """ """ """
key = self.getBrowserIdManager().getToken(create=create) key = self.getBrowserIdManager().getBrowserId(create=create)
if key is not None: if key is not None:
return self._getSessionDataObject(key) return self._getSessionDataObject(key)
...@@ -179,23 +178,23 @@ class SessionDataManager(Item, Implicit, Persistent, RoleManager, Owned, Tabs): ...@@ -179,23 +178,23 @@ class SessionDataManager(Item, Implicit, Persistent, RoleManager, Owned, Tabs):
self.id = id self.id = id
self.setContainerPath(path) self.setContainerPath(path)
self.setTitle(title) self.setTitle(title)
self._requestSessionName = requestName
if requestName:
self._requestSessionName=requestName
else:
self._requestSessionName=None
security.declareProtected(CHANGE_DATAMGR_PERM, 'manage_changeSDM') security.declareProtected(CHANGE_DATAMGR_PERM, 'manage_changeSDM')
def manage_changeSDM(self, title, path=None, requestName=None, REQUEST=None): def manage_changeSDM(self, title, path=None, requestName=None,
REQUEST=None):
""" """ """ """
self.setContainerPath(path) self.setContainerPath(path)
self.setTitle(title) self.setTitle(title)
if requestName: if requestName:
self.updateTraversalData(requestName) if requestName != self._requestSessionName:
self.updateTraversalData(requestName)
else: else:
self.updateTraversalData(None) self.updateTraversalData(None)
if REQUEST is not None: if REQUEST is not None:
return self.manage_sessiondatamgr(self, REQUEST) return self.manage_sessiondatamgr(
self, REQUEST, manage_tabs_message = 'Changes saved.'
)
security.declareProtected(CHANGE_DATAMGR_PERM, 'setTitle') security.declareProtected(CHANGE_DATAMGR_PERM, 'setTitle')
def setTitle(self, title): def setTitle(self, title):
...@@ -271,8 +270,8 @@ class SessionDataManager(Item, Implicit, Persistent, RoleManager, Owned, Tabs): ...@@ -271,8 +270,8 @@ class SessionDataManager(Item, Implicit, Persistent, RoleManager, Owned, Tabs):
string.join(self.obpath,'/') string.join(self.obpath,'/')
) )
security.declareProtected(MGMT_SCREEN_PERM, 'getrequestName') security.declareProtected(MGMT_SCREEN_PERM, 'getRequestName')
def getrequestName(self): def getRequestName(self):
""" """ """ """
return self._requestSessionName or '' return self._requestSessionName or ''
...@@ -285,9 +284,8 @@ class SessionDataManager(Item, Implicit, Persistent, RoleManager, Owned, Tabs): ...@@ -285,9 +284,8 @@ class SessionDataManager(Item, Implicit, Persistent, RoleManager, Owned, Tabs):
self.updateTraversalData(None) self.updateTraversalData(None)
def updateTraversalData(self, requestSessionName=None): def updateTraversalData(self, requestSessionName=None):
# Note this cant be called directly at add -- manage_afterAdd will work # Note this cant be called directly at add -- manage_afterAdd will
# though. # work though.
parent = self.aq_inner.aq_parent parent = self.aq_inner.aq_parent
if getattr(self,'_hasTraversalHook', None): if getattr(self,'_hasTraversalHook', None):
......
...@@ -96,92 +96,92 @@ class BrowserIdManagerInterface( ...@@ -96,92 +96,92 @@ class BrowserIdManagerInterface(
A Zope Browser Id Manager is responsible for assigning ids to site A Zope Browser Id Manager is responsible for assigning ids to site
visitors, and for servicing requests from Session Data Managers visitors, and for servicing requests from Session Data Managers
related to the browser token. related to the browser id.
""" """
def encodeUrl(self, url): def encodeUrl(self, url):
""" """
Encodes a provided URL with the current request's browser token Encodes a provided URL with the current request's browser id
and returns the result. For example, the call and returns the result. For example, the call
encodeUrl('http://foo.com/amethod') might return encodeUrl('http://foo.com/amethod') might return
'http://foo.com/amethod?_ZopeId=as9dfu0adfu0ad'. 'http://foo.com/amethod?_ZopeId=as9dfu0adfu0ad'.
Permission required: Access contents information Permission required: Access contents information
Raises: BrowserIdManagerErr. If there is no current session token. Raises: BrowserIdManagerErr. If there is no current browser id.
""" """
def getTokenKey(self): def getBrowserIdName(self):
""" """
Returns a string with the name of the cookie/form variable which is Returns a string with the name of the cookie/form variable which is
used by the current browser id manager as the name to look up when used by the current browser id manager as the name to look up when
attempting to obtain the browser token value. For example, '_ZopeId'. attempting to obtain the browser id value. For example, '_ZopeId'.
Permission required: Access contents information Permission required: Access contents information
""" """
def getToken(self, create=1): def getBrowserId(self, create=1):
""" """
If create=0, returns a the current browser token or None if there If create=0, returns a the current browser id or None if there
is no browser token associated with the current request. If create=1, is no browser id associated with the current request. If create=1,
returns the current browser token or a newly-created browser token if returns the current browser id or a newly-created browser id if
there is no browser token associated with the current request. This there is no browser id associated with the current request. This
method is useful in conjunction with getTokenKey if you wish to embed method is useful in conjunction with getBrowserIdName if you wish to
the token-key/token combination as a hidden value in a POST-based embed the browser-id-name/browser-id combination as a hidden value in
form. The browser token is opaque, has no business meaning, and its a POST-based form. The browser id is opaque, has no business meaning,
length, type, and composition are subject to change. and its length, type, and composition are subject to change.
Permission required: Access contents information Permission required: Access contents information
Raises: BrowserIdManagerErr. If ill-formed browser token Raises: BrowserIdManagerErr. If ill-formed browser id
is found in REQUEST. is found in REQUEST.
""" """
def hasToken(self): def hasBrowserId(self):
""" """
Returns true if there is a browser token for this request. Returns true if there is a browser id for this request.
Permission required: Access contents information Permission required: Access contents information
""" """
def isTokenNew(self): def isBrowserIdNew(self):
""" """
Returns true if browser token is 'new'. A browser token is 'new' Returns true if browser id is 'new'. A browser id is 'new'
when it is first created and the client has therefore not sent it when it is first created and the client has therefore not sent it
back to the server in any request. back to the server in any request.
Permission required: Access contents information Permission required: Access contents information
Raises: BrowserIdManagerErr. If there is no current browser token. Raises: BrowserIdManagerErr. If there is no current browser id.
""" """
def isTokenFromForm(self): def isBrowserIdFromForm(self):
""" """
Returns true if browser token comes from a form variable (query Returns true if browser id comes from a form variable (query
string or post). string or post).
Permission required: Access contents information Permission required: Access contents information
Raises: BrowserIdManagerErr. If there is no current browser token. Raises: BrowserIdManagerErr. If there is no current browser id.
""" """
def isTokenFromCookie(self): def isBrowserIdFromCookie(self):
""" """
Returns true if browser token comes from a cookie. Returns true if browser id comes from a cookie.
Permission required: Access contents information Permission required: Access contents information
Raises: BrowserIdManagerErr. If there is no current browser token. Raises: BrowserIdManagerErr. If there is no current browser id.
""" """
def flushTokenCookie(self): def flushBrowserIdCookie(self):
""" """
Deletes the token cookie from the client browser, iff the Deletes the browser id cookie from the client browser, iff the
'cookies' token key namespace is being used. 'cookies' browser id namespace is being used.
Permission required: Access contents information Permission required: Access contents information
Raises: BrowserIdManagerErr. If the 'cookies' namespace isn't Raises: BrowserIdManagerErr. If the 'cookies' namespace isn't
a token key namespace at the time of the call. a browser id namespace at the time of the call.
""" """
class SessionDataManagerInterface( class SessionDataManagerInterface(
...@@ -193,7 +193,7 @@ class SessionDataManagerInterface( ...@@ -193,7 +193,7 @@ class SessionDataManagerInterface(
A Zope Session Data Manager is responsible for maintaining Session A Zope Session Data Manager is responsible for maintaining Session
Data Objects, and for servicing requests from application code Data Objects, and for servicing requests from application code
related to Session Data Objects. It also communicates with a Browser related to Session Data Objects. It also communicates with a Browser
Id Manager to provide information about browser tokens. Id Manager to provide information about browser ids.
""" """
def getBrowserIdManager(self): def getBrowserIdManager(self):
""" """
...@@ -207,9 +207,9 @@ class SessionDataManagerInterface( ...@@ -207,9 +207,9 @@ class SessionDataManagerInterface(
def getSessionData(self, create=1): def getSessionData(self, create=1):
""" """
Returns a Session Data Object associated with the current Returns a Session Data Object associated with the current
browser token. If there is no current token, and create is true, browser id. If there is no current browser id, and create is true,
returns a new Session Data Object. If there is no current returns a new Session Data Object. If there is no current
token and create is false, returns None. browser id and create is false, returns None.
Permission required: Access session data Permission required: Access session data
""" """
...@@ -217,7 +217,7 @@ class SessionDataManagerInterface( ...@@ -217,7 +217,7 @@ class SessionDataManagerInterface(
def hasSessionData(self): def hasSessionData(self):
""" """
Returns true if a Session Data Object associated with the Returns true if a Session Data Object associated with the
current browser token is found in the Session Data Container. Does current browser id is found in the Session Data Container. Does
not create a Session Data Object if one does not exist. not create a Session Data Object if one does not exist.
Permission required: Access session data Permission required: Access session data
......
...@@ -80,5 +80,5 @@ MGMT_SCREEN_PERM = 'View management screens' ...@@ -80,5 +80,5 @@ MGMT_SCREEN_PERM = 'View management screens'
ACCESS_CONTENTS_PERM = 'Access contents information' ACCESS_CONTENTS_PERM = 'Access contents information'
ACCESS_SESSIONDATA_PERM = 'Access session data' ACCESS_SESSIONDATA_PERM = 'Access session data'
ARBITRARY_SESSIONDATA_PERM = 'Access arbitrary user session data' ARBITRARY_SESSIONDATA_PERM = 'Access arbitrary user session data'
CHANGE_IDMGR_PERM = 'Change Session Id Manager' CHANGE_IDMGR_PERM = 'Change Browser Id Manager'
MANAGE_CONTAINER_PERM = 'Manage Session Data Container' MANAGE_CONTAINER_PERM = 'Manage Session Data Container'
...@@ -15,7 +15,7 @@ objects. Developers interact with a Session Data Manager in order to store ...@@ -15,7 +15,7 @@ objects. Developers interact with a Session Data Manager in order to store
and retrieve information during a user session. A Session Data Manager and retrieve information during a user session. A Session Data Manager
communicates with a Browser Id Manager to determine the session information communicates with a Browser Id Manager to determine the session information
for the current user, and hands out Session Data Objects related to that for the current user, and hands out Session Data Objects related to that
user obtained from a Transient Object Container. user.
</div> </div>
</tr> </tr>
<TR> <TR>
...@@ -58,7 +58,7 @@ user obtained from a Transient Object Container. ...@@ -58,7 +58,7 @@ user obtained from a Transient Object Container.
</td> </td>
<td align="LEFT" valign="TOP"> <td align="LEFT" valign="TOP">
<input class="form-element" type="TEXT" name="requestName" <input class="form-element" type="TEXT" name="requestName"
value="SESSION"> value="SESSION">
</td> </td>
</tr> </tr>
......
...@@ -9,13 +9,20 @@ ...@@ -9,13 +9,20 @@
<input type=hidden name="id" value="browser_id_manager"> <input type=hidden name="id" value="browser_id_manager">
<TABLE CELLSPACING="2"> <TABLE CELLSPACING="2">
<tr> <tr>
<td>&nbsp;</td>
</tr>
<tr>
<div class="form-help"> <div class="form-help">
Zope Browser Id Manager objects perform the task of setting and retrieving Zope Browser Id Manager objects allow Zope to differentiate between site
Zope browser ids for remote users. They are used primarily by Session visitors by "tagging" each of their browsers with a unique identifier. This
Data Manager objects. A Browser Id Manager's 'id' must always be is useful if you need to tell visitors apart from one another even if they do
'browser_id_manager' in order for it to be found by Session Data Managers. not "log in" to your site. Browser Id Managers are generally used
by interacting with the Zope sessioning machinery.
</div> </div>
</tr> </tr>
<tr>
<td>&nbsp;</td>
</tr>
<TR> <TR>
<TD ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT" VALIGN="TOP">
<div class="form-label"> <div class="form-label">
...@@ -23,7 +30,7 @@ Data Manager objects. A Browser Id Manager's 'id' must always be ...@@ -23,7 +30,7 @@ Data Manager objects. A Browser Id Manager's 'id' must always be
</div> </div>
</TD> </TD>
<TD ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT" VALIGN="TOP">
<div class="form-label">This object's Zope id will be<br> <div class="form-label">This object's Zope id must be<br>
"browser_id_manager" "browser_id_manager"
</div> </div>
</TD> </TD>
...@@ -41,56 +48,51 @@ Data Manager objects. A Browser Id Manager's 'id' must always be ...@@ -41,56 +48,51 @@ Data Manager objects. A Browser Id Manager's 'id' must always be
<TR> <TR>
<TD ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT" VALIGN="TOP">
<div class="form-label"> <div class="form-label">
Browser Token Key Browser Id Name
</div> </div>
</TD> </TD>
<TD ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT" VALIGN="TOP">
<INPUT TYPE="TEXT" NAME="tokenkey" SIZE="20" value="_ZopeId"> <INPUT TYPE="TEXT" NAME="idname" SIZE="20" value="_ZopeId">
</TD> </TD>
</TR> </TR>
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
</tr> </tr>
<th align="left"><strong><em>Token Key Search Namespaces</strong></em></th>
<th align="left"><strong><em>Priority (1 is highest)</strong></em></th>
<tr> <tr>
<th align=left class="form-label">Cookies</th> <td>
<td> <div align=left class="form-label">Look for Browser Id Name in</th>
<table border=1> </td>
<tr> <td>
<td align=left> <table border=0>
<input type="radio" name="cookiepri:int" value="1" CHECKED> 1 <tr>
</td>
<td align=left> <td align=left>
<input type="radio" name="cookiepri:int" value="2"> 2 <input type="radio" name="location" value="cookiesonly"> Cookies only
</td> </td>
</tr>
<tr>
<td align=left> <td align=left>
<input type="radio" name="cookiepri:int" value="0"> Off <input type="radio" name="location" value="cookiesthenform" CHECKED> Cookies then form
</td> </td>
</tr>
</table>
</td>
</tr> </tr>
<tr> <tr>
<th align=left class="form-label">Form vars</th>
<td align=left> <td align=left>
<table border=1> <input type="radio" name="location" value="formonly"> Form only
<tr> </td>
<td align=left> </tr>
<input type="radio" name="formpri:int" value="1"> 1 <tr>
</td>
<td align=left> <td align=left>
<input type="radio" name="formpri:int" value="2" CHECKED> 2 <input type="radio" name="location" value="formthencookies"> Form then cookies
</td> </td>
<td align=left>
<input type="radio" name="formpri:int" value="0"> Off
</td> </tr>
</table>
</td>
</tr> </tr>
<td>&nbsp;</td> </table>
</td>
</tr>
<tr> <tr>
<td>&nbsp;</td>
</tr> </tr>
<TR> <TR>
<TD ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT" VALIGN="TOP">
<div class="form-label"> <div class="form-label">
......
...@@ -8,6 +8,20 @@ ...@@ -8,6 +8,20 @@
<form action="manage_changeSDM" method="post"> <form action="manage_changeSDM" method="post">
<table cellspacing="2"> <table cellspacing="2">
<tr><td>&nbsp;</td></tr>
<tr>
<td class="form-help" colspan=2>
A Session Data Manager object is responsible for maintaining a
relationship between session data objects and Zope browser ids.
It is part of the Zope sessioning machinery. Programmers may
interact with a session data manager in order to obtain
information about session data, but will more often use the
REQUEST.SESSION object to do sessioning-related tasks.
</td>
</tr>
<tr><td>&nbsp;</td></tr>
<tr> <tr>
<td align="left" valign="top"> <td align="left" valign="top">
<div class="form-label"> <div class="form-label">
...@@ -40,7 +54,7 @@ ...@@ -40,7 +54,7 @@
</td> </td>
<td align="LEFT" valign="TOP"> <td align="LEFT" valign="TOP">
<input class="form-element" type="TEXT" name="requestName" <input class="form-element" type="TEXT" name="requestName"
value="&dtml-getrequestName;"> value="&dtml-getRequestName;">
</td> </td>
</tr> </tr>
<tr> <tr>
......
...@@ -7,20 +7,21 @@ ...@@ -7,20 +7,21 @@
<FORM ACTION="manage_changeBrowserIdManager" METHOD="POST"> <FORM ACTION="manage_changeBrowserIdManager" METHOD="POST">
<TABLE CELLSPACING="2"> <TABLE CELLSPACING="2">
<TR> <tr>
<dtml-comment> <td>&nbsp;<td>
<TD ALIGN="LEFT" VALIGN="TOP"> </tr>
<div class="form-label"> <tr class="form-help">
Browser Id Mgr On <td colspan=2>
</div> Zope Browser Id Manager objects allow Zope to differentiate between site
</TD> visitors by "tagging" each of their browsers with a unique identifier. This
<TD ALIGN="LEFT" VALIGN="TOP"> is useful if you need to tell visitors apart from one another even if they do
<INPUT TYPE="checkbox" NAME="on" not "log in" to your site. Browser Id Managers are generally used
<dtml-if isOn>CHECKED</dtml-if>> by interacting with the Zope sessioning machinery.
</TD> </td>
</dtml-comment> </tr>
<input type="hidden" name="on" value="1"> <tr>
</TR> <td>&nbsp;<td>
</tr>
<TR> <TR>
<TD ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT" VALIGN="TOP">
<div class="form-label"> <div class="form-label">
...@@ -34,57 +35,50 @@ ...@@ -34,57 +35,50 @@
<TR> <TR>
<TD ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT" VALIGN="TOP">
<div class="form-label"> <div class="form-label">
Browser Token Key Browser Id Name
</div> </div>
</TD> </TD>
<TD ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT" VALIGN="TOP">
<INPUT TYPE="TEXT" NAME="tokenkey" SIZE="20" value="&dtml-getTokenKey;"> <INPUT TYPE="TEXT" NAME="idname" SIZE="20" value="&dtml-getBrowserIdName;">
</TD> </TD>
</TR> </TR>
<th align=left><strong><em>Token Key Search Namespaces</strong></em></th>
<th align=left><strong><em>Priority</strong></em> (1 is highest)</th> <dtml-let loc=getBrowserIdLocation>
<tr>
<td>
<div align=left class="form-label">Look for Browser Id Name in</th>
</td>
<td>
<table border=0>
<tr> <tr>
<th align=left class="form-label">Cookies</th>
<td align=left>
<table border=1>
<tr>
<td align=left>
<input type="radio" name="cookiepri:int" value="1"
<dtml-if "getTokenKeyNamespaces().get(1, _.None) == 'cookies'">CHECKED</dtml-if>>1
</td>
<td align=left>
<input type="radio" name="cookiepri:int" value="2"
<dtml-if "getTokenKeyNamespaces().get(2, _.None) == 'cookies'">CHECKED</dtml-if>>2
</td>
<td align=left> <td align=left>
<input type="radio" name="cookiepri:int" value="0" <input type="radio" name="location" value="cookiesonly"
<dtml-if "'cookies' not in getTokenKeyNamespaces().values()">CHECKED</dtml-if>>Off <dtml-if "loc=='cookiesonly'">CHECKED</dtml-if>> Cookies only
</td>
</tr>
</table>
</td> </td>
</tr> </tr>
<tr> <tr>
<th align=left class="form-label">Form vars</th>
<td align=left> <td align=left>
<table border=1> <input type="radio" name="location" value="cookiesthenform"
<tr> <dtml-if "loc=='cookiesthenform'">CHECKED</dtml-if>> Cookies then form
<td align=left>
<input type="radio" name="formpri:int" value="1"
<dtml-if "getTokenKeyNamespaces().get(1, _.None) == 'form'">CHECKED</dtml-if>>1
</td> </td>
</tr>
<tr>
<td align=left> <td align=left>
<input type="radio" name="formpri:int" value="2" <input type="radio" name="location" value="formonly"
<dtml-if "getTokenKeyNamespaces().get(2, _.None) == 'form'">CHECKED</dtml-if>>2 <dtml-if "loc=='formonly'">CHECKED</dtml-if>> Form only
</td> </td>
</tr>
<tr>
<td align=left> <td align=left>
<input type="radio" name="formpri:int" value="0" <input type="radio" name="location" value="formthencookies"
<dtml-if "'form' not in getTokenKeyNamespaces().values()">CHECKED</dtml-if>>Off <dtml-if "loc=='formthencookies'">CHECKED</dtml-if>> Form then cookies
</td>
</tr>
</table>
</td> </td>
</tr> </tr>
</table>
</td>
</tr>
</dtml-let>
<TR> <TR>
<TD ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT" VALIGN="TOP">
<div class="form-label"> <div class="form-label">
...@@ -107,7 +101,7 @@ ...@@ -107,7 +101,7 @@
<div class="form-help"> <div class="form-help">
leave blank to send cookies without domain <br> leave blank to send cookies without domain <br>
info -- however, if cookie domain is not blank,<br> info -- however, if cookie domain is not blank,<br>
it must contain at least two dots) it must contain at least two dots
</div> </div>
</TD> </TD>
<TD ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT" VALIGN="TOP">
......
...@@ -96,92 +96,92 @@ class BrowserIdManagerInterface( ...@@ -96,92 +96,92 @@ class BrowserIdManagerInterface(
A Zope Browser Id Manager is responsible for assigning ids to site A Zope Browser Id Manager is responsible for assigning ids to site
visitors, and for servicing requests from Session Data Managers visitors, and for servicing requests from Session Data Managers
related to the browser token. related to the browser id.
""" """
def encodeUrl(self, url): def encodeUrl(self, url):
""" """
Encodes a provided URL with the current request's browser token Encodes a provided URL with the current request's browser id
and returns the result. For example, the call and returns the result. For example, the call
encodeUrl('http://foo.com/amethod') might return encodeUrl('http://foo.com/amethod') might return
'http://foo.com/amethod?_ZopeId=as9dfu0adfu0ad'. 'http://foo.com/amethod?_ZopeId=as9dfu0adfu0ad'.
Permission required: Access contents information Permission required: Access contents information
Raises: BrowserIdManagerErr. If there is no current session token. Raises: BrowserIdManagerErr. If there is no current browser id.
""" """
def getTokenKey(self): def getBrowserIdName(self):
""" """
Returns a string with the name of the cookie/form variable which is Returns a string with the name of the cookie/form variable which is
used by the current browser id manager as the name to look up when used by the current browser id manager as the name to look up when
attempting to obtain the browser token value. For example, '_ZopeId'. attempting to obtain the browser id value. For example, '_ZopeId'.
Permission required: Access contents information Permission required: Access contents information
""" """
def getToken(self, create=1): def getBrowserId(self, create=1):
""" """
If create=0, returns a the current browser token or None if there If create=0, returns a the current browser id or None if there
is no browser token associated with the current request. If create=1, is no browser id associated with the current request. If create=1,
returns the current browser token or a newly-created browser token if returns the current browser id or a newly-created browser id if
there is no browser token associated with the current request. This there is no browser id associated with the current request. This
method is useful in conjunction with getTokenKey if you wish to embed method is useful in conjunction with getBrowserIdName if you wish to
the token-key/token combination as a hidden value in a POST-based embed the browser-id-name/browser-id combination as a hidden value in
form. The browser token is opaque, has no business meaning, and its a POST-based form. The browser id is opaque, has no business meaning,
length, type, and composition are subject to change. and its length, type, and composition are subject to change.
Permission required: Access contents information Permission required: Access contents information
Raises: BrowserIdManagerErr. If ill-formed browser token Raises: BrowserIdManagerErr. If ill-formed browser id
is found in REQUEST. is found in REQUEST.
""" """
def hasToken(self): def hasBrowserId(self):
""" """
Returns true if there is a browser token for this request. Returns true if there is a browser id for this request.
Permission required: Access contents information Permission required: Access contents information
""" """
def isTokenNew(self): def isBrowserIdNew(self):
""" """
Returns true if browser token is 'new'. A browser token is 'new' Returns true if browser id is 'new'. A browser id is 'new'
when it is first created and the client has therefore not sent it when it is first created and the client has therefore not sent it
back to the server in any request. back to the server in any request.
Permission required: Access contents information Permission required: Access contents information
Raises: BrowserIdManagerErr. If there is no current browser token. Raises: BrowserIdManagerErr. If there is no current browser id.
""" """
def isTokenFromForm(self): def isBrowserIdFromForm(self):
""" """
Returns true if browser token comes from a form variable (query Returns true if browser id comes from a form variable (query
string or post). string or post).
Permission required: Access contents information Permission required: Access contents information
Raises: BrowserIdManagerErr. If there is no current browser token. Raises: BrowserIdManagerErr. If there is no current browser id.
""" """
def isTokenFromCookie(self): def isBrowserIdFromCookie(self):
""" """
Returns true if browser token comes from a cookie. Returns true if browser id comes from a cookie.
Permission required: Access contents information Permission required: Access contents information
Raises: BrowserIdManagerErr. If there is no current browser token. Raises: BrowserIdManagerErr. If there is no current browser id.
""" """
def flushTokenCookie(self): def flushBrowserIdCookie(self):
""" """
Deletes the token cookie from the client browser, iff the Deletes the browser id cookie from the client browser, iff the
'cookies' token key namespace is being used. 'cookies' browser id namespace is being used.
Permission required: Access contents information Permission required: Access contents information
Raises: BrowserIdManagerErr. If the 'cookies' namespace isn't Raises: BrowserIdManagerErr. If the 'cookies' namespace isn't
a token key namespace at the time of the call. a browser id namespace at the time of the call.
""" """
class SessionDataManagerInterface( class SessionDataManagerInterface(
...@@ -193,7 +193,7 @@ class SessionDataManagerInterface( ...@@ -193,7 +193,7 @@ class SessionDataManagerInterface(
A Zope Session Data Manager is responsible for maintaining Session A Zope Session Data Manager is responsible for maintaining Session
Data Objects, and for servicing requests from application code Data Objects, and for servicing requests from application code
related to Session Data Objects. It also communicates with a Browser related to Session Data Objects. It also communicates with a Browser
Id Manager to provide information about browser tokens. Id Manager to provide information about browser ids.
""" """
def getBrowserIdManager(self): def getBrowserIdManager(self):
""" """
...@@ -207,9 +207,9 @@ class SessionDataManagerInterface( ...@@ -207,9 +207,9 @@ class SessionDataManagerInterface(
def getSessionData(self, create=1): def getSessionData(self, create=1):
""" """
Returns a Session Data Object associated with the current Returns a Session Data Object associated with the current
browser token. If there is no current token, and create is true, browser id. If there is no current browser id, and create is true,
returns a new Session Data Object. If there is no current returns a new Session Data Object. If there is no current
token and create is false, returns None. browser id and create is false, returns None.
Permission required: Access session data Permission required: Access session data
""" """
...@@ -217,7 +217,7 @@ class SessionDataManagerInterface( ...@@ -217,7 +217,7 @@ class SessionDataManagerInterface(
def hasSessionData(self): def hasSessionData(self):
""" """
Returns true if a Session Data Object associated with the Returns true if a Session Data Object associated with the
current browser token is found in the Session Data Container. Does current browser id is found in the Session Data Container. Does
not create a Session Data Object if one does not exist. not create a Session Data Object if one does not exist.
Permission required: Access session data Permission required: Access session data
......
Browser Id Manager - Add Browser Id Manager - Add
Though you'll likely interact mostly with "session data manager" A browser id manager is an object which identifies visitors
objects while you develop session-aware code, before you can to your site, even if they don't log in. Browser id managers
instantiate a session data manager object, you must instantiate a are part of the Zope sessioning machinery.
"browser id manager." A browser id manager is an object which
doles out and otherwise manages session tokens. All session
data managers need to talk to a browser id manager to get token
information.
You can add an initial browser id manager anywhere in your Zope
tree, but chances are you'll want to create it in your root
folder if you don't anticipate the need for multiple browser id
managers. In other words, just put one browser id manager in
the root Folder unless you have special needs. In the container
of your choosing, select "Browser Id Manager" from the add
dropdown list in the Zope management interface.
Form options available are: Form options available are:
id -- you cannot choose an 'id' for your browser id manager. Id -- you cannot choose an 'id' for your browser id manager.
It must always be "browser_id_manager". Additionally, you cannot It must always be "browser_id_manager". Additionally, you cannot
rename a browser id manager. This is required in the current rename a browser id manager. This is required in the current
implementation so that session data managers can find browser implementation so that session data managers can find browser
id managers via Zope acquisition. This may be changed in a id managers via Zope acquisition. This may be changed in a
later release. later release.
title -- the browser id manager title. Title -- the browser id manager title.
session token key -- the cookie name and/or form variable name Look for browser id name in -- the cookie name and/or form variable name
used for this browser id manager instance. This will be the used for this browser id manager instance. This will be the
name looked up in the 'cookies' or 'form' REQUEST namespaces name looked up in the 'cookies' or 'form' REQUEST namespaces
when the browser id manager attempts to find a cookie or form when the browser id manager attempts to find a cookie or form
variable with a session token in it. variable with a browser id in it.
token key search namespaces -- choose a "priority" for each Browser id location -- select from one of the available
token key namespace. A priority of "1" is highest. For lookup ordering schemes involving cookies and forms
instance, setting 'cookies' to '1' and 'form vars' to '2'
means that the browser id manager checks for cookies with a Cookie path -- this is the 'path' element which should be sent
session token first, then form variables second. Choosing
"off" for either 'cookies' or 'form vars' entirely excludes
that namespace from being searched for a session token. The
namepace identifiers ('cookies' and 'form') refer to the
REQUEST namespaces searched for the token key
(ie. REQUEST.cookies, REQUEST.form).
cookie path -- this is the 'path' element which should be sent
in the session token cookie. For more information, see the in the session token cookie. For more information, see the
Netscape Cookie specification at Netscape Cookie specification at
http://home.netscape.com/newsref/std/cookie_spec.html. http://home.netscape.com/newsref/std/cookie_spec.html.
cookie domain -- this is the "domain" element which should be Cookie domain -- this is the "domain" element which should be
sent in the session token cookie. For more information, see sent in the browser id cookie. For more information, see
the Netscape Cookie specification at the Netscape Cookie specification at
http://home.netscape.com/newsref/std/cookie_spec.html. http://home.netscape.com/newsref/std/cookie_spec.html.
Leaving this form element blank results in no domain element Leaving this form element blank results in no domain element
...@@ -58,12 +38,12 @@ Browser Id Manager - Add ...@@ -58,12 +38,12 @@ Browser Id Manager - Add
value you enter must have at least two dots (as per the cookie value you enter must have at least two dots (as per the cookie
spec). spec).
cookie lifetime in days -- browser id cookies sent to browsers Cookie lifetime in days -- browser id cookies sent to browsers
will last this many days on a remote system before expiring if will last this many days on a remote system before expiring if
this value is set. If this value is 0, cookies will persist this value is set. If this value is 0, cookies will persist
on client browsers for only as long as the browser is open. on client browsers for only as long as the browser is open.
only send cookie over https -- if this flag is set, only send Only send cookie over https -- if this flag is set, only send
cookies to remote browsers if they're communicating with us cookies to remote browsers if they're communicating with us
over https. The browser id cookie sent under this over https. The browser id cookie sent under this
circumstance will also have the 'secure' flag set in it, which circumstance will also have the 'secure' flag set in it, which
...@@ -81,24 +61,18 @@ Browser Id Manager - Add ...@@ -81,24 +61,18 @@ Browser Id Manager - Add
Instantiating Multiple Browser Id Managers (Optional) Instantiating Multiple Browser Id Managers (Optional)
If you've got special needs, you may want to instantiate more If you've got special needs, you may want to instantiate more than
than one browser id manager. Having multiple browser id one browser id manager. In its default configuration, Zope will not
managers may be useful in cases where you have a "secure" allow you to create a browser id manager if one is installed in the
section of a site and an "insecure" section of a site, each root or in a place where the new browser id manager can acquire the
using a different browser id manager with respectively original browser id manager via its containment path (for
restrictive security settings. Some special considerations are programmers: the session id manager's class' Zope __replaceable__
required for this setup. property is set to UNIQUE). This means, practically, that if you
wish to have multiple browser id managers, you need to carefully
Once you've instantiated one browser id manager, you will not be delete the root browser id manager, then you need to place
able to instantiate another browser id manager in a place where additional browser id managers in the most deeply-nested containers
the new browser id manager can acquire the original browser id first, working your way out towards the root, finally replacing
manager via its containment path (for programmers: the session the root browser id manager if desired.
id manager's class' Zope __replaceable__ property is set to
UNIQUE). This means, practically, that if you wish to have
multiple browser id managers, you need to carefully think about
where they should go, and then you need to place them in the
most deeply-nested containers first, working your way out
towards the root.
See Also See Also
......
...@@ -2,32 +2,24 @@ Browser Id Manager - Change ...@@ -2,32 +2,24 @@ Browser Id Manager - Change
Form options available are: Form options available are:
title -- the browser id manager title. Title -- the browser id manager title.
session token key -- the cookie name and/or form variable name Browser id name -- the cookie name and/or form variable name
used for this browser id manager instance. This will be the used for this browser id manager instance. This will be the
name looked up in the 'cookies' or 'form' REQUEST namespaces name looked up in the 'cookies' or 'form' REQUEST namespaces
when the browser id manager attempts to find a cookie or form when the browser id manager attempts to find a cookie or form
variable with a session token in it. variable with a browser id in it.
token key search namespaces -- choose a "priority" for each Look for browser id name in -- select from one of the available
token key namespace. A priority of "1" is highest. For lookup ordering schemes involving cookies and forms
instance, setting 'cookies' to '1' and 'form vars' to '2'
means that the browser id manager checks for cookies with a Cookie path -- this is the 'path' element which should be sent
session token first, then form variables second. Choosing
"off" for either 'cookies' or 'form vars' entirely excludes
that namespace from being searched for a session token. The
namepace identifiers ('cookies' and 'form') refer to the
REQUEST namespaces searched for the token key
(ie. REQUEST.cookies, REQUEST.form).
cookie path -- this is the 'path' element which should be sent
in the session token cookie. For more information, see the in the session token cookie. For more information, see the
Netscape Cookie specification at Netscape Cookie specification at
http://home.netscape.com/newsref/std/cookie_spec.html. http://home.netscape.com/newsref/std/cookie_spec.html.
cookie domain -- this is the "domain" element which should be Cookie domain -- this is the "domain" element which should be
sent in the session token cookie. For more information, see sent in the browser id cookie. For more information, see
the Netscape Cookie specification at the Netscape Cookie specification at
http://home.netscape.com/newsref/std/cookie_spec.html. http://home.netscape.com/newsref/std/cookie_spec.html.
Leaving this form element blank results in no domain element Leaving this form element blank results in no domain element
...@@ -35,12 +27,12 @@ Browser Id Manager - Change ...@@ -35,12 +27,12 @@ Browser Id Manager - Change
value you enter must have at least two dots (as per the cookie value you enter must have at least two dots (as per the cookie
spec). spec).
cookie lifetime in days -- browser id cookies sent to browsers Cookie lifetime in days -- browser id cookies sent to browsers
will last this many days on a remote system before expiring if will last this many days on a remote system before expiring if
this value is set. If this value is 0, cookies will persist this value is set. If this value is 0, cookies will persist
on client browsers for only as long as the browser is open. on client browsers for only as long as the browser is open.
only send cookie over https -- if this flag is set, only send Only send cookie over https -- if this flag is set, only send
cookies to remote browsers if they're communicating with us cookies to remote browsers if they're communicating with us
over https. The browser id cookie sent under this over https. The browser id cookie sent under this
circumstance will also have the 'secure' flag set in it, which circumstance will also have the 'secure' flag set in it, which
......
Session Data Manager - Add Session Data Manager - Add
After instantiating at least one browser id manager, it's A Zope Session Data Manager is responsible for maintaining a
possible to instantiate a session data manager. You'll need to relationship between session data objects and Zope browser ids.
do this in order to use session tracking. It is part of the Zope sessioning machinery. Programmers will
sometimes interact with a session data manager in order to obtain
information about session data.
You can place a session data manager in any Zope container,as You can place a session data manager in any Zope container,as
long as a browser id manager object can be acquired from that long as a browser id manager object can be acquired from that
container. The session data manager will use the first acquired container. The session data manager will use the first acquired
browser id manager which is active (ie. it will use any acquired object named "browser_id_manager" as a browser id manager.
browser id manager that has not been been "turned off" via its
Zope management interface).
Choose "Session Data Manager" within the container you wish to Choose "Session Data Manager" within the container you wish to
house the session data manager from the "Add" dropdown box in house the session data manager from the "Add" dropdown box in
...@@ -27,7 +27,7 @@ Session Data Manager - Add ...@@ -27,7 +27,7 @@ Session Data Manager - Add
/temp_folder/transient_container in a default Zope installation. /temp_folder/transient_container in a default Zope installation.
place SESSION in REQUEST as -- place SESSION in REQUEST as --
If set, the REQUEST variable will be updated with the session If set, the REQUEST variable will be populated with the session
object, stored as the given name (default is 'SESSION') object, stored as the given name (default is 'SESSION')
After reviewing and changing these options, click the "Add" After reviewing and changing these options, click the "Add"
......
...@@ -10,7 +10,7 @@ Session Data Manager - Change ...@@ -10,7 +10,7 @@ Session Data Manager - Change
/temp_folder/transient_container in a default Zope installation. /temp_folder/transient_container in a default Zope installation.
place SESSION in REQUEST as -- place SESSION in REQUEST as --
If set, the REQUEST variable will be updated with the session If set, the REQUEST variable will be populated with the session
object, stored as the given name (default is 'SESSION') object, stored as the given name (default is 'SESSION')
After reviewing and changing these options, click the "Change" After reviewing and changing these options, click the "Change"
......
Session API Programming Session API Programming
Overview Overview
Developers generally *not* interact directly with a Session Data Sessions allow you to maintain state associated with anonymous
Manager instance in order to make use of sessioning in Zope. users between requests. A session is a temporary "scratch" area
in which you can store information related to a site visitor.
A "session" ends when a visitor who begins a session neglects to
revisit your site in some number of minutes.
Usage
All of the methods implemented by Session Data Managers, and Developers will usually interact with the SESSION object stored
Browser Id Managers are fully documented in the in REQUEST in order to perform session-related tasks.
Session API in the "See Also" section below.
More infrequently, developers will interact directly with
Browser Id Manager and Session Data Manager objects.
Common Programming Common Programming
Generally, instead of directly interacting with the session data In order to manipulate session data, you interact with the
manager, you use it's built in traversal feature to put a SESSION REQUEST.SESSION object.
object in the REQUEST. This is simple, and fairly intuitive.
For example, in DTML you might:: For example, in DTML you might::
<dtml-with SESSION mapping> <dtml-with SESSION mapping>
...@@ -26,12 +32,12 @@ Session API Programming ...@@ -26,12 +32,12 @@ Session API Programming
<dtml-var SESSION> <dtml-var SESSION>
This would print the cart object in the session, or the entire SESSION This would print the cart object in the session, or the entire SESSION
object. You could set an object. You could set an object in the session similarly to how you
object in the session similarly to how you set it in the REQUEST:: set it in the REQUEST::
<dtml-call expr="SESSION.set('cart','this is really more of a wagon')"> <dtml-call expr="SESSION.set('cart','this is really more of a wagon')">
You adjust the name of the SESSION object in the management screens You may change the name of the SESSION object in the management screens
for the session data object. You can do more complex operations on for the session data object. You can do more complex operations on
SESSION data with python scripts, e.g.:: SESSION data with python scripts, e.g.::
...@@ -42,18 +48,11 @@ Session API Programming ...@@ -42,18 +48,11 @@ Session API Programming
session['cart'] = cart # force a save back to the session session['cart'] = cart # force a save back to the session
In general, it is better to put manipulation of data in the session in
a python script than it is to do it via DTML or a page template; while
the latter is possible, it would be far better to simply place a session
management call at the top of any page which requires manipulation of
session data.
Tips Tips
Keep in mind that SESSION objects (Which are really Transient Objects) Keep in mind that SESSION objects are a lot like dictionaries; if
are basically dictionaries; if you wish to iterate through them in the you wish to iterate through them in the context of a dtml-in expression,
context of a DTML-IN expression, you should use something like:: you should use something like::
<dtml-in expr="SESSION.items()"> <dtml-in expr="SESSION.items()">
<dtml-var sequence-key>: <dtml-var sequence-item> <dtml-var sequence-key>: <dtml-var sequence-item>
......
...@@ -85,9 +85,9 @@ ...@@ -85,9 +85,9 @@
""" """
Test suite for session id manager. Test suite for session id manager.
$Id: testBrowserIdManager.py,v 1.2 2001/11/14 13:50:10 matt Exp $ $Id: testBrowserIdManager.py,v 1.3 2001/11/17 16:07:41 chrism Exp $
""" """
__version__ = "$Revision: 1.2 $"[11:-2] __version__ = "$Revision: 1.3 $"[11:-2]
import sys import sys
if __name__ == "__main__": if __name__ == "__main__":
...@@ -113,19 +113,19 @@ class TestBrowserIdManager(TestCase): ...@@ -113,19 +113,19 @@ class TestBrowserIdManager(TestCase):
def tearDown(self): def tearDown(self):
del self.m del self.m
def testSetTokenKey(self): def testSetBrowserIdName(self):
self.m.setTokenKey('foo') self.m.setBrowserIdName('foo')
assert self.m.getTokenKey()== 'foo' assert self.m.getBrowserIdName()== 'foo'
def testSetBadKeyString(self): def testSetBadBrowserIdName(self):
try: try:
self.m.setTokenKey('') self.m.setBrowserIdName('')
except BrowserIdManagerErr: except BrowserIdManagerErr:
pass pass
else: else:
assert 1 == 2 assert 1 == 2
try: try:
self.m.setTokenKey(1) self.m.setBrowserIdName(1)
except BrowserIdManagerErr: except BrowserIdManagerErr:
pass pass
else: else:
...@@ -134,7 +134,7 @@ class TestBrowserIdManager(TestCase): ...@@ -134,7 +134,7 @@ class TestBrowserIdManager(TestCase):
def testSetBadNamespaces(self): def testSetBadNamespaces(self):
d = {1:'gummy', 2:'froopy'} d = {1:'gummy', 2:'froopy'}
try: try:
self.m.setTokenKeyNamespaces(d) self.m.setBrowserIdNamespaces(d)
except BrowserIdManagerErr: except BrowserIdManagerErr:
pass pass
else: else:
...@@ -142,8 +142,22 @@ class TestBrowserIdManager(TestCase): ...@@ -142,8 +142,22 @@ class TestBrowserIdManager(TestCase):
def testSetGoodNamespaces(self): def testSetGoodNamespaces(self):
d = {1:'cookies', 2:'form'} d = {1:'cookies', 2:'form'}
self.m.setTokenKeyNamespaces(d) self.m.setBrowserIdNamespaces(d)
assert self.m.getTokenKeyNamespaces() == d assert self.m.getBrowserIdNamespaces() == d
def testSetNamespacesByLocation(self):
self.m.setBrowserIdLocation('cookiesonly')
assert self.m.getBrowserIdNamespaces() == {1:'cookies'}
assert self.m.getBrowserIdLocation() == 'cookiesonly'
self.m.setBrowserIdLocation('cookiesthenform')
assert self.m.getBrowserIdNamespaces() == {1:'cookies', 2:'form'}
assert self.m.getBrowserIdLocation() == 'cookiesthenform'
self.m.setBrowserIdLocation('formonly')
assert self.m.getBrowserIdNamespaces() == {1:'form'}
assert self.m.getBrowserIdLocation() == 'formonly'
self.m.setBrowserIdLocation('formthencookies')
assert self.m.getBrowserIdNamespaces() == {1:'form', 2:'cookies'}
assert self.m.getBrowserIdLocation() == 'formthencookies'
def testSetBadCookiePath(self): def testSetBadCookiePath(self):
path = '/;' path = '/;'
...@@ -224,131 +238,99 @@ class TestBrowserIdManager(TestCase): ...@@ -224,131 +238,99 @@ class TestBrowserIdManager(TestCase):
self.m.setCookieSecure(1) self.m.setCookieSecure(1)
assert self.m.getCookieSecure() == 1 assert self.m.getCookieSecure() == 1
def testDelegateToParent(self): def testGetBrowserIdCookie(self):
self.m.turnOff() token = self.m.getBrowserId()
try: self.m.REQUEST.browser_id_ = token
a = self.m.hasToken() self.m.REQUEST.browser_id_ns_ = 'cookies'
except BrowserIdManagerErr: tokenkey = self.m.getBrowserIdName()
pass
else:
assert 1==2
def testGetTokenCookie(self):
token = self.m.getToken()
self.m.REQUEST.browser_token_ = token
self.m.REQUEST.browser_token_ns_ = 'cookies'
tokenkey = self.m.getTokenKey()
self.m.REQUEST.cookies[tokenkey] = token self.m.REQUEST.cookies[tokenkey] = token
a = self.m.getToken() a = self.m.getBrowserId()
assert a == token, repr(a) assert a == token, repr(a)
assert self.m.isTokenFromCookie() assert self.m.isBrowserIdFromCookie()
def testSetSessionTokenDontCreate(self): def testSetBrowserIdDontCreate(self):
a = self.m.getToken(0) a = self.m.getBrowserId(0)
assert a == None assert a == None
def testSetSessionTokenCreate(self): def testSetBrowserIdCreate(self):
a = self.m.getToken(1) a = self.m.getBrowserId(1)
tokenkey = self.m.getTokenKey() tokenkey = self.m.getBrowserIdName()
b = self.m.REQUEST.RESPONSE.cookies[tokenkey] b = self.m.REQUEST.RESPONSE.cookies[tokenkey]
assert a == b['value'], (a, b) assert a == b['value'], (a, b)
def testHasToken(self): def testHasToken(self):
assert not self.m.hasToken() assert not self.m.hasBrowserId()
a = self.m.getToken() a = self.m.getBrowserId()
assert self.m.hasToken() assert self.m.hasBrowserId()
def testTokenIsNew(self): def testTokenIsNew(self):
a = self.m.getToken() a = self.m.getBrowserId()
assert self.m.isTokenNew() assert self.m.isBrowserIdNew()
def testIsTokenFromCookieFirst(self): def testIsBrowserIdFromCookieFirst(self):
token = self.m.getToken() token = self.m.getBrowserId()
self.m.REQUEST.browser_token_ = token self.m.REQUEST.browser_id_ = token
self.m.REQUEST.browser_token_ns_ = 'cookies' self.m.REQUEST.browser_id_ns_ = 'cookies'
tokenkey = self.m.getTokenKey() tokenkey = self.m.getBrowserIdName()
self.m.REQUEST.cookies[tokenkey] = token self.m.REQUEST.cookies[tokenkey] = token
self.m.setTokenKeyNamespaces({1:'cookies', 2:'form'}) self.m.setBrowserIdNamespaces({1:'cookies', 2:'form'})
a = self.m.getToken() a = self.m.getBrowserId()
assert self.m.isTokenFromCookie() assert self.m.isBrowserIdFromCookie()
def testIsTokenFromFormFirst(self): def testIsBrowserIdFromFormFirst(self):
token = self.m.getToken() token = self.m.getBrowserId()
self.m.REQUEST.browser_token_ = token self.m.REQUEST.browser_id_ = token
self.m.REQUEST.browser_token_ns_ = 'form' self.m.REQUEST.browser_id_ns_ = 'form'
tokenkey = self.m.getTokenKey() tokenkey = self.m.getBrowserIdName()
self.m.REQUEST.form[tokenkey] = token self.m.REQUEST.form[tokenkey] = token
self.m.setTokenKeyNamespaces({1:'form', 2:'cookies'}) self.m.setBrowserIdNamespaces({1:'form', 2:'cookies'})
a = self.m.getToken() a = self.m.getBrowserId()
assert self.m.isTokenFromForm() assert self.m.isBrowserIdFromForm()
def testIsTokenFromCookieOnly(self): def testIsTokenFromCookieOnly(self):
token = self.m.getToken() token = self.m.getBrowserId()
self.m.REQUEST.browser_token_ = token self.m.REQUEST.browser_id_ = token
self.m.REQUEST.browser_token_ns_ = 'cookies' self.m.REQUEST.browser_id_ns_ = 'cookies'
tokenkey = self.m.getTokenKey() tokenkey = self.m.getBrowserIdName()
self.m.REQUEST.cookies[tokenkey] = token self.m.REQUEST.form[tokenkey] = token
self.m.setTokenKeyNamespaces({1:'cookies'}) self.m.setBrowserIdNamespaces({1:'cookies'})
a = self.m.getToken() a = self.m.getBrowserId()
assert self.m.isTokenFromCookie() assert self.m.isBrowserIdFromCookie()
assert not self.m.isTokenFromForm() assert not self.m.isBrowserIdFromForm()
def testIsTokenFromFormOnly(self): def testIsTokenFromFormOnly(self):
token = self.m.getToken() token = self.m.getBrowserId()
self.m.REQUEST.browser_token_ = token self.m.REQUEST.browser_id_ = token
self.m.REQUEST.browser_token_ns_ = 'form' self.m.REQUEST.browser_id_ns_ = 'form'
tokenkey = self.m.getTokenKey() tokenkey = self.m.getBrowserIdName()
self.m.REQUEST.form[tokenkey] = token self.m.REQUEST.form[tokenkey] = token
self.m.setTokenKeyNamespaces({1:'form'}) self.m.setBrowserIdNamespaces({1:'form'})
a = self.m.getToken() a = self.m.getBrowserId()
assert self.m.isTokenFromForm() assert not self.m.isBrowserIdFromCookie()
assert not self.m.isTokenFromCookie() assert self.m.isBrowserIdFromForm()
def testFlushTokenCookie(self): def testFlushTokenCookie(self):
token = self.m.getToken() token = self.m.getBrowserId()
self.m.REQUEST.browser_token_ = token self.m.REQUEST.browser_id_ = token
self.m.REQUEST.browser_token_ns_ = 'cookies' self.m.REQUEST.browser_id_ns_ = 'cookies'
tokenkey = self.m.getTokenKey() tokenkey = self.m.getBrowserIdName()
self.m.REQUEST.cookies[tokenkey] = token self.m.REQUEST.cookies[tokenkey] = token
a = self.m.getToken() a = self.m.getBrowserId()
assert a == token, repr(a) assert a == token, repr(a)
assert self.m.isTokenFromCookie() assert self.m.isBrowserIdFromCookie()
self.m.flushTokenCookie() self.m.flushBrowserIdCookie()
c = self.m.REQUEST.RESPONSE.cookies[tokenkey] c = self.m.REQUEST.RESPONSE.cookies[tokenkey]
assert c['value'] == 'deleted', c assert c['value'] == 'deleted', c
def testDelegateToParentFail(self):
self.m.turnOff()
try:
self.m.getToken()
except BrowserIdManagerErr:
pass
else:
assert 1==2
def testDelegateToParentSucceed(self):
self.m.turnOff()
class foo:
pass
class bar:
def getToken(unself, create=1):
return 'worked'
fooi = foo()
bari = bar()
setattr(fooi, self.m.id, bari)
self.m.aq_parent = fooi
assert self.m.getToken() == 'worked'
def testEncodeUrl(self): def testEncodeUrl(self):
keystring = self.m.getTokenKey() keystring = self.m.getBrowserIdName()
key = self.m.getToken() key = self.m.getBrowserId()
u = '/home/chrism/foo' u = '/home/chrism/foo'
r = self.m.encodeUrl(u) r = self.m.encodeUrl(u)
assert r == '%s?%s=%s' % (u, keystring, key) assert r == '%s?%s=%s' % (u, keystring, key)
u = 'http://www.zope.org/Members/mcdonc?foo=bar&spam=eggs' u = 'http://www.zope.org/Members/mcdonc?foo=bar&spam=eggs'
r = self.m.encodeUrl(u) r = self.m.encodeUrl(u)
assert r == '%s&%s=%s' % (u, keystring, key) assert r == '%s&%s=%s' % (u, keystring, key)
def test_suite(): def test_suite():
testsuite = makeSuite(TestBrowserIdManager, 'test') testsuite = makeSuite(TestBrowserIdManager, 'test')
......
...@@ -202,15 +202,15 @@ class TestSessionManager(TestBase): ...@@ -202,15 +202,15 @@ class TestSessionManager(TestBase):
sd.invalidate() sd.invalidate()
assert hasattr(sd, '_invalid') assert hasattr(sd, '_invalid')
def testSessionTokenIsSet(self): def testBrowserIdIsSet(self):
sd = self.app.session_data_manager.getSessionData() sd = self.app.session_data_manager.getSessionData()
mgr = getattr(self.app, idmgr_name) mgr = getattr(self.app, idmgr_name)
assert mgr.hasToken() assert mgr.hasBrowserId()
def testGetSessionDataByKey(self): def testGetSessionDataByKey(self):
sd = self.app.session_data_manager.getSessionData() sd = self.app.session_data_manager.getSessionData()
mgr = getattr(self.app, idmgr_name) mgr = getattr(self.app, idmgr_name)
token = mgr.getToken() token = mgr.getBrowserId()
bykeysd = self.app.session_data_manager.getSessionDataByKey(token) bykeysd = self.app.session_data_manager.getSessionDataByKey(token)
assert sd == bykeysd, (sd, bykeysd, token) assert sd == bykeysd, (sd, bykeysd, token)
...@@ -324,8 +324,8 @@ class BaseReaderWriter(threading.Thread): ...@@ -324,8 +324,8 @@ class BaseReaderWriter(threading.Thread):
self.conn = db.open() self.conn = db.open()
self.app = self.conn.root()['Application'] self.app = self.conn.root()['Application']
self.app = makerequest.makerequest(self.app) self.app = makerequest.makerequest(self.app)
token = self.app.browser_id_manager._getNewToken() token = self.app.browser_id_manager._getNewBrowserId()
self.app.REQUEST.session_token_ = token self.app.REQUEST.browser_id_ = token
self.iters = iters self.iters = iters
self.sdm_name = sdm_name self.sdm_name = sdm_name
self.out = [] self.out = []
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment