import uuid from typing import Optional from fastapi import Depends, Request from fastapi_users import BaseUserManager, FastAPIUsers, UUIDIDMixin, models, exceptions from fastapi_users.authentication import BearerTransport, AuthenticationBackend from fastapi_users.authentication.strategy.db import AccessTokenDatabase, DatabaseStrategy from beanie import PydanticObjectId from fastapi import APIRouter, HTTPException from typing import List from .models import User, AccessToken, get_user_db, get_access_token_db from .schemas import UserRead, UserUpdate, UserCreate from .manager import get_user_manager def get_database_strategy( access_token_db: AccessTokenDatabase[AccessToken] = Depends(get_access_token_db), ) -> DatabaseStrategy: return DatabaseStrategy(access_token_db, lifetime_seconds=3600) bearer_transport = BearerTransport(tokenUrl="auth/jwt/login") auth_backend = AuthenticationBackend( name="db", transport=bearer_transport, get_strategy=get_database_strategy, ) fastapi_users = FastAPIUsers[User, uuid.UUID]( get_user_manager, [auth_backend], ) def get_auth_router(): return fastapi_users.get_auth_router(auth_backend) router = APIRouter() @router.post("/", response_description="User added to the database") async def create(user: UserCreate, user_manager=Depends(get_user_manager)) -> dict: await user_manager.create(user, safe=True) return {"message": "User added successfully"} @router.get("/{id}", response_description="User record retrieved") async def read_id(id: PydanticObjectId) -> UserRead: user = await User.get(id) return user @router.get("/", response_model=List[UserRead], response_description="User records retrieved") async def read_list() -> List[UserRead]: users = await User.find_all().to_list() return users @router.put("/{id}", response_description="User record updated") async def update(id: PydanticObjectId, req: UserUpdate) -> UserRead: req = {k: v for k, v in req.dict().items() if v is not None} update_query = {"$set": { field: value for field, value in req.items() }} user = await User.get(id) if not user: raise HTTPException( status_code=404, detail="Review record not found!" ) await user.update(update_query) return user @router.delete("/{id}", response_description="User record deleted from the database") async def delete(id: PydanticObjectId) -> dict: record = await User.get(id) if not record: raise HTTPException( status_code=404, detail="Review record not found!" ) await record.delete() return { "message": "Record deleted successfully" }