block expired media

This commit is contained in:
Raphael Michel
2026-06-09 12:02:08 +02:00
parent 46ad9a2f20
commit 18b380e591
4 changed files with 41 additions and 2 deletions

View File

@@ -230,7 +230,7 @@ Checking a ticket in
* ``revoked`` - Ticket code has been revoked.
* ``unapproved`` - Order has not yet been approved.
* ``already_exchanged`` - Ticket already has been exchanged for a reusable medium that must now be used for check-in.
* ``medium_invalid`` - Reusable medium identifier given was not found and could not be automatically created.
* ``medium_invalid`` - Reusable medium identifier given was not found or is not valid.
* ``medium_exists`` - Reusable medium identifier already exists, but expected to be new.
* ``error`` - Internal error.

View File

@@ -129,7 +129,7 @@ class ReusableMedium(LoggedModel):
@property
def is_expired(self):
return self.expires and self.expires > now()
return self.expires and self.expires < now()
class Meta:
unique_together = (("identifier", "type", "organizer"),)

View File

@@ -130,7 +130,15 @@ def perform_media_exchange(organizer, media_type, identifier, link_action, link_
raise CheckInError(
_('Reusable medium not found.'),
Checkin.REASON_MEDIUM_INVALID,
reason=_('Reusable medium not found.'),
)
else:
if medium.is_expired or not medium.active:
raise CheckInError(
_('Reusable medium is inactive or expired.'),
Checkin.REASON_MEDIUM_INVALID,
reason=_('Reusable medium is inactive or expired.'),
)
elif media_policy == Item.MEDIA_POLICY_REUSE_OR_NEW:
medium, created = ReusableMedium.objects.get_or_create(
@@ -144,6 +152,12 @@ def perform_media_exchange(organizer, media_type, identifier, link_action, link_
user=user,
auth=auth,
)
elif medium.is_expired or not medium.active:
raise CheckInError(
_('Reusable medium is inactive or expired.'),
Checkin.REASON_MEDIUM_INVALID,
reason=_('Reusable medium is inactive or expired.'),
)
elif media_policy == Item.MEDIA_POLICY_NEW:
try:

View File

@@ -1451,6 +1451,31 @@ def test_exchange_reuse_exists_append(token_client, organizer, clist, event, ord
assert rm.linked_orderpositions.filter(secret="z3fsn8jyufm5kpk768q69gkbyr5f4h6w").exists()
@pytest.mark.django_db
def test_exchange_reuse_expired(token_client, organizer, clist, event, order, item):
organizer.settings.reusable_media_type_nfc_uid = True
item.media_type = "nfc_uid"
item.media_policy = Item.MEDIA_POLICY_REUSE
item.save()
with scopes_disabled():
rm = ReusableMedium.objects.create(
type="nfc_uid",
identifier="12345678",
organizer=organizer,
expires=now() - datetime.timedelta(hours=2),
)
rm.linked_orderpositions.add(order.positions.last())
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
"source_type": "barcode",
"exchange_medium_type": "nfc_uid",
"exchange_medium_identifier": "12345678",
"exchange_link_action": "replace",
})
assert resp.status_code == 400
assert resp.data['status'] == 'error'
assert resp.data['reason'] == 'medium_invalid'
@pytest.mark.django_db
def test_exchange_reuse_not_exists(token_client, organizer, clist, event, order, item):
organizer.settings.reusable_media_type_nfc_uid = True