Fin-Intel / app /auth.py
Dhiraj20's picture
Sync uncommitted local backend changes
c96aca8
Raw
History Blame Contribute Delete
2.03 kB
import hashlib
import sqlite3
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import JSONResponse
from app.config import DB_PATH
class APIKeyAuthMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
# Exempt paths
if request.url.path in ["/", "/api/health", "/docs", "/openapi.json"] or request.url.path.startswith("/api/charts/"):
return await call_next(request)
# Allow CORS preflight requests
if request.method == "OPTIONS":
return await call_next(request)
api_key = request.headers.get("X-API-Key")
if not api_key:
return JSONResponse(status_code=401, content={"detail": "Missing X-API-Key header"})
# Hash the key
key_hash = hashlib.sha256(api_key.encode()).hexdigest()
# Check against SQLite
try:
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
# Ensure table exists
c.execute('''CREATE TABLE IF NOT EXISTS api_keys
(id INTEGER PRIMARY KEY AUTOINCREMENT, key_hash TEXT UNIQUE, active INTEGER DEFAULT 1)''')
# Dev auto-provision: insert a default test_key hash if DB is empty
c.execute("SELECT COUNT(*) FROM api_keys")
if c.fetchone()[0] == 0:
dev_hash = hashlib.sha256(b'test_key').hexdigest()
c.execute("INSERT INTO api_keys (key_hash) VALUES (?)", (dev_hash,))
conn.commit()
c.execute("SELECT active FROM api_keys WHERE key_hash=?", (key_hash,))
row = c.fetchone()
conn.close()
if not row or row[0] == 0:
return JSONResponse(status_code=401, content={"detail": "Invalid or revoked API Key"})
except Exception as e:
return JSONResponse(status_code=500, content={"detail": f"Auth DB error: {str(e)}"})
return await call_next(request)