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)}")