[Checkins] SVN: Products.CMFDefault/trunk/Products/CMFDefault/ - merged cookiecrumbler_with_views branch
Yvo Schubbe
y.2010 at wcm-solutions.de
Tue Jun 15 06:19:43 EDT 2010
Log message for revision 113478:
- merged cookiecrumbler_with_views branch
Changed:
U Products.CMFDefault/trunk/Products/CMFDefault/CHANGES.txt
U Products.CMFDefault/trunk/Products/CMFDefault/browser/authentication.py
U Products.CMFDefault/trunk/Products/CMFDefault/browser/configure.zcml
A Products.CMFDefault/trunk/Products/CMFDefault/browser/templates/forbidden.pt
A Products.CMFDefault/trunk/Products/CMFDefault/browser/templates/logged_out.pt
U Products.CMFDefault/trunk/Products/CMFDefault/browser/tests/authentication.txt
U Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/cookieauth.xml
U Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/metadata.xml
U Products.CMFDefault/trunk/Products/CMFDefault/skins/zpt_control/logout.py
U Products.CMFDefault/trunk/Products/CMFDefault/upgrade/configure.zcml
U Products.CMFDefault/trunk/Products/CMFDefault/upgrade/tests/test_upgrade.py
A Products.CMFDefault/trunk/Products/CMFDefault/upgrade/to23.py
-=-
Modified: Products.CMFDefault/trunk/Products/CMFDefault/CHANGES.txt
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/CHANGES.txt 2010-06-15 10:16:49 UTC (rev 113477)
+++ Products.CMFDefault/trunk/Products/CMFDefault/CHANGES.txt 2010-06-15 10:19:43 UTC (rev 113478)
@@ -4,6 +4,9 @@
2.3.0-alpha (unreleased)
------------------------
+- views: Added Unauthorized exception view.
+ This replaces CookieCrumbler's old redirect support.
+
- Deal with deprecation warnings for Zope 2.13.
- Use the standard libraries doctest module.
Modified: Products.CMFDefault/trunk/Products/CMFDefault/browser/authentication.py
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/authentication.py 2010-06-15 10:16:49 UTC (rev 113477)
+++ Products.CMFDefault/trunk/Products/CMFDefault/browser/authentication.py 2010-06-15 10:19:43 UTC (rev 113478)
@@ -15,7 +15,12 @@
$Id$
"""
+from urllib import quote
+
+from Products.Five import BrowserView
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+from zExceptions import Forbidden
+from zExceptions import Redirect
from zope.app.form.browser import TextWidget
from zope.formlib import form
from zope.interface import implements
@@ -23,15 +28,67 @@
from zope.schema import Bool
from zope.schema import Choice
from zope.schema import Password
+from zope.schema import TextLine
from zope.schema import URI
from zope.schema.interfaces import ISource
from zope.site.hooks import getSite
+from Products.CMFCore.CookieCrumbler import ATTEMPT_LOGIN
+from Products.CMFCore.CookieCrumbler import ATTEMPT_NONE
from Products.CMFCore.utils import getToolByName
from Products.CMFDefault.formlib.form import EditFormBase
from Products.CMFDefault.utils import Message as _
+from Products.CMFDefault.browser.utils import ViewBase, memoize
+def _expireAuthCookie(view):
+ try:
+ cctool = getToolByName(view, 'cookie_authentication')
+ method = cctool.getCookieMethod('expireAuthCookie',
+ cctool.defaultExpireAuthCookie)
+ method(view.request.response, cctool.auth_cookie)
+ except AttributeError:
+ view.request.response.expireCookie('__ac', path='/')
+
+
+class UnauthorizedView(BrowserView):
+
+ """Exception view for Unauthorized.
+ """
+
+ forbidden_template = ViewPageTemplateFile('templates/forbidden.pt')
+
+ def __call__(self):
+ try:
+ atool = getToolByName(self, 'portal_actions')
+ target = atool.getActionInfo('user/login')['url']
+ except (AttributeError, ValueError):
+ # re-raise the unhandled exception
+ raise self.context
+
+ req = self.request
+ attempt = getattr(req, '_cookie_auth', ATTEMPT_NONE)
+ if attempt not in (ATTEMPT_NONE, ATTEMPT_LOGIN):
+ # An authenticated user was denied access to something.
+ # XXX: hack context to get the right @@standard_macros/page
+ # why do we get the wrong without this hack?
+ self.context = self.__parent__
+ raise Forbidden(self.forbidden_template())
+
+ _expireAuthCookie(self)
+ 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' % (target, quote(came_from))
+ raise Redirect(url)
+
+
class NameSource(object):
implements(ISource)
@@ -58,10 +115,9 @@
came_from = URI(
required=False)
- name = Choice(
+ name = TextLine(
title=_(u'Member ID'),
- description=_(u'Member ID or email address'),
- source=available_names)
+ description=_(u'Case sensitive'))
password = Password(
title=_(u'Password'),
@@ -92,43 +148,55 @@
base_template = EditFormBase.template
template = ViewPageTemplateFile('templates/login.pt')
label = _(u'Log in')
+ prefix = ''
form_fields = form.FormFields(ILoginSchema)
- form_fields['name'].custom_widget = TextWidget
actions = form.Actions(
form.Action(
name='login',
label=_(u'Login'),
+ validator='handle_login_validate',
success='handle_login_success',
failure='handle_failure'))
def setUpWidgets(self, ignore_request=False):
- cctool = self._getTool('cookie_authentication')
- ac_name = self.request.get(cctool.name_cookie)
- if ac_name and not self.request.has_key('%s.name' % self.prefix):
- self.request.form['%s.name' % self.prefix] = ac_name
+ try:
+ cctool = self._getTool('cookie_authentication')
+ ac_name_id = cctool.name_cookie
+ ac_password_id = cctool.pw_cookie
+ ac_persistent_id = cctool.persist_cookie
+ except AttributeError:
+ ac_name_id = '__ac_name'
+ ac_password_id = '__ac_password'
+ ac_persistent_id = '__ac_persistent'
+ ac_name = self.request.get(ac_name_id)
+ if ac_name is not None:
+ self.request.form['name'] = ac_name
+ self.request.form[ac_name_id] = ac_name
+ ac_persistent = self.request.get(ac_persistent_id)
+ if ac_persistent is not None:
+ self.request.form['persistent'] = ac_persistent
+ ac_persistent_used = self.request.get("%s.used" % ac_persistent_id)
+ if ac_persistent_used is not None:
+ self.request.form['persistent.used'] = ac_persistent_used
super(LoginFormView,
self).setUpWidgets(ignore_request=ignore_request)
self.widgets['came_from'].hide = True
+ self.widgets['name'].name = ac_name_id
+ self.widgets['password'].name = ac_password_id
+ self.widgets['persistent'].name = ac_persistent_id
+ def handle_login_validate(self, action, data):
+ mtool = self._getTool('portal_membership')
+ if mtool.isAnonymousUser():
+ _expireAuthCookie(self)
+ return (_(u'Login failure'),)
+ return None
+
def handle_login_success(self, action, data):
- mtool = self._getTool('portal_membership')
- if not mtool.getMemberById(data['name']):
- candidates = mtool.searchMembers('email', data['name'])
- for candidate in candidates:
- if candidate['email'].lower() == data['name'].lower():
- data['name'] = candidate['username']
- break
- cctool = self._getTool('cookie_authentication')
- # logged_in uses default charset for decoding
- charset = self._getDefaultCharset()
- self.request.form[cctool.name_cookie] = data['name'].encode(charset)
- self.request.form[cctool.pw_cookie] = data['password'].encode(charset)
- self.request.form[cctool.persist_cookie] = data['persistent']
- cctool(self.context, self.request)
return self._setRedirect('portal_actions', 'user/logged_in',
- '%s.came_from' % self.prefix)
+ 'came_from')
class MailPasswordFormView(EditFormBase):
@@ -154,8 +222,12 @@
failure='handle_failure'))
def setUpWidgets(self, ignore_request=False):
- cctool = self._getTool('cookie_authentication')
- ac_name = self.request.get(cctool.name_cookie)
+ try:
+ cctool = self._getTool('cookie_authentication')
+ ac_name_id = cctool.name_cookie
+ except AttributeError:
+ ac_name_id = '__ac_name'
+ ac_name = self.request.get(ac_name_id)
if ac_name and not self.request.has_key('%s.name' % self.prefix):
self.request.form['%s.name' % self.prefix] = ac_name
super(MailPasswordFormView,
@@ -173,3 +245,32 @@
rtool.mailPassword(data['name'], self.request)
self.status = _(u'Your password has been mailed to you.')
return self._setRedirect('portal_actions', 'user/login')
+
+
+class Logout(ViewBase):
+ """Log the user out"""
+
+ @memoize
+ def logged_in(self):
+ """Check whether the user is (still logged in)"""
+ mtool = self._getTool('portal_membership')
+ return mtool.isAnonymousUser()
+
+ @memoize
+ def logout(self):
+ """Log the user out"""
+ _expireAuthCookie(self)
+
+ @memoize
+ def clear_skin_cookie(self):
+ """Remove skin cookie"""
+ stool = self._getTool('portal_skins')
+ stool.clearSkinCookie()
+
+ def __call__(self):
+ """Clear cookies and return the template"""
+ if not self.logged_in():
+ self.clear_skin_cookie()
+ self.logout()
+ return self.request.response.redirect(self.request.URL)
+ return super(Logout, self).__call__()
Modified: Products.CMFDefault/trunk/Products/CMFDefault/browser/configure.zcml
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/configure.zcml 2010-06-15 10:16:49 UTC (rev 113477)
+++ Products.CMFDefault/trunk/Products/CMFDefault/browser/configure.zcml 2010-06-15 10:19:43 UTC (rev 113478)
@@ -180,9 +180,26 @@
<browser:page
for="Products.CMFCore.interfaces.ISiteRoot"
layer="..interfaces.ICMFDefaultSkin"
+ name="logout.html"
+ class=".authentication.Logout"
+ template="templates/logged_out.pt"
+ permission="zope2.View"
+ />
+
+ <browser:page
+ for="Products.CMFCore.interfaces.ISiteRoot"
+ layer="..interfaces.ICMFDefaultSkin"
name="mail_password.html"
class=".authentication.MailPasswordFormView"
permission="zope2.View"
/>
+ <browser:page
+ for="zExceptions.Unauthorized"
+ layer="..interfaces.ICMFDefaultSkin"
+ name="index.html"
+ class=".authentication.UnauthorizedView"
+ permission="zope.Public"
+ />
+
</configure>
Copied: Products.CMFDefault/trunk/Products/CMFDefault/browser/templates/forbidden.pt (from rev 113475, Products.CMFDefault/branches/cookiecrumbler_with_views/Products/CMFDefault/browser/templates/forbidden.pt)
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/templates/forbidden.pt (rev 0)
+++ Products.CMFDefault/trunk/Products/CMFDefault/browser/templates/forbidden.pt 2010-06-15 10:19:43 UTC (rev 113478)
@@ -0,0 +1,18 @@
+<html metal:use-macro="context/@@standard_macros/page">
+<body>
+
+<metal:slot metal:fill-slot="body" i18n:domain="cmf_default">
+<h1 id="DesktopTitle">Site Error</h1>
+
+<p id="DesktopDescription" i18n:translate="">An error was encountered while
+ publishing this resource.</p>
+
+<p><strong><tal:span i18n:translate="">Error Type:</tal:span>
+ <tal:span i18n:translate="">Forbidden</tal:span></strong><br />
+ <strong><tal:span i18n:translate="">Error Value:</tal:span>
+ <tal:span i18n:translate="">You don't have all the permissions necessary
+ to see the requested page.</tal:span></strong></p>
+</metal:slot>
+
+</body>
+</html>
Copied: Products.CMFDefault/trunk/Products/CMFDefault/browser/templates/logged_out.pt (from rev 113475, Products.CMFDefault/branches/cookiecrumbler_with_views/Products/CMFDefault/browser/templates/logged_out.pt)
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/templates/logged_out.pt (rev 0)
+++ Products.CMFDefault/trunk/Products/CMFDefault/browser/templates/logged_out.pt 2010-06-15 10:19:43 UTC (rev 113478)
@@ -0,0 +1,13 @@
+<html metal:use-macro="context/@@standard_macros/page">
+<body>
+
+<metal:slot metal:fill-slot="body" i18n:domain="cmf_default">
+<p tal:condition="view/logged_in"
+ i18n:translate="">You have been logged out.</p>
+<p tal:condition="not: view/logged_in"
+ i18n:translate="">You are logged in outside the portal. You may need to
+<a href="/manage_zmi_logout">log out of the Zope management interface</a>.</p>
+</metal:slot>
+
+</body>
+</html>
Modified: Products.CMFDefault/trunk/Products/CMFDefault/browser/tests/authentication.txt
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/tests/authentication.txt 2010-06-15 10:16:49 UTC (rev 113477)
+++ Products.CMFDefault/trunk/Products/CMFDefault/browser/tests/authentication.txt 2010-06-15 10:19:43 UTC (rev 113478)
@@ -3,8 +3,10 @@
Set up user.
+ >>> from urllib import quote
>>> uf = app.site.acl_users
- >>> uf._doAddUser('mgr', 'mgrpw', ['Manager'], [])
+ >>> uf._doAddUser('mbr', 'mbrpw', ['Member'], [])
+ >>> mbr_credentials = quote('mbr:mbrpw'.encode('base64').rstrip())
Create the browser object we'll be using.
@@ -13,9 +15,73 @@
... from Testing.testbrowser import Browser
... except ImportError:
... from Products.Five.testbrowser import Browser
+ >>> browser = Browser()
+ >>> # XXX: browser has no API for disabling redirects
+ >>> browser.mech_browser.set_handle_redirect(False)
+The view for zExceptions.Unauthorized redirects anonymous requests to the
+login_form. This works if raised by the object (here by the reconfig_form).
+
+ >>> browser.open('http://localhost/site/reconfig_form')
+ Traceback (most recent call last):
+ ...
+ HTTPError: HTTP Error 302: Moved Temporarily
+ >>> browser.contents
+ ''
+ >>> browser.headers['Location']
+ 'http://localhost/site/login_form?came_from=http%3A//localhost/site/reconfig_form'
+
+And it works if raised by BaseRequest.traverse (here caused by manage_main).
+
+ >>> browser.open('http://localhost/site/manage_main')
+ Traceback (most recent call last):
+ ...
+ HTTPError: HTTP Error 302: Moved Temporarily
+ >>> browser.contents
+ ''
+ >>> browser.headers['Location']
+ 'http://localhost/site/login_form?came_from=http%3A//localhost/site/manage_main'
+
+Same redirect with a query string. The query string is preserved.
+
+ >>> browser.open('http://localhost/site/manage_main?a:int=1&x:string=y')
+ Traceback (most recent call last):
+ ...
+ HTTPError: HTTP Error 302: Moved Temporarily
+ >>> browser.contents
+ ''
+ >>> browser.headers['Location']
+ 'http://localhost/site/login_form?came_from=http%3A//localhost/site/manage_main%3Fa%3Aint%3D1%26x%3Astring%3Dy'
+ >>> quote('manage_main?a:int=1&x:string=y') in browser.headers['Location']
+ True
+
+And requests are redirected to the login_form if a login attempt fails.
+
+ >>> browser.post('http://localhost/site/manage_main',
+ ... '__ac_name=mbr&__ac_password=wrong')
+ Traceback (most recent call last):
+ ...
+ HTTPError: HTTP Error 302: Moved Temporarily
+ >>> browser.contents
+ ''
+ >>> browser.headers['Location']
+ 'http://localhost/site/login_form?came_from=http%3A//localhost/site/manage_main'
+
+The view for zExceptions.Unauthorized shows a Forbidden error if logged in.
+
+ >>> browser.cookies['__ac'] = '%s' % mbr_credentials
+ >>> browser.open('http://localhost/site/manage_main')
+ Traceback (most recent call last):
+ ...
+ HTTPError: HTTP Error 403: Forbidden
+ >>> 'zpt_stylesheet.css' in browser.contents
+ True
+ >>> '[[cmf_default][Forbidden]]' in browser.contents
+ True
+
+For the following examples we have to reset the browser object.
+
>>> browser = Browser()
- >>> browser.handleErrors = False
Use the login form without input.
@@ -33,28 +99,34 @@
>>> browser.getControl('[[cmf_default][Login]]').click()
>>> '[[zope][There were errors]]' in browser.contents
True
- >>> '[[zope][Constraint not satisfied]]' in browser.contents
+ >>> '[[cmf_default][Login failure]]' in browser.contents
True
Use the login form with valid input but wrong password.
>>> browser.open('http://localhost/site/@@login.html')
- >>> browser.getControl('[[cmf_default][Member ID]]').value = 'mgr'
+ >>> browser.getControl('[[cmf_default][Member ID]]').value = 'mbr'
>>> browser.getControl('[[cmf_default][Password]]').value = 'wrong'
>>> browser.getControl('[[cmf_default][Remember my ID.]]').selected = False
>>> browser.getControl('[[cmf_default][Login]]').click()
+ >>> '[[zope][There were errors]]' in browser.contents
+ True
>>> '[[cmf_default][Login failure]]' in browser.contents
True
+ >>> '__ac' not in browser.cookies
+ True
Use the login form with valid input and correct password.
>>> browser.open('http://localhost/site/@@login.html')
- >>> browser.getControl('[[cmf_default][Member ID]]').value = 'mgr'
- >>> browser.getControl('[[cmf_default][Password]]').value = 'mgrpw'
+ >>> browser.getControl('[[cmf_default][Member ID]]').value = 'mbr'
+ >>> browser.getControl('[[cmf_default][Password]]').value = 'mbrpw'
>>> browser.getControl('[[cmf_default][Remember my ID.]]').selected = False
>>> browser.getControl('[[cmf_default][Login]]').click()
>>> '[[cmf_default][Login success]]' in browser.contents
True
+ >>> browser.cookies['__ac'] == '"%s"' % mbr_credentials
+ True
Use the mail password form without input.
@@ -74,3 +146,14 @@
True
>>> '[[zope][Constraint not satisfied]]' in browser.contents
True
+
+Log the user in and then out
+ >>> browser.open('http://localhost/site/@@login.html')
+ >>> browser.getControl('[[cmf_default][Member ID]]').value = 'mbr'
+ >>> browser.getControl('[[cmf_default][Password]]').value = 'mbrpw'
+ >>> browser.getControl('[[cmf_default][Login]]').click()
+ >>> '[[cmf_default][Login success]]' in browser.contents
+ True
+ >>> browser.open('http://localhost/site/@@logout.html')
+ >>> '[cmf_default][You have been logged out.' in browser.contents
+ True
\ No newline at end of file
Modified: Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/cookieauth.xml
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/cookieauth.xml 2010-06-15 10:16:49 UTC (rev 113477)
+++ Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/cookieauth.xml 2010-06-15 10:19:43 UTC (rev 113478)
@@ -4,9 +4,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>
Modified: Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/metadata.xml
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/metadata.xml 2010-06-15 10:16:49 UTC (rev 113477)
+++ Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/metadata.xml 2010-06-15 10:19:43 UTC (rev 113478)
@@ -1,4 +1,4 @@
<?xml version="1.0"?>
<metadata>
- <version>2.2</version>
+ <version>2.3</version>
</metadata>
Modified: Products.CMFDefault/trunk/Products/CMFDefault/skins/zpt_control/logout.py
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/skins/zpt_control/logout.py 2010-06-15 10:16:49 UTC (rev 113477)
+++ Products.CMFDefault/trunk/Products/CMFDefault/skins/zpt_control/logout.py 2010-06-15 10:19:43 UTC (rev 113478)
@@ -1,8 +1,17 @@
## Script (Python) "logout"
##title=Logout handler
##parameters=
+from Products.CMFCore.utils import getToolByName
+
+stool = getToolByName(context, 'portal_skins')
+utool = getToolByName(context, 'portal_url')
REQUEST = context.REQUEST
-if REQUEST.has_key('portal_skin'):
- context.portal_skins.clearSkinCookie()
-REQUEST.RESPONSE.expireCookie('__ac', path='/')
-return REQUEST.RESPONSE.redirect(REQUEST.URL1+'/logged_out')
+
+stool.clearSkinCookie()
+try:
+ cctool = getToolByName(context, 'cookie_authentication')
+ cctool.logout(REQUEST.RESPONSE)
+except AttributeError:
+ REQUEST.RESPONSE.expireCookie('__ac', path='/')
+
+return REQUEST.RESPONSE.redirect(utool() + '/logged_out')
Modified: Products.CMFDefault/trunk/Products/CMFDefault/upgrade/configure.zcml
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/upgrade/configure.zcml 2010-06-15 10:16:49 UTC (rev 113477)
+++ Products.CMFDefault/trunk/Products/CMFDefault/upgrade/configure.zcml 2010-06-15 10:19:43 UTC (rev 113478)
@@ -181,4 +181,28 @@
sortkey="6"
/>
+ <genericsetup:upgradeSteps
+ source="2.2"
+ destination="2.3"
+ profile="Products.CMFDefault:default"
+ sortkey="7">
+
+ <genericsetup:upgradeStep
+ title="Upgrade cookie crumbler"
+ description="Remove obsolete cookie crumbler properties."
+ handler=".to23.upgrade_cookie_crumbler"
+ checker=".to23.check_cookie_crumbler"
+ />
+
+ </genericsetup:upgradeSteps>
+
+ <genericsetup:upgradeStep
+ title="Mark 2.3 upgrade as finished"
+ source="2.2"
+ destination="2.3"
+ profile="Products.CMFDefault:default"
+ handler=".mark_as_finished"
+ sortkey="8"
+ />
+
</configure>
Modified: Products.CMFDefault/trunk/Products/CMFDefault/upgrade/tests/test_upgrade.py
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/upgrade/tests/test_upgrade.py 2010-06-15 10:16:49 UTC (rev 113477)
+++ Products.CMFDefault/trunk/Products/CMFDefault/upgrade/tests/test_upgrade.py 2010-06-15 10:19:43 UTC (rev 113478)
@@ -70,7 +70,7 @@
stool.manage_doUpgrades(request)
self.assertEqual(stool.getLastVersionForProfile(profile_id),
- ('2', '2'))
+ ('2', '3'))
newSecurityManager(None, UnrestrictedUser('god', '', ['Manager'], ''))
setSite(self.app.site)
Copied: Products.CMFDefault/trunk/Products/CMFDefault/upgrade/to23.py (from rev 113475, Products.CMFDefault/branches/cookiecrumbler_with_views/Products/CMFDefault/upgrade/to23.py)
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/upgrade/to23.py (rev 0)
+++ Products.CMFDefault/trunk/Products/CMFDefault/upgrade/to23.py 2010-06-15 10:19:43 UTC (rev 113478)
@@ -0,0 +1,47 @@
+##############################################################################
+#
+# Copyright (c) 2010 Zope Foundation and Contributors.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Upgrade steps to CMFDefault 2.3.
+
+$Id$
+"""
+import logging
+
+from Acquisition import aq_base
+from Products.CMFCore.utils import getToolByName
+
+_MARKER = object()
+
+def check_cookie_crumbler(tool):
+ """2.2.x to 2.3.0 upgrade step checker
+ """
+ cctool = getToolByName(tool, 'cookie_authentication', None)
+ if cctool is None:
+ return False
+ cctool = aq_base(cctool)
+ for name in ('auto_login_page', 'unauth_page', 'logout_page'):
+ if getattr(cctool, name, _MARKER) is not _MARKER:
+ return True
+ return False
+
+def upgrade_cookie_crumbler(tool):
+ """2.2.x to 2.3.0 upgrade step handler
+ """
+ logger = logging.getLogger('GenericSetup.upgrade')
+ cctool = getToolByName(tool, 'cookie_authentication', None)
+ if cctool is None:
+ return
+ cctool = aq_base(cctool)
+ for name in ('auto_login_page', 'unauth_page', 'logout_page'):
+ if getattr(cctool, name, _MARKER) is not _MARKER:
+ delattr(cctool, name)
+ logger.info("Cookie crumbler property '%s' removed." % name)
More information about the checkins
mailing list