aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/data_structures.rs18
-rw-r--r--src/parser/deserializer.rs89
2 files changed, 98 insertions, 9 deletions
diff --git a/src/data_structures.rs b/src/data_structures.rs
index ef1bcc2..3e4e4ac 100644
--- a/src/data_structures.rs
+++ b/src/data_structures.rs
@@ -86,21 +86,21 @@ pub struct SPF {
// Rust interface DS for HTML generation
pub enum DMARCPolicy {
- None,
- Quarantine,
- Reject,
+ None(String),
+ Quarantine(String),
+ Reject(String),
}
pub enum DMARCAlignment {
- Relaxed,
- Strict,
+ Relaxed(String),
+ Strict(String),
}
pub enum DMARCFailureOption {
- AlignedPassFailure,
- OtherAlignedPassFailure,
- SignatureAlignmentFailure,
- SPFFailure,
+ AlignedPassFailure(String),
+ OtherAlignedPassFailure(String),
+ SignatureAlignmentFailure(String),
+ SPFFailure(String),
}
pub struct DMARCRecord {
diff --git a/src/parser/deserializer.rs b/src/parser/deserializer.rs
index e2bd108..fc81b66 100644
--- a/src/parser/deserializer.rs
+++ b/src/parser/deserializer.rs
@@ -1,4 +1,5 @@
use std::io::Read;
+use std::str::FromStr;
use crate::data_structures;
@@ -8,6 +9,79 @@ fn deserialize_dmarc_report<R: Read>(
serde_xml_rs::from_reader(reader)
}
+impl From<String> for data_structures::DMARCAlignment {
+ fn from(item: String) -> Self {
+ match item.as_str() {
+ "r" => data_structures::DMARCAlignment::Relaxed(item),
+ "s" => data_structures::DMARCAlignment::Strict(item),
+ _ => {
+ panic!("DMARC alignment value '{:?}' is not allowed", item);
+ }
+ }
+ }
+}
+
+impl From<String> for data_structures::DMARCPolicy {
+ fn from(item: String) -> Self {
+ match item.as_str() {
+ "none" => data_structures::DMARCPolicy::None(item),
+ "quarantine" => data_structures::DMARCPolicy::Quarantine(item),
+ "reject" => data_structures::DMARCPolicy::Reject(item),
+ _ => {
+ panic!("DMARC policy value '{:?}' is not allowed", item);
+ }
+ }
+ }
+}
+
+impl From<String> for data_structures::DMARCFailureOption {
+ fn from(item: String) -> Self {
+ match item.as_str() {
+ "0" => data_structures::DMARCFailureOption::AlignedPassFailure(item),
+ "1" => data_structures::DMARCFailureOption::OtherAlignedPassFailure(item),
+ "2" => data_structures::DMARCFailureOption::SignatureAlignmentFailure(item),
+ "3" => data_structures::DMARCFailureOption::SPFFailure(item),
+ _ => {
+ panic!("DMARC failure option '{:?}' is not allowed", item);
+ }
+ }
+ }
+}
+
+impl data_structures::DMARCReport {
+ pub fn from_raw_report(report: data_structures::Feedback) -> data_structures::DMARCReport {
+ data_structures::DMARCReport {
+ id: report.report_metadata.report_id,
+ org: report.report_metadata.org_name,
+ record: data_structures::DMARCRecord {
+ domain: report.policy_published.domain,
+ adkim: data_structures::DMARCAlignment::from(report.policy_published.adkim),
+ aspf: data_structures::DMARCAlignment::from(report.policy_published.aspf),
+ policy: data_structures::DMARCPolicy::from(report.policy_published.p),
+ subdomain_policy: data_structures::DMARCPolicy::from(report.policy_published.sp),
+ percentage: match u64::from_str(&report.policy_published.pct) {
+ Ok(pct) => pct,
+ Err(_) => {
+ panic!(
+ "Percentage value '{:?}' for DMARC record is not valid",
+ report.policy_published.pct
+ );
+ }
+ },
+ failure_opt: data_structures::DMARCFailureOption::from(report.policy_published.fo),
+ },
+ dkim_pass: match report.record.auth_results.dkim.result.as_str() {
+ "pass" => true,
+ _ => false,
+ },
+ spf_pass: match report.record.auth_results.spf.result.as_str() {
+ "pass" => true,
+ _ => false,
+ },
+ }
+ }
+}
+
#[cfg(test)]
mod test {
use super::*;
@@ -63,4 +137,19 @@ mod test {
}
}
}
+
+ #[test]
+ fn test_parse_dmarc_report() {
+ let dmarc_report_file = File::open("fixtures/dmarc_report_fixture.xml").unwrap();
+
+ let reader = BufReader::new(dmarc_report_file);
+
+ let raw_report = deserialize_dmarc_report(reader).unwrap();
+
+ let expected_dmarc_report_id = "3374fb5148ba40c1a5cf8e3d36f34a34".to_string();
+
+ let dmarc_report = data_structures::DMARCReport::from_raw_report(raw_report);
+
+ assert_eq!(dmarc_report.id, expected_dmarc_report_id);
+ }
}