Files
Maison/samba-api/src/routers/users.py
2026-02-10 12:12:11 +01:00

160 lines
5.5 KiB
Python

from fastapi import APIRouter, HTTPException, Depends, Query
from typing import Optional
from src.models.users import (
UserCreate, UserUpdate, UserResponse, UserList, PasswordChange
)
from src.services.user_service import user_service
from src.core.exceptions import UserNotFoundException, SambaAPIException
from src.routers.auth import get_current_user
router = APIRouter()
@router.post("/", response_model=UserResponse, status_code=201)
async def create_user(
user_data: UserCreate,
current_user: dict = Depends(get_current_user)
):
"""Create a new user"""
try:
return await user_service.create_user(user_data)
except SambaAPIException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
@router.get("/", response_model=UserList)
async def list_users(
page: int = Query(1, ge=1, description="Page number"),
page_size: int = Query(50, ge=1, le=100, description="Page size"),
search: Optional[str] = Query(None, description="Search users by username, name, or email"),
current_user: dict = Depends(get_current_user)
):
"""List users with pagination and optional search"""
try:
return await user_service.list_users(page=page, page_size=page_size, search=search)
except SambaAPIException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
@router.get("/{username}", response_model=UserResponse)
async def get_user(
username: str,
current_user: dict = Depends(get_current_user)
):
"""Get user by username"""
try:
return await user_service.get_user(username)
except UserNotFoundException:
raise HTTPException(status_code=404, detail=f"User '{username}' not found")
except SambaAPIException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
@router.put("/{username}", response_model=UserResponse)
async def update_user(
username: str,
user_data: UserUpdate,
current_user: dict = Depends(get_current_user)
):
"""Update user information"""
try:
return await user_service.update_user(username, user_data)
except UserNotFoundException:
raise HTTPException(status_code=404, detail=f"User '{username}' not found")
except SambaAPIException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
@router.delete("/{username}", status_code=204)
async def delete_user(
username: str,
current_user: dict = Depends(get_current_user)
):
"""Delete user"""
try:
await user_service.delete_user(username)
except UserNotFoundException:
raise HTTPException(status_code=404, detail=f"User '{username}' not found")
except SambaAPIException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
@router.post("/{username}/password", status_code=200)
async def change_user_password(
username: str,
password_data: PasswordChange,
current_user: dict = Depends(get_current_user)
):
"""Change user password"""
try:
# Validate passwords match
password_data.validate_passwords_match()
# For admin users, current password is not required
# For self-service, validate current password first
if current_user.get('username') == username and password_data.current_password:
# TODO: Implement current password validation
pass
await user_service.change_password(username, password_data.new_password)
return {"message": "Password changed successfully"}
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
except UserNotFoundException:
raise HTTPException(status_code=404, detail=f"User '{username}' not found")
except SambaAPIException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
@router.post("/{username}/enable", status_code=200)
async def enable_user(
username: str,
current_user: dict = Depends(get_current_user)
):
"""Enable user account"""
try:
from src.models.users import UserStatus
user_update = UserUpdate(status=UserStatus.ACTIVE)
await user_service.update_user(username, user_update)
return {"message": f"User '{username}' enabled successfully"}
except UserNotFoundException:
raise HTTPException(status_code=404, detail=f"User '{username}' not found")
except SambaAPIException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
@router.post("/{username}/disable", status_code=200)
async def disable_user(
username: str,
current_user: dict = Depends(get_current_user)
):
"""Disable user account"""
try:
from src.models.users import UserStatus
user_update = UserUpdate(status=UserStatus.DISABLED)
await user_service.update_user(username, user_update)
return {"message": f"User '{username}' disabled successfully"}
except UserNotFoundException:
raise HTTPException(status_code=404, detail=f"User '{username}' not found")
except SambaAPIException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")