fix(site-replication): judge service-account items against deletion marks too (backlog#2291)

The service-account receive path used only the live record's timestamp; a
deleted account left nothing to compare against, so a stale create from a
snapshot or a delayed delivery could recreate it. Consult the recorded
deletion mark when the record is absent, as the user path does. The site
replicator account is managed by join/rotate and stays exempt.
This commit is contained in:
唐小鸭
2026-09-05 17:40:50 +08:00
parent 18670b269b
commit 9032adcb12
@@ -6088,10 +6088,14 @@ async fn apply_iam_service_account_item(
};
let envelope = change.oidc_service_account_envelope;
if let Some(create) = change.create {
let local_updated_at = iam_sys
.get_user(&create.access_key)
.await
.map(|local| local.update_at.unwrap_or(OffsetDateTime::UNIX_EPOCH));
// Like the user path: with the account already deleted here, the
// recorded deletion mark is the timestamp a stale create/update
// (a snapshot or a delayed delivery) has to beat (backlog#2291).
let local_updated_at = match iam_sys.get_user(&create.access_key).await {
Some(local) => Some(local.update_at.unwrap_or(OffsetDateTime::UNIX_EPOCH)),
None if create.access_key == SITE_REPLICATOR_SERVICE_ACCOUNT => None,
None => local_iam_deletion_mark(&[format!("svc-acc:{}", create.access_key)]).await,
};
let replicated_policy = if create.access_key == SITE_REPLICATOR_SERVICE_ACCOUNT {
if local_updated_at.is_some_and(|local_updated_at| is_stale_update(local_updated_at, incoming_updated_at)) {
return Ok(());