secubox-deb/packages/secubox-proxypac/tests/test_rules.py
CyberMind ff8ba36ff0
Some checks are pending
License Headers / check (push) Waiting to run
feat(proxypac): WPAD/PAC auto-config routing to active mesh services (Closes #784) (#788)
* docs(spec): secubox-proxypac WPAD/PAC mesh-service routing design (ref #784)

* docs(plan): secubox-proxypac 11-task TDD implementation plan (ref #784)

* feat(annuaire): optional byte-stable pac descriptor on ServiceOffer (ref #784)

* feat(proxypac): PAC template + fail-open directive builder (ref #784)

* feat(proxypac): rules.d parsing + precedence compose (ref #784)

* feat(proxypac): p2p /services catalog reader → routing rules (ref #784)

* feat(proxypac): generator + atomic fail-safe write + CLI (ref #784)

* fix(proxypac): shadow file is <pac>.shadow not <base>.shadow (ref #784)

* feat(proxypac): WebUI API override CRUD + candidates + audit (ref #784)

* fix(proxypac): regen honors RULES_DIR + reject whitespace in override host (ref #784)

* feat(proxypac): nginx PAC/WPAD serving (LAN-only) + seed rule (ref #784)

* fix(proxypac): gate /proxy.pac to LAN/mesh (never public) (ref #784)

* feat(proxypac): regen path+timer units + DHCP 252 WPAD advertise (ref #784)

* feat(proxypac): WebUI override panel + menu entry (ref #784)

* fix(proxypac): correct menu schema (name/category) + escape panel output (ref #784)

* feat(proxypac): debian packaging (ref #784)

* fix(proxypac): drop duplicate debian/compat + correct secubox user creation (ref #784)

* docs(proxypac): README + deploy notes (ref #784)

* fix(proxypac): apply final-review follow-ups (ref #784)

- compose: overrides now last-file-wins per host, so an operator's later
  50-webui.rules override beats a shipped 00-onion.rules seed for the same glob
  (explicit policy > defaults); cross-source override>service>toolbox unchanged.
  New test test_compose_override_last_file_wins.
- packaging: declare Depends: secubox-hub — the /proxy.pac allow/deny gate matches
  $remote_addr, which behind HAProxy is 127.0.0.1 unless secubox-hub's real_ip
  (X-Forwarded-For) rewrite is loaded; without it the PAC would be world-readable.
  nginx/proxypac.conf comments the dependency; test asserts it in control.
- README: document last-file-wins precedence + the real_ip/secubox-hub dependency.

---------

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
2026-07-03 11:57:26 +02:00

30 lines
1.4 KiB
Python

from proxypac.rules import Rule, parse_rules_dir, compose
def test_parse_rules_dir(tmp_path):
(tmp_path / "10-a.rules").write_text("# c\n*.onion socks5 10.10.0.1:9050\n\n")
(tmp_path / "20-b.rules").write_text("bank.example direct\n")
rules = parse_rules_dir(tmp_path)
assert [(r.host, r.directive) for r in rules] == [
("*.onion", "SOCKS5 10.10.0.1:9050; DIRECT"),
("bank.example", "DIRECT"),
]
assert all(r.source == "override" for r in rules)
def test_compose_precedence_override_beats_service():
ov = [Rule("x.com", "DIRECT", "override")]
svc = [Rule("x.com", "PROXY p; DIRECT", "service:1"), Rule("y.com", "PROXY p; DIRECT", "service:1")]
tb = Rule("*", "PROXY t; DIRECT", "toolbox")
out = compose(ov, svc, tb)
# override wins for x.com; y.com from service; toolbox catch-all last
assert out == [("x.com", "DIRECT"), ("y.com", "PROXY p; DIRECT"), ("*", "PROXY t; DIRECT")]
def test_compose_no_toolbox():
assert compose([], [], None) == []
def test_compose_override_last_file_wins():
# A later operator override (e.g. 50-webui.rules) must beat an earlier seed
# (e.g. 00-onion.rules) for the same host glob.
ov = [Rule("*.onion", "SOCKS5 10.10.0.1:9050; DIRECT", "override"), # 00-onion seed
Rule("*.onion", "DIRECT", "override")] # 50-webui (later)
assert compose(ov, [], None) == [("*.onion", "DIRECT")]