Browse Source

Refactoring code: groups and client.

hotfix/merge
Marcos Pereira 7 years ago
parent
commit
2c176e6f8a
  1. 49
      README.md
  2. 226
      keycloak/keycloak_admin.py
  3. 20
      keycloak/keycloak_openid.py
  4. 2
      keycloak/urls_patterns.py

49
README.md

@ -66,6 +66,9 @@ token = keycloak_openid.token("user", "password")
# Get Userinfo # Get Userinfo
userinfo = keycloak_openid.userinfo(token['access_token']) userinfo = keycloak_openid.userinfo(token['access_token'])
# Refresh token
token = keycloak_openid.refresh_token(token['refresh_token'])
# Logout # Logout
keycloak_openid.logout(token['refresh_token']) keycloak_openid.logout(token['refresh_token'])
@ -113,6 +116,17 @@ new_user = keycloak_admin.create_user({"email": "example@example.com",
"realmRoles": ["user_default", ], "realmRoles": ["user_default", ],
"attributes": {"example": "1,2,3,3,"}}) "attributes": {"example": "1,2,3,3,"}})
# Add user and set password
new_user = keycloak_admin.create_user({"email": "example@example.com",
"username": "example@example.com",
"enabled": True,
"firstName": "Example",
"lastName": "Example",
"credentials": [{"value": "secret","type": "password",}],
"realmRoles": ["user_default", ],
"attributes": {"example": "1,2,3,3,"}})
# User counter # User counter
count_users = keycloak_admin.users_count() count_users = keycloak_admin.users_count()
@ -129,6 +143,9 @@ user = keycloak_admin.get_user("user-id-keycloak")
response = keycloak_admin.update_user(user_id="user-id-keycloak", response = keycloak_admin.update_user(user_id="user-id-keycloak",
payload={'firstName': 'Example Update'}) payload={'firstName': 'Example Update'})
# Update User Password
response = set_user_password(user_id="user-id-keycloak", password="secret", temporary=True)
# Delete User # Delete User
response = keycloak_admin.delete_user(user_id="user-id-keycloak") response = keycloak_admin.delete_user(user_id="user-id-keycloak")
@ -155,20 +172,36 @@ clients = keycloak_admin.get_clients()
client_id=keycloak_admin.get_client_id("my-client") client_id=keycloak_admin.get_client_id("my-client")
# Get representation of the client - id of client (not client-id) # Get representation of the client - id of client (not client-id)
client = keycloak_admin.get_client(client_id=client_id)
client = keycloak_admin.get_client(client_id="client_id")
# Get all roles for the realm or client
realm_roles = keycloak_admin.get_realm_roles()
# Get all roles for the client # Get all roles for the client
client_roles = keycloak_admin.get_client_role(client_id=client_id)
client_roles = keycloak_admin.get_client_roles(client_id="client_id")
# Create client role
keycloak_admin.create_client_role(client_id, "test")
# Get client role
role = keycloak_admin.get_client_role(client_id="client_id", role_name="role_name")
# Warning: Deprecated
# Get client role id from name # Get client role id from name
role_id = keycloak_admin.get_client_role_id(client_id=client_id, role_name="test")
role_id = keycloak_admin.get_client_role_id(client_id="client_id", role_name="test")
# Get all roles for the realm or client
realm_roles = keycloak_admin.get_roles()
# Create client role
keycloak_admin.create_client_role(client_id, "test")
# Assign client role to user. Note that BOTH role_name and role_id appear to be required. # 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")
keycloak_admin.assign_client_role(client_id="client_id", user_id="user_id", role_id="role_id", role_name="test")
# Create new group
group = keycloak_admin.create_group(name="Example Group")
# Get all groups
groups = keycloak_admin.get_groups()
# Get group
group = keycloak_admin.get_group(group_id='group_id')
# Get group by name
group = keycloak_admin.get_group_by_name(name_or_path='group_id', search_in_subgroups=True)
``` ```

226
keycloak/keycloak_admin.py

@ -17,7 +17,7 @@
# Unless otherwise stated in the comments, "id", in e.g. user_id, refers to the # Unless otherwise stated in the comments, "id", in e.g. user_id, refers to the
# internal Keycloak server ID, usually a uuid string # internal Keycloak server ID, usually a uuid string
from keycloak.urls_patterns import URL_ADMIN_CLIENT_ROLE
from .urls_patterns import \ from .urls_patterns import \
URL_ADMIN_USERS_COUNT, URL_ADMIN_USER, URL_ADMIN_USER_CONSENTS, \ URL_ADMIN_USERS_COUNT, URL_ADMIN_USER, URL_ADMIN_USER_CONSENTS, \
URL_ADMIN_SEND_UPDATE_ACCOUNT, URL_ADMIN_RESET_PASSWORD, URL_ADMIN_SEND_VERIFY_EMAIL, URL_ADMIN_GET_SESSIONS, \ URL_ADMIN_SEND_UPDATE_ACCOUNT, URL_ADMIN_RESET_PASSWORD, URL_ADMIN_SEND_VERIFY_EMAIL, URL_ADMIN_GET_SESSIONS, \
@ -145,10 +145,11 @@ class KeycloakAdmin:
Get internal keycloak user id from username Get internal keycloak user id from username
This is required for further actions against this user. This is required for further actions against this user.
:param username:
clientId in UserRepresentation
UserRepresentation
http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_userrepresentation http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_userrepresentation
:param username: id in UserRepresentation
:return: user_id :return: user_id
""" """
params_path = {"realm-name": self.realm_name, "username": username} params_path = {"realm-name": self.realm_name, "username": username}
@ -156,8 +157,8 @@ class KeycloakAdmin:
data_content = raise_error_from_response(data_raw, KeycloakGetError) data_content = raise_error_from_response(data_raw, KeycloakGetError)
for user in data_content: for user in data_content:
thisusername = json.dumps(user["username"]).strip('"')
if thisusername == username:
this_use_rname = json.dumps(user["username"]).strip('"')
if this_use_rname == username:
return json.dumps(user["id"]).strip('"') return json.dumps(user["id"]).strip('"')
return None return None
@ -220,7 +221,7 @@ class KeycloakAdmin:
params_path = {"realm-name": self.realm_name, "id": user_id} params_path = {"realm-name": self.realm_name, "id": user_id}
data_raw = self.connection.raw_put(URL_ADMIN_RESET_PASSWORD.format(**params_path), data_raw = self.connection.raw_put(URL_ADMIN_RESET_PASSWORD.format(**params_path),
data=json.dumps(payload)) data=json.dumps(payload))
return raise_error_from_response(data_raw, KeycloakGetError, expected_code=200)
return raise_error_from_response(data_raw, KeycloakGetError, expected_code=204)
def consents_user(self, user_id): def consents_user(self, user_id):
""" """
@ -317,94 +318,73 @@ class KeycloakAdmin:
GroupRepresentation GroupRepresentation
http://www.keycloak.org/docs-api/3.2/rest-api/#_grouprepresentation http://www.keycloak.org/docs-api/3.2/rest-api/#_grouprepresentation
:return: array GroupRepresentation
:return: Keycloak server response (GroupRepresentation)
""" """
params_path = {"realm-name": self.realm_name, "id": group_id} params_path = {"realm-name": self.realm_name, "id": group_id}
data_raw = self.connection.raw_get(URL_ADMIN_GROUP.format(**params_path)) data_raw = self.connection.raw_get(URL_ADMIN_GROUP.format(**params_path))
return raise_error_from_response(data_raw, KeycloakGetError) return raise_error_from_response(data_raw, KeycloakGetError)
def get_group_id(self, name=None, path=None, parent=None):
def get_group_by_name(self, name_or_path, search_in_subgroups=False):
""" """
Get group id based on name or path. Get group id based on name or path.
A straight name or path match with a top-level group will return first. A straight name or path match with a top-level group will return first.
Subgroups are traversed, the first to match path (or name with path) is returned. Subgroups are traversed, the first to match path (or name with path) is returned.
:param name: group name
:param path: group path
:param parent: parent group's id. Required to find a sub-group below level 1.
GroupRepresentation GroupRepresentation
http://www.keycloak.org/docs-api/3.2/rest-api/#_grouprepresentation http://www.keycloak.org/docs-api/3.2/rest-api/#_grouprepresentation
:return: GroupID (string)
:param name: group name
:param path: group path
:param search_in_subgroups: True if want search in the subgroups
:return: Keycloak server response (GroupRepresentation)
""" """
if parent is not None:
params_path = {"realm-name": self.realm_name, "id": parent}
data_raw = self.connection.raw_get(URL_ADMIN_GROUP.format(**params_path))
res = raise_error_from_response(data_raw, KeycloakGetError)
data_content = []
data_content.append(res)
else:
params_path = {"realm-name": self.realm_name}
data_raw = self.connection.raw_get(URL_ADMIN_GROUPS.format(**params_path))
data_content = raise_error_from_response(data_raw, KeycloakGetError)
for group in data_content:
thisgroupname = json.dumps(group["name"]).strip('"')
thisgrouppath = json.dumps(group["path"]).strip('"')
if (thisgroupname == name and name is not None) or (thisgrouppath == path and path is not None):
return json.dumps(group["id"]).strip('"')
for subgroup in group["subGroups"]:
thisgrouppath = json.dumps(subgroup["path"]).strip('"')
groups = self.get_groups()
if (thisgrouppath == path and path is not None) or (thisgrouppath == name and name is not None):
return json.dumps(subgroup["id"]).strip('"')
# TODO: Review this code is necessary
for group in groups:
if group['name'] == name_or_path or group['path'] == name_or_path:
return group
elif search_in_subgroups and group["subGroups"]:
for subgroup in group["subGroups"]:
if subgroup['name'] == name_or_path or subgroup['path'] == name_or_path:
return subgroup
return None return None
def create_group(self, name=None, client_roles={}, realm_roles=[], sub_groups=[], path=None, parent=None, skip_exists=False):
def create_group(self, name=None, client_roles={}, realm_roles=[], sub_groups=[], path=None, parent=None):
""" """
Creates a group in the Realm
Create a group in the Realm
GroupRepresentation
http://www.keycloak.org/docs-api/3.2/rest-api/#_grouprepresentation
:param name: group name :param name: group name
:param client_roles (map): Client roles to include in groupp # Not demonstrated to work
:param realm_roles (array): Realm roles to include in group # Not demonstrated to work
:param sub_groups (array): Subgroups to include in groupp # Not demonstrated to work
:param client_roles: (Dict) Client roles to include in groupp # Not demonstrated to work
:param realm_roles: (List) Realm roles to include in group # Not demonstrated to work
:param sub_groups: (List) Subgroups to include in groupp # Not demonstrated to work
:param path: group path :param path: group path
:param parent: parent group's id. Required to create a sub-group. :param parent: parent group's id. Required to create a sub-group.
GroupRepresentation
http://www.keycloak.org/docs-api/3.2/rest-api/#_grouprepresentation
:return: Http response
:return: Keycloak server response (GroupRepresentation)
""" """
if name is None and path is not None:
name=path
data={}
data["name"]=name
data["path"]=path
data["clientRoles"]=client_roles
data["realmRoles"]=realm_roles
data["subGroups"]=sub_groups
if name is not None:
exists = self.get_group_id(name=name, parent=parent)
elif path is not None:
exists = self.get_group_id(path=path, parent=parent)
if exists is not None:
return str(exists)
data = {"name": name or path,
"path": path,
"clientRoles": client_roles,
"realmRoles": realm_roles,
"subGroups": sub_groups}
if parent is None: if parent is None:
params_path = {"realm-name": self.realm_name} params_path = {"realm-name": self.realm_name}
data_raw = self.connection.raw_post(URL_ADMIN_GROUPS.format(**params_path), data_raw = self.connection.raw_post(URL_ADMIN_GROUPS.format(**params_path),
data=json.dumps(data)) data=json.dumps(data))
else: else:
params_path = {"realm-name": self.realm_name, "id": parent,}
params_path = {"realm-name": self.realm_name, "id": parent}
data_raw = self.connection.raw_post(URL_ADMIN_GROUP_CHILD.format(**params_path), data_raw = self.connection.raw_post(URL_ADMIN_GROUP_CHILD.format(**params_path),
data=json.dumps(data)) data=json.dumps(data))
return raise_error_from_response(data_raw, KeycloakGetError, expected_code=201, skip_exists=skip_exists)
return raise_error_from_response(data_raw, KeycloakGetError, expected_code=201)
def group_set_permissions(self, group_id, enabled=True): def group_set_permissions(self, group_id, enabled=True):
""" """
@ -412,15 +392,12 @@ class KeycloakAdmin:
:param group_id: id of group :param group_id: id of group
:param enabled: boolean :param enabled: boolean
:return: {}
:return: Keycloak server response
""" """
data={}
data["enabled"]=enabled
params_path = {"realm-name": self.realm_name, "id": group_id} params_path = {"realm-name": self.realm_name, "id": group_id}
data_raw = self.connection.raw_put(URL_ADMIN_GROUP_PERMISSIONS.format(**params_path), data_raw = self.connection.raw_put(URL_ADMIN_GROUP_PERMISSIONS.format(**params_path),
data=json.dumps(data))
data=json.dumps({"enabled": enabled}))
return raise_error_from_response(data_raw, KeycloakGetError) return raise_error_from_response(data_raw, KeycloakGetError)
def group_user_add(self, user_id, group_id): def group_user_add(self, user_id, group_id):
@ -430,17 +407,11 @@ class KeycloakAdmin:
:param group_id: id of group :param group_id: id of group
:param user_id: id of user :param user_id: id of user
:param group_id: id of group to add to :param group_id: id of group to add to
:return: {}
:return: Keycloak server response
""" """
data={}
data["realm"]=self.realm_name
data["userId"]=user_id
data["groupId"]=group_id
params_path = {"realm-name": self.realm_name, "id": user_id, "group-id": group_id} params_path = {"realm-name": self.realm_name, "id": user_id, "group-id": group_id}
data_raw = self.connection.raw_put(URL_ADMIN_USER_GROUP.format(**params_path),
data=json.dumps(data))
data_raw = self.connection.raw_put(URL_ADMIN_USER_GROUP.format(**params_path), data=None)
return raise_error_from_response(data_raw, KeycloakGetError, expected_code=204) return raise_error_from_response(data_raw, KeycloakGetError, expected_code=204)
def group_user_remove(self, user_id, group_id): def group_user_remove(self, user_id, group_id):
@ -450,9 +421,9 @@ class KeycloakAdmin:
:param group_id: id of group :param group_id: id of group
:param user_id: id of user :param user_id: id of user
:param group_id: id of group to add to :param group_id: id of group to add to
:return: {}
:return: Keycloak server response
""" """
params_path = {"realm-name": self.realm_name, "id": user_id, "group-id": group_id} params_path = {"realm-name": self.realm_name, "id": user_id, "group-id": group_id}
data_raw = self.connection.raw_delete(URL_ADMIN_USER_GROUP.format(**params_path)) data_raw = self.connection.raw_delete(URL_ADMIN_USER_GROUP.format(**params_path))
return raise_error_from_response(data_raw, KeycloakGetError, expected_code=204) return raise_error_from_response(data_raw, KeycloakGetError, expected_code=204)
@ -462,9 +433,9 @@ class KeycloakAdmin:
Deletes a group in the Realm Deletes a group in the Realm
:param group_id: id of group to delete :param group_id: id of group to delete
:return: Http response
:return: Keycloak server response
""" """
params_path = {"realm-name": self.realm_name, "id": group_id} params_path = {"realm-name": self.realm_name, "id": group_id}
data_raw = self.connection.raw_delete(URL_ADMIN_GROUP.format(**params_path)) data_raw = self.connection.raw_delete(URL_ADMIN_GROUP.format(**params_path))
return raise_error_from_response(data_raw, KeycloakGetError, expected_code=204) return raise_error_from_response(data_raw, KeycloakGetError, expected_code=204)
@ -476,12 +447,28 @@ class KeycloakAdmin:
ClientRepresentation ClientRepresentation
http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_clientrepresentation http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_clientrepresentation
:return: ClientRepresentation
:return: Keycloak server response (ClientRepresentation)
""" """
params_path = {"realm-name": self.realm_name} params_path = {"realm-name": self.realm_name}
data_raw = self.connection.raw_get(URL_ADMIN_CLIENTS.format(**params_path)) data_raw = self.connection.raw_get(URL_ADMIN_CLIENTS.format(**params_path))
return raise_error_from_response(data_raw, KeycloakGetError) return raise_error_from_response(data_raw, KeycloakGetError)
def get_client(self, client_id):
"""
Get representation of the client
ClientRepresentation
http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_clientrepresentation
:param client_id: id of client (not client-id)
:return: Keycloak server response (ClientRepresentation)
"""
params_path = {"realm-name": self.realm_name, "id": client_id}
data_raw = self.connection.raw_get(URL_ADMIN_CLIENT.format(**params_path))
return raise_error_from_response(data_raw, KeycloakGetError)
def get_client_id(self, client_name): def get_client_id(self, client_name):
""" """
Get internal keycloak client id from client-id. Get internal keycloak client id from client-id.
@ -489,7 +476,6 @@ class KeycloakAdmin:
:param client_name: name in ClientRepresentation :param client_name: name in ClientRepresentation
http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_clientrepresentation http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_clientrepresentation
:return: client_id (uuid as string) :return: client_id (uuid as string)
""" """
@ -501,32 +487,16 @@ class KeycloakAdmin:
return None return None
def get_client(self, client_id):
"""
Get representation of the client
ClientRepresentation
http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_clientrepresentation
:param client_id: id of client (not client-id)
:return: ClientRepresentation
"""
params_path = {"realm-name": self.realm_name, "id": client_id}
data_raw = self.connection.raw_get(URL_ADMIN_CLIENT.format(**params_path))
return raise_error_from_response(data_raw, KeycloakGetError)
def create_client(self, payload): def create_client(self, payload):
""" """
Create a client Create a client
:param payload: ClientRepresentation
:return: UserRepresentation
ClientRepresentation: http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_clientrepresentation ClientRepresentation: http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_clientrepresentation
:param payload: ClientRepresentation
:return: Keycloak server response (UserRepresentation)
""" """
params_path = {"realm-name": self.realm_name} params_path = {"realm-name": self.realm_name}
data_raw = self.connection.raw_post(URL_ADMIN_CLIENTS.format(**params_path), data_raw = self.connection.raw_post(URL_ADMIN_CLIENTS.format(**params_path),
data=json.dumps(payload)) data=json.dumps(payload))
@ -540,13 +510,27 @@ class KeycloakAdmin:
http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_clientrepresentation http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_clientrepresentation
:param client_id: keycloak client id (not oauth client-id) :param client_id: keycloak client id (not oauth client-id)
:return: ClientRepresentation
:return: Keycloak server response (ClientRepresentation)
""" """
params_path = {"realm-name": self.realm_name, "id": client_id} params_path = {"realm-name": self.realm_name, "id": client_id}
data_raw = self.connection.raw_delete(URL_ADMIN_CLIENT.format(**params_path)) data_raw = self.connection.raw_delete(URL_ADMIN_CLIENT.format(**params_path))
return raise_error_from_response(data_raw, KeycloakGetError, expected_code=204) return raise_error_from_response(data_raw, KeycloakGetError, expected_code=204)
def get_realm_roles(self):
"""
Get all roles for the realm or client
RoleRepresentation
http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_rolerepresentation
:return: Keycloak server response (RoleRepresentation)
"""
params_path = {"realm-name": self.realm_name}
data_raw = self.connection.raw_get(URL_ADMIN_REALM_ROLES.format(**params_path))
return raise_error_from_response(data_raw, KeycloakGetError)
def get_client_roles(self, client_id): def get_client_roles(self, client_id):
""" """
Get all roles for the client Get all roles for the client
@ -556,13 +540,14 @@ class KeycloakAdmin:
RoleRepresentation RoleRepresentation
http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_rolerepresentation http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_rolerepresentation
:return: RoleRepresentation
:return: Keycloak server response (RoleRepresentation)
""" """
params_path = {"realm-name": self.realm_name, "id": client_id} params_path = {"realm-name": self.realm_name, "id": client_id}
data_raw = self.connection.raw_get(URL_ADMIN_CLIENT_ROLES.format(**params_path)) data_raw = self.connection.raw_get(URL_ADMIN_CLIENT_ROLES.format(**params_path))
return raise_error_from_response(data_raw, KeycloakGetError) return raise_error_from_response(data_raw, KeycloakGetError)
def get_client_role_id(self, client_id, role_name):
def get_client_role(self, client_id, role_name):
""" """
Get client role id by name Get client role id by name
This is required for further actions with this role. This is required for further actions with this role.
@ -575,37 +560,39 @@ class KeycloakAdmin:
:return: role_id :return: role_id
""" """
roles = self.get_client_roles(client_id)
params_path = {"realm-name": self.realm_name, "id": client_id, "role-name": role_name}
data_raw = self.connection.raw_get(URL_ADMIN_CLIENT_ROLE.format(**params_path))
return raise_error_from_response(data_raw, KeycloakGetError)
for role in roles:
if roles['name'] == role_name:
return role["id"]
def get_client_role_id(self, client_id, role_name):
"""
Warning: Deprecated
return None
Get client role id by name
This is required for further actions with this role.
def get_roles(self):
"""
Get all roles for the realm or client
:param client_id: id of client (not client-id)
:param role_name: roles name (not id!)
RoleRepresentation RoleRepresentation
http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_rolerepresentation http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_rolerepresentation
:return: RoleRepresentation
:return: role_id
""" """
params_path = {"realm-name": self.realm_name}
data_raw = self.connection.raw_get(URL_ADMIN_REALM_ROLES.format(**params_path))
return raise_error_from_response(data_raw, KeycloakGetError)
role = self.get_client_role(client_id, role_name)
return role.get("id")
def create_client_role(self, payload): def create_client_role(self, payload):
""" """
Create a client role Create a client role
:param payload: id of client (not client-id), role_name: name of role
RoleRepresentation RoleRepresentation
http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_rolerepresentation http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_rolerepresentation
:param payload: id of client (not client-id), role_name: name of role
:return: Keycloak server response (RoleRepresentation)
""" """
params_path = {"realm-name": self.realm_name, "id": self.client_id} params_path = {"realm-name": self.realm_name, "id": self.client_id}
data_raw = self.connection.raw_post(URL_ADMIN_CLIENT_ROLES.format(**params_path), data_raw = self.connection.raw_post(URL_ADMIN_CLIENT_ROLES.format(**params_path),
data=json.dumps(payload)) data=json.dumps(payload))
@ -615,14 +602,13 @@ class KeycloakAdmin:
""" """
Create a client role Create a client role
:param role_name: roles name (not id!)
RoleRepresentation RoleRepresentation
http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_rolerepresentation http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_rolerepresentation
:param role_name: roles name (not id!)
""" """
params_path = {"realm-name": self.realm_name, "id": self.client_id, "role-name": role_name} params_path = {"realm-name": self.realm_name, "id": self.client_id, "role-name": role_name}
data_raw = self.connection.raw_delete(URL_ADMIN_CLIENT_ROLES.format(**params_path))
data_raw = self.connection.raw_delete(URL_ADMIN_CLIENT_ROLE.format(**params_path))
return raise_error_from_response(data_raw, KeycloakGetError, expected_code=204) return raise_error_from_response(data_raw, KeycloakGetError, expected_code=204)
def assign_client_role(self, user_id, client_id, roles): def assign_client_role(self, user_id, client_id, roles):
@ -633,9 +619,7 @@ class KeycloakAdmin:
:param user_id: id of user :param user_id: id of user
:param client_id: id of client containing role, :param client_id: id of client containing role,
:param roles: roles list or role (use RoleRepresentation) :param roles: roles list or role (use RoleRepresentation)
:return
:return Keycloak server response
""" """
payload = roles if isinstance(roles, list) else [roles] payload = roles if isinstance(roles, list) else [roles]

20
keycloak/keycloak_openid.py

@ -165,6 +165,26 @@ class KeycloakOpenID:
data=payload) data=payload)
return raise_error_from_response(data_raw, KeycloakGetError) return raise_error_from_response(data_raw, KeycloakGetError)
def refresh_token(self, refresh_token, grant_type=["refresh_token"]):
"""
The token endpoint is used to obtain tokens. Tokens can either be obtained by
exchanging an authorization code or by supplying credentials directly depending on
what flow is used. The token endpoint is also used to obtain new access tokens
when they expire.
http://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
:param refresh_token:
:param grant_type:
:return:
"""
params_path = {"realm-name": self.realm_name}
payload = {"client_id": self.client_id, "grant_type": grant_type, "refresh_token": refresh_token}
payload = self._add_secret_key(payload)
data_raw = self.connection.raw_post(URL_TOKEN.format(**params_path),
data=payload)
return raise_error_from_response(data_raw, KeycloakGetError)
def userinfo(self, token): def userinfo(self, token):
""" """
The userinfo endpoint returns standard claims about the authenticated user, The userinfo endpoint returns standard claims about the authenticated user,

2
keycloak/urls_patterns.py

@ -46,6 +46,6 @@ URL_ADMIN_GROUP_PERMISSIONS = "admin/realms/{realm-name}/groups/{id}/management/
URL_ADMIN_CLIENTS = "admin/realms/{realm-name}/clients" URL_ADMIN_CLIENTS = "admin/realms/{realm-name}/clients"
URL_ADMIN_CLIENT = "admin/realms/{realm-name}/clients/{id}" URL_ADMIN_CLIENT = "admin/realms/{realm-name}/clients/{id}"
URL_ADMIN_CLIENT_ROLES = "admin/realms/{realm-name}/clients/{id}/roles" URL_ADMIN_CLIENT_ROLES = "admin/realms/{realm-name}/clients/{id}/roles"
URL_ADMIN_CLIENT_ROLES = "/admin/realms/{realm}/clients/{id}/roles/{role-name}"
URL_ADMIN_CLIENT_ROLE = "admin/realms/{realm-name}/clients/{id}/roles/{role-name}"
URL_ADMIN_REALM_ROLES = "admin/realms/{realm-name}/roles" URL_ADMIN_REALM_ROLES = "admin/realms/{realm-name}/roles"
Loading…
Cancel
Save