summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2014-02-27 16:54:04 -0500
committerMichael Merickel <michael@merickel.org>2014-02-27 16:54:04 -0500
commit551e8c69a90883072b905c5b2eb19fd50fa53535 (patch)
treef97b8201b43c4ab86b7e6022048d2d177ff9f78e
parent89dc4659eedfe75bada6d131722fbb00f1bbc49f (diff)
parentb2dd47336c200bbbfea31526f85652226c335687 (diff)
downloadpyramid-551e8c69a90883072b905c5b2eb19fd50fa53535.tar.gz
pyramid-551e8c69a90883072b905c5b2eb19fd50fa53535.tar.bz2
pyramid-551e8c69a90883072b905c5b2eb19fd50fa53535.zip
Merge branch 'fix.1247'
-rw-r--r--pyramid/session.py48
-rw-r--r--pyramid/tests/test_session.py25
2 files changed, 53 insertions, 20 deletions
diff --git a/pyramid/session.py b/pyramid/session.py
index 9fe2add60..56d99e9de 100644
--- a/pyramid/session.py
+++ b/pyramid/session.py
@@ -27,8 +27,9 @@ def manage_accessed(wrapped):
method is called."""
def accessed(session, *arg, **kw):
session.accessed = now = int(time.time())
- if now - session.renewed > session._reissue_time:
- session.changed()
+ if session._reissue_time is not None:
+ if now - session.renewed > session._reissue_time:
+ session.changed()
return wrapped(session, *arg, **kw)
accessed.__doc__ = wrapped.__doc__
return accessed
@@ -165,10 +166,10 @@ def BaseCookieSessionFactory(
Parameters:
``serializer``
- An object with two methods: ``loads`` and ``dumps``. The ``loads`` method
- should accept bytes and return a Python object. The ``dumps`` method
- should accept a Python object and return bytes. A ``ValueError`` should
- be raised for malformed inputs.
+ An object with two methods: ``loads`` and ``dumps``. The ``loads``
+ method should accept bytes and return a Python object. The ``dumps``
+ method should accept a Python object and return bytes. A ``ValueError``
+ should be raised for malformed inputs.
``cookie_name``
The name of the cookie used for sessioning. Default: ``'session'``.
@@ -256,17 +257,24 @@ def BaseCookieSessionFactory(
if value is not None:
try:
- renewed, created, state = value
+ # since the value is not necessarily signed, we have
+ # to unpack it a little carefully
+ rval, cval, sval = value
+ renewed = float(rval)
+ created = float(cval)
+ state = sval
new = False
- if now - renewed > self._timeout:
- # expire the session because it was not renewed
- # before the timeout threshold
- state = {}
- except TypeError:
+ except (TypeError, ValueError):
# value failed to unpack properly or renewed was not
# a numeric type so we'll fail deserialization here
state = {}
+ if self._timeout is not None:
+ if now - renewed > self._timeout:
+ # expire the session because it was not renewed
+ # before the timeout threshold
+ state = {}
+
self.created = created
self.accessed = renewed
self.renewed = renewed
@@ -473,8 +481,8 @@ def UnencryptedCookieSessionFactoryConfig(
deprecated(
'UnencryptedCookieSessionFactoryConfig',
'The UnencryptedCookieSessionFactoryConfig callable is deprecated as of '
- 'Pyramid 1.5. Use ``pyramid.session.SignedCookieSessionFactory`` instead. '
- 'Caveat: Cookies generated using SignedCookieSessionFactory are not '
+ 'Pyramid 1.5. Use ``pyramid.session.SignedCookieSessionFactory`` instead.'
+ ' Caveat: Cookies generated using SignedCookieSessionFactory are not '
'compatible with cookies generated using UnencryptedCookieSessionFactory, '
'so existing user session data will be destroyed if you switch to it.'
)
@@ -578,11 +586,11 @@ def SignedCookieSessionFactory(
while rendering a view. Default: ``True``.
``serializer``
- An object with two methods: ``loads`` and ``dumps``. The ``loads`` method
- should accept bytes and return a Python object. The ``dumps`` method
- should accept a Python object and return bytes. A ``ValueError`` should
- be raised for malformed inputs. If a serializer is not passed, the
- :class:`pyramid.session.PickleSerializer` serializer will be used.
+ An object with two methods: ``loads`` and ``dumps``. The ``loads``
+ method should accept bytes and return a Python object. The ``dumps``
+ method should accept a Python object and return bytes. A ``ValueError``
+ should be raised for malformed inputs. If a serializer is not passed,
+ the :class:`pyramid.session.PickleSerializer` serializer will be used.
.. versionadded: 1.5a3
"""
@@ -591,7 +599,7 @@ def SignedCookieSessionFactory(
signed_serializer = SignedSerializer(
secret,
- salt,
+ salt,
hashalg,
serializer=serializer,
)
diff --git a/pyramid/tests/test_session.py b/pyramid/tests/test_session.py
index 1ad0729b3..1aaa7a2ba 100644
--- a/pyramid/tests/test_session.py
+++ b/pyramid/tests/test_session.py
@@ -52,6 +52,15 @@ class SharedCookieSessionTests(object):
session = self._makeOne(request, timeout=1)
self.assertEqual(dict(session), {})
+ def test_timeout_never(self):
+ import time
+ request = testing.DummyRequest()
+ LONG_TIME = 31536000
+ cookieval = self._serialize((time.time() + LONG_TIME, 0, {'state': 1}))
+ request.cookies['session'] = cookieval
+ session = self._makeOne(request, timeout=None)
+ self.assertEqual(dict(session), {'state': 1})
+
def test_changed(self):
request = testing.DummyRequest()
session = self._makeOne(request)
@@ -279,6 +288,14 @@ class TestBaseCookieSession(SharedCookieSessionTests, unittest.TestCase):
self.assertEqual(session['state'], 1)
self.assertFalse(session._dirty)
+ def test_reissue_never(self):
+ request = testing.DummyRequest()
+ cookieval = self._serialize((0, 0, {'state': 1}))
+ request.cookies['session'] = cookieval
+ session = self._makeOne(request, reissue_time=None, timeout=None)
+ self.assertEqual(session['state'], 1)
+ self.assertFalse(session._dirty)
+
class TestSignedCookieSession(SharedCookieSessionTests, unittest.TestCase):
def _makeOne(self, request, **kw):
from pyramid.session import SignedCookieSessionFactory
@@ -305,6 +322,14 @@ class TestSignedCookieSession(SharedCookieSessionTests, unittest.TestCase):
self.assertEqual(session['state'], 1)
self.assertFalse(session._dirty)
+ def test_reissue_never(self):
+ request = testing.DummyRequest()
+ cookieval = self._serialize((0, 0, {'state': 1}))
+ request.cookies['session'] = cookieval
+ session = self._makeOne(request, reissue_time=None, timeout=None)
+ self.assertEqual(session['state'], 1)
+ self.assertFalse(session._dirty)
+
def test_custom_salt(self):
import time
request = testing.DummyRequest()