Browse Source

Merge pull request #326 from marcospereirampj/test/client_scopes

Test/client scopes
test/readme v1.1.0
Richard Nemeth 2 years ago
committed by GitHub
parent
commit
d54d024aac
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 62
      src/keycloak/keycloak_admin.py
  2. 139
      tests/test_keycloak_admin.py

62
src/keycloak/keycloak_admin.py

@ -2108,6 +2108,22 @@ class KeycloakAdmin:
data_raw = self.raw_get(urls_patterns.URL_ADMIN_CLIENT_SCOPE.format(**params_path))
return raise_error_from_response(data_raw, KeycloakGetError)
def get_client_scope_by_name(self, client_scope_name):
"""
Get representation of the client scope identified by the client scope name.
https://www.keycloak.org/docs-api/18.0/rest-api/index.html#_getclientscopes
:param client_scope_name: (str) Name of the client scope
:returns: ClientScopeRepresentation or None
"""
client_scopes = self.get_client_scopes()
for client_scope in client_scopes:
if client_scope["name"] == client_scope_name:
return client_scope
return None
def create_client_scope(self, payload, skip_exists=False):
"""
Create a client scope
@ -2117,16 +2133,24 @@ class KeycloakAdmin:
:param payload: ClientScopeRepresentation
:param skip_exists: If true then do not raise an error if client scope already exists
:return: Keycloak server response (ClientScopeRepresentation)
:return: Client scope id
"""
if skip_exists:
exists = self.get_client_scope_by_name(client_scope_name=payload["name"])
if exists is not None:
return exists["id"]
params_path = {"realm-name": self.realm_name}
data_raw = self.raw_post(
urls_patterns.URL_ADMIN_CLIENT_SCOPES.format(**params_path), data=json.dumps(payload)
)
return raise_error_from_response(
raise_error_from_response(
data_raw, KeycloakPostError, expected_codes=[201], skip_exists=skip_exists
)
_last_slash_idx = data_raw.headers["Location"].rindex("/")
return data_raw.headers["Location"][_last_slash_idx + 1 :] # noqa: E203
def update_client_scope(self, client_scope_id, payload):
"""
@ -2146,6 +2170,34 @@ class KeycloakAdmin:
)
return raise_error_from_response(data_raw, KeycloakPutError, expected_codes=[204])
def delete_client_scope(self, client_scope_id):
"""
Delete existing client scope.
ClientScopeRepresentation:
https://www.keycloak.org/docs-api/18.0/rest-api/index.html#_client_scopes_resource
:param client_scope_id: The id of the client scope
:return: Keycloak server response
"""
params_path = {"realm-name": self.realm_name, "scope-id": client_scope_id}
data_raw = self.raw_delete(urls_patterns.URL_ADMIN_CLIENT_SCOPE.format(**params_path))
return raise_error_from_response(data_raw, KeycloakDeleteError, expected_codes=[204])
def get_mappers_from_client_scope(self, client_scope_id):
"""
Get a list of all mappers connected to the client scope
https://www.keycloak.org/docs-api/18.0/rest-api/index.html#_protocol_mappers_resource
:param client_scope_id: Client scope id
:returns: Keycloak server response (ProtocolMapperRepresentation)
"""
params_path = {"realm-name": self.realm_name, "scope-id": client_scope_id}
data_raw = self.raw_get(
urls_patterns.URL_ADMIN_CLIENT_SCOPES_ADD_MAPPER.format(**params_path),
)
return raise_error_from_response(data_raw, KeycloakGetError, expected_codes=[200])
def add_mapper_to_client_scope(self, client_scope_id, payload):
"""
Add a mapper to a client scope
@ -2165,20 +2217,20 @@ class KeycloakAdmin:
return raise_error_from_response(data_raw, KeycloakPostError, expected_codes=[201])
def delete_mapper_from_client_scope(self, client_scope_id, protocol_mppaer_id):
def delete_mapper_from_client_scope(self, client_scope_id, protocol_mapper_id):
"""
Delete a mapper from a client scope
https://www.keycloak.org/docs-api/18.0/rest-api/index.html#_delete_mapper
:param client_scope_id: The id of the client scope
:param payload: ProtocolMapperRepresentation
:param protocol_mapper_id: Protocol mapper id
:return: Keycloak server Response
"""
params_path = {
"realm-name": self.realm_name,
"scope-id": client_scope_id,
"protocol-mapper-id": protocol_mppaer_id,
"protocol-mapper-id": protocol_mapper_id,
}
data_raw = self.raw_delete(

139
tests/test_keycloak_admin.py

@ -1243,3 +1243,142 @@ def test_sync_users(admin: KeycloakAdmin, realm: str):
with pytest.raises(KeycloakPostError) as err:
admin.sync_users(storage_id="does-not-exist", action="triggerFullSync")
assert err.match('404: b\'{"error":"Could not find component"}\'')
def test_client_scopes(admin: KeycloakAdmin, realm: str):
admin.realm_name = realm
# Test get client scopes
res = admin.get_client_scopes()
scope_names = {x["name"] for x in res}
assert len(res) == 10
assert "email" in scope_names
assert "profile" in scope_names
assert "offline_access" in scope_names
with pytest.raises(KeycloakGetError) as err:
admin.get_client_scope(client_scope_id="does-not-exist")
assert err.match('404: b\'{"error":"Could not find client scope"}\'')
scope = admin.get_client_scope(client_scope_id=res[0]["id"])
assert res[0] == scope
scope = admin.get_client_scope_by_name(client_scope_name=res[0]["name"])
assert res[0] == scope
# Test create client scope
res = admin.create_client_scope(payload={"name": "test-scope"}, skip_exists=True)
assert res
res2 = admin.create_client_scope(payload={"name": "test-scope"}, skip_exists=True)
assert res == res2
with pytest.raises(KeycloakPostError) as err:
admin.create_client_scope(payload={"name": "test-scope"}, skip_exists=False)
assert err.match('409: b\'{"errorMessage":"Client Scope test-scope already exists"}\'')
# Test update client scope
with pytest.raises(KeycloakPutError) as err:
admin.update_client_scope(client_scope_id="does-not-exist", payload=dict())
assert err.match('404: b\'{"error":"Could not find client scope"}\'')
res_update = admin.update_client_scope(
client_scope_id=res, payload={"name": "test-scope-update"}
)
assert res_update == dict()
admin.get_client_scope(client_scope_id=res)["name"] == "test-scope-update"
# Test get mappers
mappers = admin.get_mappers_from_client_scope(client_scope_id=res)
assert mappers == list()
# Test add mapper
with pytest.raises(KeycloakPostError) as err:
admin.add_mapper_to_client_scope(client_scope_id=res, payload=dict())
assert err.match('404: b\'{"error":"ProtocolMapper provider not found"}\'')
res_add = admin.add_mapper_to_client_scope(
client_scope_id=res,
payload={
"name": "test-mapper",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
},
)
assert res_add == b""
assert len(admin.get_mappers_from_client_scope(client_scope_id=res)) == 1
# Test update mapper
test_mapper = admin.get_mappers_from_client_scope(client_scope_id=res)[0]
with pytest.raises(KeycloakPutError) as err:
admin.update_mapper_in_client_scope(
client_scope_id="does-not-exist", protocol_mapper_id=test_mapper["id"], payload=dict()
)
assert err.match('404: b\'{"error":"Could not find client scope"}\'')
test_mapper["config"]["user.attribute"] = "test"
res_update = admin.update_mapper_in_client_scope(
client_scope_id=res,
protocol_mapper_id=test_mapper["id"],
payload=test_mapper,
)
assert res_update == dict()
assert (
admin.get_mappers_from_client_scope(client_scope_id=res)[0]["config"]["user.attribute"]
== "test"
)
# Test delete mapper
res_del = admin.delete_mapper_from_client_scope(
client_scope_id=res, protocol_mapper_id=test_mapper["id"]
)
assert res_del == dict()
with pytest.raises(KeycloakDeleteError) as err:
admin.delete_mapper_from_client_scope(
client_scope_id=res, protocol_mapper_id=test_mapper["id"]
)
assert err.match('404: b\'{"error":"Model not found"}\'')
# Test default default scopes
res_defaults = admin.get_default_default_client_scopes()
assert len(res_defaults) == 6
with pytest.raises(KeycloakPutError) as err:
admin.add_default_default_client_scope(scope_id="does-not-exist")
assert err.match('404: b\'{"error":"Client scope not found"}\'')
res_add = admin.add_default_default_client_scope(scope_id=res)
assert res_add == dict()
assert len(admin.get_default_default_client_scopes()) == 7
with pytest.raises(KeycloakDeleteError) as err:
admin.delete_default_default_client_scope(scope_id="does-not-exist")
assert err.match('404: b\'{"error":"Client scope not found"}\'')
res_del = admin.delete_default_default_client_scope(scope_id=res)
assert res_del == dict()
assert len(admin.get_default_default_client_scopes()) == 6
# Test default optional scopes
res_defaults = admin.get_default_optional_client_scopes()
assert len(res_defaults) == 4
with pytest.raises(KeycloakPutError) as err:
admin.add_default_optional_client_scope(scope_id="does-not-exist")
assert err.match('404: b\'{"error":"Client scope not found"}\'')
res_add = admin.add_default_optional_client_scope(scope_id=res)
assert res_add == dict()
assert len(admin.get_default_optional_client_scopes()) == 5
with pytest.raises(KeycloakDeleteError) as err:
admin.delete_default_optional_client_scope(scope_id="does-not-exist")
assert err.match('404: b\'{"error":"Client scope not found"}\'')
res_del = admin.delete_default_optional_client_scope(scope_id=res)
assert res_del == dict()
assert len(admin.get_default_optional_client_scopes()) == 4
# Test client scope delete
res_del = admin.delete_client_scope(client_scope_id=res)
assert res_del == dict()
with pytest.raises(KeycloakDeleteError) as err:
admin.delete_client_scope(client_scope_id=res)
assert err.match('404: b\'{"error":"Could not find client scope"}\'')
Loading…
Cancel
Save