use std::collections::HashSet;
use crate::ir::ArgumentSource;
use crate::ir::ScanTarget;
use crate::ir::tool_surface::PermissionType;
use super::domain::{self, DomainPolicy};
use super::merge::{AuditPolicy, RateLimitPolicy};
use super::network::NetworkPolicy;
use super::types::{EgressPolicy, CURRENT_SCHEMA_VERSION};
pub(crate) fn from_scan_targets(targets: &[ScanTarget]) -> EgressPolicy {
let mut domains = HashSet::new();
for target in targets {
for net_op in &target.execution.network_operations {
if let ArgumentSource::Literal(ref url) = net_op.url_arg {
if let Some(domain) = domain::extract_domain(url) {
domains.insert(domain);
}
}
}
for tool in &target.tools {
for perm in &tool.declared_permissions {
if matches!(perm.permission_type, PermissionType::NetworkAccess) {
if let Some(ref scope) = perm.target {
if let Some(domain) = domain::extract_domain(scope) {
domains.insert(domain);
}
}
}
}
}
}
let mut allow: Vec<String> = domains.into_iter().collect();
allow.sort();
EgressPolicy {
schema_version: CURRENT_SCHEMA_VERSION,
domains: DomainPolicy {
allow,
deny: vec![],
},
networks: NetworkPolicy::default(),
rate_limits: RateLimitPolicy::default(),
audit: AuditPolicy::default(),
}
}