use crate::csaf::types::csaf_datetime::{CsafDateTime, ValidCsafDateTime};
use crate::csaf_traits::{CsafTrait, DocumentTrait, TrackingTrait, VulnerabilityTrait};
use crate::validation::ValidationError;
use chrono::Utc;
fn create_disclosure_date_newer_than_revision_error(
disclosure_date: &ValidCsafDateTime,
newest_revision_date: &ValidCsafDateTime,
i_v: usize,
) -> ValidationError {
ValidationError {
message: format!(
"Disclosure date ({disclosure_date}) is in the past and newer than the newest revision date ({newest_revision_date})"
),
instance_path: format!("/vulnerabilities/{i_v}/disclosure_date"),
}
}
pub fn test_6_2_33_disclosure_date_newer_than_revision(doc: &impl CsafTrait) -> Result<(), Vec<ValidationError>> {
let mut revision_history = doc.get_document().get_tracking().aggregate_revision_history();
revision_history.inplace_sort_by_date_then_number();
let newest_revision_date = match revision_history.last() {
Some(rev) => match &rev.date {
CsafDateTime::Valid(date) => date,
CsafDateTime::Invalid(_) => return Ok(()), },
None => return Ok(()), };
let now = Utc::now();
let mut errors: Option<Vec<ValidationError>> = None;
for (i_v, vulnerability) in doc.get_vulnerabilities().iter().enumerate() {
if let Some(disclosure_date) = vulnerability.get_disclosure_date() {
match disclosure_date {
CsafDateTime::Valid(valid_disclosure_date) => {
if valid_disclosure_date.get_as_utc() < now && &valid_disclosure_date > newest_revision_date {
errors
.get_or_insert_default()
.push(create_disclosure_date_newer_than_revision_error(
&valid_disclosure_date,
newest_revision_date,
i_v,
));
}
},
CsafDateTime::Invalid(_) => {
},
}
}
}
errors.map_or(Ok(()), Err)
}
crate::test_validation::impl_validator!(
csaf2_1,
ValidatorForTest6_2_33,
test_6_2_33_disclosure_date_newer_than_revision
);
#[cfg(test)]
mod tests {
use super::*;
use crate::csaf2_1::testcases::TESTS_2_1;
use std::str::FromStr;
#[test]
fn test_test_6_2_33() {
let case_01_disclosure_date_newer_than_newest_rev =
Err(vec![create_disclosure_date_newer_than_revision_error(
&ValidCsafDateTime::from_str("2024-02-24T10:00:00.000Z").unwrap(),
&ValidCsafDateTime::from_str("2024-01-24T10:00:00.000Z").unwrap(),
0,
)]);
let case_02_disclosure_date_newer_than_newest_rev_with_timezone =
Err(vec![create_disclosure_date_newer_than_revision_error(
&ValidCsafDateTime::from_str("2024-02-23T14:00:00.000-21:00").unwrap(),
&ValidCsafDateTime::from_str("2024-01-24T10:00:00.000Z").unwrap(),
0,
)]);
let case_03_disclosure_date_newer_than_newest_rev_with_timezone =
Err(vec![create_disclosure_date_newer_than_revision_error(
&ValidCsafDateTime::from_str("2024-02-24T14:00:00.000-07:00").unwrap(),
&ValidCsafDateTime::from_str("2024-02-24T10:00:00.000Z").unwrap(),
0,
)]);
TESTS_2_1.test_6_2_33.expect(
case_01_disclosure_date_newer_than_newest_rev,
case_02_disclosure_date_newer_than_newest_rev_with_timezone,
case_03_disclosure_date_newer_than_newest_rev_with_timezone,
Ok(()),
Ok(()),
Ok(()),
);
}
}