relay_core_runtime/
audit.rs1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::str::FromStr;
4use std::time::{SystemTime, UNIX_EPOCH};
5use uuid::Uuid;
6
7#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
8#[serde(rename_all = "snake_case")]
9pub enum AuditActor {
10 Runtime,
11 Tauri,
12 Http,
13 Probe,
14 Cli,
15}
16
17impl AuditActor {
18 pub fn as_str(&self) -> &'static str {
19 match self {
20 Self::Runtime => "runtime",
21 Self::Tauri => "tauri",
22 Self::Http => "http",
23 Self::Probe => "probe",
24 Self::Cli => "cli",
25 }
26 }
27}
28
29impl FromStr for AuditActor {
30 type Err = ();
31
32 fn from_str(value: &str) -> Result<Self, Self::Err> {
33 match value {
34 "runtime" => Ok(Self::Runtime),
35 "tauri" => Ok(Self::Tauri),
36 "http" => Ok(Self::Http),
37 "probe" => Ok(Self::Probe),
38 "cli" => Ok(Self::Cli),
39 _ => Err(()),
40 }
41 }
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
45#[serde(rename_all = "snake_case")]
46pub enum AuditEventKind {
47 RuleChanged,
48 InterceptResolved,
49 ScriptReloaded,
50 PolicyUpdated,
51}
52
53impl AuditEventKind {
54 pub fn as_str(&self) -> &'static str {
55 match self {
56 Self::RuleChanged => "rule_changed",
57 Self::InterceptResolved => "intercept_resolved",
58 Self::ScriptReloaded => "script_reloaded",
59 Self::PolicyUpdated => "policy_updated",
60 }
61 }
62}
63
64impl FromStr for AuditEventKind {
65 type Err = ();
66
67 fn from_str(value: &str) -> Result<Self, Self::Err> {
68 match value {
69 "rule_changed" => Ok(Self::RuleChanged),
70 "intercept_resolved" => Ok(Self::InterceptResolved),
71 "script_reloaded" => Ok(Self::ScriptReloaded),
72 "policy_updated" => Ok(Self::PolicyUpdated),
73 _ => Err(()),
74 }
75 }
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
79#[serde(rename_all = "snake_case")]
80pub enum AuditOutcome {
81 Success,
82 Failed,
83}
84
85impl AuditOutcome {
86 pub fn as_str(&self) -> &'static str {
87 match self {
88 Self::Success => "success",
89 Self::Failed => "failed",
90 }
91 }
92}
93
94impl FromStr for AuditOutcome {
95 type Err = ();
96
97 fn from_str(value: &str) -> Result<Self, Self::Err> {
98 match value {
99 "success" => Ok(Self::Success),
100 "failed" => Ok(Self::Failed),
101 _ => Err(()),
102 }
103 }
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
107pub struct AuditEvent {
108 pub id: String,
109 pub timestamp_ms: u64,
110 pub actor: AuditActor,
111 pub kind: AuditEventKind,
112 pub target: String,
113 pub outcome: AuditOutcome,
114 pub details: Value,
115}
116
117impl AuditEvent {
118 pub fn new(
119 actor: AuditActor,
120 kind: AuditEventKind,
121 target: impl Into<String>,
122 outcome: AuditOutcome,
123 details: Value,
124 ) -> Self {
125 let timestamp_ms = SystemTime::now()
126 .duration_since(UNIX_EPOCH)
127 .unwrap_or_default()
128 .as_millis() as u64;
129
130 Self {
131 id: Uuid::new_v4().to_string(),
132 timestamp_ms,
133 actor,
134 kind,
135 target: target.into(),
136 outcome,
137 details,
138 }
139 }
140}