Fixed #21363 -- Added datetime.timedelta support to TimestampSigner.unsign().

This commit is contained in:
Berker Peksag 2014-11-15 12:03:04 +02:00 committed by Tim Graham
parent fa680ce1e2
commit d2d6c0c097
4 changed files with 25 additions and 2 deletions

View File

@ -36,6 +36,7 @@ These functions make use of all of them.
from __future__ import unicode_literals from __future__ import unicode_literals
import base64 import base64
import datetime
import json import json
import time import time
import zlib import zlib
@ -192,6 +193,8 @@ class TimestampSigner(Signer):
value, timestamp = result.rsplit(self.sep, 1) value, timestamp = result.rsplit(self.sep, 1)
timestamp = baseconv.base62.decode(timestamp) timestamp = baseconv.base62.decode(timestamp)
if max_age is not None: if max_age is not None:
if isinstance(max_age, datetime.timedelta):
max_age = max_age.total_seconds()
# Check timestamp is not older than max_age # Check timestamp is not older than max_age
age = time.time() - timestamp age = time.time() - timestamp
if age > max_age: if age > max_age:

View File

@ -186,6 +186,13 @@ Cache
* The ``incr()`` method of the * The ``incr()`` method of the
``django.core.cache.backends.locmem.LocMemCache`` backend is now thread-safe. ``django.core.cache.backends.locmem.LocMemCache`` backend is now thread-safe.
Cryptography
^^^^^^^^^^^^
* The ``max_age`` parameter of the
:meth:`django.core.signing.TimestampSigner.unsign` method now also accept a
:py:class:`datetime.timedelta` object.
Database backends Database backends
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^

View File

@ -114,6 +114,7 @@ Verifying timestamped values
timestamp to the value. This allows you to confirm that a signed value was timestamp to the value. This allows you to confirm that a signed value was
created within a specified period of time:: created within a specified period of time::
>>> from datetime import timedelta
>>> from django.core.signing import TimestampSigner >>> from django.core.signing import TimestampSigner
>>> signer = TimestampSigner() >>> signer = TimestampSigner()
>>> value = signer.sign('hello') >>> value = signer.sign('hello')
@ -126,6 +127,8 @@ created within a specified period of time::
SignatureExpired: Signature age 15.5289158821 > 10 seconds SignatureExpired: Signature age 15.5289158821 > 10 seconds
>>> signer.unsign(value, max_age=20) >>> signer.unsign(value, max_age=20)
'hello' 'hello'
>>> signer.unsign(value, max_age=timedelta(seconds=20))
'hello'
.. class:: TimestampSigner(key=None, sep=':', salt=None) .. class:: TimestampSigner(key=None, sep=':', salt=None)
@ -136,7 +139,12 @@ created within a specified period of time::
.. method:: unsign(value, max_age=None) .. method:: unsign(value, max_age=None)
Checks if ``value`` was signed less than ``max_age`` seconds ago, Checks if ``value`` was signed less than ``max_age`` seconds ago,
otherwise raises ``SignatureExpired``. otherwise raises ``SignatureExpired``. The ``max_age`` parameter can
accept an integer or a :py:class:`datetime.timedelta` object.
.. versionchanged:: 1.8
Previously, the ``max_age`` parameter only accepted an integer.
Protecting complex data structures Protecting complex data structures
---------------------------------- ----------------------------------

View File

@ -1,5 +1,6 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime
import time import time
from django.core import signing from django.core import signing
@ -126,9 +127,13 @@ class TestTimestampSigner(TestCase):
self.assertEqual(signer.unsign(ts), value) self.assertEqual(signer.unsign(ts), value)
time.time = lambda: 123456800 time.time = lambda: 123456800
self.assertEqual(signer.unsign(ts, max_age=13), value)
self.assertEqual(signer.unsign(ts, max_age=12), value) self.assertEqual(signer.unsign(ts, max_age=12), value)
self.assertEqual(signer.unsign(ts, max_age=11), value) # max_age parameter can also accept a datetime.timedelta object
self.assertEqual(signer.unsign(ts, max_age=datetime.timedelta(seconds=11)), value)
self.assertRaises( self.assertRaises(
signing.SignatureExpired, signer.unsign, ts, max_age=10) signing.SignatureExpired, signer.unsign, ts, max_age=10)
with self.assertRaises(signing.SignatureExpired):
self.assertEqual(signer.unsign(ts, max_age=datetime.timedelta(seconds=10)), value)
finally: finally:
time.time = _time time.time = _time