diff --git a/src/_zkapauthorizer/model.py b/src/_zkapauthorizer/model.py index fe2507b22a6b97842897bb4e60b6c36e6f20bd6c..530fb88e026c6fa1cab94c487573cf80298808b3 100644 --- a/src/_zkapauthorizer/model.py +++ b/src/_zkapauthorizer/model.py @@ -741,6 +741,35 @@ class Redeemed(object): } +@attr.s(frozen=True) +class Suspicious(object): + """ + The voucher was successfully redeemed but the public key used in the + redemption was suspicious. + + :ivar datetime finished: The time when the redemption finished. + + :ivar int token_count: The number of tokens the voucher was redeemed for. + + :ivar unicode public_key: The public part of the key used to sign the + tokens for this voucher. + """ + finished = attr.ib(validator=attr.validators.instance_of(datetime)) + token_count = attr.ib(validator=attr.validators.instance_of((int, long))) + public_key = attr.ib(validator=attr.validators.optional(attr.validators.instance_of(unicode))) + + def should_start_redemption(self): + return False + + def to_json_v1(self): + return { + u"name": u"suspicious", + u"finished": self.finished.isoformat(), + u"token-count": self.token_count, + u"public-key": self.public_key, + } + + @attr.s(frozen=True) class DoubleSpend(object): finished = attr.ib(validator=attr.validators.instance_of(datetime)) @@ -877,6 +906,12 @@ class Voucher(object): token_count=state_json[u"token-count"], public_key=state_json[u"public-key"], ) + elif state_name == u"suspicious": + state = Suspicious( + finished=parse_datetime(state_json[u"finished"]), + token_count=state_json[u"token-count"], + public_key=state_json[u"public-key"], + ) elif state_name == u"unpaid": state = Unpaid( finished=parse_datetime(state_json[u"finished"]), diff --git a/src/_zkapauthorizer/tests/strategies.py b/src/_zkapauthorizer/tests/strategies.py index a63af545766b05cd166c36db151e5d9fe4f19b2e..5a15656654c80514e9e483d44512f1fc090aa5c1 100644 --- a/src/_zkapauthorizer/tests/strategies.py +++ b/src/_zkapauthorizer/tests/strategies.py @@ -78,6 +78,7 @@ from ..model import ( Unpaid, Error, Redeemed, + Suspicious, ) # Sizes informed by @@ -310,6 +311,12 @@ def voucher_states(): token_count=one_of(integers(min_value=1)), public_key=dummy_ristretto_keys(), ), + builds( + Suspicious, + finished=datetimes(), + token_count=one_of(integers(min_value=1)), + public_key=dummy_ristretto_keys(), + ), builds( DoubleSpend, finished=datetimes(),