Initial commit: API gateway with admin console
- FastAPI async gateway with httpx proxying to multiple upstreams - SQLite database with SQLAlchemy ORM - Admin console: manage services, users, API keys, endpoint access - Per-key, per-endpoint granular access control - OpenAPI document sync and caching (5-minute TTL) - Request/response logging with full transaction inspection - In-memory rate limiting (per-key, fixed-window) - Tiered log retention (7d payloads, 90d rows, incremental vacuum) - TLS verification toggle per service (for self-signed certificates) - Service connectivity validation with automatic endpoint refresh - Request browser with filters and deep-link inspection - Docker setup with persistent volume - Modal forms for create/edit flows Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
from fastapi import Depends, HTTPException, Request, status
|
||||
from fastapi.responses import RedirectResponse
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app import config, security
|
||||
from app.database import get_db
|
||||
from app.models import User
|
||||
|
||||
|
||||
class LoginRequired(HTTPException):
|
||||
"""Raised when there is no valid session; handled by redirecting to /admin/login."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(status_code=status.HTTP_303_SEE_OTHER)
|
||||
|
||||
|
||||
def login_redirect_handler(request: Request, exc: LoginRequired):
|
||||
return RedirectResponse("/admin/login", status_code=303)
|
||||
|
||||
|
||||
def current_user(request: Request, db: Session = Depends(get_db)) -> User:
|
||||
token = request.cookies.get(config.SESSION_COOKIE)
|
||||
user_id = security.read_session_token(token) if token else None
|
||||
if user_id is None:
|
||||
raise LoginRequired()
|
||||
user = db.get(User, user_id)
|
||||
if user is None or not user.is_active:
|
||||
raise LoginRequired()
|
||||
return user
|
||||
Reference in New Issue
Block a user