Browse Source

chore: implement partialImport request (#456)

pull/430/head
Igor Pronin 12 months ago
committed by elias.hamacher
parent
commit
8d5942b4fc
  1. 23
      src/keycloak/keycloak_admin.py
  2. 2
      src/keycloak/urls_patterns.py
  3. 47
      tests/test_keycloak_admin.py

23
src/keycloak/keycloak_admin.py

@ -532,6 +532,29 @@ class KeycloakAdmin:
) )
return raise_error_from_response(data_raw, KeycloakPostError, expected_codes=[201]) return raise_error_from_response(data_raw, KeycloakPostError, expected_codes=[201])
def partial_import_realm(self, realm_name, payload):
"""Partial import realm configuration from PartialImportRepresentation.
Realm partialImport is used for modifying configuration of existing realm.
PartialImportRepresentation
https://www.keycloak.org/docs-api/18.0/rest-api/#_partialimportrepresentation
:param realm_name: Realm name (not the realm id)
:type realm_name: str
:param payload: PartialImportRepresentation
:type payload: dict
:return: PartialImportResponse
:rtype: dict
"""
params_path = {"realm-name": realm_name}
data_raw = self.connection.raw_post(
urls_patterns.URL_ADMIN_REALM_PARTIAL_IMPORT.format(**params_path),
data=json.dumps(payload),
)
return raise_error_from_response(data_raw, KeycloakPostError, expected_codes=[200])
def export_realm(self, export_clients=False, export_groups_and_role=False): def export_realm(self, export_clients=False, export_groups_and_role=False):
"""Export the realm configurations in the json format. """Export the realm configurations in the json format.

2
src/keycloak/urls_patterns.py

@ -163,6 +163,8 @@ URL_ADMIN_REALM_EXPORT = (
+ "exportGroupsAndRoles={export-groups-and-roles}" + "exportGroupsAndRoles={export-groups-and-roles}"
) )
URL_ADMIN_REALM_PARTIAL_IMPORT = "admin/realms/{realm-name}/partialImport"
URL_ADMIN_DEFAULT_DEFAULT_CLIENT_SCOPES = URL_ADMIN_REALM + "/default-default-client-scopes" URL_ADMIN_DEFAULT_DEFAULT_CLIENT_SCOPES = URL_ADMIN_REALM + "/default-default-client-scopes"
URL_ADMIN_DEFAULT_DEFAULT_CLIENT_SCOPE = URL_ADMIN_DEFAULT_DEFAULT_CLIENT_SCOPES + "/{id}" URL_ADMIN_DEFAULT_DEFAULT_CLIENT_SCOPE = URL_ADMIN_DEFAULT_DEFAULT_CLIENT_SCOPES + "/{id}"
URL_ADMIN_DEFAULT_OPTIONAL_CLIENT_SCOPES = URL_ADMIN_REALM + "/default-optional-client-scopes" URL_ADMIN_DEFAULT_OPTIONAL_CLIENT_SCOPES = URL_ADMIN_REALM + "/default-optional-client-scopes"

47
tests/test_keycloak_admin.py

@ -216,6 +216,53 @@ def test_import_export_realms(admin: KeycloakAdmin, realm: str):
assert err.match('500: b\'{"error":"unknown_error"}\'') assert err.match('500: b\'{"error":"unknown_error"}\'')
def test_partial_import_realm(admin: KeycloakAdmin, realm: str):
"""Test partial import of realm configuration.
:param admin: Keycloak Admin client
:type admin: KeycloakAdmin
:param realm: Keycloak realm
:type realm: str
"""
test_realm_role = str(uuid.uuid4())
test_user = str(uuid.uuid4())
test_client = str(uuid.uuid4())
admin.realm_name = realm
client_id = admin.create_client(payload={"name": test_client, "clientId": test_client})
realm_export = admin.export_realm(export_clients=True, export_groups_and_role=False)
client_config = [
client_entry for client_entry in realm_export["clients"] if client_entry["id"] == client_id
][0]
# delete before partial import
admin.delete_client(client_id)
payload = {
"ifResourceExists": "SKIP",
"id": realm_export["id"],
"realm": realm,
"clients": [client_config],
"roles": {"realm": [{"name": test_realm_role}]},
"users": [{"username": test_user, "email": f"{test_user}@test.test"}],
}
# check add
res = admin.partial_import_realm(realm_name=realm, payload=payload)
assert res["added"] == 3
# check skip
res = admin.partial_import_realm(realm_name=realm, payload=payload)
assert res["skipped"] == 3
# check overwrite
payload["ifResourceExists"] = "OVERWRITE"
res = admin.partial_import_realm(realm_name=realm, payload=payload)
assert res["overwritten"] == 3
def test_users(admin: KeycloakAdmin, realm: str): def test_users(admin: KeycloakAdmin, realm: str):
"""Test users. """Test users.

Loading…
Cancel
Save