"""User endpoints.""" from typing import Any, List from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app.api.deps import ( get_current_active_superuser, get_current_active_user, get_db, ) from app.core.security import get_password_hash from app.models.user import User from app.schemas.user import User as UserSchema from app.schemas.user import UserCreate, UserUpdate router = APIRouter() @router.get("/me", response_model=UserSchema) def read_current_user( current_user: User = Depends(get_current_active_user), ) -> Any: """ Get current user information. Args: current_user: Current active user Returns: User: Current user information """ return current_user @router.patch("/me", response_model=UserSchema) def update_current_user( *, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user), user_in: UserUpdate, ) -> Any: """ Update current user information. Args: db: Database session current_user: Current active user user_in: User update data Returns: User: Updated user information """ # Update user attributes for field, value in user_in.model_dump(exclude_unset=True).items(): if field == "password" and value: setattr(current_user, "hashed_password", get_password_hash(value)) elif field != "password": setattr(current_user, field, value) db.add(current_user) db.commit() db.refresh(current_user) return current_user @router.get("", response_model=List[UserSchema]) def read_users( db: Session = Depends(get_db), skip: int = 0, limit: int = 100, current_user: User = Depends(get_current_active_superuser), ) -> Any: """ Retrieve users. Only for superusers. Args: db: Database session skip: Skip first N users limit: Limit number of users to return current_user: Current active superuser Returns: List[User]: List of users """ users = db.query(User).offset(skip).limit(limit).all() return users @router.post("", response_model=UserSchema, status_code=status.HTTP_201_CREATED) def create_user( *, db: Session = Depends(get_db), user_in: UserCreate, current_user: User = Depends(get_current_active_superuser), ) -> Any: """ Create a new user. Only for superusers. Args: db: Database session user_in: User creation data current_user: Current active superuser Returns: User: Created user """ # Check if user with this email already exists user = db.query(User).filter(User.email == user_in.email).first() if user: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="A user with this email already exists", ) # Create new user user = User( email=user_in.email, hashed_password=get_password_hash(user_in.password), full_name=user_in.full_name, is_superuser=user_in.is_superuser, is_active=user_in.is_active, ) db.add(user) db.commit() db.refresh(user) return user @router.get("/{user_id}", response_model=UserSchema) def read_user( user_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_superuser), ) -> Any: """ Get a specific user by id. Only for superusers. Args: user_id: User ID db: Database session current_user: Current active superuser Returns: User: User with given ID """ user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found", ) return user @router.patch("/{user_id}", response_model=UserSchema) def update_user( *, db: Session = Depends(get_db), user_id: int, user_in: UserUpdate, current_user: User = Depends(get_current_active_superuser), ) -> Any: """ Update a user. Only for superusers. Args: db: Database session user_id: User ID user_in: User update data current_user: Current active superuser Returns: User: Updated user """ user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found", ) # Update user attributes for field, value in user_in.model_dump(exclude_unset=True).items(): if field == "password" and value: setattr(user, "hashed_password", get_password_hash(value)) elif field != "password": setattr(user, field, value) db.add(user) db.commit() db.refresh(user) return user @router.delete("/{user_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None) def delete_user( *, db: Session = Depends(get_db), user_id: int, current_user: User = Depends(get_current_active_superuser), ) -> None: """ Delete a user. Only for superusers. Args: db: Database session user_id: User ID current_user: Current active superuser """ user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found", ) db.delete(user) db.commit() return None