diff --git a/plugins/module_utils/identity/keycloak/keycloak.py b/plugins/module_utils/identity/keycloak/keycloak.py index 9a7e3e8a02..f4258c6418 100644 --- a/plugins/module_utils/identity/keycloak/keycloak.py +++ b/plugins/module_utils/identity/keycloak/keycloak.py @@ -29,7 +29,10 @@ URL_CLIENT_ROLES = "{url}/admin/realms/{realm}/clients/{id}/roles" URL_CLIENT_ROLE = "{url}/admin/realms/{realm}/clients/{id}/roles/{name}" URL_CLIENT_ROLE_COMPOSITES = "{url}/admin/realms/{realm}/clients/{id}/roles/{name}/composites" -URL_CLIENT_ROLE_SCOPE_CLIENTS = "{url}/admin/realms/{realm}/client-scopes/{scopeid}/scope-mappings/clients/{id}" +URL_CLIENT_ROLE_SCOPE_CLIENTS = "{url}/admin/realms/{realm}/clients/{id}/scope-mappings/clients/{scopeid}" + +#SUGGESTED FIX +# URL_CLIENT_ROLE_SCOPE_CLIENTS = "{url}/admin/realms/{realm}/client-scopes/{scopeid}/scope-mappings/clients/{id}" URL_CLIENT_ROLE_SCOPE_REALM = "{url}/admin/realms/{realm}/clients/{id}/scope-mappings/realm" URL_REALM_ROLES = "{url}/admin/realms/{realm}/roles" diff --git a/plugins/modules/keycloak_client_rolescope.py b/plugins/modules/keycloak_client_rolescope.py index 0b243910f0..bb9294a188 100644 --- a/plugins/modules/keycloak_client_rolescope.py +++ b/plugins/modules/keycloak_client_rolescope.py @@ -202,16 +202,24 @@ def main(): module.fail_json(msg="FullScopeAllowed is active for Client '{realm}.{clientid}'".format(realm=realm, clientid=clientid)) if client_scope_id: - objClientScope = kc.get_clientscope_by_clientscopeid(client_scope_id, realm) + objClientScope = kc.get_client_by_clientid(client_scope_id, realm) + + #SUGGESTED FIX + # objClientScope = kc.get_clientscope_by_clientscopeid(client_scope_id, realm) if not objClientScope: module.fail_json(msg="Failed to retrieve client '{realm}.{client_scope_id}'".format(realm=realm, client_scope_id=client_scope_id)) before_role_mapping = kc.get_client_role_scope_from_client(objClient["id"], objClientScope["id"], realm) else: before_role_mapping = kc.get_client_role_scope_from_realm(objClient["id"], realm) - if objClient: - # retrieve all role from client - client_scope_roles_by_name = kc.get_client_roles_by_id(objClient["id"], realm) + if client_scope_id: + # retrive all role from client_scope + client_scope_roles_by_name = kc.get_client_roles_by_id(objClientScope["id"], realm) + + #SUGGESTED FIX + # if objClient: + # # retrieve all role from client + # client_scope_roles_by_name = kc.get_client_roles_by_id(objClient["id"], realm) else: # retrieve all role from realm client_scope_roles_by_name = kc.get_realm_roles(realm) diff --git a/tests/integration/targets/keycloak_client_rolescope/tasks/main.yml b/tests/integration/targets/keycloak_client_rolescope/tasks/main.yml index d4c60d3f2e..fd3a5ebc62 100644 --- a/tests/integration/targets/keycloak_client_rolescope/tasks/main.yml +++ b/tests/integration/targets/keycloak_client_rolescope/tasks/main.yml @@ -43,6 +43,77 @@ - "{{ realm_role_admin }}" - "{{ realm_role_user }}" +############################# +### Additional Steps which lead to failure + +- name: Client private 2 + community.general.keycloak_client: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "client_name_private_2" + state: present + redirect_uris: + - "https://my-backend-api.c.org/" + fullScopeAllowed: false + attributes: "{{client_attributes1}}" + public_client: false + +- name: Create a Keycloak client role for Client private 2 + community.general.keycloak_role: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + name: "{{ item }}" + realm: "{{ realm }}" + client_id: "client_name_private_2" + with_items: + - "client_role_admin_2" + - "client_role_user_2" + +- name: Create client scope + community.general.keycloak_clientscope: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + + name: client_scope_name + protocol: openid-connect + attributes: + "include.in.token.scope": "true" + "display.on.consent.screen": "false" + state: present + register: new_scope + +# This step fails - expectation was for role to be assigned to client scope - when making suggested changes this steps works +# when client_scope_id is given instead the {{ client_name_private }} (as for the task 'Map roles to public client') this step does not fail, however no role is assigned to this scope +# With the fix I am providing, when client_scope_id is provided with the scope_id (as opposed to a client name), the role is indeed assigned +# to the scope but the 'Map roles to public client' task fails probably for the reverse reasons +# Unless mistaken, somehow the underlying code seems to be confusing the notion of a client_scope_id with that of a client_id + +- name: STEP which fails - Assign admin role to client scope + community.general.keycloak_client_rolescope: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + + client_scope_id: "{{ new_scope.end_state.id}}" + # client_scope_id: "{{ client_name_private }}" + client_id: "client_name_private_2" + + role_names: + - "client_role_admin_2" + state: present + +############################# + - name: Client private community.general.keycloak_client: auth_keycloak_url: "{{ url }}" @@ -55,7 +126,7 @@ redirect_uris: - "https://my-backend-api.c.org/" fullScopeAllowed: true - attributes: '{{client_attributes1}}' + attributes: "{{client_attributes1}}" public_client: false - name: Create a Keycloak client role @@ -81,11 +152,10 @@ client_id: "{{ client_name_public }}" redirect_uris: - "https://my-onepage-app-frontend.c.org/" - attributes: '{{client_attributes1}}' + attributes: "{{client_attributes1}}" full_scope_allowed: false public_client: true - - name: Map roles to public client community.general.keycloak_client_rolescope: auth_keycloak_url: "{{ url }}"