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 116 117 118 119 120
|
from datetime import datetime
from datetime import timedelta
from datetime import timezone
from functools import partial
import pytest
import sys
if sys.version_info > (3, 12):
pytestmark = pytest.mark.skipif(reason="For Python3 >= 3.12 dateutils throws DeprecationWarning which breaks the following tests which are ignored here")
pass
else:
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 test_itsdangerous.test_serializer import TestSerializer
from test_itsdangerous.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)
|