more audit logging
parent
8419871428
commit
4ec5d66d25
|
@ -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 <Utc>,
|
||||
last_seen: DateTime <Utc>
|
||||
) -> 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 <String>,
|
||||
audit_log: Vec <AuditEntryPretty>,
|
||||
}
|
||||
|
||||
#[derive (Serialize)]
|
||||
struct AuditEntryPretty {
|
||||
utc_pretty: String,
|
||||
data_pretty: String,
|
||||
}
|
||||
|
||||
async fn handle_server_list_internal (state: &Arc <Relay>)
|
||||
|
@ -350,8 +382,14 @@ async fn handle_unregistered_servers_internal (state: &Arc <Relay>)
|
|||
async fn handle_audit_log_internal (state: &Arc <Relay>)
|
||||
-> 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,
|
||||
|
|
|
@ -89,10 +89,10 @@ pub struct Relay {
|
|||
pub (crate) shutdown_watch_tx: watch::Sender <bool>,
|
||||
pub (crate) shutdown_watch_rx: watch::Receiver <bool>,
|
||||
|
||||
// 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 <RejectedServer>,
|
||||
|
||||
// Memory backend for audit logging
|
||||
/// Memory backend for audit logging
|
||||
// TODO: Add file / database / network server logging backend
|
||||
pub (crate) audit_log: BoundedVec <AuditEvent>,
|
||||
}
|
||||
|
@ -107,16 +107,18 @@ pub struct RejectedServer {
|
|||
#[derive (Clone, Debug)]
|
||||
pub struct AuditEvent {
|
||||
time_monotonic: Instant,
|
||||
time_utc: DateTime <Utc>,
|
||||
data: AuditData,
|
||||
pub time_utc: DateTime <Utc>,
|
||||
pub data: AuditData,
|
||||
}
|
||||
|
||||
#[derive (Clone, Debug)]
|
||||
pub enum AuditData {
|
||||
RelayStart,
|
||||
WebClientGet {
|
||||
user: Option <String>,
|
||||
req_id: String,
|
||||
server_name: String,
|
||||
uri: String,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -40,22 +40,25 @@ AIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAA" rel="icon" type="image/x-icon" />
|
|||
|
||||
<h1>Audit log</h1>
|
||||
|
||||
<p>
|
||||
(Newest events at the top)
|
||||
<p>(Newest events at the top)</p>
|
||||
|
||||
<p>CSV link goes here</p>
|
||||
|
||||
<div style="padding-top: 1em;">
|
||||
{{#if audit_log}}
|
||||
<table class="entry_list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Debug</th>
|
||||
<th>UTC</th>
|
||||
<th>Data</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{{#each audit_log}}
|
||||
<tr>
|
||||
<td><span>{{this}}</span></td>
|
||||
<td><span>{{this.utc_pretty}}</span></td>
|
||||
<td><span>{{this.data_pretty}}</span></td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
|
||||
|
|
Loading…
Reference in New Issue