From 2aa3a61ed4193d0b40731b8bc794a0564cd4c9b3 Mon Sep 17 00:00:00 2001 From: agatha Date: Sat, 14 Mar 2026 16:31:47 -0400 Subject: [PATCH] feat: add API key auth dependency --- pyproject.toml | 2 +- src/proxy_pool/accounts/auth.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/proxy_pool/accounts/auth.py diff --git a/pyproject.toml b/pyproject.toml index b58a7d9..11f90c6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,7 +53,7 @@ extend-exclude = ["alembic", "tests"] select = ["E", "F", "I", "N", "UP", "B", "A", "SIM"] [tool.ruff.lint.flake8-bugbear] -extend-immutable-calls = ["Depends", "fastapi.Depends", "Query", "fastapi.Query"] +extend-immutable-calls = ["Depends", "fastapi.Depends", "Query", "fastapi.Query", "Security", "fastapi.Security"] [tool.mypy] plugins = ["pydantic.mypy"] diff --git a/src/proxy_pool/accounts/auth.py b/src/proxy_pool/accounts/auth.py new file mode 100644 index 0000000..ab96a97 --- /dev/null +++ b/src/proxy_pool/accounts/auth.py @@ -0,0 +1,29 @@ +from fastapi import Depends, HTTPException, Security, status +from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer +from sqlalchemy.ext.asyncio import AsyncSession + +from proxy_pool.accounts.models import User +from proxy_pool.accounts.service import verify_api_key +from proxy_pool.common.dependencies import get_db + +security = HTTPBearer() + + +async def get_current_user( + credentials: HTTPAuthorizationCredentials = Security(security), + db: AsyncSession = Depends(get_db), +) -> User: + """FastAPI dependency that resolves an API key to a User. + + Usage in routes: + @router.get("/something") + async def something(user: User = Depends(get_current_user)): + """ + user = await verify_api_key(db, credentials.credentials) + if user is None: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Invalid or expired API key", + headers={"WWW-Authenticate": "Bearer"}, + ) + return user