Move admin page into API, switch to HTTP Basic Auth

This commit is contained in:
2026-04-27 19:07:23 +02:00
parent 5bb864f34f
commit 6479f74d50
4 changed files with 165 additions and 11 deletions

View File

@@ -14,6 +14,8 @@ def get_db():
conn.row_factory = sqlite3.Row
return conn
# your-very-long-random-admin-key
def init_db():
conn = get_db()
conn.execute("""

View File

@@ -1,23 +1,31 @@
from fastapi import FastAPI, HTTPException, Depends, Header, Query, Request
from fastapi.responses import JSONResponse
from .auth import init_db, verify_api_key, get_db # make sure auth.py exports get_db
from fastapi.responses import JSONResponse, FileResponse
from fastapi.security import HTTPBasic, HTTPBasicCredentials
from .auth import init_db, verify_api_key, get_db
from .models import Event, BatchEvents
from .enrichment import enrich_event
from .influx import write_event, client, INFLUX_ORG, INFLUX_BUCKET
import logging
import os
import secrets
import datetime
import pathlib
logging.basicConfig(level=logging.INFO)
# Environment variables
ADMIN_API_KEY = os.getenv("ADMIN_API_KEY", "admin-secret-change-me")
ADMIN_USERNAME = os.getenv("ADMIN_USERNAME", "admin")
ADMIN_PASSWORD = os.getenv("ADMIN_PASSWORD", "admin") # change in pod YAML!
# Initialise database (creates table if missing)
init_db()
app = FastAPI(title="Signal - Roblox Telemetry")
security = HTTPBasic()
# ---------- HTTP Basic auth dependency ----------
def require_admin(credentials: HTTPBasicCredentials = Depends(security)):
if credentials.username != ADMIN_USERNAME or credentials.password != ADMIN_PASSWORD:
raise HTTPException(status_code=401, detail="Invalid credentials",
headers={"WWW-Authenticate": "Basic"})
return True
# ---------- Original endpoints ----------
@app.get("/health")
@@ -35,11 +43,12 @@ async def ingest_event(payload: Event | BatchEvents, game: str = Depends(verify_
write_event(enriched)
return {"success": True}
# ---------- Admin authentication helper ----------
def require_admin(x_admin_key: str = Header(None)):
if not x_admin_key or x_admin_key != ADMIN_API_KEY:
raise HTTPException(status_code=403, detail="Forbidden")
return True
# ---------- Serve the admin HTML ----------
STATIC_DIR = pathlib.Path(__file__).parent.parent / "static"
@app.get("/admin", include_in_schema=False)
async def admin_page(admin: bool = Depends(require_admin)):
return FileResponse(STATIC_DIR / "index.html")
# ---------- Admin: API Keys ----------
@app.get("/admin/keys")