mirror of
https://github.com/CyberMind-FR/secubox-deb.git
synced 2026-07-29 13:59:40 +00:00
fix(profiles): load_routes must not crash on an untraversable parent
Found by deploying to the real board, not by tests: GET /status returned 500. /etc/secubox/waf is 0750 root:root while haproxy-routes.json inside it is 0644 — the file is world-readable, the directory is not traversable by the secubox user the service runs as. Path.exists() raises PermissionError in that case, and it sat OUTSIDE the try that already guarded read_text. This is the fifth instance of the same class on this branch. The previous four were 'unknown must not become a definite answer'; this one is its twin: unknown must not become a crash either. An unreadable routes file now yields None (undeterminable) as intended, so /status degrades to 'exposure unknown' instead of 500ing the whole panel. The directory permissions are the WAF module's business and are left alone — this module's job is to survive them. Co-Authored-By: Gerald KERMA <devel@cybermind.fr>
This commit is contained in:
parent
78f5e80747
commit
cedc012051
|
|
@ -52,11 +52,17 @@ def _run_cmd(argv: list[str]) -> tuple[int | None, str]:
|
|||
|
||||
def load_routes(path: Path = ROUTES_FILE) -> set[str] | None:
|
||||
"""Domaines routés par le WAF. Fichier absent = aucune route (pas une erreur).
|
||||
|
||||
`.exists()` est DANS le try : il lève PermissionError quand un parent n'est
|
||||
pas traversable, et c'est le cas réel sur la board — /etc/secubox/waf est
|
||||
0750 root:root alors que haproxy-routes.json est 0644. Le laisser dehors
|
||||
faisait remonter un 500 sur /status au lieu d'un « indéterminable ».
|
||||
Inconnu ne doit ni mentir NI planter.
|
||||
Fichier présent mais illisible/corrompu = indéterminable → None, pas set()."""
|
||||
path = Path(path)
|
||||
if not path.exists():
|
||||
return set()
|
||||
try:
|
||||
if not path.exists():
|
||||
return set()
|
||||
return set(json.loads(path.read_text(encoding="utf-8")))
|
||||
except (OSError, json.JSONDecodeError):
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -164,3 +164,20 @@ def test_observe_portal_routed_none_when_routes_undeterminable(monkeypatch):
|
|||
})
|
||||
a = observe(LXC, run=run)
|
||||
assert a.portal_routed is None
|
||||
|
||||
|
||||
def test_load_routes_untraversable_parent_is_none_not_crash(tmp_path):
|
||||
"""Cas RÉEL de la board : /etc/secubox/waf est 0750 root:root alors que
|
||||
haproxy-routes.json est 0644 — le fichier est lisible, le répertoire non
|
||||
traversable. `.exists()` lève alors PermissionError. Le laisser hors du try
|
||||
remontait un 500 sur GET /status. Inconnu ne doit ni mentir ni planter."""
|
||||
import os
|
||||
waf = tmp_path / "waf"
|
||||
waf.mkdir()
|
||||
routes = waf / "haproxy-routes.json"
|
||||
routes.write_text(json.dumps({"peertube.gk2.secubox.in": ["127.0.0.1", 9000]}))
|
||||
os.chmod(waf, 0o000) # parent non traversable
|
||||
try:
|
||||
assert load_routes(routes) is None # indéterminable, pas set(), pas d'exception
|
||||
finally:
|
||||
os.chmod(waf, 0o755) # sinon tmp_path n'est pas nettoyable
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user