[Checkins] SVN: Products.CMFCore/trunk/Products/CMFCore/ - merged cookiecrumbler_with_views branch
Yvo Schubbe
y.2010 at wcm-solutions.de
Tue Jun 15 06:16:50 EDT 2010
Log message for revision 113477:
- merged cookiecrumbler_with_views branch
Changed:
U Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt
U Products.CMFCore/trunk/Products/CMFCore/CookieCrumbler.py
U Products.CMFCore/trunk/Products/CMFCore/MembershipTool.py
U Products.CMFCore/trunk/Products/CMFCore/dtml/addCC.dtml
U Products.CMFCore/trunk/Products/CMFCore/exportimport/cookieauth.py
U Products.CMFCore/trunk/Products/CMFCore/exportimport/tests/test_cookieauth.py
U Products.CMFCore/trunk/Products/CMFCore/interfaces/_cookieCrumbler.py
U Products.CMFCore/trunk/Products/CMFCore/tests/test_CookieCrumbler.py
-=-
Modified: Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt 2010-06-15 09:29:26 UTC (rev 113476)
+++ Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt 2010-06-15 10:16:49 UTC (rev 113477)
@@ -4,6 +4,9 @@
2.3.0-alpha (unreleased)
------------------------
+- CookieCrumbler: Removed redirect support.
+ The Unauthorized handling and redirects are now part of CMFDefault.
+
- Use the standard libraries doctest module.
- Updated setDefaultRoles to use the addPermission API if available.
Modified: Products.CMFCore/trunk/Products/CMFCore/CookieCrumbler.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/CookieCrumbler.py 2010-06-15 09:29:26 UTC (rev 113476)
+++ Products.CMFCore/trunk/Products/CMFCore/CookieCrumbler.py 2010-06-15 10:16:49 UTC (rev 113477)
@@ -28,14 +28,13 @@
from OFS.SimpleItem import SimpleItem
from OFS.PropertyManager import PropertyManager
from OFS.interfaces import IObjectWillBeMovedEvent
-from zExceptions import Redirect
from zope.container.interfaces import IObjectMovedEvent
from zope.interface import implements
from ZPublisher import BeforeTraverse
from ZPublisher.HTTPRequest import HTTPRequest
from Products.CMFCore.interfaces import ICookieCrumbler
-from Products.CMFCore.utils import UniqueObject
+from Products.CMFCore.utils import UniqueObject, getToolByName
# Constants.
@@ -84,12 +83,6 @@
'label':'User password form variable'},
{'id':'persist_cookie', 'type': 'string', 'mode':'w',
'label':'User name persistence form variable'},
- {'id':'auto_login_page', 'type': 'string', 'mode':'w',
- 'label':'Login page ID'},
- {'id':'logout_page', 'type': 'string', 'mode':'w',
- 'label':'Logout page ID'},
- {'id':'unauth_page', 'type': 'string', 'mode':'w',
- 'label':'Failed authorization page ID'},
{'id':'local_cookie_path', 'type': 'boolean', 'mode':'w',
'label':'Use cookie paths to limit scope'},
{'id':'cache_header_value', 'type': 'string', 'mode':'w',
@@ -100,16 +93,11 @@
auth_cookie = '__ac'
name_cookie = '__ac_name'
- pw_cookie = '__ac_password'
+ pw_cookie = '__ac_password' # not used as cookie, just as request key
persist_cookie = '__ac_persistent'
local_cookie_path = False
cache_header_value = 'private'
log_username = True
- # the following properties are deprecated and will be replaced by
- # user actions
- auto_login_page = 'login_form'
- unauth_page = ''
- logout_page = 'logged_out'
security.declarePrivate('delRequestVar')
def delRequestVar(self, req, name):
@@ -258,15 +246,7 @@
attempt = self.modifyRequest(req, resp)
except CookieCrumblerDisabled:
return
- if req.get('disable_cookie_login__', 0):
- return
- if (self.unauth_page or
- attempt == ATTEMPT_LOGIN or attempt == ATTEMPT_NONE):
- # Modify the "unauthorized" response.
- req._hold(ResponseCleanup(resp))
- resp.unauthorized = self.unauthorized
- resp._unauthorized = self._unauthorized
if attempt != ATTEMPT_NONE:
# Trying to log in or resume a session
if self.cache_header_value:
@@ -276,126 +256,39 @@
resp.setHeader('X-Cache-Control-Hdr-Modified-By',
'CookieCrumbler')
phys_path = self.getPhysicalPath()
- if self.logout_page:
- # Cookies are in use.
- page = getattr(container, self.logout_page, None)
- if page is not None:
- # Provide a logout page.
- req._logout_path = phys_path + ('logout',)
- req._credentials_changed_path = (
- phys_path + ('credentialsChanged',))
+ # Cookies are in use.
+ # Provide a logout page.
+ req._logout_path = phys_path + ('logout',)
security.declarePublic('credentialsChanged')
- def credentialsChanged(self, user, name, pw):
- # XXX: this method violates the rules for tools/utilities:
- # it depends on self.REQUEST
+ def credentialsChanged(self, user, name, pw, request=None):
+ """
+ Updates cookie credentials if user details are changed.
+ """
+ if request is None:
+ request = self.REQUEST # BBB for Membershiptool
+ reponse = request['RESPONSE']
ac = encodestring('%s:%s' % (name, pw)).rstrip()
- method = self.getCookieMethod( 'setAuthCookie'
- , self.defaultSetAuthCookie )
- resp = self.REQUEST['RESPONSE']
- method( resp, self.auth_cookie, quote( ac ) )
+ method = self.getCookieMethod('setAuthCookie',
+ self.defaultSetAuthCookie)
+ method(reponse, self.auth_cookie, quote(ac))
- def _cleanupResponse(self):
- # XXX: this method violates the rules for tools/utilities:
- # it depends on self.REQUEST
- resp = self.REQUEST['RESPONSE']
- # No errors of any sort may propagate, and we don't care *what*
- # they are, even to log them.
- try: del resp.unauthorized
- except: pass
- try: del resp._unauthorized
- except: pass
- return resp
-
- security.declarePrivate('unauthorized')
- def unauthorized(self):
- resp = self._cleanupResponse()
- # If we set the auth cookie before, delete it now.
- if resp.cookies.has_key(self.auth_cookie):
- del resp.cookies[self.auth_cookie]
- # Redirect if desired.
- url = self.getUnauthorizedURL()
- if url is not None:
- raise Redirect, url
- # Fall through to the standard unauthorized() call.
- resp.unauthorized()
-
- def _unauthorized(self):
- resp = self._cleanupResponse()
- # If we set the auth cookie before, delete it now.
- if resp.cookies.has_key(self.auth_cookie):
- del resp.cookies[self.auth_cookie]
- # Redirect if desired.
- url = self.getUnauthorizedURL()
- if url is not None:
- resp.redirect(url, lock=1)
- # We don't need to raise an exception.
- return
- # Fall through to the standard _unauthorized() call.
- resp._unauthorized()
-
- security.declarePublic('getUnauthorizedURL')
- def getUnauthorizedURL(self):
- '''
- Redirects to the login page.
- '''
- # XXX: this method violates the rules for tools/utilities:
- # it depends on self.REQUEST
- req = self.REQUEST
- resp = req['RESPONSE']
- attempt = getattr(req, '_cookie_auth', ATTEMPT_NONE)
- if attempt == ATTEMPT_NONE:
- # An anonymous user was denied access to something.
- page_id = self.auto_login_page
- retry = ''
- elif attempt == ATTEMPT_LOGIN:
- # The login attempt failed. Try again.
- page_id = self.auto_login_page
- retry = '1'
- else:
- # An authenticated user was denied access to something.
- page_id = self.unauth_page
- retry = ''
- if page_id:
- page = self.restrictedTraverse(page_id, None)
- if page is not None:
- came_from = req.get('came_from', None)
- if came_from is None:
- came_from = req.get('ACTUAL_URL')
- query = req.get('QUERY_STRING')
- if query:
- # Include the query string in came_from
- if not query.startswith('?'):
- query = '?' + query
- came_from = came_from + query
- url = '%s?came_from=%s&retry=%s&disable_cookie_login__=1' % (
- page.absolute_url(), quote(came_from), retry)
- return url
- return None
-
- # backward compatible alias
- getLoginURL = getUnauthorizedURL
-
security.declarePublic('logout')
- def logout(self):
- '''
- Logs out the user and redirects to the logout page.
- '''
- # XXX: this method violates the rules for tools/utilities:
- # it depends on self.REQUEST
- req = self.REQUEST
- resp = req['RESPONSE']
- method = self.getCookieMethod( 'expireAuthCookie'
- , self.defaultExpireAuthCookie )
- method( resp, cookie_name=self.auth_cookie )
- if self.logout_page:
- page = self.restrictedTraverse(self.logout_page, None)
- if page is not None:
- resp.redirect('%s?disable_cookie_login__=1'
- % page.absolute_url())
- return ''
- # We should not normally get here.
- return 'Logged out.'
+ def logout(self, response=None):
+ """
+ Logs out the user
+ """
+ target = None
+ if response is None:
+ response = self.REQUEST['RESPONSE'] # BBB for App.Management
+ atool = getToolByName(self, 'portal_actions')
+ target = atool.getActionInfo('user/logout')['url']
+ method = self.getCookieMethod('expireAuthCookie',
+ self.defaultExpireAuthCookie)
+ method(response, cookie_name=self.auth_cookie)
+ # BBB for App.Management
+ if target is not None:
+ response.redirect(target)
security.declarePublic('propertyLabel')
def propertyLabel(self, id):
@@ -427,39 +320,15 @@
handle = ob.meta_type + '/' + ob.getId()
BeforeTraverse.unregisterBeforeTraverse(event.oldParent, handle)
-class ResponseCleanup:
- def __init__(self, resp):
- self.resp = resp
- def __del__(self):
- # Free the references.
- #
- # No errors of any sort may propagate, and we don't care *what*
- # they are, even to log them.
- try:
- del self.resp.unauthorized
- except:
- pass
- try:
- del self.resp._unauthorized
- except:
- pass
- try:
- del self.resp
- except:
- pass
-
-
manage_addCCForm = HTMLFile('dtml/addCC', globals())
manage_addCCForm.__name__ = 'addCC'
-def manage_addCC(dispatcher, id, create_forms=0, REQUEST=None):
+def manage_addCC(dispatcher, id, REQUEST=None):
' '
ob = CookieCrumbler()
ob.id = id
dispatcher._setObject(ob.getId(), ob)
ob = getattr(dispatcher.this(), ob.getId())
- if create_forms:
- _create_forms(ob)
if REQUEST is not None:
return dispatcher.manage_main(dispatcher, REQUEST)
Modified: Products.CMFCore/trunk/Products/CMFCore/MembershipTool.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/MembershipTool.py 2010-06-15 09:29:26 UTC (rev 113476)
+++ Products.CMFCore/trunk/Products/CMFCore/MembershipTool.py 2010-06-15 10:16:49 UTC (rev 113477)
@@ -335,11 +335,12 @@
name = user.getUserName()
# this really does need to be the user name, and not the user id,
# because we're dealing with authentication credentials
- p = getattr(REQUEST, '_credentials_changed_path', None)
- if p is not None:
- # Use an interface provided by CookieCrumbler.
- change = self.restrictedTraverse(p)
- change(user, name, password)
+ try:
+ cctool = getToolByName(self, 'cookie_authentication')
+ cctool.credentialsChanged(user, name, password, REQUEST)
+ except AttributeError:
+ # No CookieCrumbler
+ pass
security.declareProtected(ManageUsers, 'getMemberById')
def getMemberById(self, id):
Modified: Products.CMFCore/trunk/Products/CMFCore/dtml/addCC.dtml
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/dtml/addCC.dtml 2010-06-15 09:29:26 UTC (rev 113476)
+++ Products.CMFCore/trunk/Products/CMFCore/dtml/addCC.dtml 2010-06-15 10:16:49 UTC (rev 113477)
@@ -21,22 +21,10 @@
<input type="text" name="id" size="40" />
</td>
</tr>
-<!--
<tr>
<td align="left" valign="top">
- <div class="form-label"><label for="cb_createpages">
- Create login_form and logged_out DTML methods
- </label></div>
</td>
<td align="left" valign="top">
- <input type="checkbox" name="create_pages" value="1" id="cb_createpages" />
- </td>
- </tr>
--->
- <tr>
- <td align="left" valign="top">
- </td>
- <td align="left" valign="top">
<div class="form-element">
<input class="form-element" type="submit" name="submit"
value=" Add " />
Modified: Products.CMFCore/trunk/Products/CMFCore/exportimport/cookieauth.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/exportimport/cookieauth.py 2010-06-15 09:29:26 UTC (rev 113476)
+++ Products.CMFCore/trunk/Products/CMFCore/exportimport/cookieauth.py 2010-06-15 10:16:49 UTC (rev 113477)
@@ -53,11 +53,23 @@
if self.environ.shouldPurge():
self._purgeProperties()
+ self._migrateProperties(node)
self._initProperties(node)
self._logger.info('Cookie crumbler imported.')
+ def _migrateProperties(self, node):
+ # BBB: for CMF 2.2 settings
+ for child in node.childNodes:
+ if child.nodeName != 'property':
+ continue
+ if child.getAttribute('name') not in ('auto_login_page',
+ 'unauth_page', 'logout_page'):
+ continue
+ node.removeChild(child)
+ child.unlink()
+
def importCookieCrumbler(context):
"""Import cookie crumbler settings from an XML file.
"""
Modified: Products.CMFCore/trunk/Products/CMFCore/exportimport/tests/test_cookieauth.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/exportimport/tests/test_cookieauth.py 2010-06-15 09:29:26 UTC (rev 113476)
+++ Products.CMFCore/trunk/Products/CMFCore/exportimport/tests/test_cookieauth.py 2010-06-15 10:16:49 UTC (rev 113477)
@@ -35,9 +35,6 @@
<property name="name_cookie">__ac_name</property>
<property name="pw_cookie">__ac_password</property>
<property name="persist_cookie">__ac_persistent</property>
- <property name="auto_login_page">login_form</property>
- <property name="logout_page">logged_out</property>
- <property name="unauth_page"></property>
<property name="local_cookie_path">False</property>
<property name="cache_header_value">private</property>
<property name="log_username">True</property>
@@ -51,9 +48,6 @@
<property name="name_cookie">__ac_name</property>
<property name="pw_cookie">__ac_password</property>
<property name="persist_cookie">__ac_persistent</property>
- <property name="auto_login_page">login_form</property>
- <property name="logout_page">logged_out</property>
- <property name="unauth_page"></property>
<property name="local_cookie_path">False</property>
<property name="cache_header_value">private</property>
<property name="log_username">True</property>
@@ -67,6 +61,19 @@
<property name="name_cookie">value3</property>
<property name="pw_cookie">value5</property>
<property name="persist_cookie">value4</property>
+ <property name="local_cookie_path">True</property>
+ <property name="cache_header_value">value2</property>
+ <property name="log_username">False</property>
+</object>
+"""
+
+_CMF22_IMPORT = """\
+<?xml version="1.0"?>
+<object name="foo_cookiecrumbler" meta_type="Cookie Crumbler">
+ <property name="auth_cookie">value1</property>
+ <property name="name_cookie">value3</property>
+ <property name="pw_cookie">value5</property>
+ <property name="persist_cookie">value4</property>
<property name="auto_login_page">value6</property>
<property name="logout_page">value8</property>
<property name="unauth_page">value7</property>
@@ -107,9 +114,6 @@
cc.persist_cookie = 'value4'
cc.pw_cookie = 'value5'
cc.local_cookie_path = 1
- cc.auto_login_page = 'value6'
- cc.unauth_page = 'value7'
- cc.logout_page = 'value8'
return site
@@ -169,11 +173,27 @@
self.assertEqual( cc.persist_cookie, 'value4' )
self.assertEqual( cc.pw_cookie, 'value5' )
self.assertEqual( cc.local_cookie_path, 1 )
- self.assertEqual( cc.auto_login_page, 'value6' )
- self.assertEqual( cc.unauth_page, 'value7' )
- self.assertEqual( cc.logout_page, 'value8' )
+ def test_migration(self):
+ from Products.CMFCore.exportimport.cookieauth \
+ import importCookieCrumbler
+ site = self._initSite()
+ cc = site.cookie_authentication
+
+ context = DummyImportContext(site)
+ context._files['cookieauth.xml'] = _CMF22_IMPORT
+ importCookieCrumbler(context)
+
+ self.assertEqual( cc.auth_cookie, 'value1' )
+ self.assertEqual( cc.cache_header_value, 'value2' )
+ self.assertEqual( cc.name_cookie, 'value3' )
+ self.assertEqual( cc.log_username, 0 )
+ self.assertEqual( cc.persist_cookie, 'value4' )
+ self.assertEqual( cc.pw_cookie, 'value5' )
+ self.assertEqual( cc.local_cookie_path, 1 )
+
+
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(CookieCrumblerXMLAdapterTests),
Modified: Products.CMFCore/trunk/Products/CMFCore/interfaces/_cookieCrumbler.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/interfaces/_cookieCrumbler.py 2010-06-15 09:29:26 UTC (rev 113476)
+++ Products.CMFCore/trunk/Products/CMFCore/interfaces/_cookieCrumbler.py 2010-06-15 10:16:49 UTC (rev 113477)
@@ -28,9 +28,9 @@
the parent URL if local_cookie_path is True otherwise /"""
return path
- def getCookieMethod(name, default=None):
- """ Allow overridable cookie set/expiration methods."""
- return getattr(name, default)
+ def getCookieMethod(name, default):
+ """Get the cookie handler.
+ The cookie handler maybe overridden by acquisition."""
def defaultSetAuthCookie(resp, cookie_name, cookie_value):
"""Set the authorisation cookie"""
@@ -55,30 +55,16 @@
def __call__(container, req):
"""The __before_publishing_traverse__ hook."""
- def credentialsChanged(user, name, pw):
- """# XXX: this method violates the rules for tools/utilities:
- # it depends on self.REQUEST """
-
- def _cleanupResponse():
- """# XXX: this method violates the rules for tools/utilities:
- # it depends on self.REQUEST"""
-
- def unauthorized():
- """Remove authentication cookies and redirect to standard unauthorized"""
-
- def _unauthorized():
- """Remove authentication cookies and redirect to standard _unauthorized"""
-
- def getUnauthorizedURL():
+ def credentialsChanged(user, name, pw, request):
"""
- Redirects to the login page.
+ Updates cookie credentials if user details are changed.
"""
- def logout():
- """
- Logs out the user and redirects to the logout page.
- """
-
def propertyLabel(id):
"""Return a label for the given property id
- """
\ No newline at end of file
+ """
+
+ def logout(response):
+ """
+ Deprecated
+ Log the user out"""
Modified: Products.CMFCore/trunk/Products/CMFCore/tests/test_CookieCrumbler.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/tests/test_CookieCrumbler.py 2010-06-15 09:29:26 UTC (rev 113476)
+++ Products.CMFCore/trunk/Products/CMFCore/tests/test_CookieCrumbler.py 2010-06-15 10:16:49 UTC (rev 113477)
@@ -18,8 +18,9 @@
import unittest
import Testing
-from zope.app.testing.placelesssetup import PlacelessSetup
+from zope.component import eventtesting
from zope.interface.verify import verifyClass
+from zope.testing.cleanup import cleanUp
def makerequest(root, stdout, stdin=None):
# Customized version of Testing.makerequest.makerequest()
@@ -39,7 +40,7 @@
return req
-class CookieCrumblerTests(unittest.TestCase, PlacelessSetup):
+class CookieCrumblerTests(unittest.TestCase):
def _getTargetClass(self):
from Products.CMFCore.CookieCrumbler import CookieCrumbler
@@ -54,9 +55,9 @@
from Products.CMFCore.interfaces import ICookieCrumbler
from Products.CMFCore.CookieCrumbler import handleCookieCrumblerEvent
- PlacelessSetup.setUp(self)
self._finally = None
+ eventtesting.setUp()
provideHandler(handleCookieCrumblerEvent,
adapts=(ICookieCrumbler, IObjectEvent))
@@ -67,7 +68,7 @@
self._finally()
noSecurityManager()
- PlacelessSetup.tearDown(self)
+ cleanUp()
def _makeSite(self):
import base64
@@ -172,71 +173,6 @@
req.traverse('/')
self.failIf( req.has_key('__ac'))
- def testAutoLoginRedirection(self):
- # Redirect unauthorized anonymous users to the login page
- from Products.CMFCore.CookieCrumbler import Redirect
-
- root, cc, req, credentials = self._makeSite()
- self.assertRaises(Redirect, req.traverse, '/protected')
-
- def testDisabledAutoLoginRedirection(self):
- # When disable_cookie_login__ is set, don't redirect.
- from zExceptions.unauthorized import Unauthorized
-
- root, cc, req, credentials = self._makeSite()
- req['disable_cookie_login__'] = 1
- self.assertRaises(Unauthorized, req.traverse, '/protected')
-
-
- def testNoRedirectAfterAuthenticated(self):
- # Don't redirect already-authenticated users to the login page,
- # even when they try to access things they can't get.
- from zExceptions.unauthorized import Unauthorized
-
- root, cc, req, credentials = self._makeSite()
- req.cookies['__ac'] = credentials
- self.assertRaises(Unauthorized, req.traverse, '/protected')
-
- def testRetryLogin(self):
- # After a failed login, CookieCrumbler should give the user an
- # opportunity to try to log in again.
- from Products.CMFCore.CookieCrumbler import Redirect
-
- root, cc, req, credentials = self._makeSite()
- req.cookies['__ac_name'] = 'israel'
- req.cookies['__ac_password'] = 'pass-w'
- try:
- req.traverse('/protected')
- except Redirect, s:
- # Test passed
- if hasattr(s, 'args'):
- s = s.args[0]
- self.failUnless(s.find('came_from=') >= 0)
- self.failUnless(s.find('retry=1') >= 0)
- self.failUnless(s.find('disable_cookie_login__=1') >= 0)
- else:
- self.fail('Did not redirect')
-
-
- def testLoginRestoresQueryString(self):
- # When redirecting for login, the came_from form field should
- # include the submitted URL as well as the query string.
- import urllib
- from Products.CMFCore.CookieCrumbler import Redirect
-
- root, cc, req, credentials = self._makeSite()
- req['PATH_INFO'] = '/protected'
- req['QUERY_STRING'] = 'a:int=1&x:string=y'
- try:
- req.traverse('/protected')
- except Redirect, s:
- if hasattr(s, 'args'):
- s = s.args[0]
- to_find = urllib.quote('/protected?' + req['QUERY_STRING'])
- self.failUnless(s.find(to_find) >= 0, s)
- else:
- self.fail('Did not redirect')
-
def testCacheHeaderAnonymous(self):
# Should not set cache-control
root, cc, req, credentials = self._makeSite()
@@ -270,68 +206,6 @@
self.assertEqual(
req.response.headers.get('cache-control', ''), '')
- def testDisableLoginDoesNotPreventPasswordShredding(self):
- # Even if disable_cookie_login__ is set, read the cookies
- # anyway to avoid revealing the password to the app.
- # (disable_cookie_login__ does not mean disable cookie
- # authentication, it only means disable the automatic redirect
- # to the login page.)
- root, cc, req, credentials = self._makeSite()
- req.cookies['__ac_name'] = 'abraham'
- req.cookies['__ac_password'] = 'pass-w'
- req['disable_cookie_login__'] = 1
- req.traverse('/')
- self.assertEqual(req['AUTHENTICATED_USER'].getUserName(),
- 'abraham')
- # Here is the real test: the password should have been shredded.
- self.failIf( req.has_key('__ac_password'))
-
- def testDisableLoginDoesNotPreventPasswordShredding2(self):
- root, cc, req, credentials = self._makeSite()
- req.cookies['__ac'] = credentials
- req['disable_cookie_login__'] = 1
- req.traverse('/')
- self.assertEqual(req['AUTHENTICATED_USER'].getUserName(),
- 'abraham')
- self.failIf( req.has_key('__ac'))
-
- def testMidApplicationAutoLoginRedirection(self):
- # Redirect anonymous users to login page if Unauthorized
- # occurs in the middle of the app
- from zExceptions.unauthorized import Unauthorized
-
- root, cc, req, credentials = self._makeSite()
- req.traverse('/')
- try:
- raise Unauthorized
- except:
- req.response.exception()
- self.assertEqual(req.response.status, 302)
-
- def testMidApplicationAuthenticationButUnauthorized(self):
- # Don't redirect already-authenticated users to the login page,
- # even when Unauthorized happens in the middle of the app.
- from zExceptions.unauthorized import Unauthorized
-
- root, cc, req, credentials = self._makeSite()
- req.cookies['__ac'] = credentials
- req.traverse('/')
- try:
- raise Unauthorized
- except:
- req.response.exception()
- self.assertEqual(req.response.status, 401)
-
- def testRedirectOnUnauthorized(self):
- # Redirect already-authenticated users to the unauthorized
- # handler page if that's what the sysadmin really wants.
- from Products.CMFCore.CookieCrumbler import Redirect
-
- root, cc, req, credentials = self._makeSite()
- cc.unauth_page = 'login_form'
- req.cookies['__ac'] = credentials
- self.assertRaises(Redirect, req.traverse, '/protected')
-
def testLoginRatherThanResume(self):
# When the user presents both a session resume and new
# credentials, choose the new credentials (so that it's
More information about the checkins
mailing list