Explorar el Código

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

Berker Peksag hace 10 años
padre
commit
d2d6c0c097
Se han modificado 4 ficheros con 25 adiciones y 2 borrados
  1. 3 0
      django/core/signing.py
  2. 7 0
      docs/releases/1.8.txt
  3. 9 1
      docs/topics/signing.txt
  4. 6 1
      tests/signing/tests.py

+ 3 - 0
django/core/signing.py

@@ -36,6 +36,7 @@ These functions make use of all of them.
 from __future__ import unicode_literals
 
 import base64
+import datetime
 import json
 import time
 import zlib
@@ -192,6 +193,8 @@ class TimestampSigner(Signer):
         value, timestamp = result.rsplit(self.sep, 1)
         timestamp = baseconv.base62.decode(timestamp)
         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
             age = time.time() - timestamp
             if age > max_age:

+ 7 - 0
docs/releases/1.8.txt

@@ -186,6 +186,13 @@ Cache
 * The ``incr()`` method of the
   ``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
 ^^^^^^^^^^^^^^^^^
 

+ 9 - 1
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')
@@ -126,6 +127,8 @@ created within a specified period of time::
     SignatureExpired: Signature age 15.5289158821 > 10 seconds
     >>> signer.unsign(value, max_age=20)
     'hello'
+    >>> signer.unsign(value, max_age=timedelta(seconds=20))
+    'hello'
 
 .. class:: TimestampSigner(key=None, sep=':', salt=None)
 
@@ -136,7 +139,12 @@ 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``.
+        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
 ----------------------------------

+ 6 - 1
tests/signing/tests.py

@@ -1,5 +1,6 @@
 from __future__ import unicode_literals
 
+import datetime
 import time
 
 from django.core import signing
@@ -126,9 +127,13 @@ class TestTimestampSigner(TestCase):
 
             self.assertEqual(signer.unsign(ts), value)
             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=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(
                 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:
             time.time = _time