On Sun, 2009-03-29 at 20:27:50 +0200, Gustavo Narea wrote:
> I think it'd be a useful feature for AuthTktCookiePlugin, but in the
> mean time you can also create your own IIdentifier which adds this
> functionality:
> 
> """
> from zope.interface import implements
> from repoze.who.interfaces import IIdentifier
> 
> class TimeOutIdentifierPlugin(object)
>     implements(IIdentifier)
> 
>     def __init__(the arguments):
>         ...
> 
>     def identify(self, environ):
>         if session_timed_out():
>             environ['repoze.who.application'] = HTTPUnauthorized()
> """
> 
> So, basically you have to change the __init__ method and finally
> replace session_timed_out() with your own callable. The rest of the
> class should work as is.
> 
> Then pass it to repoze.what:
> 
> """
> timeout_plugin = TimeOutIdentifierPlugin()
> identifiers = [('timeout', timeout_plugin)]
> app = add_auth(..., identifiers=identifiers, ...)
> """

Thanks for your idea, I've played with it a bit, but in the end wasn't
keen with the fact that I was using Beaker session provided by Pylons to
save access time (also this is not safe in the terms of security, but
could be solved probably).  Eventually I've dug into AuthTktCookiePlugin
code to understand how it works and was pleasantly surprised to find the
basis for implementing session timeout (the timestamp value in the
cookie).  The patch with modifications I've done is attached (it is
backwards compatible).  For the time being I'm going to monkey-patch
AuthTktCookiePlugin in the project I'm working on, but it would be
really great for my patch to get merged with repoze.who and support
added for repoze.what-quickstart.  I guess there are more people besides
me who need this.

-- 
Audrius Kažukauskas
--- auth_tkt.py 2009-04-06 18:12:19.000000000 +0300
+++ auth_tkt.py.new     2009-04-06 19:49:03.000000000 +0300
@@ -8,6 +8,9 @@
 
 from repoze.who.interfaces import IIdentifier
 
+import time
+
+
 class AuthTktCookiePlugin(object):
 
     implements(IIdentifier)
@@ -24,11 +27,12 @@
         }
     
     def __init__(self, secret, cookie_name='auth_tkt',
-                 secure=False, include_ip=False):
+                 secure=False, include_ip=False, timeout=None):
         self.secret = secret
         self.cookie_name = cookie_name
         self.include_ip = include_ip
         self.secure = secure
+        self.timeout = timeout
 
     # IIdentifier
     def identify(self, environ):
@@ -49,6 +53,11 @@
         except auth_tkt.BadTicket:
             return None
 
+        if self.timeout is not None:
+            # Session expired
+            if timestamp + self.timeout*60 < int(time.time()):
+                return
+
         userid_typename = 'userid_type:'
         user_data_info = user_data.split('|')
         for datum in filter(None, user_data_info):
@@ -127,7 +136,27 @@
         old_data = (userid, tokens, userdata)
         new_data = (who_userid, who_tokens, who_userdata)
 
-        if old_data != new_data:
+        if self.timeout is None:
+            if old_data != new_data:
+                ticket = auth_tkt.AuthTicket(
+                    self.secret,
+                    who_userid,
+                    remote_addr,
+                    tokens=who_tokens,
+                    user_data=who_userdata,
+                    cookie_name=self.cookie_name,
+                    secure=self.secure)
+                new_cookie_value = ticket.cookie_value()
+
+                # XXX Do we need this?
+                #cur_domain = environ.get('HTTP_HOST',
+                #                         environ.get('SERVER_NAME'))
+                #wild_domain = '.' + cur_domain
+                if old_cookie_value != new_cookie_value:
+                    # return a set of Set-Cookie headers
+                    return self._get_cookies(environ, new_cookie_value)
+        # Set new cookie if at least a minute has passed from the last time
+        elif timestamp is None or timestamp + 60 < int(time.time()):
             ticket = auth_tkt.AuthTicket(
                 self.secret,
                 who_userid,
@@ -136,13 +165,7 @@
                 user_data=who_userdata,
                 cookie_name=self.cookie_name,
                 secure=self.secure)
-            new_cookie_value = ticket.cookie_value()
-            
-            cur_domain = environ.get('HTTP_HOST', environ.get('SERVER_NAME'))
-            wild_domain = '.' + cur_domain
-            if old_cookie_value != new_cookie_value:
-                # return a set of Set-Cookie headers
-                return self._get_cookies(environ, new_cookie_value)
+            return self._get_cookies(environ, ticket.cookie_value())
 
     def __repr__(self):
         return '<%s %s>' % (self.__class__.__name__, id(self))

Attachment: pgphtscwtSTbF.pgp
Description: PGP signature

_______________________________________________
Repoze-dev mailing list
Repoze-dev@lists.repoze.org
http://lists.repoze.org/listinfo/repoze-dev

Reply via email to