diff --git a/tests/api/test_generic.py b/tests/api/test_generic.py index 23656bb1..7e341d78 100644 --- a/tests/api/test_generic.py +++ b/tests/api/test_generic.py @@ -1,5 +1,7 @@ import pytest +from lnbits.core.models.users import User + @pytest.mark.anyio async def test_core_views_generic(client): @@ -50,3 +52,47 @@ async def test_get_extensions_no_user(client): response = await client.get("extensions") # bad request assert response.status_code == 401, f"{response.url} {response.status_code}" + + +ADMIN_PATHS = [ + "/users", + "/audit", + "/node", + "/admin", +] + + +# Test admin access to protected paths +@pytest.mark.anyio +@pytest.mark.parametrize("path", ADMIN_PATHS) +async def test_admin_paths_access_granted_for_admin( + client, admin_user: User, path: str +): + response = await client.post( + "/api/v1/auth", json={"username": admin_user.username, "password": "secret1234"} + ) + + assert response.status_code == 200, "Admin logs in OK" + access_token = response.json().get("access_token") + assert access_token is not None + + response = await client.get( + path, headers={"Authorization": f"Bearer {access_token}"} + ) + assert ( + response.status_code == 200 + ), f"{path} should be accessible for admin, got {response.status_code}" + + +# Test non-admin access to protected paths +@pytest.mark.anyio +@pytest.mark.parametrize("path", ADMIN_PATHS) +async def test_admin_paths_access_denied_for_non_admin( + client, to_user: User, path: str +): + client.cookies.clear() + response = await client.get(path, params={"usr": to_user.id}) + assert response.status_code in ( + 401, + 403, + ), f"{path} should be forbidden for non-admin, got {response.status_code}" diff --git a/tests/conftest.py b/tests/conftest.py index ea5609d3..503b2a0e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -31,6 +31,8 @@ from tests.helpers import ( asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) +ADMIN_USER_ID = uuid4().hex + @pytest.fixture(scope="session") def anyio_backend(): @@ -109,6 +111,20 @@ async def user_alan(): yield await new_user("alan") +@pytest.fixture(scope="session") +async def admin_user(): + username = "admin" + account = Account( + id=ADMIN_USER_ID, + email=f"{username}@lnbits.com", + username=username, + ) + account.hash_password("secret1234") + user = await create_user_account(account) + + return user + + @pytest.fixture(scope="session") async def from_user(): user = await create_user_account() @@ -316,7 +332,7 @@ def _settings_cleanup(settings: Settings): settings.lnbits_reserve_fee_percent = 0 settings.lnbits_wallet_limit_daily_max_withdraw = 0 settings.lnbits_admin_extensions = [] - settings.lnbits_admin_users = [] + settings.lnbits_admin_users = [ADMIN_USER_ID] settings.lnbits_max_outgoing_payment_amount_sats = 10_000_000_100 settings.lnbits_max_incoming_payment_amount_sats = 10_000_000_200 settings.stripe_limits = FiatProviderLimits()