From 3422acd14a61f5a37d2c85ddad7368a070ecb5af Mon Sep 17 00:00:00 2001 From: Iain-S <25081046+Iain-S@users.noreply.github.com> Date: Thu, 7 Dec 2023 16:42:52 +0000 Subject: [PATCH] Guard against empty RBAC lists --- rctab/routers/frontend.py | 2 +- tests/test_routes/test_frontend.py | 63 ++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/rctab/routers/frontend.py b/rctab/routers/frontend.py index 136e2d7..99321b1 100644 --- a/rctab/routers/frontend.py +++ b/rctab/routers/frontend.py @@ -286,7 +286,7 @@ async def subscription_details( # ...then sort the assignments by role sorted_all_rbac_assignments = [] for role in role_order: - sorted_all_rbac_assignments.extend(assignments_dict[role]) + sorted_all_rbac_assignments.extend(assignments_dict.get(role, [])) # pylint: disable=line-too-long views = { diff --git a/tests/test_routes/test_frontend.py b/tests/test_routes/test_frontend.py index 9c5b75c..3f82684 100644 --- a/tests/test_routes/test_frontend.py +++ b/tests/test_routes/test_frontend.py @@ -15,6 +15,7 @@ from rctab.crud.accounting_models import subscription, subscription_details from rctab.crud.schema import RoleAssignment, SubscriptionState, UserRBAC from rctab.routers.frontend import check_user_on_subscription, home +from rctab.routers.frontend import subscription_details as subscription_details_page from tests.test_routes import constants from tests.test_routes.test_routes import test_db # pylint: disable=unused-import @@ -181,3 +182,65 @@ async def test_render_home_page(mocker: MockerFixture, test_db: Database) -> Non mocker.patch("rctab.routers.frontend.check_user_access", mock_check_access) await home(mock_request, mock_user) + + +@pytest.mark.asyncio +async def test_render_details_page(mocker: MockerFixture, test_db: Database) -> None: + """Check that we can pick up on undefined variable template issues.""" + # Use StrictUndefined while testing + mocker.patch( + "rctab.routers.frontend.templates", + Jinja2Templates( + ( + Path(rctab.routers.frontend.__file__).parent.parent / "templates" + ).absolute(), + undefined=StrictUndefined, + ), + ) + subscription_id = UUID(int=random.randint(0, (2**32) - 1)) + + await test_db.execute( + subscription.insert().values(), + dict( + admin=str(constants.ADMIN_UUID), + subscription_id=str(subscription_id), + ), + ) + + await test_db.execute( + subscription_details.insert().values(), + dict( + subscription_id=str(subscription_id), + state=SubscriptionState("Enabled"), + display_name="a subscription", + role_assignments=[ + RoleAssignment( + role_definition_id="123", + role_name="Sous chef", + principal_id="456", + display_name="Max Mustermann", + # Note the missing email address, which does sometimes happen + mail=None, + scope="some/scope/string", + ).dict() + ], + ), + ) + + mock_request = mocker.Mock() + + mock_user = mocker.Mock() + mock_user.token = { + "access_token": jwt.encode( + {"unique_name": "me@my.org", "name": "My Name"}, "my key" + ) + } + mock_user.oid = str(UUID(int=434)) + + mock_check_access = AsyncMock() + mock_check_access.return_value = UserRBAC( + oid=UUID(int=111), has_access=True, is_admin=True + ) + mocker.patch("rctab.routers.frontend.check_user_access", mock_check_access) + + await subscription_details_page(subscription_id, mock_request, mock_user)