hardening
This commit is contained in:
+43
-12
@@ -1,4 +1,5 @@
|
||||
import asyncio
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
@@ -22,7 +23,48 @@ from .services.jellyfin_sync import run_daily_jellyfin_sync
|
||||
from .logging_config import configure_logging
|
||||
from .runtime import get_runtime_settings
|
||||
|
||||
app = FastAPI(title=settings.app_name)
|
||||
|
||||
def validate_security_settings() -> None:
|
||||
issues = []
|
||||
jwt_secret = (settings.jwt_secret or "").strip()
|
||||
admin_username = (settings.admin_username or "").strip()
|
||||
admin_password = (settings.admin_password or "").strip()
|
||||
if not jwt_secret:
|
||||
issues.append("JWT_SECRET is required")
|
||||
if not admin_username:
|
||||
issues.append("ADMIN_USERNAME is required")
|
||||
if not admin_password:
|
||||
issues.append("ADMIN_PASSWORD is required")
|
||||
if jwt_secret == "change-me":
|
||||
issues.append("JWT_SECRET must not use the default placeholder")
|
||||
if admin_password == "adminadmin":
|
||||
issues.append("ADMIN_PASSWORD must not use the default placeholder")
|
||||
if issues:
|
||||
raise RuntimeError("Unsafe Magent security configuration: " + "; ".join(issues))
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(_: FastAPI):
|
||||
validate_security_settings()
|
||||
init_db()
|
||||
runtime = get_runtime_settings()
|
||||
configure_logging(runtime.log_level, runtime.log_file)
|
||||
background_tasks = [
|
||||
asyncio.create_task(run_daily_jellyfin_sync(), name="daily-jellyfin-sync"),
|
||||
asyncio.create_task(startup_warmup_requests_cache(), name="startup-warmup-requests-cache"),
|
||||
asyncio.create_task(run_requests_delta_loop(), name="requests-delta-loop"),
|
||||
asyncio.create_task(run_daily_requests_full_sync(), name="daily-requests-full-sync"),
|
||||
asyncio.create_task(run_daily_db_cleanup(), name="daily-db-cleanup"),
|
||||
]
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
for task in background_tasks:
|
||||
task.cancel()
|
||||
await asyncio.gather(*background_tasks, return_exceptions=True)
|
||||
|
||||
|
||||
app = FastAPI(title=settings.app_name, lifespan=lifespan)
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
@@ -37,17 +79,6 @@ app.add_middleware(
|
||||
async def health() -> dict:
|
||||
return {"status": "ok"}
|
||||
|
||||
@app.on_event("startup")
|
||||
async def startup() -> None:
|
||||
init_db()
|
||||
runtime = get_runtime_settings()
|
||||
configure_logging(runtime.log_level, runtime.log_file)
|
||||
asyncio.create_task(run_daily_jellyfin_sync())
|
||||
asyncio.create_task(startup_warmup_requests_cache())
|
||||
asyncio.create_task(run_requests_delta_loop())
|
||||
asyncio.create_task(run_daily_requests_full_sync())
|
||||
asyncio.create_task(run_daily_db_cleanup())
|
||||
|
||||
|
||||
app.include_router(requests_router)
|
||||
app.include_router(auth_router)
|
||||
|
||||
Reference in New Issue
Block a user