feat: add /login stub and /auth/mode endpoint
This commit is contained in:
@@ -22,6 +22,7 @@ import websockets.exceptions
|
||||
from websockets.typing import Subprotocol
|
||||
|
||||
from fastapi import FastAPI, HTTPException, WebSocket
|
||||
from fastapi.responses import HTMLResponse, JSONResponse as FastJSONResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from pydantic import BaseModel
|
||||
|
||||
@@ -465,6 +466,34 @@ async def terminal_ws_proxy(websocket: WebSocket) -> None:
|
||||
pass
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Auth routes
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@app.get("/login", response_class=HTMLResponse)
|
||||
async def login_page():
|
||||
"""Stub login page — replaced in Phase 2 with branded login.html."""
|
||||
return HTMLResponse(
|
||||
"<html><body>"
|
||||
"<h1>muxplex login</h1>"
|
||||
"<form method='POST' action='/login'>"
|
||||
"<input name='password' type='password' placeholder='Password' autocomplete='current-password'>"
|
||||
"<button type='submit'>Login</button>"
|
||||
"</form>"
|
||||
"</body></html>"
|
||||
)
|
||||
|
||||
|
||||
@app.get("/auth/mode")
|
||||
async def auth_mode_endpoint():
|
||||
"""Return the current auth mode and running username."""
|
||||
username = ""
|
||||
if _auth_mode == "pam":
|
||||
username = pwd.getpwuid(os.getuid()).pw_name
|
||||
return {"mode": _auth_mode, "user": username}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Static file serving — MUST come after all API routes (first-match-wins)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -683,3 +683,25 @@ def test_non_localhost_without_auth_gets_redirected(monkeypatch):
|
||||
response = c.get("/health", follow_redirects=False)
|
||||
# Should be redirected to /login or get 307/401
|
||||
assert response.status_code in (307, 401)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Login stub and auth mode endpoint
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_get_login_returns_200_html(client):
|
||||
"""GET /login returns 200 with HTML content."""
|
||||
response = client.get("/login")
|
||||
assert response.status_code == 200
|
||||
assert "text/html" in response.headers["content-type"]
|
||||
assert "<form" in response.text
|
||||
|
||||
|
||||
def test_get_auth_mode_returns_json(client):
|
||||
"""GET /auth/mode returns JSON with mode field."""
|
||||
response = client.get("/auth/mode")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert "mode" in data
|
||||
assert data["mode"] in ("pam", "password")
|
||||
|
||||
Reference in New Issue
Block a user