use async_trait::async_trait;
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum LockoutEvent {
FailedAttempt {
identity: String,
attempt_count: u32,
max_attempts: u32,
},
ApproachingThreshold {
identity: String,
attempt_count: u32,
remaining_attempts: u32,
},
AccountLocked {
identity: String,
attempt_count: u32,
lockout_duration_secs: u64,
},
AccountUnlocked {
identity: String,
reason: UnlockReason,
},
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum UnlockReason {
Expired,
SuccessfulLogin,
AdminAction,
}
impl std::fmt::Display for UnlockReason {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Expired => write!(f, "expired"),
Self::SuccessfulLogin => write!(f, "successful_login"),
Self::AdminAction => write!(f, "admin_action"),
}
}
}
#[async_trait]
pub trait LockoutNotification: Send + Sync + 'static {
async fn on_event(&self, event: LockoutEvent);
}