feat: wire federation key into AuthMiddleware at startup
This commit is contained in:
+3
-1
@@ -60,7 +60,7 @@ from muxplex.state import (
|
|||||||
save_state,
|
save_state,
|
||||||
state_lock,
|
state_lock,
|
||||||
)
|
)
|
||||||
from muxplex.settings import load_settings, patch_settings
|
from muxplex.settings import load_federation_key, load_settings, patch_settings
|
||||||
from muxplex.ttyd import kill_orphan_ttyd, kill_ttyd, spawn_ttyd, TTYD_PORT
|
from muxplex.ttyd import kill_orphan_ttyd, kill_ttyd, spawn_ttyd, TTYD_PORT
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -244,6 +244,7 @@ def _resolve_auth() -> tuple[str, str]:
|
|||||||
_auth_mode, _auth_password = _resolve_auth()
|
_auth_mode, _auth_password = _resolve_auth()
|
||||||
_auth_secret = load_or_create_secret()
|
_auth_secret = load_or_create_secret()
|
||||||
_auth_ttl = int(os.environ.get("MUXPLEX_SESSION_TTL", "604800"))
|
_auth_ttl = int(os.environ.get("MUXPLEX_SESSION_TTL", "604800"))
|
||||||
|
_federation_key = load_federation_key()
|
||||||
|
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
AuthMiddleware,
|
AuthMiddleware,
|
||||||
@@ -251,6 +252,7 @@ app.add_middleware(
|
|||||||
secret=_auth_secret,
|
secret=_auth_secret,
|
||||||
ttl_seconds=_auth_ttl,
|
ttl_seconds=_auth_ttl,
|
||||||
password=_auth_password,
|
password=_auth_password,
|
||||||
|
federation_key=_federation_key,
|
||||||
)
|
)
|
||||||
|
|
||||||
# CORS: allow_origins=["*"] with allow_credentials=True is intentional for
|
# CORS: allow_origins=["*"] with allow_credentials=True is intentional for
|
||||||
|
|||||||
@@ -1387,3 +1387,51 @@ def test_get_auth_token_returns_401_when_not_authenticated(monkeypatch):
|
|||||||
# No cookie set — endpoint must return 401 with application/json accept
|
# No cookie set — endpoint must return 401 with application/json accept
|
||||||
response = c.get("/api/auth/token", headers={"Accept": "application/json"})
|
response = c.get("/api/auth/token", headers={"Accept": "application/json"})
|
||||||
assert response.status_code == 401
|
assert response.status_code == 401
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Federation Bearer token auth
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def test_federation_bearer_auth_accepted(monkeypatch):
|
||||||
|
"""Request with valid Bearer token gets 200 on /api/sessions when federation key is set.
|
||||||
|
|
||||||
|
Patches the federation key on the AuthMiddleware instance (since the key is
|
||||||
|
loaded once at module startup) and verifies that a Bearer-authenticated
|
||||||
|
request reaches /api/sessions with HTTP 200.
|
||||||
|
|
||||||
|
Before implementation: fails with ImportError — _federation_key not in main.py.
|
||||||
|
After implementation: _federation_key exists, middleware is found and patched,
|
||||||
|
Bearer request is accepted.
|
||||||
|
"""
|
||||||
|
from muxplex.main import _federation_key # ImportError before implementation
|
||||||
|
from muxplex.auth import AuthMiddleware
|
||||||
|
import muxplex.main as main_module
|
||||||
|
|
||||||
|
federation_key = "test-federation-key-abc123"
|
||||||
|
monkeypatch.setenv("MUXPLEX_PASSWORD", "test-password")
|
||||||
|
|
||||||
|
with TestClient(main_module.app) as c:
|
||||||
|
# Traverse the compiled middleware stack to find the AuthMiddleware instance
|
||||||
|
stack = main_module.app.middleware_stack
|
||||||
|
auth_mw = None
|
||||||
|
for _ in range(20):
|
||||||
|
if isinstance(stack, AuthMiddleware):
|
||||||
|
auth_mw = stack
|
||||||
|
break
|
||||||
|
stack = getattr(stack, "app", None)
|
||||||
|
if stack is None:
|
||||||
|
break
|
||||||
|
|
||||||
|
assert auth_mw is not None, "AuthMiddleware not found in middleware stack"
|
||||||
|
# Patch the federation key so Bearer token auth is enabled
|
||||||
|
auth_mw.federation_key = federation_key
|
||||||
|
|
||||||
|
# A request with a matching Bearer token must pass auth and get 200
|
||||||
|
response = c.get(
|
||||||
|
"/api/sessions",
|
||||||
|
headers={"Authorization": f"Bearer {federation_key}"},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
|||||||
Reference in New Issue
Block a user