From 03098c218d8cea0c69d67f26a4e786d9af91e945 Mon Sep 17 00:00:00 2001
From: Thomas Woerner <twoerner@redhat.com>
Date: Tue, 22 Feb 2022 15:04:00 +0100
Subject: [PATCH] ipauser: Set allow_empty_string for userauthtype and
 sshpubkey

The parameters userauthtype and sshpubkey allowing to use "" to reset to
the default value.

The new check in params_get is not allowing to use empty strings in lists,
therefore allow_empty_string=True had to be added to the call.

A test has been added to verify that the empty strings are supported and
working. An idempotency issue with sshpubkey has been found with the test
and fixed additionally.
---
 plugins/modules/ipauser.py                   |  13 ++-
 tests/user/test_user_empty_string_params.yml | 115 +++++++++++++++++++
 2 files changed, 126 insertions(+), 2 deletions(-)
 create mode 100644 tests/user/test_user_empty_string_params.yml

diff --git a/plugins/modules/ipauser.py b/plugins/modules/ipauser.py
index aee71cd2..fb0fbc47 100644
--- a/plugins/modules/ipauser.py
+++ b/plugins/modules/ipauser.py
@@ -892,8 +892,10 @@ def main():
     title = ansible_module.params_get("title")
     manager = ansible_module.params_get("manager")
     carlicense = ansible_module.params_get("carlicense")
-    sshpubkey = ansible_module.params_get("sshpubkey")
-    userauthtype = ansible_module.params_get("userauthtype")
+    sshpubkey = ansible_module.params_get("sshpubkey",
+                                          allow_empty_string=True)
+    userauthtype = ansible_module.params_get("userauthtype",
+                                             allow_empty_string=True)
     userclass = ansible_module.params_get("userclass")
     radius = ansible_module.params_get("radius")
     radiususer = ansible_module.params_get("radiususer")
@@ -1101,6 +1103,13 @@ def main():
                         if "noprivate" in args:
                             del args["noprivate"]
 
+                        # Ignore sshpubkey if it is empty (for resetting)
+                        # and not set in for the user
+                        if "ipasshpubkey" not in res_find and \
+                           "ipasshpubkey" in args and \
+                           args["ipasshpubkey"] == ['']:
+                            del args["ipasshpubkey"]
+
                         # Ignore userauthtype if it is empty (for resetting)
                         # and not set in for the user
                         if "ipauserauthtype" not in res_find and \
diff --git a/tests/user/test_user_empty_string_params.yml b/tests/user/test_user_empty_string_params.yml
new file mode 100644
index 00000000..ebece0c0
--- /dev/null
+++ b/tests/user/test_user_empty_string_params.yml
@@ -0,0 +1,115 @@
+---
+- name: Test user
+  hosts: "{{ ipa_test_host | default('ipaserver') }}"
+  become: true
+  gather_facts: false
+
+  tasks:
+
+  # CLEANUP TEST ITEMS
+
+  - name: Ensure user testuser absent
+    ipauser:
+      ipaadmin_password: SomeADMINpassword
+      ipaapi_context: "{{ ipa_context | default(omit) }}"
+      name: testuser
+      state: absent
+
+  # CREATE TEST ITEMS
+
+  - name: Ensure user testuser present
+    ipauser:
+      ipaadmin_password: SomeADMINpassword
+      ipaapi_context: "{{ ipa_context | default(omit) }}"
+      name: testuser
+      first: test
+      last: user
+    register: result
+    failed_when: not result.changed or result.failed
+
+  # TESTS
+
+  - name: Ensure user testuser present with userauthtype password,radius,otp
+    ipauser:
+      ipaadmin_password: SomeADMINpassword
+      ipaapi_context: "{{ ipa_context | default(omit) }}"
+      name: testuser
+      userauthtype: password,radius,otp
+    register: result
+    failed_when: not result.changed or result.failed
+
+  - name: Ensure user testuser present with userauthtype password,radius,otp, again
+    ipauser:
+      ipaadmin_password: SomeADMINpassword
+      ipaapi_context: "{{ ipa_context | default(omit) }}"
+      name: testuser
+      userauthtype: password,radius,otp
+    register: result
+    failed_when: result.changed or result.failed
+
+  - name: Ensure user testuser present with empty userauthtype
+    ipauser:
+      ipaadmin_password: SomeADMINpassword
+      ipaapi_context: "{{ ipa_context | default(omit) }}"
+      name: testuser
+      userauthtype: ""
+    register: result
+    failed_when: not result.changed or result.failed
+
+  - name: Ensure user testuser present with empty userauthtype, again
+    ipauser:
+      ipaadmin_password: SomeADMINpassword
+      ipaapi_context: "{{ ipa_context | default(omit) }}"
+      name: testuser
+      userauthtype: ""
+    register: result
+    failed_when: result.changed or result.failed
+
+  - name: Ensure user testuser present with sshpubkey
+    ipauser:
+      ipaadmin_password: SomeADMINpassword
+      ipaapi_context: "{{ ipa_context | default(omit) }}"
+      name: testuser
+      sshpubkey:
+      # yamllint disable-line rule:line-length
+      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCqmVDpEX5gnSjKuv97AyzOhaUMMKz8ahOA3GY77tVC4o68KNgMCmDSEG1/kOIaElngNLaCha3p/2iAcU9Bi1tLKUlm2bbO5NHNwHfRxY/3cJtq+/7D1vxJzqThYwI4F9vr1WxyY2+mMTv3pXbfAJoR8Mu06XaEY5PDetlDKjHLuNWF+/O7ZU8PsULTa1dJZFrtXeFpmUoLoGxQBvlrlcPI1zDciCSU24t27Zan5Py2l5QchyI7yhCyMM77KDtj5+AFVpmkb9+zq50rYJAyFVeyUvwjzErvQrKJzYpA0NyBp7vskWbt36M16/M/LxEK7HA6mkcakO3ESWx5MT1LAjvdlnxbWG3787MxweHXuB8CZU+9bZPFBaJ+VQtOfJ7I8eH0S16moPC4ak8FlcFvOH8ERDPWLFDqfy09yaZ7bVIF0//5ZI7Nf3YDe3S7GrBX5ieYuECyP6UNkTx9BRsAQeVvXEc6otzB7iCSnYBMGUGzCqeigoAWaVQUONsSR3Uatks= pinky@ipaserver.el81.local  # noqa 204
+    register: result
+    failed_when: not result.changed or result.failed
+
+  - name: Ensure user testuser present with sshpubkey, again
+    ipauser:
+      ipaadmin_password: SomeADMINpassword
+      ipaapi_context: "{{ ipa_context | default(omit) }}"
+      name: testuser
+      sshpubkey:
+      # yamllint disable-line rule:line-length
+      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCqmVDpEX5gnSjKuv97AyzOhaUMMKz8ahOA3GY77tVC4o68KNgMCmDSEG1/kOIaElngNLaCha3p/2iAcU9Bi1tLKUlm2bbO5NHNwHfRxY/3cJtq+/7D1vxJzqThYwI4F9vr1WxyY2+mMTv3pXbfAJoR8Mu06XaEY5PDetlDKjHLuNWF+/O7ZU8PsULTa1dJZFrtXeFpmUoLoGxQBvlrlcPI1zDciCSU24t27Zan5Py2l5QchyI7yhCyMM77KDtj5+AFVpmkb9+zq50rYJAyFVeyUvwjzErvQrKJzYpA0NyBp7vskWbt36M16/M/LxEK7HA6mkcakO3ESWx5MT1LAjvdlnxbWG3787MxweHXuB8CZU+9bZPFBaJ+VQtOfJ7I8eH0S16moPC4ak8FlcFvOH8ERDPWLFDqfy09yaZ7bVIF0//5ZI7Nf3YDe3S7GrBX5ieYuECyP6UNkTx9BRsAQeVvXEc6otzB7iCSnYBMGUGzCqeigoAWaVQUONsSR3Uatks= pinky@ipaserver.el81.local  # noqa 204
+    register: result
+    failed_when: result.changed or result.failed
+
+  - name: Ensure user testuser present with empty sshpubkey
+    ipauser:
+      ipaadmin_password: SomeADMINpassword
+      ipaapi_context: "{{ ipa_context | default(omit) }}"
+      name: testuser
+      sshpubkey: ""
+    register: result
+    failed_when: not result.changed or result.failed
+
+  - name: Ensure user testuser present with empty sshpubkey, again
+    ipauser:
+      ipaadmin_password: SomeADMINpassword
+      ipaapi_context: "{{ ipa_context | default(omit) }}"
+      name: testuser
+      sshpubkey: ""
+    register: result
+    failed_when: result.changed or result.failed
+
+  # CLEANUP TEST ITEMS
+
+  - name: Ensure user testuser absent
+    ipauser:
+      ipaadmin_password: SomeADMINpassword
+      ipaapi_context: "{{ ipa_context | default(omit) }}"
+      name: testuser
+      state: absent
-- 
GitLab