OmniVoice-Studio / tests /test_bind_host.py
Lê Phi Nam
Deploy to HF Space
94004a2
Raw
History Blame Contribute Delete
3.13 kB
"""
Bind-host resolution tests — guards against regressing the loopback default.
`backend/main.py` resolves its uvicorn bind host from `OMNIVOICE_BIND_HOST`
with a default of `127.0.0.1`. Binding to `0.0.0.0` by default would expose
every (currently unauthenticated) router on the user's LAN — see the security
note in `deploy/docker-compose.yml`.
These tests don't boot uvicorn. They re-evaluate the resolution expression
used in `main.py`'s `__main__` block, both as a string-level guard against
edits that swap the default back to `0.0.0.0`, and as a behavioral guard
on the env-var override path.
"""
import os
import re
from pathlib import Path
_BACKEND_MAIN = Path(__file__).resolve().parent.parent / "backend" / "main.py"
def _resolve_bind_host(env: dict) -> str:
"""Mirror of the resolution logic in `backend/main.py`'s __main__ block.
Kept in lock-step with the production expression on purpose — any code
change there should require the test to be updated as well, which is
exactly the regression boundary we want.
"""
return env.get("OMNIVOICE_BIND_HOST", "127.0.0.1")
def test_default_bind_is_loopback_when_env_unset():
assert _resolve_bind_host({}) == "127.0.0.1"
def test_explicit_loopback_env_var_is_honored():
assert _resolve_bind_host({"OMNIVOICE_BIND_HOST": "127.0.0.1"}) == "127.0.0.1"
def test_explicit_all_interfaces_env_var_is_honored():
# Used by deploy/docker-compose.yml — must still work as an opt-in override.
assert _resolve_bind_host({"OMNIVOICE_BIND_HOST": "0.0.0.0"}) == "0.0.0.0"
def test_backend_main_source_does_not_hardcode_all_interfaces_default():
"""String-level guard against re-introducing a `host="0.0.0.0"` default
in `backend/main.py`. If someone edits the production uvicorn.run call to
hardcode 0.0.0.0 again, this test fails with a pointer to the security
rationale in the surrounding comment."""
src = _BACKEND_MAIN.read_text(encoding="utf-8")
# The health-check thread legitimately binds 127.0.0.1; the production
# call should reference OMNIVOICE_BIND_HOST (env-driven), not a hardcoded
# 0.0.0.0 literal. Allow `0.0.0.0` to appear in *comments* (security
# rationale block) but not in any uvicorn.run(...) host= argument.
bad_pattern = re.compile(r'uvicorn\.run\([^)]*host\s*=\s*["\']0\.0\.0\.0["\']')
assert not bad_pattern.search(src), (
"backend/main.py contains a hardcoded host=\"0.0.0.0\" in uvicorn.run(). "
"Use OMNIVOICE_BIND_HOST env var (default 127.0.0.1) instead — see "
"the security comment block above the call site."
)
def test_backend_main_source_references_omnivoice_bind_host():
"""Companion to the above: the env-var-driven path must be present so a
future refactor doesn't accidentally remove it (which would silently
revert to whichever literal defaults the new code chose)."""
src = _BACKEND_MAIN.read_text(encoding="utf-8")
assert "OMNIVOICE_BIND_HOST" in src, (
"backend/main.py no longer references OMNIVOICE_BIND_HOST — the "
"loopback-default contract is unenforced."
)