59 lines
1.9 KiB
Python
59 lines
1.9 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from starlette.applications import Starlette
|
|
from starlette.responses import JSONResponse
|
|
from starlette.testclient import TestClient
|
|
|
|
from host_agent.mcp_token import McpTokenStore
|
|
from host_agent.web.mcp_auth import BearerAuthMiddleware
|
|
|
|
|
|
def _make_client(tmp_path: Path) -> tuple[TestClient, str]:
|
|
store = McpTokenStore(tmp_path / "host_mcp_token.json")
|
|
token = store.load_or_create().token
|
|
|
|
async def hello(request): # type: ignore[no-untyped-def]
|
|
return JSONResponse({"ok": True})
|
|
|
|
inner = Starlette(routes=[])
|
|
inner.router.add_route("/", hello, methods=["GET"])
|
|
wrapped = Starlette()
|
|
wrapped.add_middleware(BearerAuthMiddleware, token_store=store)
|
|
wrapped.mount("/", inner)
|
|
return TestClient(wrapped), token
|
|
|
|
|
|
def test_no_header_returns_401(tmp_path: Path) -> None:
|
|
client, _ = _make_client(tmp_path)
|
|
resp = client.get("/")
|
|
assert resp.status_code == 401
|
|
assert resp.headers["WWW-Authenticate"] == "Bearer"
|
|
assert resp.json() == {"error": "invalid token"}
|
|
|
|
|
|
def test_wrong_token_returns_401(tmp_path: Path) -> None:
|
|
client, _ = _make_client(tmp_path)
|
|
resp = client.get("/", headers={"Authorization": "Bearer wrong"})
|
|
assert resp.status_code == 401
|
|
|
|
|
|
def test_correct_token_passes_through(tmp_path: Path) -> None:
|
|
client, token = _make_client(tmp_path)
|
|
resp = client.get("/", headers={"Authorization": f"Bearer {token}"})
|
|
assert resp.status_code == 200
|
|
assert resp.json() == {"ok": True}
|
|
|
|
|
|
def test_non_bearer_scheme_returns_401(tmp_path: Path) -> None:
|
|
client, token = _make_client(tmp_path)
|
|
resp = client.get("/", headers={"Authorization": f"Basic {token}"})
|
|
assert resp.status_code == 401
|
|
|
|
|
|
def test_header_case_insensitive(tmp_path: Path) -> None:
|
|
client, token = _make_client(tmp_path)
|
|
resp = client.get("/", headers={"authorization": f"Bearer {token}"})
|
|
assert resp.status_code == 200
|