From 3460cd76a59054b9e2131f812d15953787f196bb Mon Sep 17 00:00:00 2001 From: luxferre Date: Wed, 3 Jun 2026 14:36:15 +0100 Subject: [PATCH] tests: super admin auth tests --- src/auth/dependencies.py | 14 +++++++++ test/conftest.py | 15 ++++++++++ test/test_auth_su.py | 62 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 test/test_auth_su.py diff --git a/src/auth/dependencies.py b/src/auth/dependencies.py index 26695c8..f1c1d78 100644 --- a/src/auth/dependencies.py +++ b/src/auth/dependencies.py @@ -69,3 +69,17 @@ async def user_model_super_admin(user_model: user_model_claims_dependency): super_admin_dependency = Annotated[type[User], Depends(user_model_super_admin)] + + +# Override for testing +async def never_super_admin(user_model: user_model_claims_dependency): + def _is_super_admin(_user_model) -> bool: + super_admin_emails = [] + if _user_model.email not in super_admin_emails: + raise UnauthorizedException(message="Must be super admin") + return True + + if _is_super_admin(user_model): + return user_model + + raise UnauthorizedException(message="Must be super admin") diff --git a/test/conftest.py b/test/conftest.py index fb974fc..2de749c 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -10,6 +10,7 @@ from src.organisation.models import Organisation as Org from src.contact.models import Contact from src.iam.models import Group, Permission from src.auth.service import get_current_user, get_dev_user +from src.auth.dependencies import user_model_super_admin, never_super_admin from src.main import app # inited FastAPI app from src.database import engine, Base, get_db @@ -44,6 +45,20 @@ async def default_client(db_session) -> AsyncGenerator[AsyncClient, None]: app.dependency_overrides.clear() +@pytest.fixture +async def no_su_client(db_session) -> AsyncGenerator[AsyncClient, None]: + def get_db_override(): + return db_session + app.dependency_overrides[get_db] = get_db_override + app.dependency_overrides[get_current_user] = get_dev_user + app.dependency_overrides[user_model_super_admin] = never_super_admin + transport = ASGITransport(app=app) + async with AsyncClient(transport=transport, base_url="http://localhost:8000/api/v1") as ac: + yield ac + + app.dependency_overrides.clear() + + def _seed(db): db.add(User(email="admin@test.com", first_name="Admin", last_name="Test", oidc_id="abcd-efgh-ijkl-mnop")) db.add(Contact(org_id=1, email="billing@test.org", phonenumber="07521539927")) diff --git a/test/test_auth_su.py b/test/test_auth_su.py new file mode 100644 index 0000000..9cef61f --- /dev/null +++ b/test/test_auth_su.py @@ -0,0 +1,62 @@ +""" +This module ensures super admin only endpoints do return a correctly formatted 401 when user is not a super admin +DELETE endpoints are not tested +""" +import pytest +from httpx import AsyncClient + +from src.organisation.models import OrgUsers +from src.user.models import User + + +@pytest.mark.anyio +async def test_get_user_auth_su(no_su_client: AsyncClient): + resp = await no_su_client.get("/user/?user_id=1") + assert resp.status_code != 422 + assert resp.status_code == 401 + assert resp.json()["detail"] == "Must be super admin" + + +@pytest.mark.anyio +async def test_patch_org_status_auth_su(no_su_client: AsyncClient): + resp = await no_su_client.patch("/org/status", json={"organisation_id": 1, "status": "submitted"}) + assert resp.status_code != 422 + assert resp.status_code == 401 + assert resp.json()["detail"] == "Must be super admin" + + +@pytest.mark.anyio +async def test_patch_org_root_user_auth_su(no_su_client: AsyncClient, db_session): + db_session.add(User(email="user@test.org", first_name="User", last_name="Test", oidc_id="abcd-efgh-ijkl-1234")) + db_session.flush() + db_session.add(OrgUsers(org_id=1, user_id=2)) + db_session.flush() + + resp = await no_su_client.patch("/org/root_user", json={"organisation_id": 1, "user_id": 2}) + assert resp.status_code != 422 + assert resp.status_code == 401 + assert resp.json()["detail"] == "Must be super admin" + + +@pytest.mark.anyio +async def test_patch_service_key_auth_su(no_su_client: AsyncClient): + resp = await no_su_client.patch("/service/key", json={"service_id": 1}) + assert resp.status_code != 422 + assert resp.status_code == 401 + assert resp.json()["detail"] == "Must be super admin" + + +@pytest.mark.anyio +async def test_post_service_auth_su(no_su_client: AsyncClient): + resp = await no_su_client.post("/service/", json={"name": "New Test Service"}) + assert resp.status_code != 422 + assert resp.status_code == 401 + assert resp.json()["detail"] == "Must be super admin" + + +@pytest.mark.anyio +async def test_post_perm_success(no_su_client: AsyncClient, db_session): + resp = await no_su_client.post("/iam/permission", json={"service_id": 1, "resource": "test_resource", "action": "create"}) + assert resp.status_code != 422 + assert resp.status_code == 401 + assert resp.json()["detail"] == "Must be super admin"