From 11e4a12c83754bf6a7ffe95f6bcc80266113b0a9 Mon Sep 17 00:00:00 2001
From: Adrian_Cin
Date: Mon, 14 Jun 2021 16:17:47 +0700
Subject: [PATCH 01/10] Correct public key format
Keycloak returns public key in PEM format
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 63abe49..28b218d 100644
--- a/README.md
+++ b/README.md
@@ -98,7 +98,7 @@ token_rpt_info = keycloak_openid.introspect(keycloak_openid.introspect(token['ac
token_info = keycloak_openid.introspect(token['access_token'])
# Decode Token
-KEYCLOAK_PUBLIC_KEY = keycloak_openid.public_key()
+KEYCLOAK_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\n" + keycloak_openid.public_key() + "\n-----END PUBLIC KEY-----"
options = {"verify_signature": True, "verify_aud": True, "verify_exp": True}
token_info = keycloak_openid.decode_token(token['access_token'], key=KEYCLOAK_PUBLIC_KEY, options=options)
From 31b4efd7ab903354bb844d9eec1671dbdaa9dbf0 Mon Sep 17 00:00:00 2001
From: bostonkenne
Date: Thu, 17 Jun 2021 15:51:11 +0100
Subject: [PATCH 02/10] add remove user realm role
---
keycloak/keycloak_admin.py | 15 ++++++++++++++-
keycloak/urls_patterns.py | 4 +++-
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/keycloak/keycloak_admin.py b/keycloak/keycloak_admin.py
index ffb5968..4272482 100644
--- a/keycloak/keycloak_admin.py
+++ b/keycloak/keycloak_admin.py
@@ -47,7 +47,8 @@ from .urls_patterns import URL_ADMIN_SERVER_INFO, URL_ADMIN_CLIENT_AUTHZ_RESOURC
URL_ADMIN_REALM_ROLES_MEMBERS, URL_ADMIN_CLIENT_PROTOCOL_MAPPER, URL_ADMIN_CLIENT_SCOPES_MAPPERS, \
URL_ADMIN_FLOWS_EXECUTIONS_EXEUCUTION, URL_ADMIN_FLOWS_EXECUTIONS_FLOW, URL_ADMIN_FLOWS_COPY, \
URL_ADMIN_FLOWS_ALIAS, URL_ADMIN_CLIENT_SERVICE_ACCOUNT_USER, URL_ADMIN_AUTHENTICATOR_CONFIG, \
- URL_ADMIN_CLIENT_ROLES_COMPOSITE_CLIENT_ROLE, URL_ADMIN_CLIENT_ALL_SESSIONS, URL_ADMIN_EVENTS
+ URL_ADMIN_CLIENT_ROLES_COMPOSITE_CLIENT_ROLE, URL_ADMIN_CLIENT_ALL_SESSIONS, URL_ADMIN_EVENTS,\
+ URL_ADMIN_DELETE_USER_ROLE
class KeycloakAdmin:
@@ -1878,3 +1879,15 @@ class KeycloakAdmin:
params_path = {"realm-name": self.realm_name, "id": client_id}
data_raw = self.connection.raw_get(URL_ADMIN_CLIENT_ALL_SESSIONS.format(**params_path))
return raise_error_from_response(data_raw, KeycloakGetError)
+
+
+ def delete_user_realm_role(self, user_id, payload):
+ """
+ Delete realm-level role mappings
+ DELETE admin/realms/{realm-name}/users/{id}/role-mappings/realm
+
+ """
+ params_path = {"realm-name": self.realm_name, "id": str(user_id) }
+ data_raw = self.connection.raw_delete(URL_ADMIN_DELETE_USER_ROLE.format(**params_path),
+ data=json.dumps(payload))
+ return raise_error_from_response(data_raw, KeycloakGetError, expected_code=204)
\ No newline at end of file
diff --git a/keycloak/urls_patterns.py b/keycloak/urls_patterns.py
index 8dfbadb..460ae8b 100644
--- a/keycloak/urls_patterns.py
+++ b/keycloak/urls_patterns.py
@@ -105,4 +105,6 @@ URL_ADMIN_KEYS = "admin/realms/{realm-name}/keys"
URL_ADMIN_USER_FEDERATED_IDENTITIES = "admin/realms/{realm-name}/users/{id}/federated-identity"
URL_ADMIN_USER_FEDERATED_IDENTITY = "admin/realms/{realm-name}/users/{id}/federated-identity/{provider}"
-URL_ADMIN_EVENTS = 'admin/realms/{realm-name}/events'
\ No newline at end of file
+URL_ADMIN_EVENTS = 'admin/realms/{realm-name}/events'
+
+URL_ADMIN_DELETE_USER_ROLE = "admin/realms/{realm-name}/users/{id}/role-mappings/realm"
\ No newline at end of file
From d7d661a38c7a6bf5daaea513616f4f9936460bef Mon Sep 17 00:00:00 2001
From: bostonkenne
Date: Thu, 17 Jun 2021 15:53:16 +0100
Subject: [PATCH 03/10] fix json response
---
keycloak/keycloak_admin.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/keycloak/keycloak_admin.py b/keycloak/keycloak_admin.py
index 4272482..15ee759 100644
--- a/keycloak/keycloak_admin.py
+++ b/keycloak/keycloak_admin.py
@@ -1890,4 +1890,4 @@ class KeycloakAdmin:
params_path = {"realm-name": self.realm_name, "id": str(user_id) }
data_raw = self.connection.raw_delete(URL_ADMIN_DELETE_USER_ROLE.format(**params_path),
data=json.dumps(payload))
- return raise_error_from_response(data_raw, KeycloakGetError, expected_code=204)
\ No newline at end of file
+ return raise_error_from_response(data_raw, KeycloakGetError, expected_codes=[204])
\ No newline at end of file
From 8f6de6c3c84faaf354484811160c8d95c33ee3c8 Mon Sep 17 00:00:00 2001
From: Yannick Chabbert
Date: Mon, 28 Jun 2021 15:42:54 +0200
Subject: [PATCH 04/10] openid - minor typo fix, change nothing yet
---
keycloak/keycloak_openid.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/keycloak/keycloak_openid.py b/keycloak/keycloak_openid.py
index 0f801ea..197dd26 100644
--- a/keycloak/keycloak_openid.py
+++ b/keycloak/keycloak_openid.py
@@ -189,7 +189,7 @@ class KeycloakOpenID:
payload = {"username": username, "password": password,
"client_id": self.client_id, "grant_type": grant_type,
"code": code, "redirect_uri": redirect_uri}
- if payload:
+ if extra:
payload.update(extra)
if totp:
From 44fe7b714aa08743fc95a8de5d9ea469dabb2799 Mon Sep 17 00:00:00 2001
From: Manjeetsinh Alonja
Date: Fri, 9 Jul 2021 11:33:35 +0530
Subject: [PATCH 05/10] Added realm partial export feature
---
keycloak/keycloak_admin.py | 13 ++++++++++++-
keycloak/urls_patterns.py | 1 +
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/keycloak/keycloak_admin.py b/keycloak/keycloak_admin.py
index ffb5968..41f71eb 100644
--- a/keycloak/keycloak_admin.py
+++ b/keycloak/keycloak_admin.py
@@ -47,7 +47,8 @@ from .urls_patterns import URL_ADMIN_SERVER_INFO, URL_ADMIN_CLIENT_AUTHZ_RESOURC
URL_ADMIN_REALM_ROLES_MEMBERS, URL_ADMIN_CLIENT_PROTOCOL_MAPPER, URL_ADMIN_CLIENT_SCOPES_MAPPERS, \
URL_ADMIN_FLOWS_EXECUTIONS_EXEUCUTION, URL_ADMIN_FLOWS_EXECUTIONS_FLOW, URL_ADMIN_FLOWS_COPY, \
URL_ADMIN_FLOWS_ALIAS, URL_ADMIN_CLIENT_SERVICE_ACCOUNT_USER, URL_ADMIN_AUTHENTICATOR_CONFIG, \
- URL_ADMIN_CLIENT_ROLES_COMPOSITE_CLIENT_ROLE, URL_ADMIN_CLIENT_ALL_SESSIONS, URL_ADMIN_EVENTS
+ URL_ADMIN_CLIENT_ROLES_COMPOSITE_CLIENT_ROLE, URL_ADMIN_CLIENT_ALL_SESSIONS, URL_ADMIN_EVENTS, \
+ URL_ADMIN_REALM_EXPORT
class KeycloakAdmin:
@@ -242,6 +243,16 @@ class KeycloakAdmin:
data=json.dumps(payload))
return raise_error_from_response(data_raw, KeycloakGetError, expected_codes=[201])
+ def export_realm(self, export_clients=False, export_groups_and_role=False):
+ """
+ Export the realm configurations in the json format
+
+ :return: realm configurations JSON
+ """
+ params_path = {"realm-name": self.realm_name, "export-clients": export_clients, "export-groups-and-roles": export_groups_and_role }
+ data_raw = self.raw_post(URL_ADMIN_REALM_EXPORT.format(**params_path), data="")
+ return raise_error_from_response(data_raw, KeycloakGetError)
+
def get_realms(self):
"""
Lists all realms in Keycloak deployment
diff --git a/keycloak/urls_patterns.py b/keycloak/urls_patterns.py
index 8dfbadb..65ffbeb 100644
--- a/keycloak/urls_patterns.py
+++ b/keycloak/urls_patterns.py
@@ -89,6 +89,7 @@ URL_ADMIN_IDP_MAPPERS = "admin/realms/{realm-name}/identity-provider/instances/{
URL_ADMIN_IDP = "admin/realms//{realm-name}/identity-provider/instances/{alias}"
URL_ADMIN_REALM_ROLES_ROLE_BY_NAME = "admin/realms/{realm-name}/roles/{role-name}"
URL_ADMIN_REALM_ROLES_COMPOSITE_REALM_ROLE = "admin/realms/{realm-name}/roles/{role-name}/composites"
+URL_ADMIN_REALM_EXPORT = "admin/realms/{realm-name}/partial-export?exportClients={export-clients}&exportGroupsAndRoles={export-groups-and-roles}"
URL_ADMIN_FLOWS = "admin/realms/{realm-name}/authentication/flows"
URL_ADMIN_FLOWS_ALIAS = "admin/realms/{realm-name}/authentication/flows/{flow-id}"
From 71a92f8b4911edfc0f7c26b6829ce519a44e9979 Mon Sep 17 00:00:00 2001
From: Manjeetsinh Alonja
Date: Fri, 9 Jul 2021 12:05:58 +0530
Subject: [PATCH 06/10] Fix feature function documents
---
keycloak/keycloak_admin.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/keycloak/keycloak_admin.py b/keycloak/keycloak_admin.py
index 41f71eb..3abf55b 100644
--- a/keycloak/keycloak_admin.py
+++ b/keycloak/keycloak_admin.py
@@ -247,6 +247,12 @@ class KeycloakAdmin:
"""
Export the realm configurations in the json format
+ RealmRepresentation
+ https://www.keycloak.org/docs-api/5.0/rest-api/index.html#_partialexport
+
+ :param export-clients: Skip if not want to export realm clients
+ :param export-groups-and-roles: Skip if not want to export realm groups and roles
+
:return: realm configurations JSON
"""
params_path = {"realm-name": self.realm_name, "export-clients": export_clients, "export-groups-and-roles": export_groups_and_role }
From 227b698b3fd1552fbac9d0e619d2ff3640ddcf8a Mon Sep 17 00:00:00 2001
From: Michael Kao
Date: Tue, 20 Jul 2021 17:23:44 +0200
Subject: [PATCH 07/10] Stopping pagination requests if response count is lower
than page size.
---
keycloak/keycloak_admin.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/keycloak/keycloak_admin.py b/keycloak/keycloak_admin.py
index ffb5968..e018dbc 100644
--- a/keycloak/keycloak_admin.py
+++ b/keycloak/keycloak_admin.py
@@ -223,6 +223,8 @@ class KeycloakAdmin:
if not partial_results:
break
results.extend(partial_results)
+ if len(partial_results) < query['max']:
+ break
page += 1
return results
From a9b39248543b521fe2a5936fe09b3d8509d681c0 Mon Sep 17 00:00:00 2001
From: Jacky Boen
Date: Mon, 2 Aug 2021 10:27:17 +0800
Subject: [PATCH 08/10] Fix KeycloakAdmin using wrong realm when authenticating
with a service account
Signed-off-by: Jacky Boen
---
keycloak/keycloak_admin.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/keycloak/keycloak_admin.py b/keycloak/keycloak_admin.py
index ffb5968..5feceaf 100644
--- a/keycloak/keycloak_admin.py
+++ b/keycloak/keycloak_admin.py
@@ -1827,14 +1827,17 @@ class KeycloakAdmin:
return r
def get_token(self):
+ token_realm_name = 'master' if self.client_secret_key else self.user_realm_name or self.realm_name
self.keycloak_openid = KeycloakOpenID(server_url=self.server_url, client_id=self.client_id,
- realm_name=self.user_realm_name or self.realm_name, verify=self.verify,
+ realm_name=token_realm_name, verify=self.verify,
client_secret_key=self.client_secret_key,
custom_headers=self.custom_headers)
grant_type = ["password"]
if self.client_secret_key:
grant_type = ["client_credentials"]
+ if self.user_realm_name:
+ self.realm_name = self.user_realm_name
self._token = self.keycloak_openid.token(self.username, self.password, grant_type=grant_type)
From bd8af2924e8b479428a4f2ee3000cbf9bba0e7bf Mon Sep 17 00:00:00 2001
From: Julien Bouquillon
Date: Wed, 18 Aug 2021 00:45:53 +0200
Subject: [PATCH 09/10] feat: add KeycloakAdmin.set_events
---
keycloak/keycloak_admin.py | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/keycloak/keycloak_admin.py b/keycloak/keycloak_admin.py
index ffb5968..0344721 100644
--- a/keycloak/keycloak_admin.py
+++ b/keycloak/keycloak_admin.py
@@ -1774,6 +1774,20 @@ class KeycloakAdmin:
data=None, **query)
return raise_error_from_response(data_raw, KeycloakGetError)
+ def set_events(self, payload):
+ """
+ Set realm events configuration
+
+ RealmEventsConfigRepresentation
+ https://www.keycloak.org/docs-api/8.0/rest-api/index.html#_realmeventsconfigrepresentation
+
+ :return: Http response
+ """
+ params_path = {"realm-name": self.realm_name}
+ data_raw = self.raw_put(URL_ADMIN_EVENTS.format(**params_path),
+ data=json.dumps(payload))
+ return raise_error_from_response(data_raw, KeycloakGetError, expected_codes=[204])
+
def raw_get(self, *args, **kwargs):
"""
Calls connection.raw_get.
From 81b12d2d556883f5770e81818b9e3f5eb666a10b Mon Sep 17 00:00:00 2001
From: Bas van der Linden <33874522+BvdLind@users.noreply.github.com>
Date: Thu, 19 Aug 2021 19:50:37 +0200
Subject: [PATCH 10/10] Update README example create_client_role syntax
In the README the `create_client_role` function has a `client_id` argument, but in [keycloak_admin.py](https://github.com/marcospereirampj/python-keycloak/blob/0ebcf990941f600e6ff562091a81cbeafbd21f3e/keycloak/keycloak_admin.py#L1001) `client_role_id` seems to be used instead.
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 63abe49..d076555 100644
--- a/README.md
+++ b/README.md
@@ -215,7 +215,7 @@ role = keycloak_admin.get_client_role(client_id="client_id", role_name="role_nam
role_id = keycloak_admin.get_client_role_id(client_id="client_id", role_name="test")
# Create client role
-keycloak_admin.create_client_role(client_id='client_id', {'name': 'roleName', 'clientRole': True})
+keycloak_admin.create_client_role(client_role_id='client_id', {'name': 'roleName', 'clientRole': True})
# Assign client role to user. Note that BOTH role_name and role_id appear to be required.
keycloak_admin.assign_client_role(client_id="client_id", user_id="user_id", role_id="role_id", role_name="test")