deleting a device

This commit is contained in:
Jörn-Michael Miehe 2022-03-29 15:56:12 +00:00
parent 0c8298871f
commit 617ae92d72
4 changed files with 75 additions and 2 deletions

View file

@ -85,6 +85,15 @@ class Device(DeviceBase, table=True):
# device already existed
return None
@classmethod
def get(cls, id: int) -> Device | None:
"""
Load device from database by id.
"""
with Connection.session as db:
return db.get(cls, id)
def update(self) -> None:
"""
Update this device in the database.

View file

@ -202,3 +202,17 @@ class User(UserBase, table=True):
capability_name=capability.value,
) for capability in capabilities
]
def owns(
self,
device: Device,
) -> bool:
"""
Check if this user owns a device.
"""
return (
device.owner_name == self.name
# admin owns everything
or self.can(UserCapabilityType.admin)
)

View file

@ -7,7 +7,7 @@ from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from ..config import Config, Settings
from ..db import User, UserCapabilityType
from ..db import Device, User, UserCapabilityType
oauth2_scheme = OAuth2PasswordBearer(
tokenUrl=f"{Settings._.api_v1_prefix}/user/authenticate"
@ -128,3 +128,31 @@ async def get_user_by_name(
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
return user
async def get_device_by_id(
device_id: int,
current_config: Config | None = Depends(Config.load),
) -> Device | None:
# can't connect to an unconfigured database
if current_config is None:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)
return Device.get(device_id)
async def get_device_by_id_if_editable(
device: Device | None = Depends(get_device_by_id),
current_user: User = Depends(get_current_user_if_exists),
) -> Device:
# fail if device doesn't exist
if device is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
# fail if device is not owned by current user
if not current_user.owns(device):
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
return device

View file

@ -5,7 +5,7 @@
from fastapi import APIRouter, Depends, HTTPException, status
from ..db import Device, DeviceCreate, DeviceRead, User
from ._common import Responses, get_user_by_name
from ._common import Responses, get_device_by_id_if_editable, get_user_by_name
router = APIRouter(prefix="/device", tags=["device"])
@ -42,3 +42,25 @@ async def add_device(
# return the created device on success
return new_device
@router.delete(
"/{device_id}",
responses={
status.HTTP_200_OK: Responses.OK,
status.HTTP_400_BAD_REQUEST: Responses.NOT_INSTALLED,
status.HTTP_401_UNAUTHORIZED: Responses.NEEDS_USER,
status.HTTP_403_FORBIDDEN: Responses.NEEDS_ADMIN,
status.HTTP_404_NOT_FOUND: Responses.ENTRY_DOESNT_EXIST,
},
response_model=User,
)
async def remove_device(
device: Device = Depends(get_device_by_id_if_editable),
):
"""
DELETE ./{device_id}: Remove a device from the database.
"""
# delete device
device.delete()