Four read-only, service-token-protected MCP provider endpoints (operations summary, attention vehicles, vehicle details, knowledge search facade). Shared-secret auth reusing the M4 callback pattern. Service-request audit trail for every call. Extracted shared operations-summary logic out of the dashboard router to avoid duplicating retrieval logic. 66 backend tests passing, ruff clean. Verified all four endpoints and audit trail directly via curl against the live stack (no live MCP Hub instance available in this environment).
53 lines
1.6 KiB
Python
53 lines
1.6 KiB
Python
from __future__ import annotations
|
|
|
|
from collections.abc import Generator
|
|
|
|
from fastapi import Depends, Header, HTTPException, Request, status
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.core.config import get_settings
|
|
from app.core.db import SessionLocal
|
|
from app.core.security import SessionPayload, read_session_token
|
|
from app.schemas import CurrentUser
|
|
|
|
settings = get_settings()
|
|
|
|
|
|
def get_db() -> Generator[Session, None, None]:
|
|
db = SessionLocal()
|
|
try:
|
|
yield db
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
def get_current_user(request: Request) -> CurrentUser:
|
|
token = request.cookies.get(settings.session_cookie_name)
|
|
payload: SessionPayload | None = read_session_token(token) if token else None
|
|
if payload is None:
|
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Not authenticated")
|
|
return CurrentUser(
|
|
public_ref=payload.public_ref, display_name=payload.display_name, role=payload.role
|
|
)
|
|
|
|
|
|
def require_operations_manager(
|
|
user: CurrentUser = Depends(get_current_user),
|
|
) -> CurrentUser:
|
|
if user.role != "operations_manager":
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN, detail="Operations Manager role required"
|
|
)
|
|
return user
|
|
|
|
|
|
def require_mcp_service_token(
|
|
x_service_token: str = Header(..., alias="X-Service-Token"),
|
|
x_client_id: str = Header(default="unknown-mcp-client", alias="X-Client-Id"),
|
|
) -> str:
|
|
if x_service_token != settings.mcp_hub_service_token:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid service token"
|
|
)
|
|
return x_client_id
|