admin / Bid-Sentinel
publicBid Scrape and Tracking Application with AI Capability
Bid-Sentinel / bid-sentinel-v2 / backend / app / routers / users.py
2680 B · main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | """User administration endpoints (admin only). Role-based management stub.""" from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.database import get_db from app.deps import get_current_admin from app.models import User from app.schemas import UserCreate, UserOut, UserUpdate from app.security import hash_password router = APIRouter(prefix="/users", tags=["users"]) @router.get("", response_model=list[UserOut]) async def list_users( db: AsyncSession = Depends(get_db), _admin: User = Depends(get_current_admin), ): result = await db.execute(select(User).order_by(User.id)) return result.scalars().all() @router.post("", response_model=UserOut, status_code=status.HTTP_201_CREATED) async def create_user( payload: UserCreate, db: AsyncSession = Depends(get_db), _admin: User = Depends(get_current_admin), ): exists = await db.execute(select(User).where(User.email == payload.email)) if exists.scalar_one_or_none(): raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="Email already registered") user = User( email=payload.email, full_name=payload.full_name, role=payload.role, hashed_password=hash_password(payload.password), ) db.add(user) await db.commit() await db.refresh(user) return user @router.patch("/{user_id}", response_model=UserOut) async def update_user( user_id: int, payload: UserUpdate, db: AsyncSession = Depends(get_db), _admin: User = Depends(get_current_admin), ): user = await db.get(User, user_id) if not user: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found") if payload.full_name is not None: user.full_name = payload.full_name if payload.role is not None: user.role = payload.role if payload.is_active is not None: user.is_active = payload.is_active if payload.password: user.hashed_password = hash_password(payload.password) await db.commit() await db.refresh(user) return user @router.delete("/{user_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_user( user_id: int, db: AsyncSession = Depends(get_db), admin: User = Depends(get_current_admin), ): if user_id == admin.id: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Cannot delete yourself") user = await db.get(User, user_id) if not user: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found") await db.delete(user) await db.commit() |