Add complete NexaFabric project structure including: - FastAPI backend with SQLAlchemy models, JWT auth, RBAC, audit logging, and provider interfaces - React + TypeScript frontend with Vite, Tailwind CSS, TanStack Query, and Zustand - Docker Compose configuration for PostgreSQL, Redis, API, worker, frontend, and nginx - GitHub Actions and GitLab CI workflows for testing, linting, building, and security scanning - Environment
43 lines
1.5 KiB
Python
43 lines
1.5 KiB
Python
from typing import Annotated
|
|
|
|
from fastapi import Depends, HTTPException, status
|
|
from fastapi.security import OAuth2PasswordBearer
|
|
from jose import JWTError
|
|
from sqlalchemy import select
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.core.security import decode_token
|
|
from app.db.session import get_db
|
|
from app.models.domain import User
|
|
|
|
|
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/login")
|
|
DbSession = Annotated[Session, Depends(get_db)]
|
|
|
|
|
|
def current_user(db: DbSession, token: Annotated[str, Depends(oauth2_scheme)]) -> User:
|
|
try:
|
|
payload = decode_token(token)
|
|
except JWTError as exc:
|
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token") from exc
|
|
if payload.get("typ") != "access":
|
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token type")
|
|
user = db.scalar(select(User).where(User.id == payload["sub"], User.is_active.is_(True)))
|
|
if not user:
|
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Inactive or missing user")
|
|
return user
|
|
|
|
|
|
CurrentUser = Annotated[User, Depends(current_user)]
|
|
|
|
|
|
def require_permission(permission: str):
|
|
def dependency(user: CurrentUser) -> User:
|
|
permissions = {permission for role in user.roles for permission in role.permissions}
|
|
if "*" not in permissions and permission not in permissions:
|
|
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Missing permission")
|
|
return user
|
|
|
|
return dependency
|
|
|