fix: resolve_auth file password log prints actual path, not module name

Add `get_password_path` to top-level imports in main.py and fix the file
password resolution branch to log the actual file path instead of
`load_password.__module__` (which printed "muxplex.auth").

Also adds 4 tests covering all _resolve_auth logging paths:
- test_resolve_auth_pam_mode_logs_pam
- test_resolve_auth_env_password_logs_env
- test_resolve_auth_file_password_logs_file
- test_resolve_auth_generates_password_as_last_resort
This commit is contained in:
Brian Krabach
2026-03-28 23:06:27 -07:00
parent 387e19a2a2
commit 575cebbcac
2 changed files with 83 additions and 3 deletions
+2 -3
View File
@@ -33,6 +33,7 @@ from muxplex.auth import (
authenticate_pam,
create_session_cookie,
generate_and_save_password,
get_password_path,
load_or_create_secret,
load_password,
pam_available,
@@ -221,15 +222,13 @@ def _resolve_auth() -> tuple[str, str]:
file_pw = load_password()
if file_pw:
print(
f" muxplex auth: password (file: {load_password.__module__})",
f" muxplex auth: password (file: {get_password_path()})",
file=sys.stderr,
)
return "password", file_pw
# Last resort: auto-generate
generated = generate_and_save_password()
from muxplex.auth import get_password_path
print(
f" muxplex auth: password generated — {generated} — saved to {get_password_path()}",
file=sys.stderr,
+81
View File
@@ -366,3 +366,84 @@ def test_middleware_login_path_excluded():
client = TestClient(app, base_url="http://192.168.1.1")
response = client.get("/login")
assert response.status_code == 200
# ---------------------------------------------------------------------------
# _resolve_auth startup logging
# ---------------------------------------------------------------------------
def test_resolve_auth_pam_mode_logs_pam(monkeypatch, capsys, tmp_path):
"""_resolve_auth() in PAM mode logs 'PAM' to stderr."""
monkeypatch.setattr(Path, "home", staticmethod(lambda: tmp_path))
monkeypatch.delenv("MUXPLEX_AUTH", raising=False)
monkeypatch.delenv("MUXPLEX_PASSWORD", raising=False)
monkeypatch.setattr("muxplex.main.pam_available", lambda: True)
from muxplex.main import _resolve_auth
mode, pw = _resolve_auth()
captured = capsys.readouterr()
assert mode == "pam"
assert "PAM" in captured.err
def test_resolve_auth_env_password_logs_env(monkeypatch, capsys, tmp_path):
"""_resolve_auth() with MUXPLEX_PASSWORD env var logs 'env' to stderr."""
monkeypatch.setattr(Path, "home", staticmethod(lambda: tmp_path))
monkeypatch.setenv("MUXPLEX_AUTH", "password")
monkeypatch.setenv("MUXPLEX_PASSWORD", "from-env")
monkeypatch.setattr("muxplex.main.pam_available", lambda: False)
from muxplex.main import _resolve_auth
mode, pw = _resolve_auth()
captured = capsys.readouterr()
assert mode == "password"
assert pw == "from-env"
assert "env" in captured.err
def test_resolve_auth_file_password_logs_file(monkeypatch, capsys, tmp_path):
"""_resolve_auth() with a file password logs the file path to stderr (not module name)."""
monkeypatch.setattr(Path, "home", staticmethod(lambda: tmp_path))
monkeypatch.setenv("MUXPLEX_AUTH", "password")
monkeypatch.delenv("MUXPLEX_PASSWORD", raising=False)
monkeypatch.setattr("muxplex.main.pam_available", lambda: False)
# Create password file
pw_path = tmp_path / ".config" / "muxplex" / "password"
pw_path.parent.mkdir(parents=True, exist_ok=True)
pw_path.write_text("file-secret-pw\n")
pw_path.chmod(0o600)
from muxplex.main import _resolve_auth
mode, pw = _resolve_auth()
captured = capsys.readouterr()
assert mode == "password"
assert pw == "file-secret-pw"
# Should log the actual file path, NOT the module name (Phase 1 bug fix)
assert "muxplex.auth" not in captured.err
assert "file" in captured.err or "password" in captured.err
def test_resolve_auth_generates_password_as_last_resort(monkeypatch, capsys, tmp_path):
"""_resolve_auth() generates a password when no env or file password exists."""
monkeypatch.setattr(Path, "home", staticmethod(lambda: tmp_path))
monkeypatch.setenv("MUXPLEX_AUTH", "password")
monkeypatch.delenv("MUXPLEX_PASSWORD", raising=False)
monkeypatch.setattr("muxplex.main.pam_available", lambda: False)
from muxplex.main import _resolve_auth
mode, pw = _resolve_auth()
captured = capsys.readouterr()
assert mode == "password"
assert len(pw) > 10
assert "generated" in captured.err
assert pw in captured.err