use openmoat_hosts::Host;
use super::Outcome;
use crate::protection::Protection;
fn step(host: Host) -> Option<&'static str> {
host.spec().install.as_ref()?.trust_step
}
pub fn after_install(host: Host, outcome: Outcome) -> Option<&'static str> {
if outcome == Outcome::Unchanged {
return None;
}
step(host)
}
pub fn protection_line(agent: &Protection) -> Option<String> {
let line = format!("{:<16} protection: {}", agent.name, agent.summary()?);
let step = Host::ALL
.iter()
.find(|host| host.id() == agent.host)
.and_then(|host| step(*host));
Some(match step {
Some(step) => format!("{line}; {step}"),
None => line,
})
}
#[cfg(test)]
mod tests {
use super::*;
fn agent(host: Host) -> Protection {
Protection {
host: host.id(),
name: host.display_name(),
level: crate::protection::Level::HookOnly,
reason: None,
gaps: "",
}
}
#[test]
fn a_host_with_a_trust_step_gets_it_only_when_its_entry_changed() {
let with: Vec<Host> = Host::ALL
.iter()
.copied()
.filter(|h| step(*h).is_some())
.collect();
assert!(!with.is_empty(), "a host has a trust step");
for host in with {
assert!(
after_install(host, Outcome::Installed).is_some(),
"{host:?}"
);
assert!(after_install(host, Outcome::Updated).is_some(), "{host:?}");
assert_eq!(after_install(host, Outcome::Unchanged), None, "{host:?}");
let line = protection_line(&agent(host)).unwrap_or_default();
assert!(line.contains("protection: hook only; "), "{line}");
assert!(line.contains("/hooks"), "{line}");
}
}
#[test]
fn other_hosts_get_no_note() {
for host in Host::ALL.iter().copied().filter(|h| step(*h).is_none()) {
assert_eq!(after_install(host, Outcome::Installed), None, "{host:?}");
let line = protection_line(&agent(host)).unwrap_or_default();
assert!(line.ends_with("protection: hook only"), "{line}");
}
}
}