Commit 463185cb authored by Chris McDonough's avatar Chris McDonough

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.
parent 4e42440b
############################################################################ ############################################################################
# #
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved. # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
# #
# This software is subject to the provisions of the Zope Public License, # This software is subject to the provisions of the Zope Public License,
...@@ -25,11 +25,11 @@ import SessionInterfaces ...@@ -25,11 +25,11 @@ import SessionInterfaces
from SessionPermissions import * from SessionPermissions import *
from types import StringType from types import StringType
from common import DEBUG from common import DEBUG
from BrowserIdManager import isAWellFormedBrowserId, getNewBrowserId,\
BROWSERID_MANAGER_NAME
from ZPublisher.BeforeTraverse import registerBeforeTraverse, \ from ZPublisher.BeforeTraverse import registerBeforeTraverse, \
unregisterBeforeTraverse unregisterBeforeTraverse
BID_MGR_NAME = 'browser_id_manager'
bad_path_chars_in=re.compile('[^a-zA-Z0-9-_~\,\. \/]').search bad_path_chars_in=re.compile('[^a-zA-Z0-9-_~\,\. \/]').search
class SessionDataManagerErr(Exception): pass class SessionDataManagerErr(Exception): pass
...@@ -103,19 +103,20 @@ class SessionDataManager(Item, Implicit, Persistent, RoleManager, Owned, Tabs): ...@@ -103,19 +103,20 @@ class SessionDataManager(Item, Implicit, Persistent, RoleManager, Owned, Tabs):
security.declareProtected(ARBITRARY_SESSIONDATA_PERM,'getSessionDataByKey') security.declareProtected(ARBITRARY_SESSIONDATA_PERM,'getSessionDataByKey')
def getSessionDataByKey(self, key): def getSessionDataByKey(self, key):
return self._getSessionDataObjectByKey(key) return self._getSessionDataObjectByKey(key)
security.declareProtected(ACCESS_CONTENTS_PERM, 'getBrowserIdManager') security.declareProtected(ACCESS_CONTENTS_PERM, 'getBrowserIdManager')
def getBrowserIdManager(self): def getBrowserIdManager(self):
""" """ """ """
mgr = getattr(self, BID_MGR_NAME, None) mgr = getattr(self, BROWSERID_MANAGER_NAME, None)
if mgr is None: if mgr is None:
raise SessionDataManagerErr,( 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 return mgr
# END INTERFACE METHODS # END INTERFACE METHODS
def __init__(self, id, path=None, title='', requestName=None): def __init__(self, id, path=None, title='', requestName=None):
self.id = id self.id = id
self.setContainerPath(path) self.setContainerPath(path)
...@@ -160,14 +161,14 @@ class SessionDataManager(Item, Implicit, Persistent, RoleManager, Owned, Tabs): ...@@ -160,14 +161,14 @@ class SessionDataManager(Item, Implicit, Persistent, RoleManager, Owned, Tabs):
self.obpath = list(path) # sequence self.obpath = list(path) # sequence
else: else:
raise SessionDataManagerErr, ('Bad path value %s' % path) raise SessionDataManagerErr, ('Bad path value %s' % path)
security.declareProtected(MGMT_SCREEN_PERM, 'getContainerPath') security.declareProtected(MGMT_SCREEN_PERM, 'getContainerPath')
def getContainerPath(self): def getContainerPath(self):
""" """ """ """
if self.obpath is not None: if self.obpath is not None:
return string.join(self.obpath, '/') return string.join(self.obpath, '/')
return '' # blank string represents undefined state return '' # blank string represents undefined state
def _hasSessionDataObject(self, key): def _hasSessionDataObject(self, key):
""" """ """ """
c = self._getSessionDataContainer() c = self._getSessionDataContainer()
...@@ -251,6 +252,12 @@ class SessionDataManagerTraverser(Persistent): ...@@ -251,6 +252,12 @@ class SessionDataManagerTraverser(Persistent):
self._sessionDataManager = sessionDataManagerName self._sessionDataManager = sessionDataManagerName
def __call__(self, container, request, StringType=StringType): 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: try:
sdmName = self._sessionDataManager sdmName = self._sessionDataManager
if not isinstance(sdmName, StringType): if not isinstance(sdmName, StringType):
...@@ -268,7 +275,10 @@ class SessionDataManagerTraverser(Persistent): ...@@ -268,7 +275,10 @@ class SessionDataManagerTraverser(Persistent):
msg = 'Session automatic traversal failed to get session data' msg = 'Session automatic traversal failed to get session data'
LOG('Session Tracking', WARNING, msg, error=sys.exc_info()) LOG('Session Tracking', WARNING, msg, error=sys.exc_info())
return return
# set the getSessionData method in the "lazy" namespace
if self._requestSessionName is not None: if self._requestSessionName is not None:
request.set_lazy(self._requestSessionName, getSessionData) request.set_lazy(self._requestSessionName, getSessionData)
Globals.InitializeClass(SessionDataManager) Globals.InitializeClass(SessionDataManager)
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
############################################################################ ############################################################################
""" """
Sessioning-related Object APIs Session APIs
See Also See Also
...@@ -32,12 +32,24 @@ class BrowserIdManagerInterface( ...@@ -32,12 +32,24 @@ class BrowserIdManagerInterface(
visitors, and for servicing requests from Session Data Managers visitors, and for servicing requests from Session Data Managers
related to the browser id. related to the browser id.
""" """
def encodeUrl(url): def encodeUrl(url, style='querystring'):
""" """
Encodes a provided URL with the current request's browser id Encodes a provided URL with the current request's browser id
and returns the result. For example, the call and returns the result. Two forms of URL-encoding are supported:
encodeUrl('http://foo.com/amethod') might return 'querystring' and 'inline'. 'querystring' is the default.
'http://foo.com/amethod?_ZopeId=as9dfu0adfu0ad'.
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 Permission required: Access contents information
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
)"> )">
<FORM ACTION="constructBrowserIdManager" METHOD="POST"> <FORM ACTION="constructBrowserIdManager" METHOD="POST">
<input type=hidden name="id" value="browser_id_manager">
<TABLE CELLSPACING="2"> <TABLE CELLSPACING="2">
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
...@@ -60,30 +59,25 @@ by interacting with the Zope sessioning machinery. ...@@ -60,30 +59,25 @@ by interacting with the Zope sessioning machinery.
</tr> </tr>
<tr> <tr>
<td> <td>
<div align=left class="form-label">Look for Browser Id Name in</th> <div align=left class="form-label">Look for Browser Id in</th>
</td> </td>
<td> <td>
<table border=0> <table border=0>
<tr> <tr>
<td align=left> <td align=left>
<input type="radio" name="location" value="cookiesonly"> Cookies only <input type="checkbox" name="location:list" value="cookies" CHECKED> Cookies
</td> </td>
</tr> </tr>
<tr> <tr>
<td align=left> <td align=left>
<input type="radio" name="location" value="cookiesthenform" CHECKED> Cookies then form <input type="checkbox" name="location:list" value="form" CHECKED> Forms and Query Strings
</td> </td>
</tr> </tr>
<tr> <tr>
<td align=left> <td align=left>
<input type="radio" name="location" value="formonly"> Form only <input type="checkbox" name="location:list" value="url" CHECKED> URLs
</td> </td>
</tr> </tr>
<tr>
<td align=left>
<input type="radio" name="location" value="formthencookies"> Form then cookies
</td>
</tr>
</table> </table>
</td> </td>
</tr> </tr>
...@@ -93,6 +87,16 @@ by interacting with the Zope sessioning machinery. ...@@ -93,6 +87,16 @@ by interacting with the Zope sessioning machinery.
<td>&nbsp;</td> <td>&nbsp;</td>
</tr> </tr>
<TR>
<TD ALIGN="LEFT" VALIGN="TOP">
<div class="form-label">
Automatically Encode Zope-Generated<br>URLs With A Browser Id
</div>
</TD>
<TD ALIGN="LEFT" VALIGN="TOP">
<INPUT TYPE="checkbox" NAME="auto_url_encoding" SIZE="20">
</TD>
</TR>
<TR> <TR>
<TD ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT" VALIGN="TOP">
<div class="form-label"> <div class="form-label">
......
...@@ -37,42 +37,47 @@ ...@@ -37,42 +37,47 @@
</TD> </TD>
</TR> </TR>
<dtml-let loc=getBrowserIdLocation> <dtml-let namespaces=getBrowserIdNamespaces>
<tr valign="top"> <tr valign="top">
<td> <td>
<div align=left class="form-label">Look for Browser Id Name in</th> <div align=left class="form-label">Look for Browser Id in</th>
</td> </td>
<td> <td>
<table border=0> <table border=0>
<tr> <tr>
<td align=left> <td align=left>
<input type="radio" name="location" value="cookiesonly" <input type="checkbox" name="location:list" value="cookies"
<dtml-if "loc=='cookiesonly'">CHECKED</dtml-if>> Cookies only <dtml-if "'cookies' in namespaces">CHECKED</dtml-if>> Cookies
</td> </td>
</tr> </tr>
<tr> <tr>
<td align=left> <td align=left>
<input type="radio" name="location" value="cookiesthenform" <input type="checkbox" name="location:list" value="form"
<dtml-if "loc=='cookiesthenform'">CHECKED</dtml-if>> Cookies then form <dtml-if "'form' in namespaces">CHECKED</dtml-if>> Forms and Query Strings
</td> </td>
</tr> </tr>
<tr> <tr>
<td align=left> <td align=left>
<input type="radio" name="location" value="formonly" <input type="checkbox" name="location:list" value="url"
<dtml-if "loc=='formonly'">CHECKED</dtml-if>> Form only <dtml-if "'url' in namespaces">CHECKED</dtml-if>> URLs
</td> </td>
</tr> </tr>
<tr>
<td align=left>
<input type="radio" name="location" value="formthencookies"
<dtml-if "loc=='formthencookies'">CHECKED</dtml-if>> Form then cookies
</td>
</tr>
</table> </table>
</td> </td>
</tr> </tr>
</dtml-let> </dtml-let>
<TR>
<TD ALIGN="LEFT" VALIGN="TOP">
<div class="form-label">
Automatically Encode Zope-Generated<br>URLs With A Browser Id
</div>
</TD>
<TD ALIGN="LEFT" VALIGN="TOP">
<INPUT TYPE="checkbox" NAME="auto_url_encoding"
<dtml-if getAutoUrlEncoding>CHECKED</dtml-if>>
</TD>
</TR>
<TR> <TR>
<TD ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT" VALIGN="TOP">
<div class="form-label"> <div class="form-label">
......
...@@ -32,12 +32,24 @@ class BrowserIdManagerInterface( ...@@ -32,12 +32,24 @@ class BrowserIdManagerInterface(
visitors, and for servicing requests from Session Data Managers visitors, and for servicing requests from Session Data Managers
related to the browser id. related to the browser id.
""" """
def encodeUrl(url): def encodeUrl(url, style='querystring'):
""" """
Encodes a provided URL with the current request's browser id Encodes a provided URL with the current request's browser id
and returns the result. For example, the call and returns the result. Two forms of URL-encoding are supported:
encodeUrl('http://foo.com/amethod') might return 'querystring' and 'inline'. 'querystring' is the default.
'http://foo.com/amethod?_ZopeId=as9dfu0adfu0ad'.
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 Permission required: Access contents information
......
...@@ -15,14 +15,21 @@ Browser Id Manager - Add ...@@ -15,14 +15,21 @@ Browser Id Manager - Add
Title -- the browser id manager title. Title -- the browser id manager title.
Look for browser id name in -- the cookie name and/or form variable name Browser Id Name -- the cookie name and/or form variable
used for this browser id manager instance. This will be the name 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 browser id in it. variable with a browser id in it.
Browser id location -- select from one of the available Look for Browser Id In -- choose any of 'Forms and Query Strings',
lookup ordering schemes involving cookies and forms 'URLs', or 'Cookies'. The browser id name/value will be looked
for within these places.
Automatically Encode Zope-Generated URLs With A Browser Id -- if
this is selected, URLs generated by Zope (such as URLs which come
as a result of calling an object's 'absolute_url' method) will be
encoded with a browser name and browser id as the first two
elements of the URL path.
Cookie path -- this is the 'path' element which should be sent 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
......
...@@ -4,14 +4,20 @@ Browser Id Manager - Change ...@@ -4,14 +4,20 @@ Browser Id Manager - Change
Title -- the browser id manager title. Title -- the browser id manager title.
Browser id name -- the cookie name and/or form variable name Browser id name -- the cookie or forms 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 namespaces specified by "Look for browser
when the browser id manager attempts to find a cookie or form id name in" (below).
variable with a browser id in it.
Look for Browser Id In -- choose any of 'Forms and Query Strings',
Look for browser id name in -- select from one of the available 'URLs', or 'Cookies'. The browser id name/value will be looked
lookup ordering schemes involving cookies and forms for within these places.
Automatically Encode Zope-Generated URLs With A Browser Id -- if
this is selected, URLs generated by Zope (such as URLs which come
as a result of calling an object's 'absolute_url' method) will be
encoded with a browser name and browser id as the first two
elements of the URL path.
Cookie path -- this is the 'path' element which should be sent 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
......
...@@ -18,7 +18,7 @@ from Testing import makerequest ...@@ -18,7 +18,7 @@ from Testing import makerequest
import ZODB # in order to get Persistence.Persistent working import ZODB # in order to get Persistence.Persistent working
import Acquisition import Acquisition
from Acquisition import aq_base from Acquisition import aq_base
from Products.Sessions.BrowserIdManager import BrowserIdManager from Products.Sessions.BrowserIdManager import BrowserIdManager, getNewBrowserId
from Products.Sessions.SessionDataManager import \ from Products.Sessions.SessionDataManager import \
SessionDataManager, SessionDataManagerErr SessionDataManager, SessionDataManagerErr
from Products.Transience.Transience import \ from Products.Transience.Transience import \
...@@ -149,7 +149,7 @@ class BaseReaderWriter(threading.Thread): ...@@ -149,7 +149,7 @@ 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._getNewBrowserId() token = getNewBrowserId()
self.app.REQUEST.browser_id_ = token self.app.REQUEST.browser_id_ = token
self.iters = iters self.iters = iters
self.sdm_name = sdm_name self.sdm_name = sdm_name
......
...@@ -13,30 +13,41 @@ ...@@ -13,30 +13,41 @@
""" """
Test suite for session id manager. Test suite for session id manager.
$Id: testBrowserIdManager.py,v 1.11 2002/08/14 22:25:10 mj Exp $ $Id: testBrowserIdManager.py,v 1.12 2002/08/19 19:50:18 chrism Exp $
""" """
__version__ = "$Revision: 1.11 $"[11:-2] __version__ = "$Revision: 1.12 $"[11:-2]
import sys import sys
import ZODB import ZODB
from Products.Sessions.BrowserIdManager import BrowserIdManager, BrowserIdManagerErr from Products.Sessions.BrowserIdManager import BrowserIdManager, \
BrowserIdManagerErr, BrowserIdManagerTraverser, \
isAWellFormedBrowserId
from unittest import TestCase, TestSuite, TextTestRunner, makeSuite from unittest import TestCase, TestSuite, TextTestRunner, makeSuite
from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPRequest import HTTPRequest
from ZPublisher.HTTPResponse import HTTPResponse from ZPublisher.HTTPResponse import HTTPResponse
from ZPublisher.BeforeTraverse import queryBeforeTraverse
from sys import stdin from sys import stdin
from os import environ from os import environ
from OFS.Application import Application
class TestBrowserIdManager(TestCase): class TestBrowserIdManager(TestCase):
def setUp(self): def setUp(self):
self.m = BrowserIdManager('foo') self.app = Application()
self.app.id = 'App'
mgr = BrowserIdManager('browser_id_manager')
self.app._setObject('browser_id_manager', mgr)
self.m = self.app.browser_id_manager
resp = HTTPResponse() resp = HTTPResponse()
environ['SERVER_NAME']='fred' environ['SERVER_NAME']='fred'
environ['SERVER_PORT']='80' environ['SERVER_PORT']='80'
req = HTTPRequest(stdin, environ, resp) self.req = HTTPRequest(stdin, environ, resp)
self.m.REQUEST = req self.req['TraversalRequestNameStack'] = ['foo', 'bar']
self.app.REQUEST = self.req
def tearDown(self): def tearDown(self):
del self.m del self.m
self.app.REQUEST = None
del self.app
def testSetBrowserIdName(self): def testSetBrowserIdName(self):
self.m.setBrowserIdName('foo') self.m.setBrowserIdName('foo')
...@@ -49,30 +60,16 @@ class TestBrowserIdManager(TestCase): ...@@ -49,30 +60,16 @@ class TestBrowserIdManager(TestCase):
lambda self=self: self.m.setBrowserIdName(1)) lambda self=self: self.m.setBrowserIdName(1))
def testSetBadNamespaces(self): def testSetBadNamespaces(self):
d = {1:'gummy', 2:'froopy'} d = ('gummy', 'froopy')
self.assertRaises(BrowserIdManagerErr, self.assertRaises(BrowserIdManagerErr,
lambda self=self,d=d: lambda self=self,d=d:
self.m.setBrowserIdNamespaces(d)) self.m.setBrowserIdNamespaces(d))
def testSetGoodNamespaces(self): def testSetGoodNamespaces(self):
d = {1:'cookies', 2:'form'} d = ('cookies', 'url', 'form')
self.m.setBrowserIdNamespaces(d) self.m.setBrowserIdNamespaces(d)
self.failUnless(self.m.getBrowserIdNamespaces() == d) self.failUnless(self.m.getBrowserIdNamespaces() == d)
def testSetNamespacesByLocation(self):
self.m.setBrowserIdLocation('cookiesonly')
self.failUnless(self.m.getBrowserIdNamespaces() == {1:'cookies'})
self.failUnless(self.m.getBrowserIdLocation() == 'cookiesonly')
self.m.setBrowserIdLocation('cookiesthenform')
self.failUnless(self.m.getBrowserIdNamespaces()=={1:'cookies',2:'form'})
self.failUnless(self.m.getBrowserIdLocation() == 'cookiesthenform')
self.m.setBrowserIdLocation('formonly')
self.failUnless(self.m.getBrowserIdNamespaces() == {1:'form'})
self.failUnless(self.m.getBrowserIdLocation() == 'formonly')
self.m.setBrowserIdLocation('formthencookies')
self.failUnless(self.m.getBrowserIdNamespaces()=={1:'form',2:'cookies'})
self.failUnless(self.m.getBrowserIdLocation() == 'formthencookies')
def testSetBadCookiePath(self): def testSetBadCookiePath(self):
path = '/;' path = '/;'
self.assertRaises(BrowserIdManagerErr, self.assertRaises(BrowserIdManagerErr,
...@@ -148,33 +145,13 @@ class TestBrowserIdManager(TestCase): ...@@ -148,33 +145,13 @@ class TestBrowserIdManager(TestCase):
a = self.m.getBrowserId() a = self.m.getBrowserId()
self.failUnless( self.m.isBrowserIdNew() ) self.failUnless( self.m.isBrowserIdNew() )
def testIsBrowserIdFromCookieFirst(self):
token = self.m.getBrowserId()
self.m.REQUEST.browser_id_ = token
self.m.REQUEST.browser_id_ns_ = 'cookies'
tokenkey = self.m.getBrowserIdName()
self.m.REQUEST.cookies[tokenkey] = token
self.m.setBrowserIdNamespaces({1:'cookies', 2:'form'})
a = self.m.getBrowserId()
self.failUnless( self.m.isBrowserIdFromCookie() )
def testIsBrowserIdFromFormFirst(self):
token = self.m.getBrowserId()
self.m.REQUEST.browser_id_ = token
self.m.REQUEST.browser_id_ns_ = 'form'
tokenkey = self.m.getBrowserIdName()
self.m.REQUEST.form[tokenkey] = token
self.m.setBrowserIdNamespaces({1:'form', 2:'cookies'})
a = self.m.getBrowserId()
self.failUnless( self.m.isBrowserIdFromForm() )
def testIsBrowserIdFromCookieOnly(self): def testIsBrowserIdFromCookieOnly(self):
token = self.m.getBrowserId() token = self.m.getBrowserId()
self.m.REQUEST.browser_id_ = token self.m.REQUEST.browser_id_ = token
self.m.REQUEST.browser_id_ns_ = 'cookies' self.m.REQUEST.browser_id_ns_ = 'cookies'
tokenkey = self.m.getBrowserIdName() tokenkey = self.m.getBrowserIdName()
self.m.REQUEST.form[tokenkey] = token self.m.REQUEST.form[tokenkey] = token
self.m.setBrowserIdNamespaces({1:'cookies'}) self.m.setBrowserIdNamespaces(('cookies',))
a = self.m.getBrowserId() a = self.m.getBrowserId()
self.failUnless( self.m.isBrowserIdFromCookie() ) self.failUnless( self.m.isBrowserIdFromCookie() )
self.failUnless( not self.m.isBrowserIdFromForm() ) self.failUnless( not self.m.isBrowserIdFromForm() )
...@@ -185,11 +162,20 @@ class TestBrowserIdManager(TestCase): ...@@ -185,11 +162,20 @@ class TestBrowserIdManager(TestCase):
self.m.REQUEST.browser_id_ns_ = 'form' self.m.REQUEST.browser_id_ns_ = 'form'
tokenkey = self.m.getBrowserIdName() tokenkey = self.m.getBrowserIdName()
self.m.REQUEST.form[tokenkey] = token self.m.REQUEST.form[tokenkey] = token
self.m.setBrowserIdNamespaces({1:'form'}) self.m.setBrowserIdNamespaces(('form',))
a = self.m.getBrowserId() a = self.m.getBrowserId()
self.failUnless( not self.m.isBrowserIdFromCookie() ) self.failUnless( not self.m.isBrowserIdFromCookie() )
self.failUnless( self.m.isBrowserIdFromForm() ) self.failUnless( self.m.isBrowserIdFromForm() )
def testIsBrowserIdFromUrlOnly(self):
token = self.m.getBrowserId()
self.m.REQUEST.browser_id_ = token
self.m.REQUEST.browser_id_ns_ = 'url'
self.m.setBrowserIdNamespaces(('url',))
a = self.m.getBrowserId()
self.failUnless( not self.m.isBrowserIdFromCookie() )
self.failUnless( self.m.isBrowserIdFromUrl() )
def testFlushBrowserIdCookie(self): def testFlushBrowserIdCookie(self):
token = self.m.getBrowserId() token = self.m.getBrowserId()
self.m.REQUEST.browser_id_ = token self.m.REQUEST.browser_id_ = token
...@@ -226,6 +212,8 @@ class TestBrowserIdManager(TestCase): ...@@ -226,6 +212,8 @@ class TestBrowserIdManager(TestCase):
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)
self.failUnless( r == '%s&amp;%s=%s' % (u, keystring, key) ) self.failUnless( r == '%s&amp;%s=%s' % (u, keystring, key) )
r = self.m.encodeUrl(u, style='inline')
self.failUnless( r == 'http://www.zope.org/%s/%s/Members/mcdonc?foo=bar&spam=eggs' % (keystring, key))
def testGetHiddenFormField(self): def testGetHiddenFormField(self):
keystring = self.m.getBrowserIdName() keystring = self.m.getBrowserIdName()
...@@ -235,6 +223,47 @@ class TestBrowserIdManager(TestCase): ...@@ -235,6 +223,47 @@ class TestBrowserIdManager(TestCase):
(keystring, key)) (keystring, key))
self.failUnless( html == expected ) self.failUnless( html == expected )
def testAutoUrlEncoding(self):
self.m.setAutoUrlEncoding(1)
self.m.setBrowserIdNamespaces(('url',))
self.m.updateTraversalData()
traverser = BrowserIdManagerTraverser()
traverser(self.app, self.req)
self.failUnless(isAWellFormedBrowserId(self.req.browser_id_))
print self.req.browser_id_
self.failUnless(self.req.browser_id_ns_ == None)
self.failUnless(self.req._script[-1] == self.req.browser_id_)
self.failUnless(self.req._script[-2] == '_ZopeId')
def testUrlBrowserIdIsFound(self):
bid = '43295340A0bpcu4nkCI'
name = '_ZopeId'
resp = HTTPResponse()
environ['SERVER_NAME']='fred'
environ['SERVER_PORT']='80'
self.req = HTTPRequest(stdin, environ, resp)
self.req['TraversalRequestNameStack'] = ['foo', 'bar', bid, name]
self.app.REQUEST = self.req
self.m.setAutoUrlEncoding(1)
self.m.setBrowserIdNamespaces(('url',))
self.m.updateTraversalData()
traverser = BrowserIdManagerTraverser()
traverser(self.app, self.req)
self.failUnless(isAWellFormedBrowserId(self.req.browser_id_))
self.failUnless(self.req.browser_id_ns_ == 'url')
self.failUnless(self.req._script[-1] == self.req.browser_id_)
self.failUnless(self.req._script[-2] == '_ZopeId')
self.failUnless(self.req['TraversalRequestNameStack'] == ['foo','bar'])
def testUpdateTraversalData(self):
self.m.setBrowserIdNamespaces(('url',))
self.m.updateTraversalData()
self.failUnless(self.m.hasTraversalHook(self.app))
self.failUnless(queryBeforeTraverse(self.app, 'BrowserIdManager'))
self.m.setBrowserIdNamespaces(('cookies', 'form'))
self.m.updateTraversalData()
self.failUnless(not queryBeforeTraverse(self.app,'BrowserIdManager'))
def test_suite(): def test_suite():
testsuite = makeSuite(TestBrowserIdManager, 'test') testsuite = makeSuite(TestBrowserIdManager, 'test')
return testsuite return testsuite
......
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