from datetime import datetime from datetime import timedelta from functools import partial import pytest from freezegun import freeze_time from .test_serializer import TestSerializer from .test_signer import TestSigner from itsdangerous import Signer from itsdangerous.exc import BadTimeSignature from itsdangerous.exc import SignatureExpired from itsdangerous.timed import TimedSerializer from itsdangerous.timed import TimestampSigner class FreezeMixin(object): @pytest.fixture() def ts(self): return datetime(2011, 6, 24, 0, 9, 5) @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) 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) 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)