[Zope-CMF] patch: CMFCore CookieCrumbler possible enhancements
Joseph Wayne Norton
norton@alum.mit.edu
Wed, 19 Sep 2001 12:54:56 +0900
Hello.
I have modified my copy of CookieCrumbler and would like to know if
the following changes would be of interest to others and/or
incorporated into the CookieCrumbler product.
1) The cookie path is dynamically calculated from the
CookieCrumbler's container object. This works much nicer when you
are using virtual hosting and moving a CMF site from different
staging (development,test,production,etc.) areas within your zope
environment.
2) I added a auto logout page handler (simliar to the auto_login
page). By adding this handler, a zope user that has already been
authenticated (has a _auth cookie) but is deleted (or
inactivated) will be automatically logged out rather than having the
browser's basic authentication popup to appear and to ask for a new
username/password.
I'm not using this feature with CMF but with another application that
creates session-based zope users. This modification is helpful for
better handling of the session (and zope user) expiration event.
regards,
- joe n
Index: CMFCore/CookieCrumbler.py
===================================================================
RCS file: /cvs-repository/CMF/CMFCore/CookieCrumbler.py,v
retrieving revision 1.8
diff -r1.8 CookieCrumbler.py
131a132,133
> {'id':'auto_logout_page', 'type': 'string', 'mode':'w',
> 'label':'Auto-logout page ID'},
140a143
> auto_logout_page = 'logout'
155a159,167
> def getCookiePath( self ):
> iself = getattr(self, 'aq_inner', self)
> parent = getattr(iself, 'aq_parent', None)
> if parent:
> return '/' + parent.absolute_url(1)
> else:
> return '/'
>
> security.declarePrivate('getCookieMethod')
161c173
< resp.setCookie( cookie_name, cookie_value, path='/')
---
> resp.setCookie( cookie_name, cookie_value, path=self.getCookiePath())
165c177
< resp.expireCookie( cookie_name, path='/')
---
> resp.expireCookie( cookie_name, path=self.getCookiePath())
192c204
< resp.setCookie(self.name_cookie, name, path='/',
---
> resp.setCookie(self.name_cookie, name, path=self.getCookiePath(),
196c208
< resp.expireCookie(self.name_cookie, path='/')
---
> resp.expireCookie(self.name_cookie, path=self.getCookiePath())
238a251,258
> if self.auto_logout_page:
> page = getattr(container, self.auto_logout_page, None)
> if page is not None:
> # Provide a logout page.
> req._hold(ResponseCleanup(resp))
> resp.unauthorized = self.unauthorized_logout
> resp._unauthorized = self._unauthorized_logout
>
285a306,343
> if page:
> retry = getattr(resp, '_auth', 0) and '1' or ''
> url = '%s?came_from=%s&retry=%s' % (
> page.absolute_url(), quote(req['URL']), retry)
> return url
> return None
>
> security.declarePrivate('unauthorized_logout')
> def unauthorized_logout(self):
> url = self.getLogoutURL()
> if url:
> raise 'Redirect', url
> # Use the standard unauthorized() call.
> resp = self._cleanupResponse()
> resp.unauthorized()
>
> def _unauthorized_logout(self):
> url = self.getLogoutURL()
> if url:
> resp = self.REQUEST['RESPONSE']
> resp.redirect(url, lock=1)
> # We don't need to raise an exception.
> return
> # Use the standard _unauthorized() call.
> resp = self._cleanupResponse()
> resp._unauthorized()
>
> security.declarePublic('getLogoutURL')
> def getLogoutURL(self):
> '''
> Redirects to the logout page.
> '''
> if self.auto_login_page:
> req = self.REQUEST
> resp = req['RESPONSE']
> iself = getattr(self, 'aq_inner', self)
> parent = getattr(iself, 'aq_parent', None)
> page = getattr(parent, 'logout', None)