Browse Source

Merge pull request #390 from M4d40/client_client_scopes

feat: Add Client Scopes of Client
pull/409/head v2.11.0
Richard Nemeth 1 year ago
committed by GitHub
parent
commit
9a3774e3b6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 136
      src/keycloak/keycloak_admin.py
  2. 8
      src/keycloak/urls_patterns.py
  3. 92
      tests/test_keycloak_admin.py

136
src/keycloak/keycloak_admin.py

@ -1561,6 +1561,142 @@ class KeycloakAdmin:
)
return raise_error_from_response(data_raw, KeycloakGetError)
def get_client_default_client_scopes(self, client_id):
"""Get all default client scopes from client.
:param client_id: id of the client in which the new default client scope should be added
:type client_id: str
:return: list of client scopes with id and name
:rtype: list
"""
params_path = {"realm-name": self.realm_name, "id": client_id}
data_raw = self.raw_get(
urls_patterns.URL_ADMIN_CLIENT_DEFAULT_CLIENT_SCOPES.format(**params_path)
)
return raise_error_from_response(data_raw, KeycloakGetError)
def add_client_default_client_scope(self, client_id, client_scope_id, payload):
"""Add a client scope to the default client scopes from client.
Payload example::
payload={
"realm":"testrealm",
"client":"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"clientScopeId":"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
}
:param client_id: id of the client in which the new default client scope should be added
:type client_id: str
:param client_scope_id: id of the new client scope that should be added
:type client_scope_id: str
:param payload: dictionary with realm, client and clientScopeId
:type payload: dict
:return: Http response
:rtype: bytes
"""
params_path = {
"realm-name": self.realm_name,
"id": client_id,
"client_scope_id": client_scope_id,
}
data_raw = self.raw_put(
urls_patterns.URL_ADMIN_CLIENT_DEFAULT_CLIENT_SCOPE.format(**params_path),
data=json.dumps(payload),
)
return raise_error_from_response(data_raw, KeycloakPutError)
def delete_client_default_client_scope(self, client_id, client_scope_id):
"""Delete a client scope from the default client scopes of the client.
:param client_id: id of the client in which the default client scope should be deleted
:type client_id: str
:param client_scope_id: id of the client scope that should be deleted
:type client_scope_id: str
:return: list of client scopes with id and name
:rtype: list
"""
params_path = {
"realm-name": self.realm_name,
"id": client_id,
"client_scope_id": client_scope_id,
}
data_raw = self.raw_delete(
urls_patterns.URL_ADMIN_CLIENT_DEFAULT_CLIENT_SCOPE.format(**params_path)
)
return raise_error_from_response(data_raw, KeycloakDeleteError)
def get_client_optional_client_scopes(self, client_id):
"""Get all optional client scopes from client.
:param client_id: id of the client in which the new optional client scope should be added
:type client_id: str
:return: list of client scopes with id and name
:rtype: list
"""
params_path = {"realm-name": self.realm_name, "id": client_id}
data_raw = self.raw_get(
urls_patterns.URL_ADMIN_CLIENT_OPTIONAL_CLIENT_SCOPES.format(**params_path)
)
return raise_error_from_response(data_raw, KeycloakGetError)
def add_client_optional_client_scope(self, client_id, client_scope_id, payload):
"""Add a client scope to the optional client scopes from client.
Payload example::
payload={
"realm":"testrealm",
"client":"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"clientScopeId":"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
}
:param client_id: id of the client in which the new optional client scope should be added
:type client_id: str
:param client_scope_id: id of the new client scope that should be added
:type client_scope_id: str
:param payload: dictionary with realm, client and clientScopeId
:type payload: dict
:return: Http response
:rtype: bytes
"""
params_path = {
"realm-name": self.realm_name,
"id": client_id,
"client_scope_id": client_scope_id,
}
data_raw = self.raw_put(
urls_patterns.URL_ADMIN_CLIENT_OPTIONAL_CLIENT_SCOPE.format(**params_path),
data=json.dumps(payload),
)
return raise_error_from_response(data_raw, KeycloakPutError)
def delete_client_optional_client_scope(self, client_id, client_scope_id):
"""Delete a client scope from the optional client scopes of the client.
:param client_id: id of the client in which the optional client scope should be deleted
:type client_id: str
:param client_scope_id: id of the client scope that should be deleted
:type client_scope_id: str
:return: list of client scopes with id and name
:rtype: list
"""
params_path = {
"realm-name": self.realm_name,
"id": client_id,
"client_scope_id": client_scope_id,
}
data_raw = self.raw_delete(
urls_patterns.URL_ADMIN_CLIENT_OPTIONAL_CLIENT_SCOPE.format(**params_path)
)
return raise_error_from_response(data_raw, KeycloakDeleteError)
def create_client(self, payload, skip_exists=False):
"""Create a client.

8
src/keycloak/urls_patterns.py

@ -95,6 +95,14 @@ URL_ADMIN_CLIENT_SCOPE_MAPPINGS_REALM_ROLES = URL_ADMIN_CLIENT + "/scope-mapping
URL_ADMIN_CLIENT_SCOPE_MAPPINGS_CLIENT_ROLES = (
URL_ADMIN_CLIENT + "/scope-mappings/clients/{client}"
)
URL_ADMIN_CLIENT_OPTIONAL_CLIENT_SCOPES = URL_ADMIN_CLIENT + "/optional-client-scopes"
URL_ADMIN_CLIENT_OPTIONAL_CLIENT_SCOPE = (
URL_ADMIN_CLIENT_OPTIONAL_CLIENT_SCOPES + "/{client_scope_id}"
)
URL_ADMIN_CLIENT_DEFAULT_CLIENT_SCOPES = URL_ADMIN_CLIENT + "/default-client-scopes"
URL_ADMIN_CLIENT_DEFAULT_CLIENT_SCOPE = (
URL_ADMIN_CLIENT_DEFAULT_CLIENT_SCOPES + "/{client_scope_id}"
)
URL_ADMIN_CLIENT_AUTHZ_SETTINGS = URL_ADMIN_CLIENT + "/authz/resource-server/settings"
URL_ADMIN_CLIENT_AUTHZ_RESOURCES = URL_ADMIN_CLIENT + "/authz/resource-server/resource?max=-1"

92
tests/test_keycloak_admin.py

@ -1327,6 +1327,98 @@ def test_client_scope_client_roles(admin: KeycloakAdmin, realm: str, client: str
assert len(roles) == 0
def test_client_default_client_scopes(admin: KeycloakAdmin, realm: str, client: str):
"""Test client assignment of default client scopes.
:param admin: Keycloak admin
:type admin: KeycloakAdmin
:param realm: Keycloak realm
:type realm: str
:param client: Keycloak client
:type client: str
"""
admin.realm_name = realm
client_id = admin.create_client(
payload={"name": "role-testing-client", "clientId": "role-testing-client"}
)
# Test get client default scopes
# keycloak default roles: web-origins, acr, profile, roles, email
default_client_scopes = admin.get_client_default_client_scopes(client_id)
assert len(default_client_scopes) == 5, default_client_scopes
# Test add a client scope to client default scopes
default_client_scope = "test-client-default-scope"
new_client_scope = {
"name": default_client_scope,
"description": f"Test Client Scope: {default_client_scope}",
"protocol": "openid-connect",
"attributes": {},
}
new_client_scope_id = admin.create_client_scope(new_client_scope, skip_exists=False)
new_default_client_scope_data = {
"realm": realm,
"client": client_id,
"clientScopeId": new_client_scope_id,
}
admin.add_client_default_client_scope(
client_id, new_client_scope_id, new_default_client_scope_data
)
default_client_scopes = admin.get_client_default_client_scopes(client_id)
assert len(default_client_scopes) == 6, default_client_scopes
# Test remove a client default scope
admin.delete_client_default_client_scope(client_id, new_client_scope_id)
default_client_scopes = admin.get_client_default_client_scopes(client_id)
assert len(default_client_scopes) == 5, default_client_scopes
def test_client_optional_client_scopes(admin: KeycloakAdmin, realm: str, client: str):
"""Test client assignment of optional client scopes.
:param admin: Keycloak admin
:type admin: KeycloakAdmin
:param realm: Keycloak realm
:type realm: str
:param client: Keycloak client
:type client: str
"""
admin.realm_name = realm
client_id = admin.create_client(
payload={"name": "role-testing-client", "clientId": "role-testing-client"}
)
# Test get client optional scopes
# keycloak optional roles: microprofile-jwt, offline_access, address, phone
optional_client_scopes = admin.get_client_optional_client_scopes(client_id)
assert len(optional_client_scopes) == 4, optional_client_scopes
# Test add a client scope to client optional scopes
optional_client_scope = "test-client-optional-scope"
new_client_scope = {
"name": optional_client_scope,
"description": f"Test Client Scope: {optional_client_scope}",
"protocol": "openid-connect",
"attributes": {},
}
new_client_scope_id = admin.create_client_scope(new_client_scope, skip_exists=False)
new_optional_client_scope_data = {
"realm": realm,
"client": client_id,
"clientScopeId": new_client_scope_id,
}
admin.add_client_optional_client_scope(
client_id, new_client_scope_id, new_optional_client_scope_data
)
optional_client_scopes = admin.get_client_optional_client_scopes(client_id)
assert len(optional_client_scopes) == 5, optional_client_scopes
# Test remove a client optional scope
admin.delete_client_optional_client_scope(client_id, new_client_scope_id)
optional_client_scopes = admin.get_client_optional_client_scopes(client_id)
assert len(optional_client_scopes) == 4, optional_client_scopes
def test_client_roles(admin: KeycloakAdmin, client: str):
"""Test client roles.

Loading…
Cancel
Save