Browse Source

feat: new methods for certificate key info

feat/decode_token_with_all_keys
Richard Nemeth 6 days ago
parent
commit
285fb1af20
No known key found for this signature in database GPG Key ID: 21C39470DF3DEC39
  1. 58
      src/keycloak/keycloak_admin.py
  2. 18
      tests/test_keycloak_admin.py

58
src/keycloak/keycloak_admin.py

@ -7518,6 +7518,35 @@ class KeycloakAdmin:
return res
def get_client_certificate_key_info(self, client_id: str, attribute: str) -> dict:
"""
Get client certificate key info.
:param client_id: id of the client
:type client_id: str
:param attribute: attribute to query for
:type attribute: str
:return: Certificate key info
:rtype: dict
"""
params_path = {
"realm-name": self.connection.realm_name,
"id": client_id,
"attr": attribute,
}
data_raw = self.connection.raw_get(
urls_patterns.URL_ADMIN_CLIENT_CERTS.format(**params_path)
)
res = raise_error_from_response(data_raw, KeycloakGetError)
if not isinstance(res, dict):
msg = (
"Unexpected response type. Expected 'dict', received "
f"'{type(res)}', value '{res}'."
)
raise TypeError(msg)
return res
def upload_certificate(self, client_id: str, certcont: str) -> dict:
"""
Upload a new certificate for the client.
@ -14313,6 +14342,35 @@ class KeycloakAdmin:
return res
async def a_get_client_certificate_key_info(self, client_id: str, attribute: str) -> dict:
"""
Get client certificate key info.
:param client_id: id of the client
:type client_id: str
:param attribute: attribute to query for
:type attribute: str
:return: Certificate key info
:rtype: dict
"""
params_path = {
"realm-name": self.connection.realm_name,
"id": client_id,
"attr": attribute,
}
data_raw = await self.connection.a_raw_get(
urls_patterns.URL_ADMIN_CLIENT_CERTS.format(**params_path)
)
res = raise_error_from_response(data_raw, KeycloakGetError)
if not isinstance(res, dict):
msg = (
"Unexpected response type. Expected 'dict', received "
f"'{type(res)}', value '{res}'."
)
raise TypeError(msg)
return res
async def a_upload_certificate(self, client_id: str, certcont: str) -> dict:
"""
Upload a new certificate for the client asynchronously.

18
tests/test_keycloak_admin.py

@ -40,6 +40,7 @@ ILLEGAL_EXECUTION_REGEX = '404: b\'{"error":"Illegal execution".*}\''
NO_CLIENT_SCOPE_REGEX = '404: b\'{"error":"Could not find client scope".*}\''
UNKOWN_ERROR_REGEX = 'b\'{"error":"unknown_error".*}\''
USER_NOT_FOUND_REGEX = '404: b\'{"error":"User not found".*}\''
COULD_NOT_FIND_CLIENT_REGEX = '404: b\'{"error":"Could not find client"}\''
def test_keycloak_version() -> None:
@ -7697,6 +7698,23 @@ async def test_a_consents(
assert err.match(CONSENT_NOT_FOUND_REGEX)
def test_keycloak_client_get_cert_info(admin: KeycloakAdmin, client: str) -> None:
"""Test get cert info."""
assert admin.get_client_certificate_key_info(client, "jwt.credential") == {}
with pytest.raises(KeycloakGetError) as res:
admin.get_client_certificate_key_info("blah", "blah")
assert res.match(COULD_NOT_FIND_CLIENT_REGEX)
@pytest.mark.asyncio
async def test_a_keycloak_client_get_cert_info(admin: KeycloakAdmin, client: str) -> None:
"""Test get cert info."""
assert await admin.a_get_client_certificate_key_info(client, "jwt.credential") == {}
with pytest.raises(KeycloakGetError) as res:
await admin.a_get_client_certificate_key_info("blah", "blah")
assert res.match(COULD_NOT_FIND_CLIENT_REGEX)
def test_counter_part() -> None:
"""Test that each function has its async counter part."""
admin_methods = [func for func in dir(KeycloakAdmin) if callable(getattr(KeycloakAdmin, func))]

Loading…
Cancel
Save