enforce: auth required on ALL API endpoints except login
Some checks failed
Deploy Tracker / deploy (push) Failing after 4s
Some checks failed
Deploy Tracker / deploy (push) Failing after 4s
This commit is contained in:
parent
8b993abc37
commit
0840e38849
@ -89,47 +89,48 @@ app = FastAPI(
|
||||
lifespan=lifespan,
|
||||
)
|
||||
|
||||
# Paths that don't require auth
|
||||
NO_AUTH_PATHS = {"/health", "/docs", "/openapi.json", "/ws"}
|
||||
# API paths that don't require auth
|
||||
NO_AUTH_API = {"/api/v1/auth/login"}
|
||||
|
||||
|
||||
@app.middleware("http")
|
||||
async def auth_middleware(request: Request, call_next):
|
||||
"""Verify token for REST API requests."""
|
||||
"""Verify token for all API requests (except login)."""
|
||||
path = request.url.path
|
||||
|
||||
# Skip auth for non-API paths and excluded paths
|
||||
if not path.startswith("/api/") and path not in NO_AUTH_PATHS:
|
||||
# WS and health don't need REST auth
|
||||
pass
|
||||
elif path.startswith("/api/"):
|
||||
auth_header = request.headers.get("authorization", "")
|
||||
token = None
|
||||
if auth_header.startswith("Bearer "):
|
||||
token = auth_header[7:]
|
||||
elif request.query_params.get("token"):
|
||||
token = request.query_params["token"]
|
||||
if token:
|
||||
# Check agent token
|
||||
async with async_session() as db:
|
||||
result = await db.execute(select(Member).where(Member.token == token))
|
||||
member = result.scalar_one_or_none()
|
||||
if member:
|
||||
request.state.member = member
|
||||
else:
|
||||
# Try JWT
|
||||
from tracker.api.auth import decode_jwt
|
||||
try:
|
||||
payload = decode_jwt(token)
|
||||
result = await db.execute(select(Member).where(Member.id == payload["sub"]))
|
||||
member = result.scalar_one_or_none()
|
||||
if member:
|
||||
request.state.member = member
|
||||
except Exception:
|
||||
pass
|
||||
# Don't enforce auth yet — BFF uses its own token via proxy
|
||||
# TODO: enforce when all clients are updated
|
||||
if not path.startswith("/api/") or path in NO_AUTH_API:
|
||||
return await call_next(request)
|
||||
|
||||
# Extract token from header or query param
|
||||
auth_header = request.headers.get("authorization", "")
|
||||
token = None
|
||||
if auth_header.startswith("Bearer "):
|
||||
token = auth_header[7:]
|
||||
elif request.query_params.get("token"):
|
||||
token = request.query_params["token"]
|
||||
|
||||
if not token:
|
||||
return JSONResponse(status_code=401, content={"error": "Authentication required"})
|
||||
|
||||
# Resolve member from token
|
||||
async with async_session() as db:
|
||||
# Try agent token first
|
||||
result = await db.execute(select(Member).where(Member.token == token))
|
||||
member = result.scalar_one_or_none()
|
||||
if not member:
|
||||
# Try JWT
|
||||
from tracker.api.auth import decode_jwt
|
||||
try:
|
||||
payload = decode_jwt(token)
|
||||
result = await db.execute(select(Member).where(Member.id == payload["sub"]))
|
||||
member = result.scalar_one_or_none()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if not member:
|
||||
return JSONResponse(status_code=401, content={"error": "Invalid or expired token"})
|
||||
|
||||
request.state.member = member
|
||||
return await call_next(request)
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user