use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use serde::{Deserialize, Serialize};
type AuditEventFuture = Pin<Box<dyn Future<Output = ()> + Send>>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum SsoAuditSeverity {
Info,
Warn,
Error,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum SsoAuditEventKind {
ProviderRegistered,
ProviderUpdated,
ProviderDeleted,
DomainVerificationRequested,
DomainVerificationSucceeded,
DomainVerificationFailed,
DomainVerificationRevoked,
SamlReplayRejected,
SamlSignatureFailed,
SamlSloSessionDeleted,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SsoAuditEvent {
pub kind: SsoAuditEventKind,
pub severity: SsoAuditSeverity,
pub provider_id: Option<String>,
pub user_id: Option<String>,
pub organization_id: Option<String>,
pub reason: Option<String>,
}
impl SsoAuditEvent {
pub fn new(kind: SsoAuditEventKind, severity: SsoAuditSeverity) -> Self {
Self {
kind,
severity,
provider_id: None,
user_id: None,
organization_id: None,
reason: None,
}
}
#[must_use]
pub fn provider_id(mut self, provider_id: impl Into<String>) -> Self {
self.provider_id = Some(provider_id.into());
self
}
#[must_use]
pub fn user_id(mut self, user_id: impl Into<String>) -> Self {
self.user_id = Some(user_id.into());
self
}
#[must_use]
pub fn organization_id(mut self, organization_id: impl Into<String>) -> Self {
self.organization_id = Some(organization_id.into());
self
}
#[must_use]
pub fn reason(mut self, reason: impl Into<String>) -> Self {
self.reason = Some(reason.into());
self
}
}
#[derive(Clone)]
pub struct SsoAuditEventResolver {
resolver: Arc<dyn Fn(SsoAuditEvent) -> AuditEventFuture + Send + Sync>,
}
impl SsoAuditEventResolver {
pub fn new<F, Fut>(resolver: F) -> Self
where
F: Fn(SsoAuditEvent) -> Fut + Send + Sync + 'static,
Fut: Future<Output = ()> + Send + 'static,
{
Self {
resolver: Arc::new(move |event| Box::pin(resolver(event))),
}
}
pub async fn resolve(&self, event: SsoAuditEvent) {
(self.resolver)(event).await;
}
}
impl std::fmt::Debug for SsoAuditEventResolver {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("SsoAuditEventResolver(..)")
}
}
impl PartialEq for SsoAuditEventResolver {
fn eq(&self, _other: &Self) -> bool {
true
}
}
impl Eq for SsoAuditEventResolver {}