use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct TrivialRewriteEvent {
pub timestamp: DateTime<Utc>,
pub pid: Option<u32>,
pub event_type: TrivialRewriteEventType,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum TrivialRewriteEventType {
ConfigOverrideWarning {
file_path: String,
line_number: u32,
parameter_name: String,
parameter_value: String,
},
DomainConfigWarning {
domain: String,
domain_list1: String, domain_list2: String, message: String,
},
}
impl TrivialRewriteEvent {
pub fn new(
timestamp: DateTime<Utc>,
pid: Option<u32>,
event_type: TrivialRewriteEventType,
) -> Self {
Self {
timestamp,
pid,
event_type,
}
}
pub fn config_override_warning(
timestamp: DateTime<Utc>,
pid: Option<u32>,
file_path: String,
line_number: u32,
parameter_name: String,
parameter_value: String,
) -> Self {
Self::new(
timestamp,
pid,
TrivialRewriteEventType::ConfigOverrideWarning {
file_path,
line_number,
parameter_name,
parameter_value,
},
)
}
pub fn domain_config_warning(
timestamp: DateTime<Utc>,
pid: Option<u32>,
domain: String,
domain_list1: String,
domain_list2: String,
message: String,
) -> Self {
Self::new(
timestamp,
pid,
TrivialRewriteEventType::DomainConfigWarning {
domain,
domain_list1,
domain_list2,
message,
},
)
}
pub fn description(&self) -> String {
match &self.event_type {
TrivialRewriteEventType::ConfigOverrideWarning {
file_path,
line_number,
parameter_name,
parameter_value,
} => {
format!(
"Config override in {}:{} - parameter '{}' set to '{}'",
file_path, line_number, parameter_name, parameter_value
)
}
TrivialRewriteEventType::DomainConfigWarning {
domain,
domain_list1,
domain_list2,
message,
} => {
format!(
"Domain config warning for '{}': {} (conflicts between {} and {})",
domain, message, domain_list1, domain_list2
)
}
}
}
pub fn severity(&self) -> &'static str {
match &self.event_type {
TrivialRewriteEventType::ConfigOverrideWarning { .. } => "warning",
TrivialRewriteEventType::DomainConfigWarning { .. } => "warning",
}
}
pub fn parameter_name(&self) -> Option<&str> {
match &self.event_type {
TrivialRewriteEventType::ConfigOverrideWarning { parameter_name, .. } => {
Some(parameter_name)
}
TrivialRewriteEventType::DomainConfigWarning { .. } => None,
}
}
pub fn domain(&self) -> Option<&str> {
match &self.event_type {
TrivialRewriteEventType::ConfigOverrideWarning { .. } => None,
TrivialRewriteEventType::DomainConfigWarning { domain, .. } => Some(domain),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use chrono::TimeZone;
#[test]
fn test_config_override_warning_event() {
let timestamp = Utc.with_ymd_and_hms(2024, 4, 8, 17, 54, 42).unwrap();
let event = TrivialRewriteEvent::config_override_warning(
timestamp,
Some(81),
"/etc/postfix/main.cf".to_string(),
820,
"smtpd_recipient_restrictions".to_string(),
"check_client_access pcre:/etc/postfix/filter_trusted,permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination,pcre:/etc/postfix/filter_default".to_string(),
);
assert_eq!(event.timestamp, timestamp);
assert_eq!(event.pid, Some(81));
assert_eq!(event.severity(), "warning");
assert_eq!(event.parameter_name(), Some("smtpd_recipient_restrictions"));
assert!(event.description().contains("Config override"));
assert!(event.description().contains("/etc/postfix/main.cf:820"));
}
#[test]
fn test_domain_config_warning_event() {
let timestamp = Utc.with_ymd_and_hms(2024, 4, 9, 14, 42, 34).unwrap();
let event = TrivialRewriteEvent::domain_config_warning(
timestamp,
Some(81),
"qq.com".to_string(),
"virtual_alias_domains".to_string(),
"relay_domains".to_string(),
"do not list domain qq.com in BOTH virtual_alias_domains and relay_domains".to_string(),
);
assert_eq!(event.timestamp, timestamp);
assert_eq!(event.pid, Some(81));
assert_eq!(event.severity(), "warning");
assert_eq!(event.domain(), Some("qq.com"));
assert!(event.description().contains("Domain config warning"));
assert!(event.description().contains("qq.com"));
assert!(event
.description()
.contains("virtual_alias_domains and relay_domains"));
}
#[test]
fn test_event_equality() {
let timestamp = Utc.with_ymd_and_hms(2024, 4, 8, 17, 54, 42).unwrap();
let event1 = TrivialRewriteEvent::config_override_warning(
timestamp,
Some(81),
"/etc/postfix/main.cf".to_string(),
820,
"smtpd_recipient_restrictions".to_string(),
"value1".to_string(),
);
let event2 = TrivialRewriteEvent::config_override_warning(
timestamp,
Some(81),
"/etc/postfix/main.cf".to_string(),
820,
"smtpd_recipient_restrictions".to_string(),
"value1".to_string(),
);
assert_eq!(event1, event2);
}
}