Replaced all inline error messages with the standardized `api_error` helper for consistent error response formatting. This improves clarity, maintainability, and ensures uniform error structures across the application. Updated logging for collector failures to include error class and switched to warning level for target unreachable scenarios.
59 lines
1.9 KiB
Python
59 lines
1.9 KiB
Python
from fastapi import Depends, HTTPException, status
|
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
|
import jwt
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from app.core.config import get_settings
|
|
from app.core.db import get_db
|
|
from app.core.errors import api_error
|
|
from app.models.models import User
|
|
|
|
settings = get_settings()
|
|
bearer = HTTPBearer(auto_error=False)
|
|
|
|
|
|
async def get_current_user(
|
|
credentials: HTTPAuthorizationCredentials | None = Depends(bearer),
|
|
db: AsyncSession = Depends(get_db),
|
|
) -> User:
|
|
if not credentials:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail=api_error("missing_token", "Missing token"),
|
|
)
|
|
token = credentials.credentials
|
|
try:
|
|
payload = jwt.decode(token, settings.jwt_secret_key, algorithms=[settings.jwt_algorithm])
|
|
except jwt.InvalidTokenError as exc:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail=api_error("invalid_token", "Invalid token"),
|
|
) from exc
|
|
|
|
if payload.get("type") != "access":
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail=api_error("invalid_token_type", "Invalid token type"),
|
|
)
|
|
|
|
user_id = payload.get("sub")
|
|
user = await db.scalar(select(User).where(User.id == int(user_id)))
|
|
if not user:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail=api_error("user_not_found", "User not found"),
|
|
)
|
|
return user
|
|
|
|
|
|
def require_roles(*roles: str):
|
|
async def role_dependency(user: User = Depends(get_current_user)) -> User:
|
|
if user.role not in roles:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail=api_error("forbidden", "Forbidden"),
|
|
)
|
|
return user
|
|
|
|
return role_dependency
|