from uuid import UUID from fastapi import APIRouter, HTTPException from fastapi.params import Depends from sqlalchemy import select from sqlalchemy.orm import Session from app.database import get_db from app.schemas.auth_token import AccessToken from app.schemas.id_token import IdToken, IdTokenCreate, IdTokenUpdate from app.models.id_token import IdToken as DbIdToken from app.models.user import User as DbUser from app.schemas.user import Role from app.security.jwt_bearer import JWTBearer router = APIRouter( prefix="/id-tokens", tags=["IdToken (v1)"] ) @router.get(path="", response_model=list[IdToken]) async def get_id_tokens( skip: int = 0, limit: int = 20, db: Session = Depends(get_db), token: AccessToken = Depends(JWTBearer()), ): stmt = select(Session) if token.role != Role.ADMINISTRATOR: stmt = stmt.where(DbIdToken.owner_id == token.subject) stmt = stmt.order_by(DbIdToken.id).offset(skip).limit(limit) result = db.execute(stmt) return result.scalars().all() @router.get(path="/{id_token_id}", response_model=IdToken) async def get_id_token( id_token_id: UUID, db: Session = Depends(get_db), token: AccessToken = Depends(JWTBearer()), ): stmt = select(DbIdToken).where(DbIdToken.id == id_token_id) result = db.execute(stmt) id_token = result.scalars().first() if id_token == None: raise HTTPException(status_code=404, detail="IdToken not found") if token.role != Role.ADMINISTRATOR & id_token.owner_id != token.subject: raise HTTPException(status_code=404, detail="IdToken not found") return id_token @router.post(path="", status_code=201, response_model=IdToken) async def create_id_token( create_id_token: IdTokenCreate, db: Session = Depends(get_db), token: AccessToken = Depends(JWTBearer(required_roles=["administrator"])), ): stmt = select(DbUser).where(DbUser.id == create_id_token.owner_id) result = db.execute(stmt) owner = result.scalars().first() if owner == None: raise HTTPException(status_code=422, detail=[{ "loc": ["body", "owner_id"], "msg": "Owner not found", "type": "invalid_relation" }]) id_token = DbIdToken( friendly_name=create_id_token.friendly_name, is_active=create_id_token.is_active, token=create_id_token.token, owner_id=create_id_token.owner_id ) db.add(id_token) db.commit() db.refresh(id_token) return id_token @router.patch(path="/{id_token_id}", response_model=IdToken) async def update_id_token( id_token_id: UUID, id_token_update: IdTokenUpdate, db: Session = Depends(get_db), token: AccessToken = Depends(JWTBearer(required_roles=["administrator"])), ): stmt = select(DbIdToken).where(DbIdToken.id == id_token_id) result = db.execute(stmt) id_token = result.scalars().first() if id_token is None: raise HTTPException(status_code=404, detail="IdToken not found") for key, value in id_token_update.model_dump(exclude_unset=True).items(): if key == "owner_id": stmt = select(DbUser).where(DbUser.id == id_token_update.owner_id) result = db.execute(stmt) owner = result.scalars().first() if owner == None: raise HTTPException(status_code=422, detail=[{ "loc": ["body", "owner_id"], "msg": "Owner not found", "type": "invalid_relation" }]) setattr(id_token, key, value) db.commit() return id_token @router.delete(path="/{id_token_id}", response_model=None) async def delete_id_token( id_token_id: UUID, db: Session = Depends(get_db), token: AccessToken = Depends(JWTBearer(required_roles=["administrator"])), ): stmt = select(DbIdToken).where(DbIdToken.id == id_token_id) result = db.execute(stmt) id_token = result.scalars().first() if id_token == None: raise HTTPException(status_code=404, detail="IdToken not found") db.delete(id_token) db.commit() return []