fix(scheduling): reject stale invitation actions
This commit is contained in:
@@ -2866,6 +2866,19 @@ def _participant_for_invitation_action(
|
||||
return participant
|
||||
|
||||
|
||||
def _require_current_invitation_participant_revision(
|
||||
participant: SchedulingParticipant,
|
||||
*,
|
||||
participant_revision: str,
|
||||
) -> None:
|
||||
"""Reject a stale invitation command while the participant row is locked."""
|
||||
|
||||
if participant_revision != scheduling_participant_revision(participant):
|
||||
raise SchedulingConflictError(
|
||||
"Scheduling participant invitation changed; reload and try again"
|
||||
)
|
||||
|
||||
|
||||
def _new_public_invitation_expiry(
|
||||
request: SchedulingRequest,
|
||||
) -> datetime | None:
|
||||
@@ -2904,6 +2917,7 @@ def issue_scheduling_participant_invitation(
|
||||
tenant_id: str,
|
||||
request_id: str,
|
||||
participant_id: str,
|
||||
participant_revision: str,
|
||||
action: str,
|
||||
) -> SchedulingInvitationActionResult:
|
||||
"""Rotate one bearer link for explicit copy or immediate delivery.
|
||||
@@ -2925,6 +2939,10 @@ def issue_scheduling_participant_invitation(
|
||||
request,
|
||||
participant_id=participant_id,
|
||||
)
|
||||
_require_current_invitation_participant_revision(
|
||||
participant,
|
||||
participant_revision=participant_revision,
|
||||
)
|
||||
if request.poll_id is None:
|
||||
raise SchedulingError("Scheduling invitation action is unavailable")
|
||||
participation_provider = _poll_participation_provider()
|
||||
@@ -3016,8 +3034,9 @@ def revoke_scheduling_participant_invitation(
|
||||
tenant_id: str,
|
||||
request_id: str,
|
||||
participant_id: str,
|
||||
participant_revision: str,
|
||||
) -> SchedulingInvitationActionResult:
|
||||
"""Immediately revoke the current link; exact repeats are safe no-ops."""
|
||||
"""Revoke the current link; refreshed no-link projections replay safely."""
|
||||
|
||||
request = _lock_scheduling_request(
|
||||
session,
|
||||
@@ -3029,6 +3048,10 @@ def revoke_scheduling_participant_invitation(
|
||||
request,
|
||||
participant_id=participant_id,
|
||||
)
|
||||
_require_current_invitation_participant_revision(
|
||||
participant,
|
||||
participant_revision=participant_revision,
|
||||
)
|
||||
invitation_id = participant.poll_invitation_id
|
||||
replayed = invitation_id is None
|
||||
if invitation_id is not None:
|
||||
|
||||
Reference in New Issue
Block a user