diff --git a/changelogs/fragments/5750-bugfixing-keycloak-usrfed-fail-when-update-default-mapper-simultaneously.yml b/changelogs/fragments/5750-bugfixing-keycloak-usrfed-fail-when-update-default-mapper-simultaneously.yml new file mode 100644 index 0000000000..93cfc3adcb --- /dev/null +++ b/changelogs/fragments/5750-bugfixing-keycloak-usrfed-fail-when-update-default-mapper-simultaneously.yml @@ -0,0 +1,7 @@ +bugfixes: + - >- + keycloak_user_federation - fixes federation creation issue. When a new + federation was created and at the same time a default / standard mapper + was also changed / updated the creation process failed as a bad None + set variable led to a bad malformed url request + (https://github.com/ansible-collections/community.general/pull/5750). diff --git a/plugins/modules/keycloak_user_federation.py b/plugins/modules/keycloak_user_federation.py index 3659d757ac..fbb31e695d 100644 --- a/plugins/modules/keycloak_user_federation.py +++ b/plugins/modules/keycloak_user_federation.py @@ -923,6 +923,8 @@ def main(): updated_mappers = desired_comp.pop('mappers', []) after_comp = kc.create_component(desired_comp, realm) + cid = after_comp['id'] + for mapper in updated_mappers: found = kc.get_components(urlencode(dict(parent=cid, name=mapper['name'])), realm) if len(found) > 1: diff --git a/tests/integration/targets/keycloak_user_federation/tasks/main.yml b/tests/integration/targets/keycloak_user_federation/tasks/main.yml index 139d6ee2be..ae0b4bf162 100644 --- a/tests/integration/targets/keycloak_user_federation/tasks/main.yml +++ b/tests/integration/targets/keycloak_user_federation/tasks/main.yml @@ -270,6 +270,14 @@ useKerberosForPasswordAuthentication: false debug: false mappers: + # overwrite / update pre existing default mapper + - name: "username" + providerId: "user-attribute-ldap-mapper" + config: + ldap.attribute: ldap_user + user.model.attribute: usr + read.only: true + # create new mapper - name: "full name" providerId: "full-name-ldap-mapper" providerType: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper" @@ -335,3 +343,83 @@ - result is not changed - result.existing == {} - result.end_state == {} + +- name: Create new user federation together with mappers + community.general.keycloak_user_federation: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + name: "{{ federation }}" + state: present + provider_id: ldap + provider_type: org.keycloak.storage.UserStorageProvider + config: + enabled: true + priority: 0 + fullSyncPeriod: -1 + changedSyncPeriod: -1 + cachePolicy: DEFAULT + batchSizeForSync: 1000 + editMode: READ_ONLY + importEnabled: true + syncRegistrations: false + vendor: other + usernameLDAPAttribute: uid + rdnLDAPAttribute: uid + uuidLDAPAttribute: entryUUID + userObjectClasses: "inetOrgPerson, organizationalPerson" + connectionUrl: "ldaps://ldap.example.com:636" + usersDn: "ou=Users,dc=example,dc=com" + authType: simple + bindDn: cn=directory reader + bindCredential: secret + searchScope: 1 + validatePasswordPolicy: false + trustEmail: false + useTruststoreSpi: "ldapsOnly" + connectionPooling: true + pagination: true + allowKerberosAuthentication: false + useKerberosForPasswordAuthentication: false + debug: false + mappers: + # overwrite / update pre existing default mapper + - name: "username" + providerId: "user-attribute-ldap-mapper" + config: + ldap.attribute: ldap_user + user.model.attribute: usr + read.only: true + # create new mapper + - name: "full name" + providerId: "full-name-ldap-mapper" + providerType: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper" + config: + ldap.full.name.attribute: cn + read.only: true + write.only: false + register: result + +- name: Debug + debug: + var: result + +- name: Assert user federation created + assert: + that: + - result is changed + - result.existing == {} + - result.end_state.name == "{{ federation }}" + +## no point in retesting this, just doing it to clean up introduced server changes +- name: Delete absent user federation + community.general.keycloak_user_federation: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + name: "{{ federation }}" + state: absent