use allow_core::{AllowConfig, CargoAllowResult, Finding, FindingKind};
use std::path::Path;
pub(crate) fn canonical_companion_findings(
root: &Path,
cfg: &AllowConfig,
inventory_files: &[std::path::PathBuf],
) -> CargoAllowResult<Vec<Finding>> {
let mut findings = Vec::new();
if has_allow_family(cfg, FindingKind::GeneratedCode, "generated_code") {
findings.extend(allow_policy_legacy::generated_findings_from_gitattributes(
root,
)?);
}
if has_allow_family(cfg, FindingKind::PolicyException, "executable_file") {
findings.extend(allow_policy_legacy::executable_findings_from_git(root)?);
}
if has_policy_family(cfg, &["github_workflow", "workflow_external_action"]) {
findings.extend(allow_policy_legacy::workflow_findings_from_files(root)?);
}
if has_allow_family(cfg, FindingKind::PolicyException, "dependency_surface") {
findings.extend(allow_policy_legacy::dependency_surface_findings_from_paths(
inventory_files,
cfg,
));
}
if has_allow_family(cfg, FindingKind::PolicyException, "process_spawn") {
findings.extend(allow_policy_legacy::process_findings_from_config(cfg));
}
if has_allow_family(cfg, FindingKind::PolicyException, "network_destination") {
findings.extend(allow_policy_legacy::network_findings_from_config(cfg));
}
Ok(findings)
}
fn has_policy_family(cfg: &AllowConfig, families: &[&str]) -> bool {
cfg.allow.iter().any(|entry| {
entry.kind == FindingKind::PolicyException
&& entry
.family
.as_deref()
.is_some_and(|family| families.contains(&family))
})
}
fn has_allow_family(cfg: &AllowConfig, kind: FindingKind, family: &str) -> bool {
cfg.allow
.iter()
.any(|entry| entry.kind == kind && entry.family.as_deref() == Some(family))
}
pub(crate) fn extend_unique_findings(findings: &mut Vec<Finding>, additional: Vec<Finding>) {
for finding in additional {
if !findings
.iter()
.any(|existing| same_finding_identity(existing, &finding))
{
findings.push(finding);
}
}
}
fn same_finding_identity(left: &Finding, right: &Finding) -> bool {
allow_core::finding_identity_key(left) == allow_core::finding_identity_key(right)
}