From fa4c2e45ab94992a32d4c0de434f8d62796b8d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn-Michael=20Miehe?= <40151420+ldericher@users.noreply.github.com> Date: Thu, 7 Apr 2022 11:59:42 +0000 Subject: [PATCH] HTTP 2XX rework --- api/kiwi_vpn_api/routers/_common.py | 7 +++++ api/kiwi_vpn_api/routers/admin.py | 6 ++--- api/kiwi_vpn_api/routers/device.py | 42 +++++++++++++++++++---------- api/kiwi_vpn_api/routers/service.py | 2 +- api/kiwi_vpn_api/routers/user.py | 8 +++--- 5 files changed, 43 insertions(+), 22 deletions(-) diff --git a/api/kiwi_vpn_api/routers/_common.py b/api/kiwi_vpn_api/routers/_common.py index c5a3ce8..d7ce88c 100644 --- a/api/kiwi_vpn_api/routers/_common.py +++ b/api/kiwi_vpn_api/routers/_common.py @@ -22,8 +22,15 @@ class Responses: """ OK = { + "description": "Operation successful", + } + OK_NONE = { + "description": "Operation successful", "content": None, } + OK_WAIT = { + "description": "Operation successful, waiting for approval", + } NOT_INSTALLED = { "description": "kiwi-vpn not installed", "content": None, diff --git a/api/kiwi_vpn_api/routers/admin.py b/api/kiwi_vpn_api/routers/admin.py index f7fa78e..c636df2 100644 --- a/api/kiwi_vpn_api/routers/admin.py +++ b/api/kiwi_vpn_api/routers/admin.py @@ -15,7 +15,7 @@ router = APIRouter(prefix="/admin", tags=["admin"]) @router.put( "/install/config", responses={ - status.HTTP_200_OK: Responses.OK, + status.HTTP_200_OK: Responses.OK_NONE, status.HTTP_409_CONFLICT: Responses.ENTRY_EXISTS, }, ) @@ -43,7 +43,7 @@ async def initial_configure( @router.put( "/install/admin", responses={ - status.HTTP_201_CREATED: Responses.OK, + status.HTTP_201_CREATED: Responses.OK_NONE, status.HTTP_400_BAD_REQUEST: Responses.NOT_INSTALLED, status.HTTP_409_CONFLICT: Responses.ENTRY_EXISTS, }, @@ -77,7 +77,7 @@ async def create_initial_admin( @router.put( "/config", responses={ - status.HTTP_200_OK: Responses.OK, + status.HTTP_200_OK: Responses.OK_NONE, status.HTTP_400_BAD_REQUEST: Responses.NOT_INSTALLED, status.HTTP_401_UNAUTHORIZED: Responses.NEEDS_USER, status.HTTP_403_FORBIDDEN: Responses.NEEDS_PERMISSION, diff --git a/api/kiwi_vpn_api/routers/device.py b/api/kiwi_vpn_api/routers/device.py index 310a403..69c3645 100644 --- a/api/kiwi_vpn_api/routers/device.py +++ b/api/kiwi_vpn_api/routers/device.py @@ -2,7 +2,7 @@ /device endpoints. """ -from fastapi import APIRouter, Depends, HTTPException, status +from fastapi import APIRouter, Depends, HTTPException, Response, status from ..db import Device, DeviceCreate, DeviceRead, DeviceStatus, User from ..easyrsa import DistinguishedName, EasyRSA @@ -59,7 +59,7 @@ async def add_device( @router.delete( "/{device_id}", responses={ - status.HTTP_200_OK: Responses.OK, + status.HTTP_200_OK: Responses.OK_NONE, status.HTTP_400_BAD_REQUEST: Responses.NOT_INSTALLED, status.HTTP_401_UNAUTHORIZED: Responses.NEEDS_USER, status.HTTP_403_FORBIDDEN: Responses.NEEDS_PERMISSION, @@ -87,10 +87,11 @@ async def remove_device( device.delete() -@router.post( - "/{device_id}/issue", +@router.put( + "/{device_id}/certificate", responses={ - status.HTTP_200_OK: Responses.OK, + status.HTTP_200_OK: Responses.OK | {"model": DeviceRead}, + status.HTTP_202_ACCEPTED: Responses.OK_WAIT | {"model": DeviceRead}, status.HTTP_400_BAD_REQUEST: Responses.NOT_INSTALLED, status.HTTP_401_UNAUTHORIZED: Responses.NEEDS_USER, status.HTTP_403_FORBIDDEN: Responses.NEEDS_PERMISSION, @@ -99,17 +100,21 @@ async def remove_device( status.HTTP_425_TOO_EARLY: Responses.NEEDS_PKI, }, response_model=DeviceRead, + status_code=status.HTTP_202_ACCEPTED, ) async def request_certificate_issuance( + response: Response, current_user: User = Depends(get_current_user), device: Device = Depends(get_device_by_id), pki: EasyRSA = Depends(get_pki), ) -> Device: """ - POST ./{device_id}/issue: Request certificate issuance for a device. + PUT ./{device_id}/certificate: Request certificate issuance for a device. Status: + - 200: certificate issued + - 202: issuance requested - 403: no user permission to edit device - 409: device certificate cannot be "issued" """ @@ -132,15 +137,18 @@ async def request_certificate_issuance( device.set_status(DeviceStatus.certified) device.expiry = certificate.not_valid_after + response.status_code = status.HTTP_200_OK + # return updated device device.update() return device -@router.post( - "/{device_id}/renew", +@router.patch( + "/{device_id}/certificate", responses={ - status.HTTP_200_OK: Responses.OK, + status.HTTP_200_OK: Responses.OK | {"model": DeviceRead}, + status.HTTP_202_ACCEPTED: Responses.OK_WAIT | {"model": DeviceRead}, status.HTTP_400_BAD_REQUEST: Responses.NOT_INSTALLED, status.HTTP_401_UNAUTHORIZED: Responses.NEEDS_USER, status.HTTP_403_FORBIDDEN: Responses.NEEDS_PERMISSION, @@ -149,17 +157,21 @@ async def request_certificate_issuance( status.HTTP_425_TOO_EARLY: Responses.NEEDS_PKI, }, response_model=DeviceRead, + status_code=status.HTTP_202_ACCEPTED, ) async def request_certificate_renewal( + response: Response, current_user: User = Depends(get_current_user), device: Device = Depends(get_device_by_id), pki: EasyRSA = Depends(get_pki), ) -> Device: """ - POST ./{device_id}/renew: Request certificate renewal for a device. + PATCH ./{device_id}/certificate: Request certificate renewal for a device. Status: + - 200: certificate renewed + - 202: renewal requested - 403: no user permission to edit device - 409: device certificate cannot be "renewed" """ @@ -182,15 +194,17 @@ async def request_certificate_renewal( device.set_status(DeviceStatus.certified) device.expiry = certificate.not_valid_after + response.status_code = status.HTTP_200_OK + # return updated device device.update() return device -@router.post( - "/{device_id}/revoke", +@router.delete( + "/{device_id}/certificate", responses={ - status.HTTP_200_OK: Responses.OK, + status.HTTP_200_OK: Responses.OK_NONE, status.HTTP_400_BAD_REQUEST: Responses.NOT_INSTALLED, status.HTTP_401_UNAUTHORIZED: Responses.NEEDS_USER, status.HTTP_403_FORBIDDEN: Responses.NEEDS_PERMISSION, @@ -206,7 +220,7 @@ async def revoke_certificate( pki: EasyRSA = Depends(get_pki), ) -> Device: """ - POST ./{device_id}/revoke: Revoke a device certificate. + DELETE ./{device_id}/certificate: Revoke a device certificate. Status: diff --git a/api/kiwi_vpn_api/routers/service.py b/api/kiwi_vpn_api/routers/service.py index 42d1c23..f04a4ca 100644 --- a/api/kiwi_vpn_api/routers/service.py +++ b/api/kiwi_vpn_api/routers/service.py @@ -14,7 +14,7 @@ router = APIRouter(prefix="/service", tags=["service"]) @router.put( "/pki/init", responses={ - status.HTTP_200_OK: Responses.OK, + status.HTTP_200_OK: Responses.OK_NONE, status.HTTP_400_BAD_REQUEST: Responses.NOT_INSTALLED, status.HTTP_401_UNAUTHORIZED: Responses.NEEDS_USER, status.HTTP_403_FORBIDDEN: Responses.NEEDS_PERMISSION, diff --git a/api/kiwi_vpn_api/routers/user.py b/api/kiwi_vpn_api/routers/user.py index b75e441..ed86e37 100644 --- a/api/kiwi_vpn_api/routers/user.py +++ b/api/kiwi_vpn_api/routers/user.py @@ -26,7 +26,7 @@ class Token(BaseModel): @router.post( "/authenticate", responses={ - status.HTTP_200_OK: Responses.OK, + status.HTTP_200_OK: Responses.OK_NONE, status.HTTP_400_BAD_REQUEST: Responses.NOT_INSTALLED, status.HTTP_401_UNAUTHORIZED: Responses.NEEDS_USER, }, @@ -64,7 +64,7 @@ async def login( @router.get( "/current", responses={ - status.HTTP_200_OK: Responses.OK, + status.HTTP_200_OK: Responses.OK_NONE, status.HTTP_400_BAD_REQUEST: Responses.NOT_INSTALLED, status.HTTP_401_UNAUTHORIZED: Responses.NEEDS_USER, status.HTTP_403_FORBIDDEN: Responses.NEEDS_USER, @@ -127,7 +127,7 @@ async def add_user( @router.delete( "/{user_name}", responses={ - status.HTTP_200_OK: Responses.OK, + status.HTTP_200_OK: Responses.OK_NONE, status.HTTP_400_BAD_REQUEST: Responses.NOT_INSTALLED, status.HTTP_401_UNAUTHORIZED: Responses.NEEDS_USER, status.HTTP_403_FORBIDDEN: Responses.NEEDS_PERMISSION, @@ -189,7 +189,7 @@ async def extend_tags( @router.delete( "/{user_name}/tags", responses={ - status.HTTP_200_OK: Responses.OK, + status.HTTP_200_OK: Responses.OK_NONE, status.HTTP_400_BAD_REQUEST: Responses.NOT_INSTALLED, status.HTTP_401_UNAUTHORIZED: Responses.NEEDS_USER, status.HTTP_403_FORBIDDEN: Responses.NEEDS_PERMISSION,