scaffolding hermes flow and audit logging
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use tokio::sync::RwLock;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AuditStore {
|
||||
inner: Arc<RwLock<AuditState>>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct AuditState {
|
||||
event_types_by_name: HashMap<String, Uuid>,
|
||||
events: Vec<AuditEventSnapshot>,
|
||||
attributes: Vec<AuditEventAttributeSnapshot>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[allow(dead_code)]
|
||||
struct AuditEventSnapshot {
|
||||
id: Uuid,
|
||||
audit_event_type_id: Uuid,
|
||||
session_id: Option<Uuid>,
|
||||
user_id: Option<Uuid>,
|
||||
occurred_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[allow(dead_code)]
|
||||
struct AuditEventAttributeSnapshot {
|
||||
id: Uuid,
|
||||
audit_event_id: Uuid,
|
||||
attribute_key: String,
|
||||
attribute_value: String,
|
||||
}
|
||||
|
||||
impl AuditStore {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
inner: Arc::new(RwLock::new(AuditState::default())),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn record<I, K, V>(
|
||||
&self,
|
||||
action: impl Into<String>,
|
||||
session_id: Option<Uuid>,
|
||||
user_id: Option<Uuid>,
|
||||
occurred_at: DateTime<Utc>,
|
||||
attributes: I,
|
||||
) where
|
||||
I: IntoIterator<Item = (K, V)>,
|
||||
K: Into<String>,
|
||||
V: Into<String>,
|
||||
{
|
||||
let mut state = self.inner.write().await;
|
||||
let action = action.into();
|
||||
let event_type_id = *state
|
||||
.event_types_by_name
|
||||
.entry(action)
|
||||
.or_insert_with(Uuid::new_v4);
|
||||
|
||||
let audit_event_id = Uuid::new_v4();
|
||||
state.events.push(AuditEventSnapshot {
|
||||
id: audit_event_id,
|
||||
audit_event_type_id: event_type_id,
|
||||
session_id,
|
||||
user_id,
|
||||
occurred_at,
|
||||
});
|
||||
|
||||
for (key, value) in attributes {
|
||||
state.attributes.push(AuditEventAttributeSnapshot {
|
||||
id: Uuid::new_v4(),
|
||||
audit_event_id,
|
||||
attribute_key: key.into(),
|
||||
attribute_value: value.into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn counts(&self) -> (usize, usize) {
|
||||
let state = self.inner.read().await;
|
||||
(state.events.len(), state.attributes.len())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user