diff --git a/crates/ptth_relay/src/lib.rs b/crates/ptth_relay/src/lib.rs index ee56ee1..7fd0d06 100644 --- a/crates/ptth_relay/src/lib.rs +++ b/crates/ptth_relay/src/lib.rs @@ -123,7 +123,9 @@ async fn handle_http_request ( } } - let req = match http_serde::RequestParts::from_hyper (req.method, uri, req.headers) { + let user = req.headers.get ("X-Email").map (|x| Some (x.to_str ().ok ()?.to_string ())).flatten (); + + let req = match http_serde::RequestParts::from_hyper (req.method, uri.clone (), req.headers) { Ok (x) => x, Err (_) => return Err (BadRequest), }; @@ -133,8 +135,10 @@ async fn handle_http_request ( let req_id = rusty_ulid::generate_ulid_string (); state.audit_log.push (AuditEvent::new (AuditData::WebClientGet { + user, req_id: req_id.clone (), server_name: server_name.to_string (), + uri, })).await; trace! ("Created request {}", req_id); @@ -196,6 +200,28 @@ enum LastSeen { Description (String), } +fn pretty_print_utc ( + now: DateTime , + last_seen: DateTime +) -> String +{ + let dur = now.signed_duration_since (last_seen); + + if dur < chrono::Duration::zero () { + return last_seen.to_rfc3339_opts (SecondsFormat::Secs, true); + } + + if dur.num_minutes () < 1 { + return format! ("{} s ago", dur.num_seconds ()); + } + + if dur.num_hours () < 1 { + return format! ("{} m ago", dur.num_minutes ()); + } + + last_seen.to_rfc3339_opts (SecondsFormat::Secs, true) +} + // Mnemonic is "now - last_seen" fn pretty_print_last_seen ( @@ -258,7 +284,13 @@ struct UnregisteredServer { #[derive (Serialize)] struct AuditLogPage { - audit_log: Vec , + audit_log: Vec , +} + +#[derive (Serialize)] +struct AuditEntryPretty { + utc_pretty: String, + data_pretty: String, } async fn handle_server_list_internal (state: &Arc ) @@ -350,8 +382,14 @@ async fn handle_unregistered_servers_internal (state: &Arc ) async fn handle_audit_log_internal (state: &Arc ) -> AuditLogPage { + let utc_now = Utc::now (); let audit_log = state.audit_log.to_vec ().await - .iter ().rev ().map (|e| format! ("{:?}", e)).collect (); + .iter ().rev ().map (|e| { + AuditEntryPretty { + utc_pretty: pretty_print_utc (utc_now, e.time_utc), + data_pretty: format! ("{:?}", e.data), + } + }).collect (); AuditLogPage { audit_log, diff --git a/crates/ptth_relay/src/relay_state.rs b/crates/ptth_relay/src/relay_state.rs index a66892e..037b83c 100644 --- a/crates/ptth_relay/src/relay_state.rs +++ b/crates/ptth_relay/src/relay_state.rs @@ -89,10 +89,10 @@ pub struct Relay { pub (crate) shutdown_watch_tx: watch::Sender , pub (crate) shutdown_watch_rx: watch::Receiver , - // List of recently rejected server names (Used to approve servers) + /// List of recently rejected server names (Used to approve servers) pub (crate) unregistered_servers: BoundedVec , - // Memory backend for audit logging + /// Memory backend for audit logging // TODO: Add file / database / network server logging backend pub (crate) audit_log: BoundedVec , } @@ -107,16 +107,18 @@ pub struct RejectedServer { #[derive (Clone, Debug)] pub struct AuditEvent { time_monotonic: Instant, - time_utc: DateTime , - data: AuditData, + pub time_utc: DateTime , + pub data: AuditData, } #[derive (Clone, Debug)] pub enum AuditData { RelayStart, WebClientGet { + user: Option , req_id: String, server_name: String, + uri: String, }, } diff --git a/handlebars/relay/audit_log.hbs b/handlebars/relay/audit_log.hbs index 6adebd6..80c83dc 100644 --- a/handlebars/relay/audit_log.hbs +++ b/handlebars/relay/audit_log.hbs @@ -40,22 +40,25 @@ AIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAA" rel="icon" type="image/x-icon" />

Audit log

-

-(Newest events at the top) +

(Newest events at the top)

+ +

CSV link goes here

{{#if audit_log}} - + + {{#each audit_log}} - + + {{/each}}
DebugUTCData
{{this}}{{this.utc_pretty}}{{this.data_pretty}}