summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-06-25 07:07:55 +0000
committerChris McDonough <chrism@agendaless.com>2009-06-25 07:07:55 +0000
commit3bef31e78563997ecaec0bf6bf1715ce66f5605b (patch)
treed06c219460f741aea3abf4faa798a0c025df6057
parent27d23ae34362f20ff1504bc80b941b18d472b9e3 (diff)
downloadpyramid-3bef31e78563997ecaec0bf6bf1715ce66f5605b.tar.gz
pyramid-3bef31e78563997ecaec0bf6bf1715ce66f5605b.tar.bz2
pyramid-3bef31e78563997ecaec0bf6bf1715ce66f5605b.zip
- Add optional ``max_age`` keyword value to the ``remember`` method of
``repoze.bfg.authentication.AuthTktAuthenticationPolicy``; if this value is passed to ``remember``, the generated cookie will have a corresponding Max-Age value.
-rw-r--r--CHANGES.txt8
-rw-r--r--repoze/bfg/authentication.py34
-rw-r--r--repoze/bfg/tests/test_authentication.py38
3 files changed, 70 insertions, 10 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 45ba8752c..783349c81 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,6 +1,14 @@
Next release
============
+Features
+--------
+
+- Add optional ``max_age`` keyword value to the ``remember`` method of
+ ``repoze.bfg.authentication.AuthTktAuthenticationPolicy``; if this
+ value is passed to ``remember``, the generated cookie will have a
+ corresponding Max-Age value.
+
Documentation
-------------
diff --git a/repoze/bfg/authentication.py b/repoze/bfg/authentication.py
index 154934c45..90c6ca90b 100644
--- a/repoze/bfg/authentication.py
+++ b/repoze/bfg/authentication.py
@@ -1,3 +1,4 @@
+import datetime
import time
from codecs import utf_8_decode
@@ -226,7 +227,9 @@ class AuthTktAuthenticationPolicy(CallbackAuthenticationPolicy):
return result['userid']
def remember(self, request, principal, **kw):
- return self.cookie.remember(request, principal)
+ """ Accepts the following kw args: ``tokens``, ``userdata``,
+ ``max_age``."""
+ return self.cookie.remember(request, principal, **kw)
def forget(self, request):
return self.cookie.forget(request)
@@ -298,16 +301,27 @@ class AuthTktCookieHelper(object):
identity['userdata'] = user_data
return identity
- def _get_cookies(self, environ, value):
+ def _get_cookies(self, environ, value, max_age=None):
+ if max_age is not None:
+ later = datetime.datetime.now() + datetime.timedelta(
+ seconds=int(max_age))
+ # Wdy, DD-Mon-YY HH:MM:SS GMT
+ expires = later.strftime('%a, %d %b %Y %H:%M:%S')
+ # the Expires header is *required* at least for IE7 (IE7 does
+ # not respect Max-Age)
+ max_age = "; Max-Age=%s; Expires=%s" % (max_age, expires)
+ else:
+ max_age = ''
+
cur_domain = environ.get('HTTP_HOST', environ.get('SERVER_NAME'))
wild_domain = '.' + cur_domain
cookies = [
- ('Set-Cookie', '%s="%s"; Path=/' % (
- self.cookie_name, value)),
- ('Set-Cookie', '%s="%s"; Path=/; Domain=%s' % (
- self.cookie_name, value, cur_domain)),
- ('Set-Cookie', '%s="%s"; Path=/; Domain=%s' % (
- self.cookie_name, value, wild_domain))
+ ('Set-Cookie', '%s="%s"; Path=/%s' % (
+ self.cookie_name, value, max_age)),
+ ('Set-Cookie', '%s="%s"; Path=/; Domain=%s%s' % (
+ self.cookie_name, value, cur_domain, max_age)),
+ ('Set-Cookie', '%s="%s"; Path=/; Domain=%s%s' % (
+ self.cookie_name, value, wild_domain, max_age))
]
return cookies
@@ -318,7 +332,7 @@ class AuthTktCookieHelper(object):
return self._get_cookies(environ, '""')
# IIdentifier
- def remember(self, request, userid, tokens='', userdata=''):
+ def remember(self, request, userid, tokens='', userdata='', max_age=None):
environ = request.environ
if self.include_ip:
remote_addr = environ['REMOTE_ADDR']
@@ -368,5 +382,5 @@ class AuthTktCookieHelper(object):
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, new_cookie_value, max_age)
diff --git a/repoze/bfg/tests/test_authentication.py b/repoze/bfg/tests/test_authentication.py
index 2032f53c3..12ecb6b16 100644
--- a/repoze/bfg/tests/test_authentication.py
+++ b/repoze/bfg/tests/test_authentication.py
@@ -248,6 +248,13 @@ class TestAutkTktAuthenticationPolicy(unittest.TestCase):
policy = self._makeOne(None, None)
result = policy.remember(request, 'fred')
self.assertEqual(result, [])
+
+ def test_remember_with_extra_kargs(self):
+ request = DummyRequest({})
+ policy = self._makeOne(None, None)
+ result = policy.remember(request, 'fred', a=1, b=2)
+ self.assertEqual(policy.cookie.kw, {'a':1, 'b':2})
+ self.assertEqual(result, [])
def test_forget(self):
request = DummyRequest({})
@@ -491,6 +498,36 @@ class TestAuthTktCookieHelper(unittest.TestCase):
('Set-Cookie',
'auth_tkt="%s"; Path=/' % new_val))
+ def test_remember_max_age(self):
+ plugin = self._makeOne('secret')
+ environ = {'HTTP_HOST':'example.com'}
+ tkt = self._makeTicket(userid='chris', userdata='')
+ request = self._makeRequest(environ)
+ result = plugin.remember(request, 'chris', max_age='500')
+
+ name,value = result.pop(0)
+ self.assertEqual('Set-Cookie', name)
+ self.failUnless(
+ value.startswith('auth_tkt="%s"; Path=/; Max-Age=500' % tkt),
+ value)
+ self.failUnless('; Expires=' in value)
+
+ name,value = result.pop(0)
+ self.assertEqual('Set-Cookie', name)
+ self.failUnless(
+ value.startswith(
+ 'auth_tkt="%s"; Path=/; Domain=example.com; Max-Age=500'
+ % tkt), value)
+ self.failUnless('; Expires=' in value)
+
+ name,value = result.pop(0)
+ self.assertEqual('Set-Cookie', name)
+ self.failUnless(
+ value.startswith(
+ 'auth_tkt="%s"; Path=/; Domain=.example.com; Max-Age=500' % tkt),
+ value)
+ self.failUnless('; Expires=' in value)
+
def test_forget(self):
plugin = self._makeOne('secret')
request = self._makeRequest()
@@ -546,6 +583,7 @@ class DummyCookieHelper:
return self.result
def remember(self, *arg, **kw):
+ self.kw = kw
return []
def forget(self, *arg):