sentinel_modsec/actions/
metadata.rs1use super::RuleMetadata;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
7#[repr(u8)]
8pub enum Severity {
9 Emergency = 0,
10 Alert = 1,
11 Critical = 2,
12 Error = 3,
13 Warning = 4,
14 Notice = 5,
15 Info = 6,
16 Debug = 7,
17}
18
19impl From<u8> for Severity {
20 fn from(value: u8) -> Self {
21 match value {
22 0 => Severity::Emergency,
23 1 => Severity::Alert,
24 2 => Severity::Critical,
25 3 => Severity::Error,
26 4 => Severity::Warning,
27 5 => Severity::Notice,
28 6 => Severity::Info,
29 _ => Severity::Debug,
30 }
31 }
32}
33
34impl Severity {
35 pub fn name(&self) -> &'static str {
37 match self {
38 Severity::Emergency => "EMERGENCY",
39 Severity::Alert => "ALERT",
40 Severity::Critical => "CRITICAL",
41 Severity::Error => "ERROR",
42 Severity::Warning => "WARNING",
43 Severity::Notice => "NOTICE",
44 Severity::Info => "INFO",
45 Severity::Debug => "DEBUG",
46 }
47 }
48}
49
50impl RuleMetadata {
51 pub fn severity_level(&self) -> Option<Severity> {
53 self.severity.map(Severity::from)
54 }
55
56 pub fn format_log(&self) -> String {
58 let mut parts = Vec::new();
59
60 if let Some(ref id) = self.id {
61 parts.push(format!("[id \"{}\"]", id));
62 }
63
64 if let Some(ref msg) = self.msg {
65 parts.push(format!("[msg \"{}\"]", msg));
66 }
67
68 if let Some(sev) = self.severity {
69 parts.push(format!("[severity \"{}\"]", Severity::from(sev).name()));
70 }
71
72 for tag in &self.tags {
73 parts.push(format!("[tag \"{}\"]", tag));
74 }
75
76 if let Some(ref rev) = self.rev {
77 parts.push(format!("[rev \"{}\"]", rev));
78 }
79
80 if let Some(ref ver) = self.ver {
81 parts.push(format!("[ver \"{}\"]", ver));
82 }
83
84 parts.join(" ")
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91
92 #[test]
93 fn test_severity_from_u8() {
94 assert_eq!(Severity::from(0), Severity::Emergency);
95 assert_eq!(Severity::from(2), Severity::Critical);
96 assert_eq!(Severity::from(4), Severity::Warning);
97 assert_eq!(Severity::from(99), Severity::Debug);
98 }
99
100 #[test]
101 fn test_format_log() {
102 let meta = RuleMetadata {
103 id: Some("942100".to_string()),
104 msg: Some("SQL Injection Attack".to_string()),
105 severity: Some(2),
106 tags: vec!["attack-sqli".to_string(), "OWASP_CRS".to_string()],
107 ..Default::default()
108 };
109
110 let log = meta.format_log();
111 assert!(log.contains("[id \"942100\"]"));
112 assert!(log.contains("[msg \"SQL Injection Attack\"]"));
113 assert!(log.contains("[severity \"CRITICAL\"]"));
114 assert!(log.contains("[tag \"attack-sqli\"]"));
115 }
116}