pub mod basic;
use crate::model::{Config, Finding};
pub trait Rule {
fn name(&self) -> &'static str;
fn check(&self, config: &Config) -> Vec<Finding>;
}
pub fn run_all(config: &Config) -> Vec<Finding> {
let rules: Vec<Box<dyn Rule>> = vec![
Box::new(basic::DuplicateHost),
Box::new(basic::IdentityFileExists),
Box::new(basic::WildcardHostOrder),
Box::new(basic::DeprecatedWeakAlgorithms),
Box::new(basic::DuplicateDirectives),
Box::new(basic::InsecureOption),
Box::new(basic::UnsafeControlPath),
];
let mut findings = Vec::new();
for rule in &rules {
findings.extend(rule.check(config));
}
findings
}
#[cfg(test)]
mod tests {
use super::*;
use crate::model::{Config, Finding, Item, Severity, Span};
struct DummyRule;
impl Rule for DummyRule {
fn name(&self) -> &'static str {
"dummy"
}
fn check(&self, _config: &Config) -> Vec<Finding> {
vec![Finding::new(
Severity::Info,
"dummy",
"TEST",
"this is a test",
Span::new(1),
)]
}
}
#[test]
fn trait_rule_returns_finding() {
let config = Config { items: vec![] };
let rule = DummyRule;
let findings = rule.check(&config);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].rule, "dummy");
}
#[test]
fn run_all_merges_findings() {
let config = Config { items: vec![] };
let findings = run_all(&config);
assert!(findings.is_empty());
}
#[test]
fn run_all_on_config_with_duplicates() {
let config = Config {
items: vec![
Item::HostBlock {
patterns: vec!["github.com".to_string()],
span: Span::new(1),
items: vec![],
},
Item::HostBlock {
patterns: vec!["github.com".to_string()],
span: Span::new(5),
items: vec![],
},
],
};
let findings = run_all(&config);
assert!(findings.iter().any(|f| f.rule == "duplicate-host"));
}
}