Fixed #16182: Increase timestamp precision on TimestampSigner. Thanks to Eric Florenzano.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16356 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
66436ad171
commit
44a2cbad35
|
@ -158,8 +158,12 @@ class Signer(object):
|
||||||
|
|
||||||
|
|
||||||
class TimestampSigner(Signer):
|
class TimestampSigner(Signer):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.time_func = kwargs.pop('time', time.time)
|
||||||
|
super(TimestampSigner, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def timestamp(self):
|
def timestamp(self):
|
||||||
return baseconv.base62.encode(int(time.time()))
|
return baseconv.base62.encode(int(self.time_func() * 10000))
|
||||||
|
|
||||||
def sign(self, value):
|
def sign(self, value):
|
||||||
value = smart_str('%s%s%s' % (value, self.sep, self.timestamp()))
|
value = smart_str('%s%s%s' % (value, self.sep, self.timestamp()))
|
||||||
|
@ -168,10 +172,10 @@ class TimestampSigner(Signer):
|
||||||
def unsign(self, value, max_age=None):
|
def unsign(self, value, max_age=None):
|
||||||
result = super(TimestampSigner, self).unsign(value)
|
result = super(TimestampSigner, self).unsign(value)
|
||||||
value, timestamp = result.rsplit(self.sep, 1)
|
value, timestamp = result.rsplit(self.sep, 1)
|
||||||
timestamp = baseconv.base62.decode(timestamp)
|
timestamp = baseconv.base62.decode(timestamp) / 10000.0
|
||||||
if max_age is not None:
|
if max_age is not None:
|
||||||
# Check timestamp is not older than max_age
|
# Check timestamp is not older than max_age
|
||||||
age = time.time() - timestamp
|
age = self.time_func() - timestamp
|
||||||
if age > max_age:
|
if age > max_age:
|
||||||
raise SignatureExpired(
|
raise SignatureExpired(
|
||||||
'Signature age %s > %s seconds' % (age, max_age))
|
'Signature age %s > %s seconds' % (age, max_age))
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import time
|
|
||||||
|
|
||||||
from django.core import signing
|
from django.core import signing
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.utils.encoding import force_unicode
|
from django.utils.encoding import force_unicode
|
||||||
|
@ -98,19 +96,21 @@ class TestTimestampSigner(TestCase):
|
||||||
|
|
||||||
def test_timestamp_signer(self):
|
def test_timestamp_signer(self):
|
||||||
value = u'hello'
|
value = u'hello'
|
||||||
_time = time.time
|
signer = signing.TimestampSigner('predictable-key',
|
||||||
time.time = lambda: 123456789
|
time=lambda: 123456789)
|
||||||
try:
|
ts = signer.sign(value)
|
||||||
signer = signing.TimestampSigner('predictable-key')
|
self.assertNotEqual(ts,
|
||||||
ts = signer.sign(value)
|
signing.Signer('predictable-key').sign(value))
|
||||||
self.assertNotEqual(ts,
|
|
||||||
signing.Signer('predictable-key').sign(value))
|
|
||||||
|
|
||||||
self.assertEqual(signer.unsign(ts), value)
|
self.assertEqual(signer.unsign(ts), value)
|
||||||
time.time = lambda: 123456800
|
signer = signing.TimestampSigner('predictable-key',
|
||||||
self.assertEqual(signer.unsign(ts, max_age=12), value)
|
time=lambda: 123456800)
|
||||||
self.assertEqual(signer.unsign(ts, max_age=11), value)
|
self.assertEqual(signer.unsign(ts, max_age=12), value)
|
||||||
self.assertRaises(
|
self.assertEqual(signer.unsign(ts, max_age=11), value)
|
||||||
signing.SignatureExpired, signer.unsign, ts, max_age=10)
|
self.assertRaises(
|
||||||
finally:
|
signing.SignatureExpired, signer.unsign, ts, max_age=10)
|
||||||
time.time = _time
|
|
||||||
|
def test_timestamp_precision(self):
|
||||||
|
one = signing.TimestampSigner('key', time=lambda: 123.4567).sign('v')
|
||||||
|
two = signing.TimestampSigner('key', time=lambda: 123.4568).sign('v')
|
||||||
|
self.assertNotEqual(one, two)
|
||||||
|
|
Loading…
Reference in New Issue