From 8e126ea62b3c79dd0957d4ad80433e0ba309f3e5 Mon Sep 17 00:00:00 2001 From: Jeroen Vijgen Date: Wed, 16 Jul 2025 10:57:16 +0000 Subject: [PATCH 1/4] Add user creation route and /me route --- api/asset_manager/src/modules/auth/router.py | 50 +-------------- api/asset_manager/src/modules/auth/utils.py | 6 +- api/asset_manager/src/modules/users/router.py | 59 +++++++++++++---- .../test_authentication.py | 34 ---------- .../src/tests/test_users_routes/test_users.py | 63 +++++++++++++++++++ 5 files changed, 117 insertions(+), 95 deletions(-) create mode 100644 api/asset_manager/src/tests/test_users_routes/test_users.py diff --git a/api/asset_manager/src/modules/auth/router.py b/api/asset_manager/src/modules/auth/router.py index c42b8931..4d8d10dd 100644 --- a/api/asset_manager/src/modules/auth/router.py +++ b/api/asset_manager/src/modules/auth/router.py @@ -10,8 +10,6 @@ from modules.auth.models import Token from fastapi import Depends, HTTPException, status from tortoise.expressions import Q from config import settings -from modules.users.schemas import user_model -from modules.auth.schemas import register_model router = APIRouter(prefix="/api/v1/auth", tags=["auth"]) @@ -31,7 +29,7 @@ async def login(form: Annotated[OAuth2PasswordRequestForm, Depends()]): Logs the user into our API, creates tokens and passes them back to User. """ user: User | None = await User.filter( - Q(email=form.username) | Q(username=form.username) + (Q(email=form.username) | Q(username=form.username)) & Q(disabled=False) ).first() if user is None: @@ -44,11 +42,6 @@ async def login(form: Annotated[OAuth2PasswordRequestForm, Depends()]): status_code=status.HTTP_401_UNAUTHORIZED, detail=account_error ) - if user.disabled is True: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail=account_error - ) - tokens = await create_jwt_tokens(user) return {"jwt": tokens} @@ -61,7 +54,7 @@ async def logout(user: Annotated[User, Depends(get_current_active_user)]): Logout destroys all tokens for User that are currently active. """ - get_all_tokens = await Token.filter(Q(user__id=user.id)) + get_all_tokens = await Token.filter(Q(user__id=user.id) & Q(disabled=False)) if get_all_tokens is None: raise HTTPException( status_code=status.HTTP_204_NO_CONTENT, detail="An error occurred." @@ -98,12 +91,6 @@ async def refresh_login( detail=token_error, ) - if refresh_token.disabled is True: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail=token_error, - ) - get_all_tokens = await Token.filter(Q(user__id=refresh_token.user_id)) for token in get_all_tokens: @@ -115,36 +102,3 @@ async def refresh_login( ) return {"jwt": tokens} - - -@router.post( - "/register", status_code=status.HTTP_201_CREATED, response_model=user_model -) -async def register(user: register_model): - # Prevent existing users from reapplying for our system. - existing_user: User | None = await User.filter( - Q(email=user.email) - & Q(username=user.username) - & Q(name=user.name) - & Q(surname=user.surname) - ).get_or_none() - - if existing_user is not None: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail=user_exists, - ) - - if user.password != user.validate_password: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail=password_failed, - ) - - return await User.create( - email=user.email, - username=user.username, - name=user.name, - surname=user.surname, - password=crypt.hash(user.password), - ) diff --git a/api/asset_manager/src/modules/auth/utils.py b/api/asset_manager/src/modules/auth/utils.py index 75ab6ac0..d0b2560a 100644 --- a/api/asset_manager/src/modules/auth/utils.py +++ b/api/asset_manager/src/modules/auth/utils.py @@ -61,7 +61,7 @@ async def create_jwt_tokens(user: User) -> Token: async def get_tokens_from_logged_in_user( - token: Annotated[str, Depends(settings.OAUTH2_SCHEME)] + token: Annotated[str, Depends(settings.OAUTH2_SCHEME)], ) -> User | None: credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, @@ -79,4 +79,6 @@ async def get_tokens_from_logged_in_user( except: raise credentials_exception - return await Token.filter(Q(refresh_token=token) & Q(user__id=user_id)).first() + return await Token.filter( + Q(refresh_token=token) & Q(user__id=user_id) & Q(disabled=False) + ).first() diff --git a/api/asset_manager/src/modules/users/router.py b/api/asset_manager/src/modules/users/router.py index 4418c8e8..6717653b 100644 --- a/api/asset_manager/src/modules/users/router.py +++ b/api/asset_manager/src/modules/users/router.py @@ -1,20 +1,57 @@ -from fastapi import APIRouter +from typing import Annotated +from fastapi import APIRouter, Depends +from fastapi import HTTPException, status + +from tortoise.expressions import Q + +from modules.users.utils import get_current_active_user +from modules.auth.schemas import register_model from modules.users.models import User +from modules.users.schemas import user_model + +from config import settings router = APIRouter(prefix="/api/v1/users", tags=["users"]) +crypt = settings.CRYPT -@router.get("/") -def get_all_users(): - pass - -@router.post("/") -def create_user(): - pass +user_exists: str = "Account failed to create, please contact support." +password_failed: str = "Password validation failed, please try again." -@router.get("/me") -def get_user(): - pass +@router.post("/", status_code=status.HTTP_201_CREATED, response_model=user_model) +async def create_user(user: register_model): + # Prevent existing users from reapplying for our system. + existing_user: User | None = await User.filter( + Q(email=user.email) + & Q(username=user.username) + & Q(name=user.name) + & Q(surname=user.surname) + ).get_or_none() + + if existing_user is not None: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=user_exists, + ) + + if user.password != user.validate_password: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=password_failed, + ) + + return await User.create( + email=user.email, + username=user.username, + name=user.name, + surname=user.surname, + password=crypt.hash(user.password), + ) + + +@router.get("/me", response_model=user_model) +async def get_user(user: Annotated[User, Depends(get_current_active_user)]): + return user diff --git a/api/asset_manager/src/tests/test_authentication/test_authentication.py b/api/asset_manager/src/tests/test_authentication/test_authentication.py index 96d0b510..9a50648e 100644 --- a/api/asset_manager/src/tests/test_authentication/test_authentication.py +++ b/api/asset_manager/src/tests/test_authentication/test_authentication.py @@ -1,9 +1,7 @@ from tests.base_test import Test -from modules.users.models import User from httpx import AsyncClient from config import settings from unittest.mock import ANY -from tortoise.expressions import Q crypt = settings.CRYPT @@ -161,35 +159,3 @@ class TestAuthentication(Test): } } - async def test_setup_new_account(self, client: AsyncClient): - # Ensure account is never available. Prevents account already being available. - check_if_account_exists: User | None = await User.filter( - Q(email="superuser@localhost.com") - ).get_or_none() - if check_if_account_exists: - await check_if_account_exists.delete(force=True) - - account = await client.post( - "https://localhost/api/v1/auth/register", - json={ - "email": "superuser@localhost.com", - "username": "superuser", - "name": "awesome", - "surname": "superuser", - "password": "superuserpassword", - "validate_password": "superuserpassword", - }, - ) - - assert account.status_code == 201 - assert account.json() == { - "created_at": ANY, - "disabled": False, - "disabled_at": None, - "email": "superuser@localhost.com", - "id": ANY, - "modified_at": ANY, - "name": "awesome", - "surname": "superuser", - "username": "superuser", - } diff --git a/api/asset_manager/src/tests/test_users_routes/test_users.py b/api/asset_manager/src/tests/test_users_routes/test_users.py new file mode 100644 index 00000000..7f5e9f08 --- /dev/null +++ b/api/asset_manager/src/tests/test_users_routes/test_users.py @@ -0,0 +1,63 @@ +from tests.base_test import Test +from tortoise.expressions import Q +from tests.base_test import Test +from httpx import AsyncClient +from unittest.mock import ANY +from modules.users.models import User + +class TestAccounts(Test): + async def test_setup_new_account(self, client: AsyncClient): + # Ensure account is never available. Prevents account already being available. + check_if_account_exists: User | None = await User.filter( + Q(email="superuser@localhost.com") + ).get_or_none() + if check_if_account_exists: + await check_if_account_exists.delete(force=True) + + account = await client.post( + "https://localhost/api/v1/users/", + json={ + "email": "superuser@localhost.com", + "username": "superuser", + "name": "awesome", + "surname": "superuser", + "password": "superuserpassword", + "validate_password": "superuserpassword", + }, + ) + + assert account.status_code == 201 + assert account.json() == { + "created_at": ANY, + "disabled": False, + "disabled_at": None, + "email": "superuser@localhost.com", + "id": ANY, + "modified_at": ANY, + "name": "awesome", + "surname": "superuser", + "username": "superuser", + } + + async def test_me_route(self, client: AsyncClient, create_user_with_org): + # Ensure account is never available. Prevents account already being available. + _, _, _, tokens = await create_user_with_org() + + + account = await client.get( + "https://localhost/api/v1/users/me", + headers={"Authorization": f"Bearer {tokens.access_token}"}, + ) + + assert account.status_code == 200 + assert account.json() == { + "created_at": ANY, + "disabled": False, + "disabled_at": None, + "email": "user@localhost.com", + "id": ANY, + "modified_at": ANY, + "name": "awesome", + "surname": "user", + "username": "user", + } \ No newline at end of file From c2801858c52104ed7f33dedf093edec31ef9742b Mon Sep 17 00:00:00 2001 From: Jeroen Vijgen Date: Wed, 16 Jul 2025 18:10:10 +0000 Subject: [PATCH 2/4] Add updateable route for my user --- api/asset_manager/src/modules/auth/schemas.py | 11 +--- api/asset_manager/src/modules/users/models.py | 6 +- api/asset_manager/src/modules/users/router.py | 23 +++++++- .../src/modules/users/schemas.py | 18 ++++++ api/asset_manager/src/modules/users/utils.py | 11 +--- .../src/tests/test_users_routes/test_users.py | 56 ++++++++++++++++++- 6 files changed, 101 insertions(+), 24 deletions(-) diff --git a/api/asset_manager/src/modules/auth/schemas.py b/api/asset_manager/src/modules/auth/schemas.py index 08d312bc..a7c680d4 100644 --- a/api/asset_manager/src/modules/auth/schemas.py +++ b/api/asset_manager/src/modules/auth/schemas.py @@ -1,14 +1,5 @@ -from pydantic import BaseModel, EmailStr from tortoise.contrib.pydantic import pydantic_model_creator from modules.auth.models import Token -token_model = pydantic_model_creator(Token) - -class register_model(BaseModel): - email: EmailStr - username: str - name: str - surname: str - password: str - validate_password: str \ No newline at end of file +token_model = pydantic_model_creator(Token) \ No newline at end of file diff --git a/api/asset_manager/src/modules/users/models.py b/api/asset_manager/src/modules/users/models.py index be2c70dc..0fa03330 100644 --- a/api/asset_manager/src/modules/users/models.py +++ b/api/asset_manager/src/modules/users/models.py @@ -1,5 +1,6 @@ from datetime import datetime import uuid +from fastapi import HTTPException, status from pydantic import EmailStr import pytz from tortoise.models import Model @@ -41,9 +42,10 @@ class User(Model): def __str__(self) -> str: return f"{self.id} - {self.name} {self.surname}" - async def set_password(self, password: str) -> None: + async def set_password(self, password: str) -> bool: self.password = crypt.hash(password) await self.save() # Make sure to save the model in DB + return True def check_against_password(self, password: str) -> bool: return crypt.verify(password, self.password) @@ -55,7 +57,7 @@ class User(Model): return False if new_password is not verify_new_password: return False - await self.set_password(new_password) + return await self.set_password(new_password) async def delete(self, force: bool = False) -> None: if force: diff --git a/api/asset_manager/src/modules/users/router.py b/api/asset_manager/src/modules/users/router.py index 6717653b..ed19541b 100644 --- a/api/asset_manager/src/modules/users/router.py +++ b/api/asset_manager/src/modules/users/router.py @@ -6,7 +6,7 @@ from fastapi import HTTPException, status from tortoise.expressions import Q from modules.users.utils import get_current_active_user -from modules.auth.schemas import register_model +from modules.users.schemas import register_model, update_user_model from modules.users.models import User from modules.users.schemas import user_model @@ -24,12 +24,13 @@ password_failed: str = "Password validation failed, please try again." @router.post("/", status_code=status.HTTP_201_CREATED, response_model=user_model) async def create_user(user: register_model): # Prevent existing users from reapplying for our system. - existing_user: User | None = await User.filter( + existing_user: User | None = await User.get_or_none( Q(email=user.email) & Q(username=user.username) & Q(name=user.name) & Q(surname=user.surname) - ).get_or_none() + & Q(disabled=False) + ) if existing_user is not None: raise HTTPException( @@ -52,6 +53,22 @@ async def create_user(user: register_model): ) +@router.put("/me", status_code=status.HTTP_204_NO_CONTENT) +async def update_user(user: Annotated[User, Depends(get_current_active_user)], + updated_user: update_user_model): + if updated_user.email: + user.email = updated_user.email + if updated_user.name: + user.name = updated_user.name + if updated_user.surname: + user.surname = updated_user.surname + + if updated_user.old_password and updated_user.password and updated_user.validate_password: + user.update_password(updated_user.old_password, updated_user.password, updated_user.validate_password) + + await user.save() + + @router.get("/me", response_model=user_model) async def get_user(user: Annotated[User, Depends(get_current_active_user)]): return user diff --git a/api/asset_manager/src/modules/users/schemas.py b/api/asset_manager/src/modules/users/schemas.py index 07504195..50134f37 100644 --- a/api/asset_manager/src/modules/users/schemas.py +++ b/api/asset_manager/src/modules/users/schemas.py @@ -1,5 +1,23 @@ +from pydantic import BaseModel, EmailStr from tortoise.contrib.pydantic import pydantic_model_creator from modules.users.models import User user_model = pydantic_model_creator(User, exclude=["password"]) + +class register_model(BaseModel): + email: EmailStr + username: str + name: str + surname: str + password: str + validate_password: str + + +class update_user_model(BaseModel): + email: EmailStr | None + name: str | None + surname: str | None + old_password: str | None + password: str | None + validate_password: str | None diff --git a/api/asset_manager/src/modules/users/utils.py b/api/asset_manager/src/modules/users/utils.py index 5af250df..a700730e 100644 --- a/api/asset_manager/src/modules/users/utils.py +++ b/api/asset_manager/src/modules/users/utils.py @@ -10,7 +10,7 @@ from config import settings async def get_user_from_token( - token: Annotated[str, Depends(settings.OAUTH2_SCHEME)] + token: Annotated[str, Depends(settings.OAUTH2_SCHEME)], ) -> User | None: credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, @@ -28,7 +28,7 @@ async def get_user_from_token( except: raise credentials_exception - return await User.filter(Q(id=user_id)).first() + return await User.filter(Q(id=user_id) & Q(disabled=False)).first() async def get_current_active_user( @@ -37,11 +37,6 @@ async def get_current_active_user( if user is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, - detail="User is not found or active", - ) - if user.disabled: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="User is not found or active", + detail="The requested token does not exist or you are not logged in.", ) return user diff --git a/api/asset_manager/src/tests/test_users_routes/test_users.py b/api/asset_manager/src/tests/test_users_routes/test_users.py index 7f5e9f08..12a0808b 100644 --- a/api/asset_manager/src/tests/test_users_routes/test_users.py +++ b/api/asset_manager/src/tests/test_users_routes/test_users.py @@ -40,7 +40,6 @@ class TestAccounts(Test): } async def test_me_route(self, client: AsyncClient, create_user_with_org): - # Ensure account is never available. Prevents account already being available. _, _, _, tokens = await create_user_with_org() @@ -60,4 +59,59 @@ class TestAccounts(Test): "name": "awesome", "surname": "user", "username": "user", + } + + async def test_update_me_route(self, client: AsyncClient, create_user_with_org): + _, _, _, tokens = await create_user_with_org() + + + account = await client.get( + "https://localhost/api/v1/users/me", + headers={"Authorization": f"Bearer {tokens.access_token}"}, + ) + + assert account.status_code == 200 + assert account.json() == { + "created_at": ANY, + "disabled": False, + "disabled_at": None, + "email": "user@localhost.com", + "id": ANY, + "modified_at": ANY, + "name": "awesome", + "surname": "user", + "username": "user", + } + + account = await client.put( + "https://localhost/api/v1/users/me", + json={ + "email": None, + "name": None, + "surname": "bluey", + "old_password": None, + "password": None, + "validate_password": None, + }, + headers={"Authorization": f"Bearer {tokens.access_token}"}, + ) + + assert account.status_code == 204 + + account = await client.get( + "https://localhost/api/v1/users/me", + headers={"Authorization": f"Bearer {tokens.access_token}"}, + ) + + assert account.status_code == 200 + assert account.json() == { + "created_at": ANY, + "disabled": False, + "disabled_at": None, + "email": "user@localhost.com", + "id": ANY, + "modified_at": ANY, + "name": "awesome", + "surname": "bluey", + "username": "user", } \ No newline at end of file From 9f8f7cc1127d8e2019957dbd120bab84a473eb9b Mon Sep 17 00:00:00 2001 From: Jeroen Vijgen Date: Wed, 16 Jul 2025 18:43:52 +0000 Subject: [PATCH 3/4] Refresh some magic numbers with status codes, add delete for account and make people able to update password --- .../src/modules/organizations/router.py | 6 +-- api/asset_manager/src/modules/users/router.py | 39 +++++++++++++--- .../src/modules/users/schemas.py | 4 ++ .../src/tests/test_users_routes/test_users.py | 45 +++++++++++++++++-- 4 files changed, 80 insertions(+), 14 deletions(-) diff --git a/api/asset_manager/src/modules/organizations/router.py b/api/asset_manager/src/modules/organizations/router.py index ba4be69a..75b92191 100644 --- a/api/asset_manager/src/modules/organizations/router.py +++ b/api/asset_manager/src/modules/organizations/router.py @@ -1,5 +1,5 @@ import uuid -from fastapi import APIRouter, Depends, HTTPException +from fastapi import APIRouter, Depends, HTTPException, status from typing import Annotated, List @@ -27,7 +27,7 @@ async def all_active_organizations( organizations: List[Organization] = [] if len(memberships) < 1: - raise HTTPException(status_code=404, detail="No active organizations found!") + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="No active organizations found!") for member in memberships: organizations.append(member.organization) @@ -35,7 +35,7 @@ async def all_active_organizations( return organizations -@router.delete("/{org_id}", status_code=204) +@router.delete("/{org_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_organization( user: Annotated[User, Depends(get_current_active_user)], org_id: uuid.UUID ) -> None: diff --git a/api/asset_manager/src/modules/users/router.py b/api/asset_manager/src/modules/users/router.py index ed19541b..a61ee9df 100644 --- a/api/asset_manager/src/modules/users/router.py +++ b/api/asset_manager/src/modules/users/router.py @@ -1,13 +1,14 @@ -from typing import Annotated +from typing import Annotated, List from fastapi import APIRouter, Depends from fastapi import HTTPException, status from tortoise.expressions import Q +from modules.auth.models import Token from modules.users.utils import get_current_active_user -from modules.users.schemas import register_model, update_user_model -from modules.users.models import User +from modules.users.schemas import delete_user_model, register_model, update_user_model +from modules.users.models import Membership, User from modules.users.schemas import user_model from config import settings @@ -54,8 +55,10 @@ async def create_user(user: register_model): @router.put("/me", status_code=status.HTTP_204_NO_CONTENT) -async def update_user(user: Annotated[User, Depends(get_current_active_user)], - updated_user: update_user_model): +async def update_user( + user: Annotated[User, Depends(get_current_active_user)], + updated_user: update_user_model, +): if updated_user.email: user.email = updated_user.email if updated_user.name: @@ -63,12 +66,34 @@ async def update_user(user: Annotated[User, Depends(get_current_active_user)], if updated_user.surname: user.surname = updated_user.surname - if updated_user.old_password and updated_user.password and updated_user.validate_password: - user.update_password(updated_user.old_password, updated_user.password, updated_user.validate_password) + if ( + updated_user.old_password + and updated_user.password + and updated_user.validate_password + ): + user.update_password( + updated_user.old_password, + updated_user.password, + updated_user.validate_password, + ) await user.save() +@router.delete("/me", status_code=status.HTTP_204_NO_CONTENT) +async def update_user( + user: Annotated[User, Depends(get_current_active_user)], +): + memberships: List[Membership] = await Membership.filter(Q(user__id=user.id) & Q(disabled=False)) + for membership in memberships: + await membership.acl.delete() + await membership.delete() + tokens: List[Token] = await Token.filter(Q(user__id=user.id) & Q(disabled=False)) + for token in tokens: + await token.delete() + await user.delete() + + @router.get("/me", response_model=user_model) async def get_user(user: Annotated[User, Depends(get_current_active_user)]): return user diff --git a/api/asset_manager/src/modules/users/schemas.py b/api/asset_manager/src/modules/users/schemas.py index 50134f37..5196064b 100644 --- a/api/asset_manager/src/modules/users/schemas.py +++ b/api/asset_manager/src/modules/users/schemas.py @@ -21,3 +21,7 @@ class update_user_model(BaseModel): old_password: str | None password: str | None validate_password: str | None + +class delete_user_model(BaseModel): + password: str + diff --git a/api/asset_manager/src/tests/test_users_routes/test_users.py b/api/asset_manager/src/tests/test_users_routes/test_users.py index 12a0808b..d2fe5017 100644 --- a/api/asset_manager/src/tests/test_users_routes/test_users.py +++ b/api/asset_manager/src/tests/test_users_routes/test_users.py @@ -5,6 +5,7 @@ from httpx import AsyncClient from unittest.mock import ANY from modules.users.models import User + class TestAccounts(Test): async def test_setup_new_account(self, client: AsyncClient): # Ensure account is never available. Prevents account already being available. @@ -42,7 +43,6 @@ class TestAccounts(Test): async def test_me_route(self, client: AsyncClient, create_user_with_org): _, _, _, tokens = await create_user_with_org() - account = await client.get( "https://localhost/api/v1/users/me", headers={"Authorization": f"Bearer {tokens.access_token}"}, @@ -64,7 +64,6 @@ class TestAccounts(Test): async def test_update_me_route(self, client: AsyncClient, create_user_with_org): _, _, _, tokens = await create_user_with_org() - account = await client.get( "https://localhost/api/v1/users/me", headers={"Authorization": f"Bearer {tokens.access_token}"}, @@ -82,7 +81,7 @@ class TestAccounts(Test): "surname": "user", "username": "user", } - + account = await client.put( "https://localhost/api/v1/users/me", json={ @@ -114,4 +113,42 @@ class TestAccounts(Test): "name": "awesome", "surname": "bluey", "username": "user", - } \ No newline at end of file + } + + async def test_remove_account(self, client: AsyncClient, create_user_with_org): + _, _, _, tokens = await create_user_with_org(email="sup3rus3r@gmail.com") + + account = await client.get( + "https://localhost/api/v1/users/me", + headers={"Authorization": f"Bearer {tokens.access_token}"}, + ) + + assert account.status_code == 200 + assert account.json() == { + "created_at": ANY, + "disabled": False, + "disabled_at": None, + "email": "sup3rus3r@gmail.com", + "id": ANY, + "modified_at": ANY, + "name": "awesome", + "surname": "user", + "username": "user", + } + + delete = await client.delete( + "https://localhost/api/v1/users/me", + headers={"Authorization": f"Bearer {tokens.access_token}"}, + ) + + assert delete.status_code == 204 + + old = await client.get( + "https://localhost/api/v1/users/me", + headers={"Authorization": f"Bearer {tokens.access_token}"}, + ) + + assert old.status_code == 401 + assert old.json() == { + "detail": "The requested token does not exist or you are not logged in.", + } From 96550b92dd364b3b7b095159756d53a1560805d6 Mon Sep 17 00:00:00 2001 From: Jeroen Vijgen Date: Wed, 16 Jul 2025 18:45:05 +0000 Subject: [PATCH 4/4] Remove dead code --- api/asset_manager/src/modules/users/router.py | 2 +- api/asset_manager/src/modules/users/schemas.py | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/api/asset_manager/src/modules/users/router.py b/api/asset_manager/src/modules/users/router.py index a61ee9df..0b5020b3 100644 --- a/api/asset_manager/src/modules/users/router.py +++ b/api/asset_manager/src/modules/users/router.py @@ -7,7 +7,7 @@ from tortoise.expressions import Q from modules.auth.models import Token from modules.users.utils import get_current_active_user -from modules.users.schemas import delete_user_model, register_model, update_user_model +from modules.users.schemas import register_model, update_user_model from modules.users.models import Membership, User from modules.users.schemas import user_model diff --git a/api/asset_manager/src/modules/users/schemas.py b/api/asset_manager/src/modules/users/schemas.py index 5196064b..5e7280c7 100644 --- a/api/asset_manager/src/modules/users/schemas.py +++ b/api/asset_manager/src/modules/users/schemas.py @@ -22,6 +22,3 @@ class update_user_model(BaseModel): password: str | None validate_password: str | None -class delete_user_model(BaseModel): - password: str -