revocation.rs 36 lignes · 1744 octets
//! Remote identity revocation hook (RFC 0018 / F10).
//!
//! When a federated user's `remote_identities` row is disabled (manual
//! revoke, `kill_domain`, or auto-kill on signature failure), any
//! outstanding remote JWT minted for that identity must be rejected at
//! the next middleware pass. The check used to live directly in
//! `AuthService`, but doing so required `rustwarden-core` to know the
//! `remote_identity` SeaORM entity — which now lives in
//! `rustwarden-fediverse`. To keep the dependency arrow strictly
//! `fediverse → core` (no cycle), `core` only exposes this trait; the
//! federation crate provides a SeaORM-backed implementation and
//! injects it as a Tower `Extension` when it mounts its routes.
//!
//! Consumers that don't link `rustwarden-fediverse` simply don't
//! register the extension: `AuthService` then skips the check, which
//! is the correct behaviour because remote JWTs can only be minted by
//! the federation crate in the first place.

use async_trait::async_trait;
use uuid::Uuid;

/// Predicate consulted by `AuthService` to decide whether a remote JWT
/// must be refused because its backing `remote_identities` row has
/// been disabled.
///
/// `is_revoked` returns `true` when the JWT must be refused. Network
/// or database errors should map to `false` (fail-open) so a transient
/// outage doesn't lock every federated user out: the worst case is a
/// disabled identity getting one more request through, which the next
/// poll will catch.
#[async_trait]
pub trait RemoteIdentityRevocationChecker: Send + Sync {
    /// Return `true` if the remote identity has been disabled and the
    /// JWT must be refused.
    async fn is_revoked(&self, remote_identity_id: Uuid) -> bool;
}