use async_trait::async_trait;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum EventKind {
SecretLoaded,
SecretRefreshed,
SecretExpired,
SecretAccessFailure,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AuditEvent {
pub kind: EventKind,
pub at: DateTime<Utc>,
pub key: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub provider: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
}
impl AuditEvent {
#[must_use]
pub fn new(kind: EventKind, key: impl Into<String>) -> Self {
Self {
kind,
at: Utc::now(),
key: key.into(),
provider: None,
message: None,
}
}
#[must_use]
pub fn with_provider(mut self, provider: impl Into<String>) -> Self {
self.provider = Some(provider.into());
self
}
#[must_use]
pub fn with_message(mut self, message: impl Into<String>) -> Self {
self.message = Some(message.into());
self
}
}
#[async_trait]
pub trait Auditor: Send + Sync {
async fn record(&self, event: AuditEvent);
}
#[derive(Debug, Default, Clone, Copy)]
pub struct NoopAuditor;
#[async_trait]
impl Auditor for NoopAuditor {
async fn record(&self, _event: AuditEvent) {}
}