1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
from datetime import datetime
from datetime import timedelta
from datetime import timezone
from functools import partial
import pytest
from freezegun import freeze_time
from itsdangerous.exc import BadTimeSignature
from itsdangerous.exc import SignatureExpired
from itsdangerous.signer import Signer
from itsdangerous.timed import TimedSerializer
from itsdangerous.timed import TimestampSigner
from __tests__.test_serializer import TestSerializer
from __tests__.test_signer import TestSigner
class FreezeMixin:
@pytest.fixture()
def ts(self):
return datetime(2011, 6, 24, 0, 9, 5, tzinfo=timezone.utc)
@pytest.fixture(autouse=True)
def freeze(self, ts):
with freeze_time(ts) as ft:
yield ft
class TestTimestampSigner(FreezeMixin, TestSigner):
@pytest.fixture()
def signer_factory(self):
return partial(TimestampSigner, secret_key="secret-key")
def test_max_age(self, signer, ts, freeze):
signed = signer.sign("value")
freeze.tick()
assert signer.unsign(signed, max_age=10) == b"value"
freeze.tick(timedelta(seconds=10))
with pytest.raises(SignatureExpired) as exc_info:
signer.unsign(signed, max_age=10)
assert exc_info.value.date_signed == ts
def test_return_timestamp(self, signer, ts):
signed = signer.sign("value")
assert signer.unsign(signed, return_timestamp=True) == (b"value", ts)
def test_timestamp_missing(self, signer):
other = Signer("secret-key")
signed = other.sign("value")
with pytest.raises(BadTimeSignature) as exc_info:
signer.unsign(signed)
assert "missing" in str(exc_info.value)
assert exc_info.value.date_signed is None
def test_malformed_timestamp(self, signer):
other = Signer("secret-key")
signed = other.sign(b"value.____________")
with pytest.raises(BadTimeSignature) as exc_info:
signer.unsign(signed)
assert "Malformed" in str(exc_info.value)
assert exc_info.value.date_signed is None
def test_malformed_future_timestamp(self, signer):
signed = b"value.TgPVoaGhoQ.AGBfQ6G6cr07byTRt0zAdPljHOY"
with pytest.raises(BadTimeSignature) as exc_info:
signer.unsign(signed)
assert "Malformed" in str(exc_info.value)
assert exc_info.value.date_signed is None
def test_future_age(self, signer):
signed = signer.sign("value")
with freeze_time("1971-05-31"):
with pytest.raises(SignatureExpired) as exc_info:
signer.unsign(signed, max_age=10)
assert isinstance(exc_info.value.date_signed, datetime)
def test_sig_error_date_signed(self, signer):
signed = signer.sign("my string").replace(b"my", b"other", 1)
with pytest.raises(BadTimeSignature) as exc_info:
signer.unsign(signed)
assert isinstance(exc_info.value.date_signed, datetime)
class TestTimedSerializer(FreezeMixin, TestSerializer):
@pytest.fixture()
def serializer_factory(self):
return partial(TimedSerializer, secret_key="secret_key")
def test_max_age(self, serializer, value, ts, freeze):
signed = serializer.dumps(value)
freeze.tick()
assert serializer.loads(signed, max_age=10) == value
freeze.tick(timedelta(seconds=10))
with pytest.raises(SignatureExpired) as exc_info:
serializer.loads(signed, max_age=10)
assert exc_info.value.date_signed == ts
assert serializer.load_payload(exc_info.value.payload) == value
def test_return_payload(self, serializer, value, ts):
signed = serializer.dumps(value)
assert serializer.loads(signed, return_timestamp=True) == (value, ts)
|