Paul Johnston <paul....@gmail.com> added the comment:
Ok, I've produced a patch for this, let me know what you think.
----------
status: unread -> chatting
__________________________________
Repoze Bugs <b...@bugs.repoze.org>
<http://bugs.repoze.org/issue83>
__________________________________
Index: repoze/who/plugins/tests/test_authtkt.py
===================================================================
--- repoze/who/plugins/tests/test_authtkt.py (revision 5195)
+++ repoze/who/plugins/tests/test_authtkt.py (working copy)
@@ -29,7 +29,8 @@
def _makeTicket(self, userid='userid', remote_addr='0.0.0.0',
tokens = [], userdata='userdata',
- cookie_name='auth_tkt', secure=False):
+ cookie_name='auth_tkt', secure=False,
+ time=None):
from paste.auth import auth_tkt
ticket = auth_tkt.AuthTicket(
'secret',
@@ -37,6 +38,7 @@
remote_addr,
tokens=tokens,
user_data=userdata,
+ time=time,
cookie_name=cookie_name,
secure=secure)
return ticket.cookie_value()
@@ -115,6 +117,14 @@
result = plugin.identify(environ)
self.assertEqual(result, None)
+ def test_identify_bad_cookie_expired(self):
+ import time
+ plugin = self._makeOne('secret', timeout=2, reissue_time=1)
+ val = self._makeTicket(userid='userid', time=time.time()-3)
+ environ = self._makeEnviron({'HTTP_COOKIE':'auth_tkt=%s' % val})
+ result = plugin.identify(environ)
+ self.assertEqual(result, None)
+
def test_remember_creds_same(self):
plugin = self._makeOne('secret')
val = self._makeTicket(userid='userid')
@@ -250,6 +260,20 @@
('Set-Cookie',
'auth_tkt="%s"; Path=/' % new_val))
+ def test_remember_creds_reissue(self):
+ import time
+ plugin = self._makeOne('secret', reissue_time=1)
+ old_val = self._makeTicket(userid='userid', userdata='', time=time.time()-2)
+ environ = self._makeEnviron({'HTTP_COOKIE':'auth_tkt=%s' % old_val})
+ new_val = self._makeTicket(userid='userid', userdata='')
+ result = plugin.remember(environ, {'repoze.who.userid':'userid',
+ 'userdata':''})
+ self.assertEqual(type(result[0][1]), str)
+ self.assertEqual(len(result), 3)
+ self.assertEqual(result[0],
+ ('Set-Cookie',
+ 'auth_tkt="%s"; Path=/' % new_val))
+
def test_forget(self):
plugin = self._makeOne('secret')
environ = self._makeEnviron()
@@ -301,3 +325,9 @@
plugin = make_plugin(secretfile=path)
self.assertEqual(plugin.secret, 's33kr1t')
+ def test_timeout_reissue(self):
+ try:
+ self._makeOne('userid', timeout=1)
+ self.assertEqual(1, 2)
+ except ValueError, e:
+ pass
Index: repoze/who/plugins/auth_tkt.py
===================================================================
--- repoze/who/plugins/auth_tkt.py (revision 5195)
+++ repoze/who/plugins/auth_tkt.py (working copy)
@@ -1,6 +1,7 @@
from codecs import utf_8_decode
from codecs import utf_8_encode
import os
+import time
from paste.request import get_cookies
from paste.auth import auth_tkt
@@ -25,11 +26,17 @@
}
def __init__(self, secret, cookie_name='auth_tkt',
- secure=False, include_ip=False):
+ secure=False, include_ip=False,
+ timeout=None, reissue_time=None):
self.secret = secret
self.cookie_name = cookie_name
self.include_ip = include_ip
self.secure = secure
+ if timeout and (not reissue_time or reissue_time > timeout):
+ raise ValueError('When timeout is specified, reissue_time must '
+ 'be set to a lower value')
+ self.timeout = timeout
+ self.reissue_time = reissue_time
# IIdentifier
def identify(self, environ):
@@ -50,6 +57,9 @@
except auth_tkt.BadTicket:
return None
+ if self.timeout and timestamp + self.timeout < time.time():
+ return None
+
userid_typename = 'userid_type:'
user_data_info = user_data.split('|')
for datum in filter(None, user_data_info):
@@ -126,7 +136,8 @@
old_data = (userid, tokens, userdata)
new_data = (who_userid, who_tokens, who_userdata)
- if old_data != new_data:
+ if old_data != new_data or (self.reissue_time and
+ timestamp + self.reissue_time < time.time()):
ticket = auth_tkt.AuthTicket(
self.secret,
who_userid,
@@ -157,6 +168,8 @@
cookie_name='auth_tkt',
secure=False,
include_ip=False,
+ timeout=None,
+ reissue_time=None,
):
if (secret is None and secretfile is None):
raise ValueError("One of 'secret' or 'secretfile' must not be None.")
@@ -168,6 +181,8 @@
raise ValueError("No such 'secretfile': %s" % secretfile)
secret = open(secretfile).read().strip()
plugin = AuthTktCookiePlugin(secret, cookie_name,
- _bool(secure), _bool(include_ip))
+ _bool(secure), _bool(include_ip),
+ timeout and int(timeout),
+ reissue_time and int(reissue_time))
return plugin
Index: docs/narr.rst
===================================================================
--- docs/narr.rst (revision 5195)
+++ docs/narr.rst (working copy)
@@ -212,7 +212,7 @@
.. module:: repoze.who.plugins.auth_tkt
-.. class:: AuthTktCookiePlugin(secret [, cookie_name='auth_tkt' [, secure=False [, include_ip=False]]])
+.. class:: AuthTktCookiePlugin(secret [, cookie_name='auth_tkt' [, secure=False [, include_ip=False [, timeout=None [, reissue_time=None]]]]])
An :class:`AuthTktCookiePlugin` is an ``IIdentifier`` plugin which
remembers its identity state in a client-side cookie. This plugin
@@ -224,7 +224,12 @@
will be sent across any HTTP or HTTPS connection; if it is True, the
cookie will be sent only across an HTTPS connection. If
*include_ip* is True, the ``REMOTE_ADDR`` of the WSGI environment
- will be placed in the cookie.
+ will be placed in the cookie. If *timeout* is specfied, it is the
+ maximum age in seconds allowed for a cookie. If *reissue_time* is
+ specified, when we encounter a cookie that is older than the reissue
+ time (in seconds), but younger that the timeout, a new cookie will
+ be issued. If *timeout* is specified, you must also set
+ *reissue_time* to a lower value.
.. note::
Using the *include_ip* setting for public-facing applications may
_______________________________________________
Repoze-dev mailing list
Repoze-dev@lists.repoze.org
http://lists.repoze.org/listinfo/repoze-dev