diff --git a/README.md b/README.md index 3507448..4c3d164 100644 --- a/README.md +++ b/README.md @@ -249,6 +249,9 @@ 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 realm or client that their names includes the searched text +realm_roles = keycloak_admin.get_realm_roles(search_text="CompanyA_") + # Get all roles for the client client_roles = keycloak_admin.get_client_roles(client_id="client_id") diff --git a/src/keycloak/keycloak_admin.py b/src/keycloak/keycloak_admin.py index a5052f3..56b415e 100644 --- a/src/keycloak/keycloak_admin.py +++ b/src/keycloak/keycloak_admin.py @@ -2147,7 +2147,7 @@ class KeycloakAdmin: ) return raise_error_from_response(data_raw, KeycloakGetError, expected_codes=[200]) - def get_realm_roles(self, brief_representation=True): + def get_realm_roles(self, brief_representation=True, search_text=""): """Get all roles for the realm or client. RoleRepresentation @@ -2155,14 +2155,24 @@ class KeycloakAdmin: :param brief_representation: whether to omit role attributes in the response :type brief_representation: bool + :param search_text: optional search text to limit the returned result. + :type search_text: str :return: Keycloak server response (RoleRepresentation) :rtype: list """ + url = urls_patterns.URL_ADMIN_REALM_ROLES params_path = {"realm-name": self.connection.realm_name} params = {"briefRepresentation": brief_representation} data_raw = self.connection.raw_get( urls_patterns.URL_ADMIN_REALM_ROLES.format(**params_path), **params ) + + # set the search_text path param, if it is a valid string + if search_text is not None and search_text.strip() != "": + params_path["search-text"] = search_text + url = urls_patterns.URL_ADMIN_REALM_ROLES_SEARCH + + data_raw = self.connection.raw_get(url.format(**params_path), **params) return raise_error_from_response(data_raw, KeycloakGetError) def get_realm_role_members(self, role_name, query=None): diff --git a/src/keycloak/urls_patterns.py b/src/keycloak/urls_patterns.py index bb5042e..a618260 100644 --- a/src/keycloak/urls_patterns.py +++ b/src/keycloak/urls_patterns.py @@ -140,6 +140,7 @@ URL_ADMIN_CLIENT_SCOPES_ADD_MAPPER = URL_ADMIN_CLIENT_SCOPE + "/protocol-mappers URL_ADMIN_CLIENT_SCOPES_MAPPERS = URL_ADMIN_CLIENT_SCOPES_ADD_MAPPER + "/{protocol-mapper-id}" URL_ADMIN_REALM_ROLES = "admin/realms/{realm-name}/roles" +URL_ADMIN_REALM_ROLES_SEARCH = URL_ADMIN_REALM_ROLES + "?search={search-text}" URL_ADMIN_REALM_ROLES_MEMBERS = URL_ADMIN_REALM_ROLES + "/{role-name}/users" URL_ADMIN_REALMS = "admin/realms" URL_ADMIN_REALM = "admin/realms/{realm-name}" diff --git a/tests/test_keycloak_admin.py b/tests/test_keycloak_admin.py index eec3a28..cb96de3 100644 --- a/tests/test_keycloak_admin.py +++ b/tests/test_keycloak_admin.py @@ -1103,6 +1103,12 @@ def test_realm_roles(admin: KeycloakAdmin, realm: str): assert "uma_authorization" in role_names, role_names assert "offline_access" in role_names, role_names + # Test get realm roles with search text + searched_roles = admin.get_realm_roles(search_text="uma_a") + searched_role_names = [x["name"] for x in searched_roles] + assert "uma_authorization" in searched_role_names, searched_role_names + assert "offline_access" not in searched_role_names, searched_role_names + # Test empty members with pytest.raises(KeycloakGetError) as err: admin.get_realm_role_members(role_name="does-not-exist")