diff --git a/api/src/main.py b/api/src/main.py index 23299cf..fb106bb 100644 --- a/api/src/main.py +++ b/api/src/main.py @@ -9,8 +9,9 @@ from pathlib import Path import torch import uvicorn -from fastapi import FastAPI +from fastapi import Depends, FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware +from fastapi.security import HTTPBasic, HTTPBasicCredentials from loguru import logger from .core.config import settings @@ -43,6 +44,27 @@ def setup_logger(): # Configure logger setup_logger() +security = HTTPBasic() + +def get_http_credentials(credentials: HTTPBasicCredentials = Depends(security)): + """Conditionally verify HTTP Basic Auth credentials""" + username = os.getenv("HTTP_USERNAME") + password = os.getenv("HTTP_PASSWORD") + + # Skip authentication if credentials not configured + if not username or not password: + return + + # Perform authentication check if credentials are configured + if (credentials.username != username or credentials.password != password): + raise HTTPException( + status_code=401, + detail="Incorrect username or password", + headers={"WWW-Authenticate": "Basic"}, + ) + return credentials.username + + @asynccontextmanager async def lifespan(app: FastAPI): @@ -128,11 +150,11 @@ if settings.cors_enabled: ) # Include routers -app.include_router(openai_router, prefix="/v1") -app.include_router(dev_router) # Development endpoints -app.include_router(debug_router) # Debug endpoints +app.include_router(openai_router, prefix="/v1", dependencies=[Depends(get_http_credentials)]) +app.include_router(dev_router, dependencies=[Depends(get_http_credentials)]) # Development endpoints +app.include_router(debug_router, dependencies=[Depends(get_http_credentials)]) # Debug endpoints if settings.enable_web_player: - app.include_router(web_router, prefix="/web") # Web player static files + app.include_router(web_router, prefix="/web", dependencies=[Depends(get_http_credentials)]) # Web player static files # Health check endpoint