46 lines
1.5 KiB
Python
46 lines
1.5 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from dataclasses import dataclass
|
||
|
|
|
||
|
|
from fastapi import Depends, HTTPException, status
|
||
|
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
||
|
|
|
||
|
|
from app.core.security import verify_token
|
||
|
|
|
||
|
|
bearer_scheme = HTTPBearer(auto_error=False)
|
||
|
|
|
||
|
|
|
||
|
|
@dataclass(frozen=True)
|
||
|
|
class AuthSession:
|
||
|
|
role: str
|
||
|
|
email: str
|
||
|
|
name: str
|
||
|
|
tenant_id: str | None = None
|
||
|
|
|
||
|
|
|
||
|
|
def get_auth_session(credentials: HTTPAuthorizationCredentials | None = Depends(bearer_scheme)) -> AuthSession:
|
||
|
|
if credentials is None:
|
||
|
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Authentication required")
|
||
|
|
|
||
|
|
payload = verify_token(credentials.credentials)
|
||
|
|
return AuthSession(
|
||
|
|
role=str(payload.get("role", "")),
|
||
|
|
email=str(payload.get("email", "")),
|
||
|
|
name=str(payload.get("name", "")),
|
||
|
|
tenant_id=payload.get("tenant_id"),
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def require_client_session(session: AuthSession = Depends(get_auth_session)) -> AuthSession:
|
||
|
|
if session.role != "client":
|
||
|
|
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Client access required")
|
||
|
|
if not session.tenant_id:
|
||
|
|
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Client tenant is missing")
|
||
|
|
return session
|
||
|
|
|
||
|
|
|
||
|
|
def require_admin_session(session: AuthSession = Depends(get_auth_session)) -> AuthSession:
|
||
|
|
if session.role != "admin":
|
||
|
|
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Admin access required")
|
||
|
|
return session
|