termivar_scanner/
post_exploitation.rs1use serde::{Deserialize, Serialize};
19
20#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
25pub struct AssessmentObservation {
26 pub observation_id: String,
27 pub assessment_id: String,
28 pub asset_id: String,
29 pub summary: String,
30 pub evidence_references: Vec<String>,
31 pub observed_at: u64,
32 pub disposition: ObservationDisposition,
33}
34
35#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
37pub enum ObservationDisposition {
38 #[serde(rename = "unreviewed")]
39 Unreviewed,
40 #[serde(rename = "confirmed")]
41 Confirmed,
42 #[serde(rename = "dismissed")]
43 Dismissed,
44}
45
46impl ObservationDisposition {
47 pub fn as_str(self) -> &'static str {
48 match self {
49 Self::Unreviewed => "unreviewed",
50 Self::Confirmed => "confirmed",
51 Self::Dismissed => "dismissed",
52 }
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn observation_is_caller_supplied_metadata() {
62 let observation = AssessmentObservation {
63 observation_id: "observation-1".to_owned(),
64 assessment_id: "assessment-1".to_owned(),
65 asset_id: "asset-1".to_owned(),
66 summary: "Manual review requested".to_owned(),
67 evidence_references: vec!["evidence-1".to_owned()],
68 observed_at: 1_000,
69 disposition: ObservationDisposition::Unreviewed,
70 };
71
72 let encoded = serde_json::to_string(&observation).expect("record serializes");
73 let decoded: AssessmentObservation =
74 serde_json::from_str(&encoded).expect("record deserializes");
75
76 assert_eq!(decoded, observation);
77 assert_eq!(decoded.disposition.as_str(), "unreviewed");
78 }
79}