From 673c91bc33e3255147f0e343b31431d9e0c38a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn-Michael=20Miehe?= <40151420+ldericher@users.noreply.github.com> Date: Wed, 23 Mar 2022 13:25:00 +0000 Subject: [PATCH] User creation/deletion --- api/kiwi_vpn_api/db/models.py | 12 +++++++--- api/kiwi_vpn_api/db/schemas.py | 16 +++++++++++++ api/kiwi_vpn_api/routers/_common.py | 4 ++++ api/kiwi_vpn_api/routers/user.py | 35 +++++++++++++++++++++++++++-- 4 files changed, 62 insertions(+), 5 deletions(-) diff --git a/api/kiwi_vpn_api/db/models.py b/api/kiwi_vpn_api/db/models.py index 9d3949e..421dbed 100644 --- a/api/kiwi_vpn_api/db/models.py +++ b/api/kiwi_vpn_api/db/models.py @@ -20,9 +20,15 @@ class User(ORMBaseModel): name = Column(String, primary_key=True, index=True) password = Column(String) - capabilities = relationship("UserCapability", lazy="joined") - certificates = relationship("Certificate", lazy="select") - distinguished_names = relationship("DistinguishedName", lazy="select") + capabilities: list[UserCapability] = relationship( + "UserCapability", lazy="joined", cascade="all, delete-orphan" + ) + certificates: list[Certificate] = relationship( + "Certificate", lazy="select" + ) + distinguished_names: list[DistinguishedName] = relationship( + "DistinguishedName", lazy="select" + ) @classmethod def load(cls, db: Session, name: str) -> User | None: diff --git a/api/kiwi_vpn_api/db/schemas.py b/api/kiwi_vpn_api/db/schemas.py index 04122de..c45d35d 100644 --- a/api/kiwi_vpn_api/db/schemas.py +++ b/api/kiwi_vpn_api/db/schemas.py @@ -209,3 +209,19 @@ class User(UserBase): db.delete(capability) db.commit() + + def delete( + self, + db: Session, + ) -> bool: + """ + Delete this user from the database. + """ + + if (db_user := models.User.load(db, self.name)) is None: + # nonexistent user + return False + + db.delete(db_user) + db.commit() + return True diff --git a/api/kiwi_vpn_api/routers/_common.py b/api/kiwi_vpn_api/routers/_common.py index d4e01c1..588b129 100644 --- a/api/kiwi_vpn_api/routers/_common.py +++ b/api/kiwi_vpn_api/routers/_common.py @@ -44,6 +44,10 @@ class Responses: "description": "Entry exists in database", "content": None, } + ENTRY_DOESNT_EXIST = { + "description": "Entry does not exist in database", + "content": None, + } async def get_current_user( diff --git a/api/kiwi_vpn_api/routers/user.py b/api/kiwi_vpn_api/routers/user.py index b66b19e..7f68f6a 100644 --- a/api/kiwi_vpn_api/routers/user.py +++ b/api/kiwi_vpn_api/routers/user.py @@ -69,7 +69,7 @@ async def get_current_user( @router.post( - "/new", + "/", responses={ status.HTTP_200_OK: Responses.OK, status.HTTP_400_BAD_REQUEST: Responses.NOT_INSTALLED, @@ -86,7 +86,7 @@ async def add_user( db: Session | None = Depends(Connection.get), ): """ - POST ./new: Create a new user in the database. + POST ./: Create a new user in the database. """ # actually create the new user @@ -104,6 +104,37 @@ async def add_user( return new_user +@router.delete( + "/{user_name}", + 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_409_CONFLICT: Responses.ENTRY_DOESNT_EXIST, + }, + response_model=User, +) +async def remove_user( + user_name: str, + _: User = Depends(get_current_user_if_admin), + db: Session | None = Depends(Connection.get), +): + """ + DELETE ./{user_name}: Remove a user from the database. + """ + + # get the user + user = User.from_db( + db=db, + name=user_name, + ) + + # fail if deletion was unsuccessful + if not user.delete(): + raise HTTPException(status_code=status.HTTP_409_CONFLICT) + + @router.post( "/{user_name}/capabilities", responses={