import time from typing import Dict, List from fastapi import APIRouter, Depends, Request import app.container as container from app.api.deps import auth_dependency, caller_identity from app.core.errors import ApiError from app.core.models import ApiResponse, GroupCreateRequest, UserCreateRequest, UserGroupsUpdateRequest, UserPasswordUpdateRequest router = APIRouter(dependencies=[Depends(auth_dependency)]) @router.get("/health") def health() -> Dict: return {"server_name": container.app_state.settings.server_name, "status": "online"} @router.post("/users", response_model=ApiResponse) def create_user(payload: UserCreateRequest, request: Request) -> ApiResponse: identity = caller_identity(request) started = time.perf_counter() try: container.app_state.service.create_user(payload) container.app_state.audit.log(operation="create_user", target=payload.username, result="success", request_id=identity["request_id"], source_ip=identity["ip"]) return ApiResponse(message="User created.") except ApiError as exc: container.app_state.audit.log(operation="create_user", target=payload.username, result="failed", error_code=exc.code, request_id=identity["request_id"], source_ip=identity["ip"], elapsed_ms=int((time.perf_counter() - started) * 1000)) raise @router.delete("/users/{username}", response_model=ApiResponse) def delete_user(username: str, request: Request) -> ApiResponse: identity = caller_identity(request) container.app_state.service.delete_user(username) container.app_state.audit.log(operation="delete_user", target=username, result="success", request_id=identity["request_id"], source_ip=identity["ip"]) return ApiResponse(message="User deleted.") @router.patch("/users/{username}/password", response_model=ApiResponse) def change_user_password(username: str, payload: UserPasswordUpdateRequest, request: Request) -> ApiResponse: identity = caller_identity(request) container.app_state.service.change_user_password(username=username, password_hash=payload.password_hash) container.app_state.audit.log(operation="change_user_password", target=username, result="success", request_id=identity["request_id"], source_ip=identity["ip"]) return ApiResponse(message="User password updated.") @router.get("/users") def list_users() -> List[Dict]: return [item.model_dump() for item in container.app_state.service.list_users()] @router.get("/users/{username}") def get_user(username: str) -> Dict: return container.app_state.service.get_user(username).model_dump() @router.post("/groups", response_model=ApiResponse) def create_group(payload: GroupCreateRequest, request: Request) -> ApiResponse: identity = caller_identity(request) container.app_state.service.create_group(payload.groupname) container.app_state.audit.log(operation="create_group", target=payload.groupname, result="success", request_id=identity["request_id"], source_ip=identity["ip"]) return ApiResponse(message="Group created.") @router.delete("/groups/{groupname}", response_model=ApiResponse) def delete_group(groupname: str, request: Request) -> ApiResponse: identity = caller_identity(request) container.app_state.service.delete_group(groupname) container.app_state.audit.log(operation="delete_group", target=groupname, result="success", request_id=identity["request_id"], source_ip=identity["ip"]) return ApiResponse(message="Group deleted.") @router.get("/groups") def list_groups() -> List[Dict]: return [item.model_dump() for item in container.app_state.service.list_groups()] @router.get("/groups/{groupname}") def get_group(groupname: str) -> Dict: return container.app_state.service.get_group(groupname).model_dump() @router.post("/users/{username}/groups", response_model=ApiResponse) def add_user_groups(username: str, payload: UserGroupsUpdateRequest) -> ApiResponse: container.app_state.service.add_user_groups(username=username, groups=payload.groups, replace=payload.mode == "replace") return ApiResponse(message="User groups updated.") @router.delete("/users/{username}/groups", response_model=ApiResponse) def remove_user_groups(username: str, payload: UserGroupsUpdateRequest) -> ApiResponse: container.app_state.service.remove_user_groups(username=username, groups=payload.groups) return ApiResponse(message="User groups removed.") @router.get("/users/{username}/groups") def get_user_groups(username: str) -> Dict: return {"username": username, "groups": container.app_state.service.get_user_groups(username)}