[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)