From dd7860d07feee0de3f6c0050f2a3adda6b584110 Mon Sep 17 00:00:00 2001 From: Vladimir Brik <22751545+vbrik@users.noreply.github.com> Date: Tue, 16 Apr 2024 09:50:16 -0500 Subject: [PATCH] use new version of keycloak server with unit tests (#74) * use new version of keycloak server with unit tests --- .github/workflows/wipac_cicd.yaml | 11 ++++++----- tests/test_api_users.py | 11 +++++------ tests/test_cache.py | 22 +++++++++++----------- user_mgmt/handler.py | 6 +++--- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/workflows/wipac_cicd.yaml b/.github/workflows/wipac_cicd.yaml index 5555327..241f9b8 100644 --- a/.github/workflows/wipac_cicd.yaml +++ b/.github/workflows/wipac_cicd.yaml @@ -24,7 +24,7 @@ jobs: uses: actions/checkout@v3 with: token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} - - uses: WIPACrepo/wipac-dev-py-setup-action@v2.6 + - uses: WIPACrepo/wipac-dev-py-setup-action@v3.1 py-versions: needs: [py-setup] @@ -58,10 +58,11 @@ jobs: runs-on: ubuntu-latest services: keycloak: - image: quay.io/keycloak/keycloak:10.0.2 + image: ghcr.io/wipacrepo/keycloak-rest-services:test-keycloak-master env: - KEYCLOAK_USER: admin - KEYCLOAK_PASSWORD: admin + KEYCLOAK_ADMIN: admin + KEYCLOAK_ADMIN_PASSWORD: admin + CMD: start-dev ports: - 8080:8080 mongo: @@ -83,7 +84,7 @@ jobs: pip install .[tests] - name: Run Tests run: | - python -m pytest tests --tb=short --log-level=INFO + python -m pytest tests --tb=short --log-level=INFO -v web-tests: needs: [py-versions] diff --git a/tests/test_api_users.py b/tests/test_api_users.py index 448121c..8d74615 100644 --- a/tests/test_api_users.py +++ b/tests/test_api_users.py @@ -94,9 +94,11 @@ async def test_user_put(server): with pytest.raises(Exception): await client.request('PUT', '/api/users/test', {'loginShell': 'foo'}) + # Sometime after version 15, Keycloak started to delete empty attributes + # (not sure if this still applies if user profiles are enabled) await client.request('PUT', '/api/users/test', {'loginShell': ''}) ret = await krs.users.user_info('test', rest_client=krs_client) - assert ret['attributes']['loginShell'] == '' + assert 'loginShell' not in ret['attributes'] @pytest.mark.asyncio @@ -111,7 +113,7 @@ async def test_user_unauthorized(server): @pytest.mark.asyncio async def test_user_inst_admin(server): rest, krs_client, *_ = server - + await krs.groups.create_group('/institutions', rest_client=krs_client) await krs.groups.create_group('/institutions/IceCube', rest_client=krs_client) await krs.groups.create_group('/institutions/IceCube/UW-Madison', rest_client=krs_client) @@ -119,7 +121,7 @@ async def test_user_inst_admin(server): client = await rest('test', groups=['/institutions/IceCube/UW-Madison']) client2 = await rest('test2', groups=['/institutions/IceCube/UW-Madison/_admin']) - + ret = await client.request('GET', '/api/users/test') assert ret['firstName'] == 'first' assert ret['lastName'] == 'last' @@ -202,9 +204,6 @@ async def test_username_select(server, reg_token_client): ] invalid_usernames_put = [ 'foĆ²', # unicode - 'fo=o', # invalid char - 'fo o', # space - 'f\'oo', # quote ] @pytest.mark.parametrize('username', valid_usernames_put) diff --git a/tests/test_cache.py b/tests/test_cache.py index 9644387..9e3b2d2 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -41,8 +41,8 @@ async def test_get_group_info_from_id(keycloak_bootstrap): @pytest.mark.asyncio async def test_get_members_large(keycloak_bootstrap): - users = string.ascii_lowercase - groups = string.ascii_lowercase + users = [c*3 for c in string.ascii_lowercase] + groups = [c*3 for c in string.ascii_lowercase] for u in users: await krs.users.create_user(u, 'first', 'last', f'{u}@email', rest_client=keycloak_bootstrap) for g in groups: @@ -53,16 +53,16 @@ async def test_get_members_large(keycloak_bootstrap): cache = user_mgmt.cache.KeycloakGroupCache(krs_client=keycloak_bootstrap) for g in groups: ret = await cache.get_members(f'/{g}') - assert ret == list(users) + assert ret == users - await krs.groups.remove_user_group('/a', 'a', rest_client=keycloak_bootstrap) - ret = await cache.get_members('/a') - assert ret == list(users) + await krs.groups.remove_user_group('/aaa', 'aaa', rest_client=keycloak_bootstrap) + ret = await cache.get_members('/aaa') + assert ret == users @pytest.mark.asyncio async def test_invalidate_one(keycloak_bootstrap): await krs.groups.create_group('/foo', rest_client=keycloak_bootstrap) - await krs.users.create_user('testuser', 'first', 'last', 'email', rest_client=keycloak_bootstrap) + await krs.users.create_user('testuser', 'first', 'last', 'email@email', rest_client=keycloak_bootstrap) await krs.groups.add_user_group('/foo', 'testuser', rest_client=keycloak_bootstrap) cache = user_mgmt.cache.KeycloakGroupCache(krs_client=keycloak_bootstrap) @@ -80,7 +80,7 @@ async def test_invalidate_one(keycloak_bootstrap): @pytest.mark.asyncio async def test_invalidate_all(keycloak_bootstrap): await krs.groups.create_group('/foo', rest_client=keycloak_bootstrap) - await krs.users.create_user('testuser', 'first', 'last', 'email', rest_client=keycloak_bootstrap) + await krs.users.create_user('testuser', 'first', 'last', 'email@email', rest_client=keycloak_bootstrap) await krs.groups.add_user_group('/foo', 'testuser', rest_client=keycloak_bootstrap) cache = user_mgmt.cache.KeycloakGroupCache(krs_client=keycloak_bootstrap) @@ -97,7 +97,7 @@ async def test_invalidate_all(keycloak_bootstrap): @pytest.mark.asyncio async def test_list_users(keycloak_bootstrap): - await krs.users.create_user('testuser', 'first', 'last', 'email', rest_client=keycloak_bootstrap) + await krs.users.create_user('testuser', 'first', 'last', 'email@email', rest_client=keycloak_bootstrap) cache = user_mgmt.cache.KeycloakUserCache(ttl=1, krs_client=keycloak_bootstrap) @@ -106,7 +106,7 @@ async def test_list_users(keycloak_bootstrap): @pytest.mark.asyncio async def test_get_user(keycloak_bootstrap): - await krs.users.create_user('testuser', 'first', 'last', 'email', rest_client=keycloak_bootstrap) + await krs.users.create_user('testuser', 'first', 'last', 'email@email', rest_client=keycloak_bootstrap) cache = user_mgmt.cache.KeycloakUserCache(ttl=1, krs_client=keycloak_bootstrap) @@ -115,7 +115,7 @@ async def test_get_user(keycloak_bootstrap): @pytest.mark.asyncio async def test_get_users(keycloak_bootstrap): - await krs.users.create_user('testuser', 'first', 'last', 'email', rest_client=keycloak_bootstrap) + await krs.users.create_user('testuser', 'first', 'last', 'email@email', rest_client=keycloak_bootstrap) cache = user_mgmt.cache.KeycloakUserCache(ttl=1, krs_client=keycloak_bootstrap) diff --git a/user_mgmt/handler.py b/user_mgmt/handler.py index bbdd436..88c75a4 100644 --- a/user_mgmt/handler.py +++ b/user_mgmt/handler.py @@ -75,7 +75,7 @@ async def is_associate(self, experiment, username): def is_super_admin(self): """Is the current user a super admin?""" - return '/admin' in self.auth_data['groups'] + return '/admin' in self.auth_data.get('groups', []) async def get_admins(self, group_path): ret = await self.group_cache.get_members(group_path+'/_admin') @@ -110,7 +110,7 @@ async def get_admin_groups(self): if self.is_super_admin(): # super admin - all groups admin_groups = await self.group_cache.list_groups() else: - admin_groups = [g[:-7] for g in self.auth_data['groups'] if g.endswith('/_admin')] + admin_groups = [g[:-7] for g in self.auth_data.get('groups', []) if g.endswith('/_admin')] groups = set() for group in admin_groups: val = group.strip('/').split('/') @@ -130,7 +130,7 @@ async def get_admin_institutions(self): val = group.split('/') insts[val[2]].append(val[3]) else: - admin_groups = [g[:-7] for g in self.auth_data['groups'] if g.endswith('/_admin')] + admin_groups = [g[:-7] for g in self.auth_data.get('groups', []) if g.endswith('/_admin')] insts = defaultdict(list) for group in admin_groups: val = group.strip('/').split('/')