From 9d348cb36816188f81c9427cca65ddc02736b4cd Mon Sep 17 00:00:00 2001
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
Date: Mon, 6 Apr 2020 17:49:17 -0300
Subject: [PATCH] Fixes removal of `all` from sudorule categories.

This patch allows the removal of option `all` from user, host, group,
runasuser, and runasgroup categories, by allowing an empty string as
a valid choice for each option.
---
 README-sudorule.md                          |  10 +-
 plugins/modules/ipasudorule.py              |  27 +--
 tests/sudorule/test_sudorule_categories.yml | 182 ++++++++++++++++++++
 3 files changed, 204 insertions(+), 15 deletions(-)
 create mode 100644 tests/sudorule/test_sudorule_categories.yml

diff --git a/README-sudorule.md b/README-sudorule.md
index 4bec5e65..daa6c0a3 100644
--- a/README-sudorule.md
+++ b/README-sudorule.md
@@ -122,11 +122,11 @@ Variable | Description | Required
 `ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
 `name` \| `cn` | The list of sudorule name strings. | yes
 `description` | The sudorule description string. | no
-`usercategory` | User category the rule applies to. Choices: ["all"] | no
-`hostcategory` | Host category the rule applies to. Choices: ["all"] | no
-`cmdcategory` | Command category the rule applies to. Choices: ["all"] | no
-`runasusercategory` | RunAs User category the rule applies to. Choices: ["all"] | no
-`runasgroupcategory` | RunAs Group category the rule applies to. Choices: ["all"] | no
+`usercategory` \| `usercat` | User category the rule applies to. Choices: ["all", ""] | no
+`hostcategory` \| `hostcat` | Host category the rule applies to. Choices: ["all", ""] | no
+`cmdcategory` \| `cmdcat` | Command category the rule applies to. Choices: ["all", ""] | no
+`runasusercategory` \| `rusasusercat` | RunAs User category the rule applies to. Choices: ["all", ""] | no
+`runasgroupcategory` \| `runasgroupcat` | RunAs Group category the rule applies to. Choices: ["all", ""] | no
 `nomembers` | Suppress processing of membership attributes. (bool) | no
 `host` | List of host name strings assigned to this sudorule. | no
 `hostgroup` | List of host group name strings assigned to this sudorule. | no
diff --git a/plugins/modules/ipasudorule.py b/plugins/modules/ipasudorule.py
index 24d0d7ee..72c5a73b 100644
--- a/plugins/modules/ipasudorule.py
+++ b/plugins/modules/ipasudorule.py
@@ -51,18 +51,21 @@ options:
   usercategory:
     description: User category the sudo rule applies to
     required: false
-    choices: ["all"]
+    choices: ["all", ""]
+    aliases: ["usercat"]
   usergroup:
     description: List of user groups assigned to the sudo rule.
     required: false
   runasgroupcategory:
     description: RunAs Group category applied to the sudo rule.
     required: false
-    choices: ["all"]
+    choices: ["all", ""]
+    aliases: ["runasgroupcat"]
   runasusercategory:
     description: RunAs User category applied to the sudorule.
     required: false
-    choices: ["all"]
+    choices: ["all", ""]
+    aliases: ["runasusercat"]
   nomembers:
     description: Suppress processing of membership attributes
     required: false
@@ -78,7 +81,8 @@ options:
   hostcategory:
     description: Host category the sudo rule applies to.
     required: false
-    choices: ["all"]
+    choices: ["all", ""]
+    aliases: ["hostcat"]
   allow_sudocmd:
     description: List of allowed sudocmds assigned to this sudorule.
     required: false
@@ -98,7 +102,8 @@ options:
   cmdcategory:
     description: Command category the sudo rule applies to
     required: false
-    choices: ["all"]
+    choices: ["all", ""]
+    aliases: ["cmdcat"]
   order:
     description: Order to apply this rule.
     required: false
@@ -241,9 +246,9 @@ def main():
             # present
             description=dict(required=False, type="str", default=None),
             usercategory=dict(required=False, type="str", default=None,
-                              choices=["all"]),
+                              choices=["all", ""], aliases=['usercat']),
             hostcategory=dict(required=False, type="str", default=None,
-                              choices=["all"]),
+                              choices=["all", ""], aliases=['hostcat']),
             nomembers=dict(required=False, type='bool', default=None),
             host=dict(required=False, type='list', default=None),
             hostgroup=dict(required=False, type='list', default=None),
@@ -254,11 +259,13 @@ def main():
             allow_sudocmdgroup=dict(required=False, type="list", default=None),
             deny_sudocmdgroup=dict(required=False, type="list", default=None),
             cmdcategory=dict(required=False, type="str", default=None,
-                             choices=["all"]),
+                             choices=["all", ""], aliases=['cmdcat']),
             runasusercategory=dict(required=False, type="str", default=None,
-                                   choices=["all"]),
+                                   choices=["all", ""],
+                                   aliases=['runasusercat']),
             runasgroupcategory=dict(required=False, type="str", default=None,
-                                    choices=["all"]),
+                                    choices=["all", ""],
+                                    aliases=['runasgroupcat']),
             runasuser=dict(required=False, type="list", default=None),
             runasgroup=dict(required=False, type="list", default=None),
             order=dict(type="int", required=False, aliases=['sudoorder']),
diff --git a/tests/sudorule/test_sudorule_categories.yml b/tests/sudorule/test_sudorule_categories.yml
new file mode 100644
index 00000000..c4aaeda6
--- /dev/null
+++ b/tests/sudorule/test_sudorule_categories.yml
@@ -0,0 +1,182 @@
+---
+- name: Test sudorule user category
+  hosts: ipaserver
+  become: true
+  gather_facts: false
+
+  tasks:
+
+  - name: Ensure sudorules are absent
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name:
+      - allusers
+      state: absent
+
+  - name: Ensure sudorule is present, with usercategory 'all'
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      usercategory: all
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with usercategory 'all', again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      usercategory: all
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with no usercategory.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      usercategory: ""
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with no usercategory, again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      usercategory: ""
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with hostcategory 'all'
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      hostcategory: all
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with hostcategory 'all', again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      hostcategory: all
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with no usercategory.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      hostcategory: ""
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with no hostcategory, again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      hostcategory: ""
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with cmdcategory 'all'
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      cmdcategory: all
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with cmdcategory 'all', again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      cmdcategory: all
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with no cmdcategory.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      cmdcategory: ""
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with no cmdcategory, again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      cmdcategory: ""
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with runasusercategory 'all'
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      runasusercategory: all
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with runasusercategory 'all', again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      runasusercategory: all
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with no runasusercategory.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      runasusercategory: ""
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with no runasusercategory, again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      runasusercategory: ""
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with runasgroupcategory 'all'
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      runasgroupcategory: all
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with runasgroupcategory 'all', again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      runasgroupcategory: all
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with no runasgroupcategory.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      runasgroupcategory: ""
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with no runasgroupcategory, again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      runasgroupcategory: ""
+    register: result
+    failed_when: result.changed
+
+  # cleanup
+  - name: Ensure sudorules are absent
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name:
+      - allusers
+      state: absent
-- 
GitLab