Refresh scanner details of findings that are seen again

A rescan only touched the timestamp of findings it had seen before, so a
newly published fix version, a changed severity and the package source
never reached existing rows. The repository now updates those fields
while keeping first_seen and the status the user set.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Dennis Nemec
2026-09-03 19:50:18 +02:00
parent aba2c69416
commit 70cf25fc7f
5 changed files with 93 additions and 23 deletions

View File

@ -363,3 +363,48 @@ async fn targets_are_reported_with_their_scope_and_open_count() {
// an image without findings is not listed
assert!(targets.iter().all(|t| t.target != PG));
}
#[tokio::test]
async fn rescan_refreshes_scanner_details_of_findings_that_are_still_present() {
let mut first = raw("CVE-1", "openssl", "3.0.1", Severity::Medium, None);
first.source = String::new();
let scanner = FakeScanner::default().with("os", Ok(vec![first]));
let (f, svc) = fixture(scanner);
svc.scan(&VecLog::default()).await.unwrap();
let before = f.findings.0.lock().unwrap()[0].clone();
svc.set_status(before.id, FindingStatus::Acknowledged)
.await
.unwrap();
// the scanner now rates it higher, knows a fix and reports the package source
let mut updated = raw(
"CVE-1",
"openssl",
"3.0.1",
Severity::Critical,
Some("3.0.2"),
);
updated.source = "debian".into();
updated.title = "openssl: corrected title".into();
*f.results.lock().unwrap() =
std::collections::HashMap::from([("os".to_string(), Ok(vec![updated]))]);
let report = svc.scan(&VecLog::default()).await.unwrap();
assert!(
report.new_findings.is_empty(),
"same finding, not a new one"
);
let after = f.findings.0.lock().unwrap()[0].clone();
assert_eq!(after.id, before.id);
assert_eq!(after.raw.severity, Severity::Critical);
assert_eq!(after.raw.fixed_version.as_deref(), Some("3.0.2"));
assert_eq!(after.raw.source, "debian");
assert_eq!(after.raw.title, "openssl: corrected title");
assert_eq!(after.first_seen, before.first_seen, "first_seen is kept");
assert!(after.last_seen > before.last_seen);
assert_eq!(
after.status,
FindingStatus::Acknowledged,
"the user's decision is kept"
);
}