use crate::evidence::Evidence;
use crate::finding::Finding;
use crate::kind::FindingKind;
use crate::severity::Severity as UniversalSeverity;
use crate::status::FindingStatus;
use std::sync::Arc;
pub fn to_universal(
ir: &secir::finding::Finding,
scanner_name: &str,
) -> Result<Finding, crate::FindingBuildError> {
let severity = map_severity(ir.severity);
let kind = map_kind(&ir.kind);
let title = if ir.template_name.is_empty() {
ir.template_id.clone()
} else {
ir.template_name.clone()
};
let mut builder = Finding::builder(scanner_name, &ir.target, severity)
.title(title)
.detail(ir.description.clone().unwrap_or_default())
.kind(kind)
.status(FindingStatus::Open)
.timestamp(ir.timestamp);
if let Some(req) = &ir.request {
builder = builder.evidence(Evidence::Raw(Arc::from(format!("[request]\n{req}"))));
}
if let Some(resp) = &ir.response {
builder = builder.evidence(Evidence::Raw(Arc::from(format!("[response]\n{resp}"))));
}
for matched in &ir.matched_values {
builder = builder.evidence(Evidence::PatternMatch {
pattern: Arc::from(
ir.matcher_name
.clone()
.unwrap_or_else(|| "template-match".to_string()),
),
matched: Arc::from(matched.clone()),
});
}
for tag in &ir.tags {
builder = builder.tag(tag.clone());
}
for cve in &ir.cve_ids {
builder = builder.cve(cve.clone());
}
for reference in &ir.references {
builder = builder.reference(reference.clone());
}
if let Some(conf) = ir.confidence {
builder = builder.confidence(conf);
}
if let Some(curl) = &ir.curl_command {
builder = builder.exploit_hint(curl.clone());
}
for matched in &ir.matched_values {
builder = builder.matched_value(matched.clone());
}
builder.build()
}
pub fn map_severity(ir: secir::Severity) -> UniversalSeverity {
match ir {
secir::Severity::Info => UniversalSeverity::Info,
secir::Severity::Low => UniversalSeverity::Low,
secir::Severity::Medium => UniversalSeverity::Medium,
secir::Severity::High => UniversalSeverity::High,
secir::Severity::Critical => UniversalSeverity::Critical,
_ => UniversalSeverity::Info,
}
}
pub fn map_kind(ir: &secir::finding::FindingKind) -> FindingKind {
match ir {
secir::finding::FindingKind::Vulnerability => FindingKind::Vulnerability,
secir::finding::FindingKind::Misconfiguration => FindingKind::Misconfiguration,
secir::finding::FindingKind::Exposure => FindingKind::Exposure,
secir::finding::FindingKind::TechDetect => FindingKind::TechDetect,
secir::finding::FindingKind::DefaultCredentials => FindingKind::DefaultCredentials,
secir::finding::FindingKind::InfoDisclosure => FindingKind::InfoDisclosure,
secir::finding::FindingKind::FileDiscovery => FindingKind::FileDiscovery,
secir::finding::FindingKind::Other => FindingKind::Other,
_ => FindingKind::Other,
}
}