Files
RustProxy/tools/checks/dynamic_acl_0325.py
T
2026-10-14 14:54:22 +02:00

33 lines
2.6 KiB
Python
Executable File

#!/usr/bin/env python3
"""Static source contract for DDNS ACL 0.32.7; NOT a Rust test."""
from pathlib import Path
import json
import tomllib
ROOT = Path(__file__).resolve().parents[2]
read = lambda p: (ROOT / p).read_text(encoding="utf-8")
acl = read('src/acl.rs')
dns = read('src/acl/dynamic.rs')
js = read('src/admin/web/management.js')
checks = {
'keep static IP/CIDR checks': 'RuleMatch::Ip(net) => net.contains(&peer)' in acl,
'dynamic DNS only allows explicit allow rules': 'dynamic DNS ACL rules only support allow' in acl,
'deny precedence retained': 'return Some(Action::Deny)' in acl,
'strict hostname validation': 'pub(crate) fn hostname(' in dns,
'scope scan covers vhosts, locations, profiles, host policies and docker': all(f in dns for f in [
'config.host_policies', 'config.acl_profiles', 'config.vhosts', 'vhost.routes', 'config.docker_agents.agents', 'agent.assignments'
]),
'bounded asynchronous DNS work': all(x in dns for x in ['REFRESH_SECONDS: u64 = 60', 'MAX_AGE_SECONDS: u64 = 180', 'MAX_NAMES: usize = 128', 'MAX_ADDRESSES: usize = 32', 'PARALLEL_LOOKUPS: usize = 8', 'LOOKUP_SECONDS: u64 = 4', 'buffer_unordered(PARALLEL_LOOKUPS)']),
'lookup on refresh, not on request': 'lookup_host' in dns and 'lookup_host' not in acl and 'dynamic::matches' in acl,
'resolver owns the cache key independently of the DNS future (E0505)': 'let lookup_name = name.clone();' in dns and 'lookup_host((lookup_name.as_str(), 0u16))' in dns and 'lookup_host((name.as_str(), 0u16))' not in dns,
'fail closed on empty or failed resolution': 'CACHE.store(Arc::new(results))' in dns and 'return (name, None);' in dns and 'entry.valid_until > Instant::now()' in dns,
'update after configuration commit': all('crate::acl::dynamic::config_changed()' in read(p) for p in ['src/runtime/updates.rs', 'src/runtime/docker.rs', 'src/runtime/certificates.rs']),
'startup background refresh': 'state.start_dns_acl_updates();' in read('src/main/admin_runtime.rs'),
'visual selector and disabled DNS deny': '.acl-profile-rule-type' in js and 'aclDnsAllowOnly' in js,
'old network field persisted': 'network: normalizeNetwork(' in js,
'PL/EN translations': all(k in json.loads(read(f'langs/{loc}.json'))['translations'] for loc in ('en_US','pl_pl') for k in ('aclRuleType','aclRuleDns','aclDnsHelp','aclDnsAllowOnly')),
'package version': tomllib.loads(read('Cargo.toml'))['package']['version'] == '0.32.7',
}
for name, ok in checks.items():
if not ok: raise AssertionError(name)
print(f'PASS: {len(checks)} DNS ACL 0.32.7 static source checks (not compiled or network-tested)')