diff --git a/.gitignore b/.gitignore index b7ce21c..b8298e5 100644 --- a/.gitignore +++ b/.gitignore @@ -108,6 +108,6 @@ main2.py s3air-authz-config.json .vscode _build - +.ruff_cache test.py \ No newline at end of file diff --git a/src/keycloak/authorization/role.py b/src/keycloak/authorization/role.py index 2c15182..0ffb193 100644 --- a/src/keycloak/authorization/role.py +++ b/src/keycloak/authorization/role.py @@ -22,6 +22,8 @@ """The authorization Role module.""" +from __future__ import annotations + class Role: """ @@ -59,7 +61,7 @@ class Role: """ return self.name - def __eq__(self, other: str) -> bool: + def __eq__(self, other: str | Role) -> bool: """ Eq method. @@ -71,4 +73,8 @@ class Role: if isinstance(other, str): return self.name == other - raise NotImplementedError + if isinstance(other, Role): + return self.name == other.name + + msg = f"Cannot compare Role with {type(other)}" + raise NotImplementedError(msg) diff --git a/src/keycloak/keycloak_admin.py b/src/keycloak/keycloak_admin.py index 26a3e14..960904b 100644 --- a/src/keycloak/keycloak_admin.py +++ b/src/keycloak/keycloak_admin.py @@ -628,7 +628,7 @@ class KeycloakAdmin: expected_codes=[HTTP_NO_CONTENT], ) - def create_user(self, payload: str, exist_ok: bool = False) -> str: + def create_user(self, payload: dict, exist_ok: bool = False) -> str: """ Create a new user. @@ -6415,9 +6415,9 @@ class KeycloakAdmin: async def a_create_group( self, - payload: dict | None, + payload: dict, parent: str | None = None, - skip_exists: bool | None = False, + skip_exists: bool = False, ) -> str | None: """ Create a group in the Realm asynchronously. diff --git a/src/keycloak/uma_permissions.py b/src/keycloak/uma_permissions.py index 0f7cffd..dc5cda6 100644 --- a/src/keycloak/uma_permissions.py +++ b/src/keycloak/uma_permissions.py @@ -265,9 +265,9 @@ def build_permission_param(permissions: str | list | dict) -> set: if permissions is None or permissions == "": return set() if isinstance(permissions, str): - return set(permissions) + return {permissions} if isinstance(permissions, UMAPermission): - return set(str(permissions)) + return {str(permissions)} try: # treat as dictionary of permissions result = set() diff --git a/tests/test_authorization.py b/tests/test_authorization.py index f0acd50..2ceb622 100644 --- a/tests/test_authorization.py +++ b/tests/test_authorization.py @@ -41,3 +41,8 @@ def test_authorization_objects() -> None: assert r.get_name() == "test" assert r == r # noqa: PLR0124 assert r == "test" + + with pytest.raises(NotImplementedError) as err: + assert r == 1 + + assert str(err.value) == "Cannot compare Role with " diff --git a/tests/test_keycloak_admin.py b/tests/test_keycloak_admin.py index c81ec75..cca2c55 100644 --- a/tests/test_keycloak_admin.py +++ b/tests/test_keycloak_admin.py @@ -956,14 +956,14 @@ def test_clients(admin: KeycloakAdmin, realm: str) -> None: # Test get clients clients = admin.get_clients() assert len(clients) == 6, clients - assert {x["name"] for x in clients} == set( + assert {x["name"] for x in clients} == { "${client_admin-cli}", "${client_security-admin-console}", "${client_account-console}", "${client_broker}", "${client_account}", "${client_realm-management}", - ), clients + }, clients # Test create client client_id = admin.create_client(payload={"name": "test-client", "clientId": "test-client"}) @@ -2541,7 +2541,7 @@ def test_authentication_configs(admin: KeycloakAdmin, realm: str) -> None: # Test list of auth providers res = admin.get_authenticator_providers() - assert len(res) <= 38 + assert len(res) <= 40 res = admin.get_authenticator_provider_config_description(provider_id="auth-cookie") assert res == { @@ -2598,7 +2598,7 @@ def test_client_scopes(admin: KeycloakAdmin, realm: str) -> None: # Test get client scopes res = admin.get_client_scopes() scope_names = {x["name"] for x in res} - assert len(res) in [10, 11, 13] + assert len(res) in [10, 11, 13, 14] assert "email" in scope_names assert "profile" in scope_names assert "offline_access" in scope_names @@ -2894,9 +2894,9 @@ def test_auto_refresh(admin_frozen: KeycloakAdmin, realm: str) -> None: # Freeze time to simulate the access token expiring with freezegun.freeze_time("2023-02-25 10:05:00"): - assert admin.connection.expires_at < datetime_parser.parse("2023-02-25 10:05:00") + assert admin.connection.expires_at < datetime_parser.parse("2023-02-25T10:05:00Z") assert admin.get_realm(realm_name=realm) - assert admin.connection.expires_at > datetime_parser.parse("2023-02-25 10:05:00") + assert admin.connection.expires_at > datetime_parser.parse("2023-02-25T10:05:00Z") # Test bad refresh token, but first make sure access token has expired again with freezegun.freeze_time("2023-02-25 10:10:00"): @@ -2911,26 +2911,26 @@ def test_auto_refresh(admin_frozen: KeycloakAdmin, realm: str) -> None: # Test post refresh with freezegun.freeze_time("2023-02-25 10:15:00"): - assert admin.connection.expires_at < datetime_parser.parse("2023-02-25 10:15:00") + assert admin.connection.expires_at < datetime_parser.parse("2023-02-25T10:15:00Z") admin.connection.token = None assert admin.create_realm(payload={"realm": "test-refresh"}) == b"" - assert admin.connection.expires_at > datetime_parser.parse("2023-02-25 10:15:00") + assert admin.connection.expires_at > datetime_parser.parse("2023-02-25T10:15:00Z") # Test update refresh with freezegun.freeze_time("2023-02-25 10:25:00"): - assert admin.connection.expires_at < datetime_parser.parse("2023-02-25 10:25:00") + assert admin.connection.expires_at < datetime_parser.parse("2023-02-25T10:25:00Z") admin.connection.token = None assert ( admin.update_realm(realm_name="test-refresh", payload={"accountTheme": "test"}) == {} ) - assert admin.connection.expires_at > datetime_parser.parse("2023-02-25 10:25:00") + assert admin.connection.expires_at > datetime_parser.parse("2023-02-25T10:25:00Z") # Test delete refresh with freezegun.freeze_time("2023-02-25 10:35:00"): - assert admin.connection.expires_at < datetime_parser.parse("2023-02-25 10:35:00") + assert admin.connection.expires_at < datetime_parser.parse("2023-02-25T10:35:00Z") admin.connection.token = None assert admin.delete_realm(realm_name="test-refresh") == {} - assert admin.connection.expires_at > datetime_parser.parse("2023-02-25 10:35:00") + assert admin.connection.expires_at > datetime_parser.parse("2023-02-25T10:35:00Z") def test_get_required_actions(admin: KeycloakAdmin, realm: str) -> None: @@ -3100,7 +3100,7 @@ def test_get_bruteforce_status_for_user( assert res["bruteForceProtected"] is True # Test login user with wrong credentials - with contextlib.supress(KeycloakAuthenticationError): + with contextlib.suppress(KeycloakAuthenticationError): oid.token(username=username, password="wrongpassword") # noqa: S106 user_id = admin.get_user_id(username) @@ -4207,14 +4207,14 @@ async def test_a_clients(admin: KeycloakAdmin, realm: str) -> None: # Test get clients clients = await admin.a_get_clients() assert len(clients) == 6, clients - assert {x["name"] for x in clients} == set( + assert {x["name"] for x in clients} == { "${client_admin-cli}", "${client_security-admin-console}", "${client_account-console}", "${client_broker}", "${client_account}", "${client_realm-management}", - ), clients + }, clients # Test create client client_id = await admin.a_create_client( @@ -5962,7 +5962,7 @@ async def test_a_authentication_configs(admin: KeycloakAdmin, realm: str) -> Non # Test list of auth providers res = await admin.a_get_authenticator_providers() - assert len(res) <= 38 + assert len(res) <= 40 res = await admin.a_get_authenticator_provider_config_description(provider_id="auth-cookie") assert res == { @@ -6021,7 +6021,7 @@ async def test_a_client_scopes(admin: KeycloakAdmin, realm: str) -> None: # Test get client scopes res = await admin.a_get_client_scopes() scope_names = {x["name"] for x in res} - assert len(res) in [10, 11, 13] + assert len(res) in [10, 11, 13, 14] assert "email" in scope_names assert "profile" in scope_names assert "offline_access" in scope_names @@ -6326,9 +6326,9 @@ async def test_a_auto_refresh(admin_frozen: KeycloakAdmin, realm: str) -> None: # Freeze time to simulate the access token expiring with freezegun.freeze_time("2023-02-25 10:05:00"): - assert admin.connection.expires_at < datetime_parser.parse("2023-02-25 10:05:00") + assert admin.connection.expires_at < datetime_parser.parse("2023-02-25T10:05:00Z") assert await admin.a_get_realm(realm_name=realm) - assert admin.connection.expires_at > datetime_parser.parse("2023-02-25 10:05:00") + assert admin.connection.expires_at > datetime_parser.parse("2023-02-25T10:05:00Z") # Test bad refresh token, but first make sure access token has expired again with freezegun.freeze_time("2023-02-25 10:10:00"): @@ -6343,27 +6343,27 @@ async def test_a_auto_refresh(admin_frozen: KeycloakAdmin, realm: str) -> None: # Test post refresh with freezegun.freeze_time("2023-02-25 10:15:00"): - assert admin.connection.expires_at < datetime_parser.parse("2023-02-25 10:15:00") + assert admin.connection.expires_at < datetime_parser.parse("2023-02-25T10:15:00Z") admin.connection.token = None assert await admin.a_create_realm(payload={"realm": "test-refresh"}) == b"" - assert admin.connection.expires_at > datetime_parser.parse("2023-02-25 10:15:00") + assert admin.connection.expires_at > datetime_parser.parse("2023-02-25T10:15:00Z") # Test update refresh with freezegun.freeze_time("2023-02-25 10:25:00"): - assert admin.connection.expires_at < datetime_parser.parse("2023-02-25 10:25:00") + assert admin.connection.expires_at < datetime_parser.parse("2023-02-25T10:25:00Z") admin.connection.token = None assert ( await admin.a_update_realm(realm_name="test-refresh", payload={"accountTheme": "test"}) == {} ) - assert admin.connection.expires_at > datetime_parser.parse("2023-02-25 10:25:00") + assert admin.connection.expires_at > datetime_parser.parse("2023-02-25T10:25:00Z") # Test delete refresh with freezegun.freeze_time("2023-02-25 10:35:00"): - assert admin.connection.expires_at < datetime_parser.parse("2023-02-25 10:35:00") + assert admin.connection.expires_at < datetime_parser.parse("2023-02-25T10:35:00Z") admin.connection.token = None assert await admin.a_delete_realm(realm_name="test-refresh") == {} - assert admin.connection.expires_at > datetime_parser.parse("2023-02-25 10:35:00") + assert admin.connection.expires_at > datetime_parser.parse("2023-02-25T10:35:00Z") @pytest.mark.asyncio @@ -6845,7 +6845,7 @@ def test_counter_part() -> None: assert async_method in admin_methods sync_sign = signature(getattr(KeycloakAdmin, method)) async_sign = signature(getattr(KeycloakAdmin, async_method)) - assert sync_sign.parameters == async_sign.parameters + assert sync_sign.parameters == async_sign.parameters, f"Parameters mismatch for {method}" for async_method in async_methods: if async_method[2:].startswith("_"): diff --git a/tests/test_license.py b/tests/test_license.py index 41a7eb6..07cb883 100644 --- a/tests/test_license.py +++ b/tests/test_license.py @@ -12,5 +12,5 @@ def test_license_present() -> None: with pathlib.Path(pathlib.Path(path) / _file).open("r") as fp: content = fp.read() assert content.startswith( - "# -*- coding: utf-8 -*-\n#\n# The MIT License (MIT)\n#\n#", + "#\n# The MIT License (MIT)\n#\n#", ) diff --git a/tox.ini b/tox.ini index e9340e9..4fabd9f 100644 --- a/tox.ini +++ b/tox.ini @@ -6,7 +6,7 @@ envlist = check, apply-check, docs, tests, build, changelog [testenv] allowlist_externals = poetry, ./test_keycloak_init.sh commands_pre = - poetry install --sync + poetry sync [testenv:check] commands =