Browse Source

fix: make sure to not call sync IO functions inside async functions (#615)

* Don't use sync functions to introspect token

* One more async

* Fix some spacing

* A few more async functions

* Fix compatibility issue

* Comment

* Formatting
master v4.7.1
Cristi 4 days ago
committed by GitHub
parent
commit
239e40434b
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 14
      src/keycloak/keycloak_admin.py
  2. 31
      src/keycloak/keycloak_openid.py

14
src/keycloak/keycloak_admin.py

@ -6199,7 +6199,7 @@ class KeycloakAdmin:
:rtype: str :rtype: str
""" """
if skip_exists: if skip_exists:
client_id = self.get_client_id(client_id=payload["clientId"])
client_id = await self.a_get_client_id(client_id=payload["clientId"])
if client_id is not None: if client_id is not None:
return client_id return client_id
@ -6369,7 +6369,7 @@ class KeycloakAdmin:
""" """
params_path = { params_path = {
"realm-name": self.connection.realm_name, "realm-name": self.connection.realm_name,
"role-id": self.get_default_realm_role_id(),
"role-id": await self.a_get_default_realm_role_id(),
} }
data_raw = await self.connection.a_raw_get( data_raw = await self.connection.a_raw_get(
urls_patterns.URL_ADMIN_REALM_ROLE_COMPOSITES_REALM.format(**params_path) urls_patterns.URL_ADMIN_REALM_ROLE_COMPOSITES_REALM.format(**params_path)
@ -6386,7 +6386,7 @@ class KeycloakAdmin:
""" """
params_path = { params_path = {
"realm-name": self.connection.realm_name, "realm-name": self.connection.realm_name,
"role-id": self.get_default_realm_role_id(),
"role-id": await self.a_get_default_realm_role_id(),
} }
data_raw = await self.connection.a_raw_delete( data_raw = await self.connection.a_raw_delete(
urls_patterns.URL_ADMIN_REALM_ROLE_COMPOSITES.format(**params_path), urls_patterns.URL_ADMIN_REALM_ROLE_COMPOSITES.format(**params_path),
@ -6404,7 +6404,7 @@ class KeycloakAdmin:
""" """
params_path = { params_path = {
"realm-name": self.connection.realm_name, "realm-name": self.connection.realm_name,
"role-id": self.get_default_realm_role_id(),
"role-id": await self.a_get_default_realm_role_id(),
} }
data_raw = await self.connection.a_raw_post( data_raw = await self.connection.a_raw_post(
urls_patterns.URL_ADMIN_REALM_ROLE_COMPOSITES.format(**params_path), urls_patterns.URL_ADMIN_REALM_ROLE_COMPOSITES.format(**params_path),
@ -7536,7 +7536,7 @@ class KeycloakAdmin:
:rtype: dict :rtype: dict
""" """
params_path = {"realm-name": self.connection.realm_name, "provider-id": provider_id} params_path = {"realm-name": self.connection.realm_name, "provider-id": provider_id}
data_raw = self.connection.raw_get(
data_raw = await self.connection.a_raw_get(
urls_patterns.URL_ADMIN_AUTHENTICATOR_CONFIG_DESCRIPTION.format(**params_path) urls_patterns.URL_ADMIN_AUTHENTICATOR_CONFIG_DESCRIPTION.format(**params_path)
) )
return raise_error_from_response(data_raw, KeycloakGetError) return raise_error_from_response(data_raw, KeycloakGetError)
@ -7678,7 +7678,7 @@ class KeycloakAdmin:
:rtype: str :rtype: str
""" """
if skip_exists: if skip_exists:
exists = self.get_client_scope_by_name(client_scope_name=payload["name"])
exists = await self.a_get_client_scope_by_name(client_scope_name=payload["name"])
if exists is not None: if exists is not None:
return exists["id"] return exists["id"]
@ -8002,7 +8002,7 @@ class KeycloakAdmin:
"realm-name": self.connection.realm_name, "realm-name": self.connection.realm_name,
"scope-id": client_scope_id, "scope-id": client_scope_id,
} }
data_raw = self.connection.raw_get(
data_raw = await self.connection.a_raw_get(
urls_patterns.URL_ADMIN_CLIENT_SCOPE_ROLE_MAPPINGS.format(**params_path) urls_patterns.URL_ADMIN_CLIENT_SCOPE_ROLE_MAPPINGS.format(**params_path)
) )
return raise_error_from_response(data_raw, KeycloakGetError) return raise_error_from_response(data_raw, KeycloakGetError)

31
src/keycloak/keycloak_openid.py

@ -674,7 +674,7 @@ class KeycloakOpenID:
return list(set(policies)) return list(set(policies))
def get_permissions(self, token, method_token_info="introspect", **kwargs): def get_permissions(self, token, method_token_info="introspect", **kwargs):
"""Get permission by user token .
"""Get permission by user token.
:param token: user token :param token: user token
:type token: str :type token: str
@ -689,7 +689,7 @@ class KeycloakOpenID:
""" """
if not self.authorization.policies: if not self.authorization.policies:
raise KeycloakAuthorizationConfigError( raise KeycloakAuthorizationConfigError(
"Keycloak settings not found. Load Authorization Keycloak settings ."
"Keycloak settings not found. Load Authorization Keycloak settings."
) )
token_info = self._token_info(token, method_token_info, **kwargs) token_info = self._token_info(token, method_token_info, **kwargs)
@ -892,6 +892,25 @@ class KeycloakOpenID:
) )
return raise_error_from_response(data_raw, KeycloakPutError) return raise_error_from_response(data_raw, KeycloakPutError)
async def _a_token_info(self, token, method_token_info, **kwargs):
"""Asynchronous getter for the token data.
:param token: Token
:type token: str
:param method_token_info: Token info method to use
:type method_token_info: str
:param kwargs: Additional keyword arguments passed to the decode_token method
:type kwargs: dict
:returns: Token info
:rtype: dict
"""
if method_token_info == "introspect":
token_info = await self.a_introspect(token)
else:
token_info = await self.a_decode_token(token, **kwargs)
return token_info
async def a_well_known(self): async def a_well_known(self):
"""Get the well_known object asynchronously. """Get the well_known object asynchronously.
@ -1301,7 +1320,7 @@ class KeycloakOpenID:
"Keycloak settings not found. Load Authorization Keycloak settings." "Keycloak settings not found. Load Authorization Keycloak settings."
) )
token_info = self._token_info(token, method_token_info, **kwargs)
token_info = await self._a_token_info(token, method_token_info, **kwargs)
if method_token_info == "introspect" and not token_info["active"]: if method_token_info == "introspect" and not token_info["active"]:
raise KeycloakInvalidTokenError("Token expired or invalid.") raise KeycloakInvalidTokenError("Token expired or invalid.")
@ -1339,7 +1358,7 @@ class KeycloakOpenID:
"Keycloak settings not found. Load Authorization Keycloak settings." "Keycloak settings not found. Load Authorization Keycloak settings."
) )
token_info = self._token_info(token, method_token_info, **kwargs)
token_info = await self._a_token_info(token, method_token_info, **kwargs)
if method_token_info == "introspect" and not token_info["active"]: if method_token_info == "introspect" and not token_info["active"]:
raise KeycloakInvalidTokenError("Token expired or invalid.") raise KeycloakInvalidTokenError("Token expired or invalid.")
@ -1378,7 +1397,7 @@ class KeycloakOpenID:
params_path = {"realm-name": self.realm_name} params_path = {"realm-name": self.realm_name}
payload = { payload = {
"grant_type": "urn:ietf:params:oauth:grant-type:uma-ticket", "grant_type": "urn:ietf:params:oauth:grant-type:uma-ticket",
"permission": permission,
"permission": list(permission), # httpx does not handle `set` correctly
"response_mode": "permissions", "response_mode": "permissions",
"audience": self.client_id, "audience": self.client_id,
} }
@ -1387,7 +1406,7 @@ class KeycloakOpenID:
self.connection.add_param_headers("Authorization", "Bearer " + token) self.connection.add_param_headers("Authorization", "Bearer " + token)
content_type = self.connection.headers.get("Content-Type") content_type = self.connection.headers.get("Content-Type")
self.connection.add_param_headers("Content-Type", "application/x-www-form-urlencoded") self.connection.add_param_headers("Content-Type", "application/x-www-form-urlencoded")
data_raw = self.connection.raw_post(URL_TOKEN.format(**params_path), data=payload)
data_raw = await self.connection.a_raw_post(URL_TOKEN.format(**params_path), data=payload)
( (
self.connection.add_param_headers("Content-Type", content_type) self.connection.add_param_headers("Content-Type", content_type)
if content_type if content_type

Loading…
Cancel
Save