feat: findings refinement, new scanners, and deployment tooling (#6)
Some checks failed
CI / Format (push) Successful in 3s
CI / Clippy (push) Successful in 4m3s
CI / Security Audit (push) Successful in 1m38s
CI / Tests (push) Successful in 4m44s
CI / Detect Changes (push) Successful in 2s
CI / Deploy Agent (push) Successful in 2s
CI / Deploy Dashboard (push) Successful in 2s
CI / Deploy Docs (push) Has been skipped
CI / Deploy MCP (push) Failing after 2s
Some checks failed
CI / Format (push) Successful in 3s
CI / Clippy (push) Successful in 4m3s
CI / Security Audit (push) Successful in 1m38s
CI / Tests (push) Successful in 4m44s
CI / Detect Changes (push) Successful in 2s
CI / Deploy Agent (push) Successful in 2s
CI / Deploy Dashboard (push) Successful in 2s
CI / Deploy Docs (push) Has been skipped
CI / Deploy MCP (push) Failing after 2s
This commit was merged in pull request #6.
This commit is contained in:
@@ -64,6 +64,8 @@ impl CveScanner {
|
||||
}
|
||||
|
||||
async fn query_osv_batch(&self, entries: &[SbomEntry]) -> Result<Vec<Vec<OsvVuln>>, CoreError> {
|
||||
const OSV_BATCH_SIZE: usize = 500;
|
||||
|
||||
let queries: Vec<_> = entries
|
||||
.iter()
|
||||
.filter_map(|e| {
|
||||
@@ -79,32 +81,34 @@ impl CveScanner {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
|
||||
let body = serde_json::json!({ "queries": queries });
|
||||
let mut all_vulns: Vec<Vec<OsvVuln>> = Vec::with_capacity(queries.len());
|
||||
|
||||
let resp = self
|
||||
.http
|
||||
.post("https://api.osv.dev/v1/querybatch")
|
||||
.json(&body)
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| CoreError::Http(format!("OSV.dev request failed: {e}")))?;
|
||||
for chunk in queries.chunks(OSV_BATCH_SIZE) {
|
||||
let body = serde_json::json!({ "queries": chunk });
|
||||
|
||||
if !resp.status().is_success() {
|
||||
let status = resp.status();
|
||||
let body = resp.text().await.unwrap_or_default();
|
||||
tracing::warn!("OSV.dev returned {status}: {body}");
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
let resp = self
|
||||
.http
|
||||
.post("https://api.osv.dev/v1/querybatch")
|
||||
.json(&body)
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| CoreError::Http(format!("OSV.dev request failed: {e}")))?;
|
||||
|
||||
let result: OsvBatchResponse = resp
|
||||
.json()
|
||||
.await
|
||||
.map_err(|e| CoreError::Http(format!("Failed to parse OSV.dev response: {e}")))?;
|
||||
if !resp.status().is_success() {
|
||||
let status = resp.status();
|
||||
let body = resp.text().await.unwrap_or_default();
|
||||
tracing::warn!("OSV.dev returned {status}: {body}");
|
||||
// Push empty results for this chunk so indices stay aligned
|
||||
all_vulns.extend(std::iter::repeat_with(Vec::new).take(chunk.len()));
|
||||
continue;
|
||||
}
|
||||
|
||||
let vulns = result
|
||||
.results
|
||||
.into_iter()
|
||||
.map(|r| {
|
||||
let result: OsvBatchResponse = resp
|
||||
.json()
|
||||
.await
|
||||
.map_err(|e| CoreError::Http(format!("Failed to parse OSV.dev response: {e}")))?;
|
||||
|
||||
let chunk_vulns = result.results.into_iter().map(|r| {
|
||||
r.vulns
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
@@ -116,10 +120,12 @@ impl CveScanner {
|
||||
}),
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.collect();
|
||||
});
|
||||
|
||||
Ok(vulns)
|
||||
all_vulns.extend(chunk_vulns);
|
||||
}
|
||||
|
||||
Ok(all_vulns)
|
||||
}
|
||||
|
||||
async fn query_nvd(&self, cve_id: &str) -> Result<Option<f64>, CoreError> {
|
||||
|
||||
Reference in New Issue
Block a user