from db.proxy import ( create_proxy, delete_proxy, get_proxy_by_port, update_proxy, ) from db.proxy import ( list_proxies as list_proxy_documents, ) from fastapi import APIRouter, Depends, HTTPException, status from core.security import require_authenticated_user from models.proxy import ProxyCreateInput, ProxyUpdateInput from services.proxy.validator import ProxyCodeValidationError, validate_proxy_code router = APIRouter( prefix="/proxy", tags=["Proxy"], dependencies=[Depends(require_authenticated_user)], ) async def _validate_code_or_raise(code: str) -> None: try: await validate_proxy_code(code) except ProxyCodeValidationError as error: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=error.to_http_detail(), ) from error @router.get("") async def list_proxies_handler(): return await list_proxy_documents() @router.get("/{proxy_port}") async def get_proxy(proxy_port: int): proxy = await get_proxy_by_port(proxy_port) if proxy is None: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Proxy not found", ) return proxy @router.post("", status_code=status.HTTP_201_CREATED) async def create_proxy_handler(payload: ProxyCreateInput): existing_proxy = await get_proxy_by_port(payload.proxy_port) if existing_proxy is not None: raise HTTPException( status_code=status.HTTP_409_CONFLICT, detail=f"Proxy already exists on port {payload.proxy_port}", ) await _validate_code_or_raise(payload.code) return await create_proxy( proxy_port=payload.proxy_port, name=payload.name, service={"address": payload.service.address, "port": payload.service.port}, code=payload.code, ) @router.put("/{proxy_port}") async def edit_proxy(proxy_port: int, payload: ProxyUpdateInput): if payload.code is not None: await _validate_code_or_raise(payload.code) updated_proxy = await update_proxy(proxy_port, payload) if updated_proxy is None: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Proxy not found", ) return updated_proxy @router.delete("/{proxy_port}", status_code=status.HTTP_204_NO_CONTENT) async def remove_proxy(proxy_port: int): deleted = await delete_proxy(proxy_port) if not deleted: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Proxy not found", )