mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-03-22 05:09:12 +00:00
keycloak_user_rolemapping: handle None response for client role lookup (#11471)
* fix(keycloak_user_rolemapping): handle None response for client role lookup When adding a client role to a user who has no existing roles for that client, get_client_user_rolemapping_by_id() returns None. The existing code indexed directly into the result causing a TypeError. Add the same None check that already existed for realm roles since PR #11256. Fixes #10960 * fix(tests): use dict format for task vars in keycloak_user_rolemapping tests Task-level vars requires a YAML mapping, not a sequence. The leading dash (- roles:) produced a list instead of a dict, which ansible-core 2.20 rejects with "Vars in a Task must be specified as a dictionary". * Update changelogs/fragments/keycloak-user-rolemapping-client-none-check.yml Co-authored-by: Felix Fontein <felix@fontein.de> --------- Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
parent
80d21f2a0d
commit
34938ca1ef
4 changed files with 73 additions and 11 deletions
|
|
@ -0,0 +1,5 @@
|
||||||
|
bugfixes:
|
||||||
|
- keycloak_user_rolemapping - fix ``TypeError`` crash when adding a client
|
||||||
|
role to a user who has no existing roles for that client
|
||||||
|
(https://github.com/ansible-collections/community.general/issues/10960,
|
||||||
|
https://github.com/ansible-collections/community.general/pull/11471).
|
||||||
|
|
@ -356,9 +356,9 @@ def main():
|
||||||
if role_rep is not None:
|
if role_rep is not None:
|
||||||
role["name"] = role_rep["name"]
|
role["name"] = role_rep["name"]
|
||||||
else:
|
else:
|
||||||
role["name"] = kc.get_client_user_rolemapping_by_id(
|
role_rep = kc.get_client_user_rolemapping_by_id(uid=uid, cid=cid, rid=role.get("id"), realm=realm)
|
||||||
uid=uid, cid=cid, rid=role.get("id"), realm=realm
|
if role_rep is not None:
|
||||||
)["name"]
|
role["name"] = role_rep["name"]
|
||||||
if role.get("name") is None:
|
if role.get("name") is None:
|
||||||
module.fail_json(
|
module.fail_json(
|
||||||
msg=f"Could not fetch role {role.get('id')} for client_id {client_id} or realm {realm}"
|
msg=f"Could not fetch role {role.get('id')} for client_id {client_id} or realm {realm}"
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
- name: Map a realm role to client service account
|
- name: Map a realm role to client service account
|
||||||
vars:
|
vars:
|
||||||
- roles:
|
roles:
|
||||||
- name: '{{ role }}'
|
- name: '{{ role }}'
|
||||||
community.general.keycloak_user_rolemapping:
|
community.general.keycloak_user_rolemapping:
|
||||||
auth_keycloak_url: "{{ url }}"
|
auth_keycloak_url: "{{ url }}"
|
||||||
|
|
@ -58,7 +58,7 @@
|
||||||
|
|
||||||
- name: Unmap a realm role from client service account
|
- name: Unmap a realm role from client service account
|
||||||
vars:
|
vars:
|
||||||
- roles:
|
roles:
|
||||||
- name: '{{ role }}'
|
- name: '{{ role }}'
|
||||||
community.general.keycloak_user_rolemapping:
|
community.general.keycloak_user_rolemapping:
|
||||||
auth_keycloak_url: "{{ url }}"
|
auth_keycloak_url: "{{ url }}"
|
||||||
|
|
@ -89,6 +89,18 @@
|
||||||
name: "{{ role }}"
|
name: "{{ role }}"
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
|
- name: Create second client (for cross-client role mapping test)
|
||||||
|
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_id_2 }}"
|
||||||
|
service_accounts_enabled: true
|
||||||
|
state: present
|
||||||
|
register: client_2
|
||||||
|
|
||||||
- name: Create new client role
|
- name: Create new client role
|
||||||
community.general.keycloak_role:
|
community.general.keycloak_role:
|
||||||
auth_keycloak_url: "{{ url }}"
|
auth_keycloak_url: "{{ url }}"
|
||||||
|
|
@ -101,9 +113,53 @@
|
||||||
description: "{{ description_1 }}"
|
description: "{{ description_1 }}"
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
|
- name: Map a client role to a user with no existing roles for that client
|
||||||
|
vars:
|
||||||
|
roles:
|
||||||
|
- name: '{{ role }}'
|
||||||
|
community.general.keycloak_user_rolemapping:
|
||||||
|
auth_keycloak_url: "{{ url }}"
|
||||||
|
auth_realm: "{{ admin_realm }}"
|
||||||
|
auth_username: "{{ admin_user }}"
|
||||||
|
auth_password: "{{ admin_password }}"
|
||||||
|
realm: "{{ realm }}"
|
||||||
|
client_id: "{{ client_id }}"
|
||||||
|
service_account_user_client_id: "{{ client_id_2 }}"
|
||||||
|
roles: "{{ roles }}"
|
||||||
|
state: present
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Assert client role is assigned to user with no prior roles
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
- result.end_state | selectattr("clientRole", "eq", true) | selectattr("name", "eq", role) | list | count > 0
|
||||||
|
|
||||||
|
- name: Unmap the cross-client role mapping
|
||||||
|
vars:
|
||||||
|
roles:
|
||||||
|
- name: '{{ role }}'
|
||||||
|
community.general.keycloak_user_rolemapping:
|
||||||
|
auth_keycloak_url: "{{ url }}"
|
||||||
|
auth_realm: "{{ admin_realm }}"
|
||||||
|
auth_username: "{{ admin_user }}"
|
||||||
|
auth_password: "{{ admin_password }}"
|
||||||
|
realm: "{{ realm }}"
|
||||||
|
client_id: "{{ client_id }}"
|
||||||
|
service_account_user_client_id: "{{ client_id_2 }}"
|
||||||
|
roles: "{{ roles }}"
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Assert cross-client role mapping is removed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
- result.end_state == []
|
||||||
|
|
||||||
- name: Map a client role to client service account
|
- name: Map a client role to client service account
|
||||||
vars:
|
vars:
|
||||||
- roles:
|
roles:
|
||||||
- name: '{{ role }}'
|
- name: '{{ role }}'
|
||||||
community.general.keycloak_user_rolemapping:
|
community.general.keycloak_user_rolemapping:
|
||||||
auth_keycloak_url: "{{ url }}"
|
auth_keycloak_url: "{{ url }}"
|
||||||
|
|
@ -125,7 +181,7 @@
|
||||||
|
|
||||||
- name: Unmap a client role from client service account
|
- name: Unmap a client role from client service account
|
||||||
vars:
|
vars:
|
||||||
- roles:
|
roles:
|
||||||
- name: '{{ role }}'
|
- name: '{{ role }}'
|
||||||
community.general.keycloak_user_rolemapping:
|
community.general.keycloak_user_rolemapping:
|
||||||
auth_keycloak_url: "{{ url }}"
|
auth_keycloak_url: "{{ url }}"
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ admin_user: admin
|
||||||
admin_password: password
|
admin_password: password
|
||||||
realm: myrealm
|
realm: myrealm
|
||||||
client_id: myclient
|
client_id: myclient
|
||||||
|
client_id_2: myotherclient
|
||||||
role: myrole
|
role: myrole
|
||||||
description_1: desc 1
|
description_1: desc 1
|
||||||
description_2: desc 2
|
description_2: desc 2
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue