Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fixed #21363 - TimestampSigner.unsign accepts a timedelta #1835

Closed
wants to merge 1 commit into from

3 participants

docs/topics/signing.txt
@@ -121,10 +121,11 @@ created within a specified period of time::
'hello:1NMg5H:oPVuCqlJWmChm1rA2lyTUtelC-c'
>>> signer.unsign(value)
u'hello'
- >>> signer.unsign(value, max_age=10)
+ >>> import datetime
@bmispelon Collaborator

To tidy things up a bit, you could move the import to the top of the example and also import timedelta directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@bmispelon bmispelon commented on the diff
tests/signing/tests.py
((11 lines not shown))
finally:
time.time = _time
+
+ def test_seconds(self):
@bmispelon Collaborator

Adding a comment here about the deprecation will make it easier to come and remove the feature when the time comes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@gavinwahl gavinwahl Fixed #21363 - TimestampSigner.unsign accepts a timedelta
Using a number of seconds for `max_age` is deprecated.
ccb0c80
@gavinwahl

Thanks for the review, I fixed those issues.

@timgraham
Owner

Per the discussion in the ticket, this has been rejected in its current form.

@timgraham timgraham closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 31, 2013
  1. @gavinwahl

    Fixed #21363 - TimestampSigner.unsign accepts a timedelta

    gavinwahl authored
    Using a number of seconds for `max_age` is deprecated.
This page is out of date. Refresh to see the latest.
View
10 django/core/signing.py
@@ -36,8 +36,10 @@
from __future__ import unicode_literals
import base64
+import datetime
import json
import time
+import warnings
import zlib
from django.conf import settings
@@ -191,9 +193,13 @@ def unsign(self, value, max_age=None):
value, timestamp = result.rsplit(self.sep, 1)
timestamp = baseconv.base62.decode(timestamp)
if max_age is not None:
+ if not isinstance(max_age, datetime.timedelta):
+ warnings.warn("Using a number of seconds for `max_age` is deprecated, "
+ "use a timedelta instead.", PendingDeprecationWarning, 2)
+ max_age = datetime.timedelta(seconds=max_age)
# Check timestamp is not older than max_age
- age = time.time() - timestamp
+ age = datetime.datetime.fromtimestamp(time.time()) - datetime.datetime.fromtimestamp(timestamp)
if age > max_age:
raise SignatureExpired(
- 'Signature age %s > %s seconds' % (age, max_age))
+ 'Signature age %s > %s' % (age, max_age))
return value
View
4 docs/internals/deprecation.txt
@@ -476,6 +476,10 @@ these changes.
* The class ``django.utils.datastructures.MergeDict`` will be removed.
+* The ``max_age`` parameter of
+ :meth:`django.core.signing.TimestampSigner.unsign` will no longer accept a
+ number of seconds.
+
2.0
---
View
6 docs/releases/1.7.txt
@@ -690,3 +690,9 @@ deprecated and will be removed in Django 1.9.
arguments into a ``REQUEST`` property on ``WSGIRequest``. To merge
dictionaries, use ``dict.update()`` instead. The class ``MergeDict`` is
deprecated and will be removed in Django 1.9.
+
+Change to the ``max_age`` parameter of :meth:`TimestampSigner.unsign<django.core.signing.TimestampSigner.unsign>`
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Passing a number of seconds to ``unsign`` as the ``max_age`` has been
+deprecated. Use a :class:`datetime.timedelta<python:datetime.timedelta>`
+instead.
View
13 docs/topics/signing.txt
@@ -114,6 +114,7 @@ Verifying timestamped values
timestamp to the value. This allows you to confirm that a signed value was
created within a specified period of time::
+ >>> from datetime import timedelta
>>> from django.core.signing import TimestampSigner
>>> signer = TimestampSigner()
>>> value = signer.sign('hello')
@@ -121,10 +122,10 @@ created within a specified period of time::
'hello:1NMg5H:oPVuCqlJWmChm1rA2lyTUtelC-c'
>>> signer.unsign(value)
u'hello'
- >>> signer.unsign(value, max_age=10)
+ >>> signer.unsign(value, max_age=timedelta(seconds=10))
...
- SignatureExpired: Signature age 15.5289158821 > 10 seconds
- >>> signer.unsign(value, max_age=20)
+ SignatureExpired: Signature age 0:00:15.978808 > 0:00:10
+ >>> signer.unsign(value, max_age=timedelta(seconds=20))
u'hello'
.. class:: TimestampSigner(key=None, sep=':', salt=None)
@@ -135,8 +136,10 @@ created within a specified period of time::
.. method:: unsign(value, max_age=None)
- Checks if ``value`` was signed less than ``max_age`` seconds ago,
- otherwise raises ``SignatureExpired``.
+ Checks if ``value`` was signed less than ``max_age`` ago, otherwise
+ raises ``django.core.signing.SignatureExpired``. The ``max_age``
+ parameter should be a
+ :class:`datetime.timedelta<python:datetime.timedelta>` object.
Protecting complex data structures
----------------------------------
View
22 tests/signing/tests.py
@@ -1,6 +1,8 @@
from __future__ import unicode_literals
+import datetime
import time
+import warnings
from django.core import signing
from django.test import TestCase
@@ -107,7 +109,10 @@ def test_decode_detects_tampering(self):
class TestTimestampSigner(TestCase):
- def test_timestamp_signer(self):
+ def run_test_timestamp_signer(self, timedelta_fn):
+ # we need to run the same test with an number of seconds and with a
+ # timedelta, so timedelta_fn takes a number of seconds and converts it
+ # to the value to be used as max_age.
value = 'hello'
_time = time.time
time.time = lambda: 123456789
@@ -119,9 +124,18 @@ def test_timestamp_signer(self):
self.assertEqual(signer.unsign(ts), value)
time.time = lambda: 123456800
- self.assertEqual(signer.unsign(ts, max_age=12), value)
- self.assertEqual(signer.unsign(ts, max_age=11), value)
+ self.assertEqual(signer.unsign(ts, max_age=timedelta_fn(12)), value)
+ self.assertEqual(signer.unsign(ts, max_age=timedelta_fn(11)), value)
self.assertRaises(
- signing.SignatureExpired, signer.unsign, ts, max_age=10)
+ signing.SignatureExpired, signer.unsign, ts, max_age=timedelta_fn(10))
finally:
time.time = _time
+
+ def test_seconds(self):
@bmispelon Collaborator

Adding a comment here about the deprecation will make it easier to come and remove the feature when the time comes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ # deprecated, remove this in django 1.9
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter('always')
+ self.run_test_timestamp_signer(lambda s: s)
+
+ def test_timedelta(self):
+ self.run_test_timestamp_signer(lambda s: datetime.timedelta(seconds=s))
Something went wrong with that request. Please try again.