tests.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import time
  2. from django.core import signing
  3. from django.test import TestCase
  4. from django.utils.encoding import force_unicode
  5. class TestSigner(TestCase):
  6. def test_signature(self):
  7. "signature() method should generate a signature"
  8. signer = signing.Signer('predictable-secret')
  9. signer2 = signing.Signer('predictable-secret2')
  10. for s in (
  11. 'hello',
  12. '3098247:529:087:',
  13. u'\u2019'.encode('utf8'),
  14. ):
  15. self.assertEqual(
  16. signer.signature(s),
  17. signing.base64_hmac(signer.salt + 'signer', s,
  18. 'predictable-secret')
  19. )
  20. self.assertNotEqual(signer.signature(s), signer2.signature(s))
  21. def test_signature_with_salt(self):
  22. "signature(value, salt=...) should work"
  23. signer = signing.Signer('predictable-secret', salt='extra-salt')
  24. self.assertEqual(
  25. signer.signature('hello'),
  26. signing.base64_hmac('extra-salt' + 'signer',
  27. 'hello', 'predictable-secret'))
  28. self.assertNotEqual(
  29. signing.Signer('predictable-secret', salt='one').signature('hello'),
  30. signing.Signer('predictable-secret', salt='two').signature('hello'))
  31. def test_sign_unsign(self):
  32. "sign/unsign should be reversible"
  33. signer = signing.Signer('predictable-secret')
  34. examples = (
  35. 'q;wjmbk;wkmb',
  36. '3098247529087',
  37. '3098247:529:087:',
  38. 'jkw osanteuh ,rcuh nthu aou oauh ,ud du',
  39. u'\u2019',
  40. )
  41. for example in examples:
  42. self.assertNotEqual(
  43. force_unicode(example), force_unicode(signer.sign(example)))
  44. self.assertEqual(example, signer.unsign(signer.sign(example)))
  45. def unsign_detects_tampering(self):
  46. "unsign should raise an exception if the value has been tampered with"
  47. signer = signing.Signer('predictable-secret')
  48. value = 'Another string'
  49. signed_value = signer.sign(value)
  50. transforms = (
  51. lambda s: s.upper(),
  52. lambda s: s + 'a',
  53. lambda s: 'a' + s[1:],
  54. lambda s: s.replace(':', ''),
  55. )
  56. self.assertEqual(value, signer.unsign(signed_value))
  57. for transform in transforms:
  58. self.assertRaises(
  59. signing.BadSignature, signer.unsign, transform(signed_value))
  60. def test_dumps_loads(self):
  61. "dumps and loads be reversible for any JSON serializable object"
  62. objects = (
  63. ['a', 'list'],
  64. 'a string',
  65. u'a unicode string \u2019',
  66. {'a': 'dictionary'},
  67. )
  68. for o in objects:
  69. self.assertNotEqual(o, signing.dumps(o))
  70. self.assertEqual(o, signing.loads(signing.dumps(o)))
  71. def test_decode_detects_tampering(self):
  72. "loads should raise exception for tampered objects"
  73. transforms = (
  74. lambda s: s.upper(),
  75. lambda s: s + 'a',
  76. lambda s: 'a' + s[1:],
  77. lambda s: s.replace(':', ''),
  78. )
  79. value = {
  80. 'foo': 'bar',
  81. 'baz': 1,
  82. }
  83. encoded = signing.dumps(value)
  84. self.assertEqual(value, signing.loads(encoded))
  85. for transform in transforms:
  86. self.assertRaises(
  87. signing.BadSignature, signing.loads, transform(encoded))
  88. class TestTimestampSigner(TestCase):
  89. def test_timestamp_signer(self):
  90. value = u'hello'
  91. _time = time.time
  92. time.time = lambda: 123456789
  93. try:
  94. signer = signing.TimestampSigner('predictable-key')
  95. ts = signer.sign(value)
  96. self.assertNotEqual(ts,
  97. signing.Signer('predictable-key').sign(value))
  98. self.assertEqual(signer.unsign(ts), value)
  99. time.time = lambda: 123456800
  100. self.assertEqual(signer.unsign(ts, max_age=12), value)
  101. self.assertEqual(signer.unsign(ts, max_age=11), value)
  102. self.assertRaises(
  103. signing.SignatureExpired, signer.unsign, ts, max_age=10)
  104. finally:
  105. time.time = _time