""" L2 Server Dependency Injection. Provides common dependencies for routes. """ from typing import Optional from fastapi import Request, HTTPException, Depends from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from .config import settings security = HTTPBearer(auto_error=False) def get_templates(request: Request): """Get Jinja2 templates from app state.""" return request.app.state.templates async def get_current_user(request: Request) -> Optional[dict]: """ Get current user from cookie or header. Returns user dict or None if not authenticated. """ from auth import verify_token, get_token_claims # Try cookie first token = request.cookies.get("auth_token") # Try Authorization header if not token: auth_header = request.headers.get("Authorization", "") if auth_header.startswith("Bearer "): token = auth_header[7:] if not token: return None # Verify token username = verify_token(token) if not username: return None # Get full claims claims = get_token_claims(token) if not claims: return None return { "username": username, "actor_id": f"https://{settings.domain}/users/{username}", "token": token, **claims, } async def require_auth(request: Request) -> dict: """ Require authentication. Raises HTTPException 401 if not authenticated. """ user = await get_current_user(request) if not user: raise HTTPException(401, "Authentication required") return user def get_user_from_cookie(request: Request) -> Optional[str]: """Get username from cookie (for HTML pages).""" from auth import verify_token token = request.cookies.get("auth_token") if not token: return None return verify_token(token)