Blob Blame History Raw
From c2ba333b9681d008d9c528a79dbdd76ce11a3ecd Mon Sep 17 00:00:00 2001
From: Serhii Tsymbaliuk <stsymbal@redhat.com>
Date: Thu, 28 May 2020 08:47:49 +0200
Subject: [PATCH 01/22] WebUI: Fix "IPA Error 3007: RequirmentError" while
 adding idoverrideuser association

Add builder for association adder dialog which allows to override behavior of the component.
Replace default implementation with a custom one for idoverrideuser.
Replace text filter with 'ID view' select box in the idoverrideuser dialog.

Ticket: https://pagure.io/freeipa/issue/8335

Signed-off-by: Serhii Tsymbaliuk <stsymbal@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
 install/ui/src/freeipa/association.js | 13 ++++-
 install/ui/src/freeipa/dialog.js      | 73 ++++++++++++++++-----------
 install/ui/src/freeipa/group.js       | 14 +++++
 install/ui/src/freeipa/idviews.js     | 58 +++++++++++++++++++++
 ipaserver/plugins/internal.py         |  6 +++
 5 files changed, 133 insertions(+), 31 deletions(-)

diff --git a/install/ui/src/freeipa/association.js b/install/ui/src/freeipa/association.js
index f10ccb2a5..b083a79f9 100644
--- a/install/ui/src/freeipa/association.js
+++ b/install/ui/src/freeipa/association.js
@@ -25,6 +25,7 @@
 define([
     'dojo/_base/lang',
     'dojo/Deferred',
+    './builder',
     './metadata',
     './ipa',
     './jquery',
@@ -38,7 +39,7 @@ define([
     './facet',
     './search',
     './dialog'],
-        function(lang, Deferred, metadata_provider, IPA, $, metadata,
+        function(lang, Deferred, builder, metadata_provider, IPA, $, metadata,
                  navigation, phases, reg, rpc, su, text) {
 
 /**
@@ -1209,7 +1210,8 @@ exp.association_facet = IPA.association_facet = function (spec, no_init) {
 
         var pkeys = that.data.result.result[that.get_attribute_name()];
 
-        var dialog = IPA.association_adder_dialog({
+        var dialog = builder.build('association_adder_dialog', {
+            $type: that.other_entity.name,
             title: title,
             entity: that.entity,
             pkey: pkey,
@@ -1675,6 +1677,13 @@ IPA.attr_read_only_evaluator = function(spec) {
     return that;
 };
 
+// Create a registry for adder dialogs where key is name of 'other entity'.
+// It allows to override dialogs for some specific cases of association
+// creation.
+var dialog_builder = builder.get('association_adder_dialog');
+dialog_builder.factory = IPA.association_adder_dialog;
+reg.set('association_adder_dialog', dialog_builder.registry);
+
 phases.on('registration', function() {
     var w = reg.widget;
     var f = reg.field;
diff --git a/install/ui/src/freeipa/dialog.js b/install/ui/src/freeipa/dialog.js
index c153120df..d67d63b6d 100644
--- a/install/ui/src/freeipa/dialog.js
+++ b/install/ui/src/freeipa/dialog.js
@@ -919,35 +919,7 @@ IPA.adder_dialog = function(spec) {
             'class': 'input-group col-md-12 adder-dialog-top'
         }).appendTo(container);
 
-        var filter_placeholder = text.get('@i18n:association.filter_placeholder');
-        filter_placeholder = filter_placeholder.replace('${other_entity}',
-            that.other_entity.metadata.label);
-
-        that.filter_field = $('<input/>', {
-            type: 'text',
-            name: 'filter',
-            'class': 'form-control',
-            'placeholder': filter_placeholder,
-            keyup: function(event) {
-                if (event.keyCode === keys.ENTER) {
-                    that.search();
-                    return false;
-                }
-            }
-        }).appendTo(input_group);
-
-        var input_group_btn = $('<div/>', {
-            'class': 'input-group-btn'
-        }).appendTo(input_group);
-
-        that.find_button = IPA.button({
-            name: 'find',
-            label: '@i18n:buttons.filter',
-            click: function() {
-                that.search();
-                return false;
-            }
-        }).appendTo(input_group_btn);
+        that.filter_field = that.get_filter_field(input_group);
 
         var row = $('<div/>', { 'class': 'row adder-dialog-main'}).appendTo(container);
         //
@@ -1132,6 +1104,49 @@ IPA.adder_dialog = function(spec) {
         return that.filter_field.val();
     };
 
+    /**
+     * Return field for filtering available items
+     *
+     * Default implementation returns text input + "Filter" button.
+     * It can be overridden.
+     *
+     * @param {HTMLElement} input_group - container for a filter field
+     * @return {HTMLElement}
+     */
+    that.get_filter_field = function(input_group) {
+        var filter_placeholder = text.get(
+            '@i18n:association.filter_placeholder'
+        ).replace('${other_entity}', that.other_entity.metadata.label);
+
+        var filter_field = $('<input/>', {
+            type: 'text',
+            name: 'filter',
+            'class': 'form-control',
+            'placeholder': filter_placeholder,
+            keyup: function(event) {
+                if (event.keyCode === keys.ENTER) {
+                    that.search();
+                    return false;
+                }
+            }
+        }).appendTo(input_group);
+
+        var input_group_btn = $('<div/>', {
+            'class': 'input-group-btn'
+        }).appendTo(input_group);
+
+        that.find_button = IPA.button({
+            name: 'find',
+            label: '@i18n:buttons.filter',
+            click: function() {
+                that.search();
+                return false;
+            }
+        }).appendTo(input_group_btn);
+
+        return filter_field;
+    };
+
     /**
      * Clear rows in available table
      */
diff --git a/install/ui/src/freeipa/group.js b/install/ui/src/freeipa/group.js
index e46d8c7e3..2984bd4b2 100644
--- a/install/ui/src/freeipa/group.js
+++ b/install/ui/src/freeipa/group.js
@@ -205,6 +205,20 @@ return {
             add_title: '@i18n:objects.group.add_into_sudo',
             remove_method: 'remove_user',
             remove_title: '@i18n:objects.group.remove_from_sudo'
+        },
+        {
+            $type: 'association',
+            name: 'member_idoverrideuser',
+            associator: IPA.serial_associator,
+            add_title: '@i18n:objects.group.add_idoverride_user',
+            remove_title: '@i18n:objects.group.remove_idoverride_users',
+            columns: [
+                {
+                    name: 'ipaanchoruuid',
+                    label: '@i18n:objects.idoverrideuser.anchor_label',
+                    link: false
+                }
+            ]
         }
     ],
     standard_association_facets: true,
diff --git a/install/ui/src/freeipa/idviews.js b/install/ui/src/freeipa/idviews.js
index 35dc998c8..a4fca6205 100644
--- a/install/ui/src/freeipa/idviews.js
+++ b/install/ui/src/freeipa/idviews.js
@@ -966,6 +966,58 @@ idviews.unapply_action = function(spec) {
     return that;
 };
 
+idviews.idoverrideuser_adder_dialog = function(spec) {
+
+    spec = spec || {};
+
+    var that = IPA.association_adder_dialog(spec);
+
+    that.base_search = that.search;
+
+    that.search = function() {
+        // Search for users only in case a ID view is selected
+        if (that.get_filter()) {
+            that.base_search();
+        }
+    };
+
+    /**
+     * Replace default text filter with a select box for filtering by ID view
+     */
+    that.get_filter_field = function(input_group) {
+
+        var filter_field = $('<select/>', {
+            name: 'filter',
+            'class': 'form-control',
+            change: function(event) {
+                that.search();
+            }
+        }).appendTo(input_group);
+
+        rpc.command({
+            entity: 'idview',
+            method: 'find',
+            on_success: function(data) {
+                var results = data.result;
+
+                for (var i=0; i<results.count; i++) {
+                    var result = results.result[i];
+                    $('<option/>', {
+                        text: result.cn[0],
+                        value: result.cn[0]
+                    }).appendTo(filter_field);
+                }
+
+                that.search();
+            }
+        }).execute();
+
+        return filter_field;
+    };
+
+    return that;
+};
+
 /**
  * ID View entity specification object
  * @member idviews
@@ -993,6 +1045,7 @@ idviews.register = function() {
     var f = reg.facet;
     var a = reg.action;
     var w = reg.widget;
+    var ad = reg.association_adder_dialog;
 
     e.register({type: 'idview', spec: idviews.spec});
     e.register({
@@ -1012,6 +1065,11 @@ idviews.register = function() {
 
     w.register('idviews_certs', idviews.idviews_certs_widget);
     w.register('cert_textarea', idviews.cert_textarea_widget);
+
+    ad.register({
+        type: 'idoverrideuser',
+        factory: idviews.idoverrideuser_adder_dialog
+    });
 };
 
 phases.on('registration', idviews.register);
diff --git a/ipaserver/plugins/internal.py b/ipaserver/plugins/internal.py
index 5f2b1fdc2..7622e65dc 100644
--- a/ipaserver/plugins/internal.py
+++ b/ipaserver/plugins/internal.py
@@ -835,6 +835,9 @@ class i18n_messages(Command):
                     "Remove users from member managers for user group "
                     "'${primary_key}'"
                 ),
+                "add_idoverride_user": _(
+                    "Add user ID override into user group '${primary_key}'"
+                ),
                 "details": _("Group Settings"),
                 "external": _("External"),
                 "groups": _("Groups"),
@@ -868,6 +871,9 @@ class i18n_messages(Command):
                 "remove_users": _(
                     "Remove users from user group '${primary_key}'"
                 ),
+                "remove_idoverride_users": _(
+                    "Remove user ID overrides from user group '${primary_key}'"
+                ),
                 "type": _("Group Type"),
                 "user_groups": _("User Groups"),
             },
-- 
2.26.2

From f6c460aee8542d4d81cd9970d71051c240156973 Mon Sep 17 00:00:00 2001
From: Serhii Tsymbaliuk <stsymbal@redhat.com>
Date: Thu, 16 Jul 2020 18:52:24 +0200
Subject: [PATCH] WebUI: Fix error "unknown command
 'idoverrideuser_add_member'"

There was wrong IPA.associator class used for 'Groups' -> 'User ID overrides' association,
as a result a wrong command was sent to the server.

Ticket: https://pagure.io/freeipa/issue/8416

Signed-off-by: Serhii Tsymbaliuk <stsymbal@redhat.com>
Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
 install/ui/src/freeipa/group.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/install/ui/src/freeipa/group.js b/install/ui/src/freeipa/group.js
index 2984bd4b2..61c19a82f 100644
--- a/install/ui/src/freeipa/group.js
+++ b/install/ui/src/freeipa/group.js
@@ -209,7 +209,6 @@ return {
         {
             $type: 'association',
             name: 'member_idoverrideuser',
-            associator: IPA.serial_associator,
             add_title: '@i18n:objects.group.add_idoverride_user',
             remove_title: '@i18n:objects.group.remove_idoverride_users',
             columns: [
-- 
2.26.2

From e35739b7e9f6bb016b37abbd92bdaee71a59a288 Mon Sep 17 00:00:00 2001
From: Serhii Tsymbaliuk <stsymbal@redhat.com>
Date: Wed, 29 Jul 2020 09:41:36 +0200
Subject: [PATCH] WebUI tests: Add test case to cover user ID override feature

The test case includes adding an user ID override to Default Trust View
and adding the ID override to some IPA group.

Ticket: https://pagure.io/freeipa/issue/8416

Signed-off-by: Serhii Tsymbaliuk <stsymbal@redhat.com>
Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
 ipatests/test_webui/test_trust.py | 41 +++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/ipatests/test_webui/test_trust.py b/ipatests/test_webui/test_trust.py
index c04c2fcd8..605f8a2a7 100644
--- a/ipatests/test_webui/test_trust.py
+++ b/ipatests/test_webui/test_trust.py
@@ -21,6 +21,8 @@
 Trust tests
 """
 
+import ipatests.test_webui.data_group as group
+import ipatests.test_webui.data_idviews as idview
 from ipatests.test_webui.ui_driver import UI_driver
 from ipatests.test_webui.ui_driver import screenshot
 from ipatests.test_webui.task_range import range_tasks
@@ -29,6 +31,8 @@ import pytest
 ENTITY = 'trust'
 CONFIG_ENTITY = 'trustconfig'
 
+DEFAULT_TRUST_VIEW = 'Default Trust View'
+
 CONFIG_DATA = {
     'mod': [
         ['combobox', 'ipantfallbackprimarygroup', 'admins'],
@@ -164,3 +168,40 @@ class test_trust(trust_tasks):
 
         self.mod_record(CONFIG_ENTITY, CONFIG_DATA)
         self.mod_record(CONFIG_ENTITY, CONFIG_DATA2)
+
+    @screenshot
+    def test_group_member_idoverrideuser(self):
+
+        self.init_app()
+
+        # Create new trust
+        data = self.get_data()
+        self.add_record(ENTITY, data)
+
+        # Create an user ID override
+        ad_domain = self.config.get('ad_domain')
+        ad_admin = self.config.get('ad_admin')
+        idoverrideuser_pkey = '{}@{}'.format(ad_admin, ad_domain).lower()
+
+        self.navigate_to_record(DEFAULT_TRUST_VIEW, entity=idview.ENTITY)
+        self.add_record(idview.ENTITY, {
+            'pkey': idoverrideuser_pkey,
+            'add': [
+                ('textbox', 'ipaanchoruuid_default', idoverrideuser_pkey),
+            ],
+        }, facet='idoverrideuser')
+
+        # Create new group and add the user ID override there
+        self.navigate_to_entity(group.ENTITY)
+        self.add_record(group.ENTITY, group.DATA)
+        self.navigate_to_record(group.PKEY)
+        self.add_associations([idoverrideuser_pkey],
+                              facet='member_idoverrideuser', delete=True)
+
+        # Clean up data
+        self.navigate_to_entity(group.ENTITY)
+        self.delete_record(group.PKEY)
+        self.navigate_to_record(DEFAULT_TRUST_VIEW, entity=idview.ENTITY)
+        self.delete_record(idoverrideuser_pkey)
+        self.navigate_to_entity(ENTITY)
+        self.delete_record(ad_domain)
-- 
2.26.2