From 8e460b05da4d419aa1b53b1c639d3e370143de4f Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Tue, 18 Jun 2024 12:38:29 -0500 Subject: Update tests for new paradigm * Create a jwt token generator in place of a static token * Update some fixtures * Skip some tests that will require more work to fix --- tests/unit/auth/conftest.py | 30 +++++++++++++--- tests/unit/auth/fixtures/group_fixtures.py | 37 ++++--------------- tests/unit/auth/fixtures/resource_fixtures.py | 31 ++++++++++++++++ tests/unit/auth/test_groups.py | 52 +++++++++++++++++++-------- tests/unit/auth/test_privileges.py | 7 +--- tests/unit/auth/test_resources.py | 23 +++++++----- tests/unit/auth/test_roles.py | 38 ++++++++++---------- 7 files changed, 134 insertions(+), 84 deletions(-) (limited to 'tests') diff --git a/tests/unit/auth/conftest.py b/tests/unit/auth/conftest.py index 7f9d42d..fa86a4c 100644 --- a/tests/unit/auth/conftest.py +++ b/tests/unit/auth/conftest.py @@ -4,19 +4,41 @@ import datetime from contextlib import contextmanager from gn_auth.auth.authentication.oauth2.models.oauth2token import OAuth2Token +from gn_auth.auth.authentication.oauth2.grants.jwt_bearer_grant import JWTBearerTokenGenerator from .fixtures import * # pylint: disable=[wildcard-import,unused-wildcard-import] -def get_tokeniser(user): +SECRET_KEY = "this is the test secret key" +SCOPE = "profile group role resource register-client" + +def _tokengenerator(user, client): + """Generate a JWT token for tests""" + _generator = JWTBearerTokenGenerator( + secret_key=SECRET_KEY, + alg="HS256") + return _generator( + grant_type="urn:ietf:params:oauth:grant-type:jwt-bearer", + client=client, + user=user, + scope=SCOPE, + expires_in=3600, + include_refresh_token=False) + +def get_tokeniser(user, client): """Get contextmanager for mocking token acquisition.""" @contextmanager def __token__(*args, **kwargs):# pylint: disable=[unused-argument] yield { usr.user_id: OAuth2Token( token_id=uuid.UUID("d32611e3-07fc-4564-b56c-786c6db6de2b"), - client=None, token_type="Bearer", access_token="123456ABCDE", - refresh_token=None, revoked=False, expires_in=864000, - user=usr, issued_at=int(datetime.datetime.now().timestamp()), + client=client, + token_type="Bearer", + access_token=_tokengenerator(user, client), + refresh_token=None, + revoked=False, + expires_in=864000, + user=usr, + issued_at=int(datetime.datetime.now().timestamp()), scope="profile group role resource register-client") for usr in TEST_USERS }[user.user_id] diff --git a/tests/unit/auth/fixtures/group_fixtures.py b/tests/unit/auth/fixtures/group_fixtures.py index 79683c0..8ddcf50 100644 --- a/tests/unit/auth/fixtures/group_fixtures.py +++ b/tests/unit/auth/fixtures/group_fixtures.py @@ -4,10 +4,10 @@ import uuid import pytest from gn_auth.auth.db import sqlite3 as db -from gn_auth.auth.authorisation.resources.groups import Group, GroupRole +from gn_auth.auth.authorisation.resources.groups import Group from gn_auth.auth.authorisation.resources import Resource, ResourceCategory -from .role_fixtures import RESOURCE_EDITOR_ROLE, RESOURCE_READER_ROLE +from .role_fixtures import RESOURCE_EDITOR_ROLE TEST_GROUP_01 = Group(uuid.UUID("9988c21d-f02f-4d45-8966-22c968ac2fbf"), "TheTestGroup", {}) @@ -135,38 +135,13 @@ def fxtr_users_in_group(fxtr_group, fxtr_users):# pylint: disable=[redefined-out "DELETE FROM group_users WHERE group_id=? AND user_id=?", query_params) -@pytest.fixture(scope="function") -def fxtr_group_roles(fxtr_group, fxtr_roles):# pylint: disable=[redefined-outer-name,unused-argument] - """Link roles to group""" - group_roles = ( - GroupRole(uuid.UUID("9c25efb2-b477-4918-a95c-9914770cbf4d"), - TEST_GROUP_01, RESOURCE_EDITOR_ROLE), - GroupRole(uuid.UUID("82aed039-fe2f-408c-ab1e-81cd1ba96630"), - TEST_GROUP_02, RESOURCE_READER_ROLE)) - conn, groups = fxtr_group - with db.cursor(conn) as cursor: - cursor.executemany( - "INSERT INTO group_roles VALUES (?, ?, ?)", - ((str(role.group_role_id), str(role.group.group_id), - str(role.role.role_id)) - for role in group_roles)) - - yield conn, groups, group_roles - - with db.cursor(conn) as cursor: - cursor.executemany( - ("DELETE FROM group_roles " - "WHERE group_role_id=? AND group_id=? AND role_id=?"), - ((str(role.group_role_id), str(role.group.group_id), - str(role.role.role_id)) - for role in group_roles)) @pytest.fixture(scope="function") -def fxtr_group_user_roles(fxtr_resources, fxtr_group_roles, fxtr_users_in_group):#pylint: disable=[redefined-outer-name,unused-argument] +def fxtr_group_user_roles(fxtr_users_in_group, fxtr_resources, fxtr_resource_roles):#pylint: disable=[redefined-outer-name,unused-argument] """Assign roles to users.""" - conn, _groups, group_roles = fxtr_group_roles - _conn, group_resources = fxtr_resources _conn, _group, group_users = fxtr_users_in_group + _conn, group_resources = fxtr_resources + conn, _groups, resource_roles = fxtr_resource_roles users = tuple(user for user in group_users if user.email not in ("unaff@iliated.user", "group@lead.er")) users_roles_resources = ( @@ -183,7 +158,7 @@ def fxtr_group_user_roles(fxtr_resources, fxtr_group_roles, fxtr_users_in_group) "VALUES (:user_id, :role_id, :resource_id)"), params) - yield conn, group_users, group_roles, group_resources + yield conn, group_users, resource_roles, group_resources with db.cursor(conn) as cursor: cursor.executemany( diff --git a/tests/unit/auth/fixtures/resource_fixtures.py b/tests/unit/auth/fixtures/resource_fixtures.py index 7f3c383..37397d2 100644 --- a/tests/unit/auth/fixtures/resource_fixtures.py +++ b/tests/unit/auth/fixtures/resource_fixtures.py @@ -3,6 +3,7 @@ import pytest from gn_auth.auth.db import sqlite3 as db +from .role_fixtures import RESOURCE_EDITOR_ROLE, RESOURCE_READER_ROLE from .group_fixtures import ( TEST_RESOURCES, TEST_GROUP_01, @@ -43,3 +44,33 @@ def fxtr_resources(fxtr_group):# pylint: disable=[redefined-outer-name] cursor.executemany("DELETE FROM resources WHERE resource_id=?", ((str(res.resource_id),) for res in TEST_RESOURCES)) + + +@pytest.fixture(scope="function") +def fxtr_resource_roles(fxtr_group, fxtr_resources, fxtr_roles):# pylint: disable=[redefined-outer-name,unused-argument] + """Link roles to resources.""" + resource_roles = ({ + "resource_id": str(TEST_RESOURCES_GROUP_01[0].resource_id), + "role_created_by": "ecb52977-3004-469e-9428-2a1856725c7f", + "role_id": str(RESOURCE_EDITOR_ROLE.role_id) + },{ + "resource_id": str(TEST_RESOURCES_GROUP_01[0].resource_id), + "role_created_by": "ecb52977-3004-469e-9428-2a1856725c7f", + "role_id": str(RESOURCE_READER_ROLE.role_id) + }) + conn, groups = fxtr_group + with db.cursor(conn) as cursor: + cursor.executemany( + "INSERT INTO resource_roles(resource_id, role_created_by, role_id) " + "VALUES (:resource_id, :role_created_by, :role_id)", + resource_roles) + + yield conn, groups, resource_roles + + with db.cursor(conn) as cursor: + cursor.executemany( + ("DELETE FROM resource_roles " + "WHERE resource_id=:resource_id " + "AND role_created_by=:role_created_by " + "AND role_id=:role_id"), + resource_roles) diff --git a/tests/unit/auth/test_groups.py b/tests/unit/auth/test_groups.py index c9d8b19..2960fe1 100644 --- a/tests/unit/auth/test_groups.py +++ b/tests/unit/auth/test_groups.py @@ -36,16 +36,20 @@ PRIVILEGES = ( create_group_failure, create_group_failure, create_group_failure, create_group_failure)))) def test_create_group(# pylint: disable=[too-many-arguments] - fxtr_app, auth_testdb_path, mocker, fxtr_users, user, expected):# pylint: disable=[unused-argument] + fxtr_app, auth_testdb_path, mocker, fxtr_users, fxtr_oauth2_clients, user, expected):# pylint: disable=[unused-argument] """ GIVEN: an authenticated user WHEN: the user attempts to create a group THEN: verify they are only able to create the group if they have the appropriate privileges """ + _conn, clients = fxtr_oauth2_clients mocker.patch("gn_auth.auth.authorisation.resources.groups.models.uuid4", conftest.uuid_fn) - mocker.patch("gn_auth.auth.authorisation.checks.require_oauth.acquire", - conftest.get_tokeniser(user)) + mocker.patch( + "gn_auth.auth.authorisation.checks.require_oauth.acquire", + conftest.get_tokeniser( + user, + tuple(client for client in clients if client.user == user)[0])) with db.connection(auth_testdb_path) as conn: assert create_group( conn, "a_test_group", user, "A test group") == expected @@ -53,15 +57,19 @@ def test_create_group(# pylint: disable=[too-many-arguments] @pytest.mark.unit_test @pytest.mark.parametrize("user", conftest.TEST_USERS[1:]) def test_create_group_raises_exception_with_non_privileged_user(# pylint: disable=[too-many-arguments] - fxtr_app, auth_testdb_path, mocker, fxtr_users, user):# pylint: disable=[unused-argument] + fxtr_app, auth_testdb_path, mocker, fxtr_users, fxtr_oauth2_clients, user):# pylint: disable=[unused-argument] """ GIVEN: an authenticated user, without appropriate privileges WHEN: the user attempts to create a group THEN: verify the system raises an exception """ + _conn, clients = fxtr_oauth2_clients mocker.patch("gn_auth.auth.authorisation.resources.groups.models.uuid4", conftest.uuid_fn) - mocker.patch("gn_auth.auth.authorisation.checks.require_oauth.acquire", - conftest.get_tokeniser(user)) + mocker.patch( + "gn_auth.auth.authorisation.checks.require_oauth.acquire", + conftest.get_tokeniser( + user, + tuple(client for client in clients if client.user == user)[0])) with db.connection(auth_testdb_path) as conn: with pytest.raises(AuthorisationError): assert create_group(conn, "a_test_group", user, "A test group") @@ -71,6 +79,8 @@ create_role_failure = { "message": "Unauthorised: Could not create the group role" } +@pytest.mark.skip("Keep as placeholder until we implement test for creating " + "a resource role.") @pytest.mark.unit_test @pytest.mark.parametrize( "user,expected", tuple(zip(conftest.TEST_USERS[0:1], ( @@ -79,17 +89,21 @@ create_role_failure = { GROUP, Role(UUID("d32611e3-07fc-4564-b56c-786c6db6de2b"), "ResourceEditor", True, PRIVILEGES)),)))) -def test_create_group_role(mocker, fxtr_users_in_group, user, expected): +def test_create_group_role(mocker, fxtr_users_in_group, fxtr_oauth2_clients, user, expected): """ GIVEN: an authenticated user WHEN: the user attempts to create a role, attached to a group THEN: verify they are only able to create the role if they have the appropriate privileges and that the role is attached to the given group """ + _conn, clients = fxtr_oauth2_clients mocker.patch("gn_auth.auth.authorisation.resources.groups.models.uuid4", conftest.uuid_fn) mocker.patch("gn_auth.auth.authorisation.roles.models.uuid4", conftest.uuid_fn) - mocker.patch("gn_auth.auth.authorisation.checks.require_oauth.acquire", - conftest.get_tokeniser(user)) + mocker.patch( + "gn_auth.auth.authorisation.checks.require_oauth.acquire", + conftest.get_tokeniser( + user, + tuple(client for client in clients if client.user == user)[0])) conn, _group, _users = fxtr_users_in_group with db.cursor(conn) as cursor: assert create_group_role( @@ -105,24 +119,28 @@ def test_create_group_role(mocker, fxtr_users_in_group, user, expected): "user,expected", tuple(zip(conftest.TEST_USERS[1:], ( create_role_failure, create_role_failure, create_role_failure)))) def test_create_group_role_raises_exception_with_unauthorised_users( - mocker, fxtr_users_in_group, user, expected): + mocker, fxtr_users_in_group, fxtr_oauth2_clients, user, expected): """ GIVEN: an authenticated user WHEN: the user attempts to create a role, attached to a group THEN: verify they are only able to create the role if they have the appropriate privileges and that the role is attached to the given group """ + _conn, clients = fxtr_oauth2_clients mocker.patch("gn_auth.auth.authorisation.resources.groups.models.uuid4", conftest.uuid_fn) mocker.patch("gn_auth.auth.authorisation.roles.models.uuid4", conftest.uuid_fn) - mocker.patch("gn_auth.auth.authorisation.checks.require_oauth.acquire", - conftest.get_tokeniser(user)) + mocker.patch( + "gn_auth.auth.authorisation.checks.require_oauth.acquire", + conftest.get_tokeniser( + user, + tuple(client for client in clients if client.user == user)[0])) conn, _group, _users = fxtr_users_in_group with pytest.raises(AuthorisationError): assert create_group_role( conn, GROUP, "ResourceEditor", PRIVILEGES) == expected @pytest.mark.unit_test -def test_create_multiple_groups(mocker, fxtr_users): +def test_create_multiple_groups(mocker, fxtr_users, fxtr_oauth2_clients): """ GIVEN: An authenticated user with appropriate authorisation WHEN: The user attempts to create a new group, while being a member of an @@ -130,12 +148,16 @@ def test_create_multiple_groups(mocker, fxtr_users): THEN: The system should prevent that, and respond with an appropriate error message """ + _conn, clients = fxtr_oauth2_clients mocker.patch("gn_auth.auth.authorisation.resources.groups.models.uuid4", conftest.uuid_fn) user = User( UUID("ecb52977-3004-469e-9428-2a1856725c7f"), "group@lead.er", "Group Leader") - mocker.patch("gn_auth.auth.authorisation.checks.require_oauth.acquire", - conftest.get_tokeniser(user)) + mocker.patch( + "gn_auth.auth.authorisation.checks.require_oauth.acquire", + conftest.get_tokeniser( + user, + tuple(client for client in clients if client.user == user)[0])) conn, _test_users = fxtr_users # First time, successfully creates the group assert create_group(conn, "a_test_group", user) == Group( diff --git a/tests/unit/auth/test_privileges.py b/tests/unit/auth/test_privileges.py index 0b5f120..a225369 100644 --- a/tests/unit/auth/test_privileges.py +++ b/tests/unit/auth/test_privileges.py @@ -25,12 +25,7 @@ PRIVILEGES = sorted( Privilege("group:resource:view-resource", "view a resource and use it in computations"), Privilege("group:resource:edit-resource", "edit/update a resource"), - Privilege("group:resource:delete-resource", "Delete a resource"), - - Privilege("group:role:create-role", "Create a new role"), - Privilege("group:role:edit-role", "edit/update an existing role"), - Privilege("group:user:assign-role", "Assign a role to an existing user"), - Privilege("group:role:delete-role", "Delete an existing role")), + Privilege("group:resource:delete-resource", "Delete a resource")), key=sort_key_privileges) @pytest.mark.unit_test diff --git a/tests/unit/auth/test_resources.py b/tests/unit/auth/test_resources.py index 85641be..b842490 100644 --- a/tests/unit/auth/test_resources.py +++ b/tests/unit/auth/test_resources.py @@ -30,11 +30,15 @@ create_resource_failure = { (Resource( uuid.UUID("d32611e3-07fc-4564-b56c-786c6db6de2b"), "test_resource", resource_category, False),)))) -def test_create_resource(mocker, fxtr_users_in_group, user, expected): +def test_create_resource(mocker, fxtr_users_in_group, fxtr_oauth2_clients, user, expected): """Test that resource creation works as expected.""" mocker.patch("gn_auth.auth.authorisation.resources.models.uuid4", conftest.uuid_fn) - mocker.patch("gn_auth.auth.authorisation.checks.require_oauth.acquire", - conftest.get_tokeniser(user)) + _conn, clients = fxtr_oauth2_clients + mocker.patch( + "gn_auth.auth.authorisation.checks.require_oauth.acquire", + conftest.get_tokeniser( + user, + tuple(client for client in clients if client.user == user)[0])) conn, _group, _users = fxtr_users_in_group resource = create_resource( conn, "test_resource", resource_category, user, False) @@ -48,9 +52,6 @@ def test_create_resource(mocker, fxtr_users_in_group, user, expected): cursor.execute( "DELETE FROM resource_ownership WHERE resource_id=?", (str(resource.resource_id),)) - cursor.execute( - "DELETE FROM group_roles WHERE group_id=?", - (str(group.group_id),)) cursor.execute( "DELETE FROM resources WHERE resource_id=?", (str(resource.resource_id),)) @@ -63,11 +64,15 @@ def test_create_resource(mocker, fxtr_users_in_group, user, expected): (create_resource_failure, create_resource_failure, create_resource_failure)))) def test_create_resource_raises_for_unauthorised_users( - mocker, fxtr_users_in_group, user, expected): + mocker, fxtr_users_in_group, fxtr_oauth2_clients, user, expected): """Test that resource creation works as expected.""" mocker.patch("gn_auth.auth.authorisation.resources.models.uuid4", conftest.uuid_fn) - mocker.patch("gn_auth.auth.authorisation.checks.require_oauth.acquire", - conftest.get_tokeniser(user)) + _conn, clients = fxtr_oauth2_clients + mocker.patch( + "gn_auth.auth.authorisation.checks.require_oauth.acquire", + conftest.get_tokeniser( + user, + tuple(client for client in clients if client.user == user)[0])) conn, _group, _users = fxtr_users_in_group with pytest.raises(AuthorisationError): assert create_resource( diff --git a/tests/unit/auth/test_roles.py b/tests/unit/auth/test_roles.py index 00148a0..e07ee98 100644 --- a/tests/unit/auth/test_roles.py +++ b/tests/unit/auth/test_roles.py @@ -21,45 +21,58 @@ PRIVILEGES = ( "view a resource and use it in computations"), Privilege("group:resource:edit-resource", "edit/update a resource")) + +@pytest.mark.skip("This still needs some work to actually tests for resource roles.") @pytest.mark.unit_test @pytest.mark.parametrize( "user,expected", tuple(zip(conftest.TEST_USERS[0:1], ( Role(uuid.UUID("d32611e3-07fc-4564-b56c-786c6db6de2b"), "a_test_role", True, PRIVILEGES),)))) def test_create_role(# pylint: disable=[too-many-arguments] - fxtr_app, auth_testdb_path, mocker, fxtr_users, user, expected):# pylint: disable=[unused-argument] + fxtr_app, auth_testdb_path, mocker, fxtr_users, fxtr_oauth2_clients, user, expected):# pylint: disable=[unused-argument] """ GIVEN: an authenticated user WHEN: the user attempts to create a role THEN: verify they are only able to create the role if they have the appropriate privileges """ + _conn, clients = fxtr_oauth2_clients mocker.patch("gn_auth.auth.authorisation.roles.models.uuid4", conftest.uuid_fn) - mocker.patch("gn_auth.auth.authorisation.checks.require_oauth.acquire", - conftest.get_tokeniser(user)) + mocker.patch( + "gn_auth.auth.authorisation.checks.require_oauth.acquire", + conftest.get_tokeniser( + user, + tuple(client for client in clients if client.user == user)[0])) with db.connection(auth_testdb_path) as conn, db.cursor(conn) as cursor: the_role = create_role(cursor, "a_test_role", PRIVILEGES) assert the_role == expected + @pytest.mark.unit_test @pytest.mark.parametrize( "user,expected", tuple(zip(conftest.TEST_USERS[1:], ( create_role_failure, create_role_failure, create_role_failure)))) def test_create_role_raises_exception_for_unauthorised_users(# pylint: disable=[too-many-arguments] - fxtr_app, auth_testdb_path, mocker, fxtr_users, user, expected):# pylint: disable=[unused-argument] + fxtr_app, auth_testdb_path, mocker, fxtr_users, fxtr_oauth2_clients, user, expected):# pylint: disable=[unused-argument] """ GIVEN: an authenticated user WHEN: the user attempts to create a role THEN: verify they are only able to create the role if they have the appropriate privileges """ + _conn, clients = fxtr_oauth2_clients mocker.patch("gn_auth.auth.authorisation.roles.models.uuid4", conftest.uuid_fn) - mocker.patch("gn_auth.auth.authorisation.checks.require_oauth.acquire", - conftest.get_tokeniser(user)) + mocker.patch( + "gn_auth.auth.authorisation.checks.require_oauth.acquire", + conftest.get_tokeniser( + user, + tuple(client for client in clients if client.user == user)[0])) with db.connection(auth_testdb_path) as conn, db.cursor(conn) as cursor: with pytest.raises(AuthorisationError): create_role(cursor, "a_test_role", PRIVILEGES) + +# This might still be incomplete, especially regarding resource roles. @pytest.mark.unit_test @pytest.mark.parametrize( "user,expected", @@ -83,22 +96,9 @@ def test_create_role_raises_exception_for_unauthorised_users(# pylint: disable=[ privilege_id='group:resource:view-resource', privilege_description=( 'view a resource and use it in computations')), - Privilege( - privilege_id='group:role:create-role', - privilege_description='Create a new role'), - Privilege( - privilege_id='group:role:delete-role', - privilege_description='Delete an existing role'), - Privilege( - privilege_id='group:role:edit-role', - privilege_description='edit/update an existing role'), Privilege( privilege_id='group:user:add-group-member', privilege_description='Add a user to a group'), - Privilege( - privilege_id='group:user:assign-role', - privilege_description=( - 'Assign a role to an existing user')), Privilege( privilege_id='group:user:remove-group-member', privilege_description='Remove a user from a group'), -- cgit v1.2.3