use crate::entry::{Builder, Entry};
use crate::store::Trail;
use rustlavel_auth::guard::AuthExt;
use rustlavel_db::Database;
use rustlavel_http::Request;
use rustlavel_http::plugin::{Plugin, Setup};
pub struct Audit {
trail: Trail,
}
impl Audit {
pub fn new(db: Database) -> Audit {
Audit { trail: Trail::new(db) }
}
pub fn with_trail(trail: Trail) -> Audit {
Audit { trail }
}
pub fn trail(&self) -> &Trail {
&self.trail
}
}
impl Plugin for Audit {
fn name(&self) -> &'static str {
"audit"
}
fn register(self: Box<Self>, setup: &mut Setup<'_>) {
setup.state(self.trail.clone());
}
}
pub trait AuditExt {
fn trail(&self) -> Option<&Trail>;
fn audit(&self, event: &str) -> Option<Builder>;
}
impl AuditExt for Request {
fn trail(&self) -> Option<&Trail> {
self.state::<Trail>()
}
fn audit(&self, event: &str) -> Option<Builder> {
let trail = self.state::<Trail>()?;
let mut entry = Entry::new(event);
if let Some(identity) = self.identity() {
entry.user_id = identity.id_as::<i64>();
}
entry.ip_address = self.ip();
entry.user_agent = self.header("user-agent").map(|agent| agent.to_string());
Some(Builder { trail: trail.clone(), entry })
}
}