From 6630fb577bb4b9a4c9e142fe3f13299f8a72a812 Mon Sep 17 00:00:00 2001 From: Jeroen Vijgen Date: Tue, 4 Mar 2025 15:36:42 +0200 Subject: [PATCH] Fix last issues regarding testing, fix generating user and admin accounts --- api/asset_manager/src/config.py | 1 - api/asset_manager/src/main.py | 1 - api/asset_manager/src/modules/auth/router.py | 4 + api/asset_manager/src/modules/auth/utils.py | 3 +- .../src/modules/organizations/models.py | 2 +- .../src/tests/fixtures/account_fixtures.py | 100 +++++++++++------- .../test_authentication.py | 5 +- 7 files changed, 72 insertions(+), 44 deletions(-) diff --git a/api/asset_manager/src/config.py b/api/asset_manager/src/config.py index a244ace7..f0b4b335 100644 --- a/api/asset_manager/src/config.py +++ b/api/asset_manager/src/config.py @@ -2,7 +2,6 @@ from pydantic_settings import BaseSettings, SettingsConfigDict # type: ignore from passlib.context import CryptContext # type: ignore import pytz - class Settings(BaseSettings): PROJECT_NAME: str = "StoneEdge Asset Management System" PROJECT_VERSION: str = "0.0.1" diff --git a/api/asset_manager/src/main.py b/api/asset_manager/src/main.py index 11d84db5..76d0ace4 100644 --- a/api/asset_manager/src/main.py +++ b/api/asset_manager/src/main.py @@ -1,5 +1,4 @@ from fastapi import FastAPI -from tortoise import Tortoise from config import settings from database import end_connections_to_db, migrate_db from responses import msgspec_jsonresponse diff --git a/api/asset_manager/src/modules/auth/router.py b/api/asset_manager/src/modules/auth/router.py index 2f69d801..5cfa6ae0 100644 --- a/api/asset_manager/src/modules/auth/router.py +++ b/api/asset_manager/src/modules/auth/router.py @@ -23,12 +23,16 @@ crypt = settings.CRYPT @router.post("/") async def login(form: Annotated[OAuth2PasswordRequestForm, Depends()]): user: User | None = await User.filter(email=form.username).first() + if user is None: raise HTTPException(status_code=401, detail=error) if user.check_against_password(form.password) is False: raise HTTPException(status_code=401, detail=error) + if user.disabled is True: + raise HTTPException(status_code=401, detail=error) + auth_token = create_token( user_id=user.id, offset=timedelta(settings.ACCESS_TOKEN_EXPIRE_MIN) ) diff --git a/api/asset_manager/src/modules/auth/utils.py b/api/asset_manager/src/modules/auth/utils.py index 90b45024..cd957719 100644 --- a/api/asset_manager/src/modules/auth/utils.py +++ b/api/asset_manager/src/modules/auth/utils.py @@ -2,6 +2,7 @@ from datetime import timedelta import uuid, time from config import settings from joserfc import jwt # type: ignore +from joserfc.jwk import OctKey # type: ignore crypt = settings.CRYPT @@ -22,7 +23,7 @@ def create_token(user_id: uuid, offset: timedelta) -> str: "iat": curr_time, "exp": int(time.time() + offset.total_seconds()), }, - settings.SECRET_KEY, + OctKey.import_key(settings.SECRET_KEY), ) diff --git a/api/asset_manager/src/modules/organizations/models.py b/api/asset_manager/src/modules/organizations/models.py index 48bc6d37..6ed02515 100644 --- a/api/asset_manager/src/modules/organizations/models.py +++ b/api/asset_manager/src/modules/organizations/models.py @@ -20,7 +20,7 @@ class EnumField(fields.CharField): raise ConfigurationError("{} is not a subclass of Enum!".format(enum_type)) self._enum_type = enum_type - def to_db_value(self, value: Enum, instance) -> str: + def to_db_value(self, value: Enum, _) -> str: return value.value def to_python_value(self, value: str) -> Enum: diff --git a/api/asset_manager/src/tests/fixtures/account_fixtures.py b/api/asset_manager/src/tests/fixtures/account_fixtures.py index d6e5d52d..26e45c9c 100644 --- a/api/asset_manager/src/tests/fixtures/account_fixtures.py +++ b/api/asset_manager/src/tests/fixtures/account_fixtures.py @@ -1,48 +1,72 @@ -import uuid -from modules.organizations.models import Organization +from modules.organizations.models import Organization, OrganizationType from modules.users.models import ACL, Membership, User -import pytest # type: ignore +import pytest # type: ignore from config import settings crypt = settings.CRYPT + @pytest.fixture() async def use_user_account(): - org = await Organization.create(name="User's Organization", type="home") - acl = await ACL.create( - READ=True, WRITE=True, REPORT=True, MANAGE=False, ADMIN=False - ) - user = await User.create( - email="user@localhost.com", - username="user", - name="awesome", - surname="user", - password=crypt.hash("userpassword"), - ) - membership = await Membership.create( - organization=org, - user=user, - acl=acl, - ) - return org, acl, user, membership + org, _ = await Organization.get_or_create( + id="6ad4c94e-0522-4912-8d16-02d451f4c92d", + name="User's Organization", + type=OrganizationType.HOME, + ) + acl, _ = await ACL.get_or_create( + id="a4e927a3-36e5-4761-badb-0a44ade6616f", + READ=True, + WRITE=True, + REPORT=True, + MANAGE=False, + ADMIN=False, + ) + user, _ = await User.get_or_create( + id="24235427-9662-4ba3-a9c5-00000000000b", + email="user@localhost.com", + username="user", + name="awesome", + surname="user", + password=crypt.hash("userpassword"), + ) + membership, _ = await Membership.get_or_create( + id="833b9511-b2da-4760-8fa4-1a5c7059911e", + organization=org, + user=user, + acl=acl, + ) + return org, acl, user, membership + @pytest.fixture() async def use_admin_account(): - org = await Organization.create(name="Admin's Organization", type="home") - acl = await ACL.create( - READ=True, WRITE=True, REPORT=True, MANAGE=True, ADMIN=True - ) - user = await User.create( - email="admin@localhost.com", - username="admin", - name="awesome", - surname="admin", - password=crypt.hash("adminpassword"), - ) - membership = await Membership.create( - organization=org, - user=user, - acl=acl, - ) - return org, acl, user, membership - + org, _ = await Organization.get_or_create( + id="de001f44-1bb8-4667-9f9d-2d62d6ad7270", + name="Admin's Organization", + type=OrganizationType.EXTRA_LARGE_ORGANIZATION, + ) + acl, _ = await ACL.get_or_create( + id="83c1bfe6-c2ed-4ba1-be03-0e5c1960ec31", + READ=True, + WRITE=True, + REPORT=True, + MANAGE=True, + ADMIN=True, + ) + user, _ = await User.get_or_create( + defaults={ + "id": "24235427-9662-4ba3-a9c5-00000000000a", + "email": "admin@localhost.com", + "username": "admin", + "name": "awesome", + "surname": "admin", + "password": crypt.hash("adminpassword"), + } + ) + membership, _ = await Membership.get_or_create( + id="393473ee-c218-4bcf-82cd-cb676c4d8a33", + organization=org, + user=user, + acl=acl, + ) + return org, acl, user, membership 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 768a3f0b..87460333 100644 --- a/api/asset_manager/src/tests/test_authentication/test_authentication.py +++ b/api/asset_manager/src/tests/test_authentication/test_authentication.py @@ -26,6 +26,7 @@ class TestAuthentication(object): async def test_authentication_with_existing_user_and_wrong_password( self, client: AsyncClient, use_admin_account ): + _, _, _, _ = use_admin_account response = await client.post( "http://localhost/api/v1/auth/", data={ @@ -41,7 +42,7 @@ class TestAuthentication(object): async def test_authentication_with_existing_user_and_password( self, client: AsyncClient, use_admin_account ): - _, _, user, _ = use_admin_account + _, _, admin, _ = use_admin_account response = await client.post( "http://localhost/api/v1/auth/", data={ @@ -54,7 +55,7 @@ class TestAuthentication(object): assert response.json() == { "jwt": { "created_at": ANY, - "user_id": str(user.id), + "user_id": str(admin.id), "id": ANY, "modified_at": ANY, "disabled_at": None,