4646class KeycloakAdmin :
4747
4848 PAGE_SIZE = 100
49-
49+
5050 _server_url = None
5151 _username = None
5252 _password = None
@@ -57,9 +57,11 @@ class KeycloakAdmin:
5757 _auto_refresh_token = None
5858 _connection = None
5959 _token = None
60+ _custom_headers = None
61+ _user_realm_name = None
6062
61- def __init__ (self , server_url , username , password , realm_name = 'master' , client_id = 'admin-cli' , verify = True , client_secret_key = None ,
62- auto_refresh_token = None ):
63+ def __init__ (self , server_url , username , password , realm_name = 'master' , client_id = 'admin-cli' , verify = True ,
64+ client_secret_key = None , custom_headers = None , user_realm_name = None , auto_refresh_token = None ):
6365 """
6466
6567 :param server_url: Keycloak server url
@@ -69,6 +71,7 @@ def __init__(self, server_url, username, password, realm_name='master', client_i
6971 :param client_id: client id
7072 :param verify: True if want check connection SSL
7173 :param client_secret_key: client secret key
74+ :param custom_headers: dict of custom header to pass to each HTML request
7275 :param auto_refresh_token: list of methods that allows automatic token refresh. ex: ['get', 'put', 'post', 'delete']
7376 """
7477 self .server_url = server_url
@@ -79,11 +82,12 @@ def __init__(self, server_url, username, password, realm_name='master', client_i
7982 self .verify = verify
8083 self .client_secret_key = client_secret_key
8184 self .auto_refresh_token = auto_refresh_token or []
85+ self .user_realm_name = user_realm_name
86+ self .custom_headers = custom_headers
8287
8388 # Get token Admin
8489 self .get_token ()
8590
86-
8791 @property
8892 def server_url (self ):
8993 return self ._server_url
@@ -160,6 +164,22 @@ def token(self, value):
160164 def auto_refresh_token (self ):
161165 return self ._auto_refresh_token
162166
167+ @property
168+ def user_realm_name (self ):
169+ return self ._user_realm_name
170+
171+ @user_realm_name .setter
172+ def user_realm_name (self , value ):
173+ self ._user_realm_name = value
174+
175+ @property
176+ def custom_headers (self ):
177+ return self ._custom_headers
178+
179+ @custom_headers .setter
180+ def custom_headers (self , value ):
181+ self ._custom_headers = value
182+
163183 @auto_refresh_token .setter
164184 def auto_refresh_token (self , value ):
165185 allowed_methods = {'get' , 'post' , 'put' , 'delete' }
@@ -226,13 +246,13 @@ def get_realms(self):
226246
227247 def create_realm (self , payload , skip_exists = False ):
228248 """
229- Create a client
249+ Create a realm
230250
231251 ClientRepresentation: http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_realmrepresentation
232252
233253 :param skip_exists: Skip if Realm already exist.
234254 :param payload: RealmRepresentation
235- :return: Keycloak server response (UserRepresentation )
255+ :return: Keycloak server response (RealmRepresentation )
236256 """
237257
238258 data_raw = self .raw_post (URL_ADMIN_REALMS ,
@@ -732,6 +752,20 @@ def create_client(self, payload, skip_exists=False):
732752 data = json .dumps (payload ))
733753 return raise_error_from_response (data_raw , KeycloakGetError , expected_code = 201 , skip_exists = skip_exists )
734754
755+ def update_client (self , client_id , payload ):
756+ """
757+ Update a client
758+
759+ :param client_id: Client id
760+ :param payload: ClientRepresentation
761+
762+ :return: Http response
763+ """
764+ params_path = {"realm-name" : self .realm_name , "id" : client_id }
765+ data_raw = self .connection .raw_put (URL_ADMIN_CLIENT .format (** params_path ),
766+ data = json .dumps (payload ))
767+ return raise_error_from_response (data_raw , KeycloakGetError , expected_code = 204 )
768+
735769 def delete_client (self , client_id ):
736770 """
737771 Get representation of the client
@@ -860,6 +894,21 @@ def assign_client_role(self, user_id, client_id, roles):
860894 data = json .dumps (payload ))
861895 return raise_error_from_response (data_raw , KeycloakGetError , expected_code = 204 )
862896
897+ def create_realm_role (self , payload , skip_exists = False ):
898+ """
899+ Create a new role for the realm or client
900+
901+ :param realm: realm name (not id)
902+ :param rep: RoleRepresentation https://www.keycloak.org/docs-api/5.0/rest-api/index.html#_rolerepresentation
903+ :return Keycloak server response
904+ """
905+
906+ params_path = {"realm-name" : self .realm_name }
907+ data_raw = self .connection .raw_post (URL_ADMIN_REALM_ROLES .format (** params_path ),
908+ data = json .dumps (payload ))
909+ return raise_error_from_response (data_raw , KeycloakGetError , expected_code = 201 , skip_exists = skip_exists )
910+
911+
863912 def assign_realm_roles (self , user_id , client_id , roles ):
864913 """
865914 Assign realm roles to a user
@@ -1109,16 +1158,27 @@ def raw_delete(self, *args, **kwargs):
11091158
11101159 def get_token (self ):
11111160 self .keycloak_openid = KeycloakOpenID (server_url = self .server_url , client_id = self .client_id ,
1112- realm_name = self .realm_name , verify = self .verify ,
1113- client_secret_key = self .client_secret_key )
1161+ realm_name = self .user_realm_name or self .realm_name , verify = self .verify ,
1162+ client_secret_key = self .client_secret_key
1163+ custom_headers = self .custom_headers )
11141164
11151165 grant_type = ["password" ]
11161166 if self .client_secret_key :
11171167 grant_type = ["client_credentials" ]
1168+
11181169 self ._token = self .keycloak_openid .token (self .username , self .password , grant_type = grant_type )
1170+
1171+ headers = {
1172+ 'Authorization' : 'Bearer ' + self .token .get ('access_token' ),
1173+ 'Content-Type' : 'application/json'
1174+ }
1175+
1176+ if self .custom_headers is not None :
1177+ # merge custom headers to main headers
1178+ headers .update (self .custom_headers )
1179+
11191180 self ._connection = ConnectionManager (base_url = self .server_url ,
1120- headers = {'Authorization' : 'Bearer ' + self .token .get ('access_token' ),
1121- 'Content-Type' : 'application/json' },
1181+ headers = headers ,
11221182 timeout = 60 ,
11231183 verify = self .verify )
11241184
0 commit comments