Skip to content

Commit

Permalink
Allow empty sp field in reports instead of failing to parse completely
Browse files Browse the repository at this point in the history
  • Loading branch information
cry-inc committed Jan 19, 2025
1 parent ba1ecb0 commit 0ebab16
Showing 1 changed file with 23 additions and 2 deletions.
25 changes: 23 additions & 2 deletions src/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Its based upon appendix C of the DMARC RFC:
// https://tools.ietf.org/html/rfc7489#appendix-C

use serde::{Deserialize, Serialize};
use serde::{de, Deserialize, Deserializer, Serialize};
use std::net::IpAddr;

/// The time range in UTC covered by messages in this report.
Expand Down Expand Up @@ -37,7 +37,7 @@ pub enum AlignmentType {
}

/// The policy actions specified by `p` and `sp` in the DMARC record.
#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[derive(Debug, Serialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum DispositionType {
/// There is no preference on how a failed DMARC should be handled.
Expand All @@ -49,6 +49,27 @@ pub enum DispositionType {
Reject,
}

// Custom Deserialize to allow the empty string value that
// some reports contain. For some reason the serde alias marco
// does not work in that case.
impl<'de> Deserialize<'de> for DispositionType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
match s.as_str() {
"quarantine" => Ok(Self::Quarantine),
"reject" => Ok(Self::Reject),
"none" => Ok(Self::None),
"" => Ok(Self::None), // Some reports have an empty `sp` field
_ => Err(de::Error::custom(format!(
"'{s}' is not a known disposition type"
))),
}
}
}

/// The DMARC policy that applied to the messages in this report.
#[derive(Debug, Serialize, Deserialize)]
pub struct PolicyPublishedType {
Expand Down

0 comments on commit 0ebab16

Please sign in to comment.