Files
ponzischeme89 6d44e05de4 v1
2026-04-18 07:23:55 +12:00

72 lines
2.0 KiB
Python

"""
FastAPI dependency helpers for authenticated member access.
Member tokens carry role='member' in the JWT payload.
"""
import uuid
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from jose import JWTError
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.auth.jwt import verify_access_token
from app.database import get_db
from app.models.member import Member
bearer_scheme = HTTPBearer()
async def _get_member_from_token(
credentials: HTTPAuthorizationCredentials,
db: AsyncSession,
) -> Member:
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = verify_access_token(credentials.credentials)
if payload.get("role") != "member":
raise credentials_exception
member_id: str = payload.get("sub")
if member_id is None:
raise credentials_exception
member_uuid = uuid.UUID(member_id)
except (JWTError, ValueError):
raise credentials_exception
result = await db.execute(select(Member).where(Member.id == member_uuid))
member = result.scalars().first()
if member is None:
raise credentials_exception
if not member.is_active:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Inactive member account",
)
return member
async def get_authenticated_member(
credentials: HTTPAuthorizationCredentials = Depends(bearer_scheme),
db: AsyncSession = Depends(get_db),
) -> Member:
return await _get_member_from_token(credentials, db)
async def get_current_member(
member: Member = Depends(get_authenticated_member),
) -> Member:
if member.member_status != "active":
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Member onboarding is not complete.",
)
return member