160 lines
5.5 KiB
Python
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)}") |