Blame SOURCES/0001-WebUI-Fix-IPA-Error-3007-RequirmentError-while-addin_rhbz#1757045.patch

f7c668
From c2ba333b9681d008d9c528a79dbdd76ce11a3ecd Mon Sep 17 00:00:00 2001
f7c668
From: Serhii Tsymbaliuk <stsymbal@redhat.com>
f7c668
Date: Thu, 28 May 2020 08:47:49 +0200
f7c668
Subject: [PATCH 01/22] WebUI: Fix "IPA Error 3007: RequirmentError" while
f7c668
 adding idoverrideuser association
f7c668
f7c668
Add builder for association adder dialog which allows to override behavior of the component.
f7c668
Replace default implementation with a custom one for idoverrideuser.
f7c668
Replace text filter with 'ID view' select box in the idoverrideuser dialog.
f7c668
f7c668
Ticket: https://pagure.io/freeipa/issue/8335
f7c668
f7c668
Signed-off-by: Serhii Tsymbaliuk <stsymbal@redhat.com>
f7c668
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
f7c668
---
f7c668
 install/ui/src/freeipa/association.js | 13 ++++-
f7c668
 install/ui/src/freeipa/dialog.js      | 73 ++++++++++++++++-----------
f7c668
 install/ui/src/freeipa/group.js       | 14 +++++
f7c668
 install/ui/src/freeipa/idviews.js     | 58 +++++++++++++++++++++
f7c668
 ipaserver/plugins/internal.py         |  6 +++
f7c668
 5 files changed, 133 insertions(+), 31 deletions(-)
f7c668
f7c668
diff --git a/install/ui/src/freeipa/association.js b/install/ui/src/freeipa/association.js
f7c668
index f10ccb2a5..b083a79f9 100644
f7c668
--- a/install/ui/src/freeipa/association.js
f7c668
+++ b/install/ui/src/freeipa/association.js
f7c668
@@ -25,6 +25,7 @@
f7c668
 define([
f7c668
     'dojo/_base/lang',
f7c668
     'dojo/Deferred',
f7c668
+    './builder',
f7c668
     './metadata',
f7c668
     './ipa',
f7c668
     './jquery',
f7c668
@@ -38,7 +39,7 @@ define([
f7c668
     './facet',
f7c668
     './search',
f7c668
     './dialog'],
f7c668
-        function(lang, Deferred, metadata_provider, IPA, $, metadata,
f7c668
+        function(lang, Deferred, builder, metadata_provider, IPA, $, metadata,
f7c668
                  navigation, phases, reg, rpc, su, text) {
f7c668
 
f7c668
 /**
f7c668
@@ -1209,7 +1210,8 @@ exp.association_facet = IPA.association_facet = function (spec, no_init) {
f7c668
 
f7c668
         var pkeys = that.data.result.result[that.get_attribute_name()];
f7c668
 
f7c668
-        var dialog = IPA.association_adder_dialog({
f7c668
+        var dialog = builder.build('association_adder_dialog', {
f7c668
+            $type: that.other_entity.name,
f7c668
             title: title,
f7c668
             entity: that.entity,
f7c668
             pkey: pkey,
f7c668
@@ -1675,6 +1677,13 @@ IPA.attr_read_only_evaluator = function(spec) {
f7c668
     return that;
f7c668
 };
f7c668
 
f7c668
+// Create a registry for adder dialogs where key is name of 'other entity'.
f7c668
+// It allows to override dialogs for some specific cases of association
f7c668
+// creation.
f7c668
+var dialog_builder = builder.get('association_adder_dialog');
f7c668
+dialog_builder.factory = IPA.association_adder_dialog;
f7c668
+reg.set('association_adder_dialog', dialog_builder.registry);
f7c668
+
f7c668
 phases.on('registration', function() {
f7c668
     var w = reg.widget;
f7c668
     var f = reg.field;
f7c668
diff --git a/install/ui/src/freeipa/dialog.js b/install/ui/src/freeipa/dialog.js
f7c668
index c153120df..d67d63b6d 100644
f7c668
--- a/install/ui/src/freeipa/dialog.js
f7c668
+++ b/install/ui/src/freeipa/dialog.js
f7c668
@@ -919,35 +919,7 @@ IPA.adder_dialog = function(spec) {
f7c668
             'class': 'input-group col-md-12 adder-dialog-top'
f7c668
         }).appendTo(container);
f7c668
 
f7c668
-        var filter_placeholder = text.get('@i18n:association.filter_placeholder');
f7c668
-        filter_placeholder = filter_placeholder.replace('${other_entity}',
f7c668
-            that.other_entity.metadata.label);
f7c668
-
f7c668
-        that.filter_field = $('<input/>', {
f7c668
-            type: 'text',
f7c668
-            name: 'filter',
f7c668
-            'class': 'form-control',
f7c668
-            'placeholder': filter_placeholder,
f7c668
-            keyup: function(event) {
f7c668
-                if (event.keyCode === keys.ENTER) {
f7c668
-                    that.search();
f7c668
-                    return false;
f7c668
-                }
f7c668
-            }
f7c668
-        }).appendTo(input_group);
f7c668
-
f7c668
-        var input_group_btn = $('
', {
f7c668
-            'class': 'input-group-btn'
f7c668
-        }).appendTo(input_group);
f7c668
-
f7c668
-        that.find_button = IPA.button({
f7c668
-            name: 'find',
f7c668
-            label: '@i18n:buttons.filter',
f7c668
-            click: function() {
f7c668
-                that.search();
f7c668
-                return false;
f7c668
-            }
f7c668
-        }).appendTo(input_group_btn);
f7c668
+        that.filter_field = that.get_filter_field(input_group);
f7c668
 
f7c668
         var row = $('
', { 'class': 'row adder-dialog-main'}).appendTo(container);
f7c668
         //
f7c668
@@ -1132,6 +1104,49 @@ IPA.adder_dialog = function(spec) {
f7c668
         return that.filter_field.val();
f7c668
     };
f7c668
 
f7c668
+    /**
f7c668
+     * Return field for filtering available items
f7c668
+     *
f7c668
+     * Default implementation returns text input + "Filter" button.
f7c668
+     * It can be overridden.
f7c668
+     *
f7c668
+     * @param {HTMLElement} input_group - container for a filter field
f7c668
+     * @return {HTMLElement}
f7c668
+     */
f7c668
+    that.get_filter_field = function(input_group) {
f7c668
+        var filter_placeholder = text.get(
f7c668
+            '@i18n:association.filter_placeholder'
f7c668
+        ).replace('${other_entity}', that.other_entity.metadata.label);
f7c668
+
f7c668
+        var filter_field = $('<input/>', {
f7c668
+            type: 'text',
f7c668
+            name: 'filter',
f7c668
+            'class': 'form-control',
f7c668
+            'placeholder': filter_placeholder,
f7c668
+            keyup: function(event) {
f7c668
+                if (event.keyCode === keys.ENTER) {
f7c668
+                    that.search();
f7c668
+                    return false;
f7c668
+                }
f7c668
+            }
f7c668
+        }).appendTo(input_group);
f7c668
+
f7c668
+        var input_group_btn = $('
', {
f7c668
+            'class': 'input-group-btn'
f7c668
+        }).appendTo(input_group);
f7c668
+
f7c668
+        that.find_button = IPA.button({
f7c668
+            name: 'find',
f7c668
+            label: '@i18n:buttons.filter',
f7c668
+            click: function() {
f7c668
+                that.search();
f7c668
+                return false;
f7c668
+            }
f7c668
+        }).appendTo(input_group_btn);
f7c668
+
f7c668
+        return filter_field;
f7c668
+    };
f7c668
+
f7c668
     /**
f7c668
      * Clear rows in available table
f7c668
      */
f7c668
diff --git a/install/ui/src/freeipa/group.js b/install/ui/src/freeipa/group.js
f7c668
index e46d8c7e3..2984bd4b2 100644
f7c668
--- a/install/ui/src/freeipa/group.js
f7c668
+++ b/install/ui/src/freeipa/group.js
f7c668
@@ -205,6 +205,20 @@ return {
f7c668
             add_title: '@i18n:objects.group.add_into_sudo',
f7c668
             remove_method: 'remove_user',
f7c668
             remove_title: '@i18n:objects.group.remove_from_sudo'
f7c668
+        },
f7c668
+        {
f7c668
+            $type: 'association',
f7c668
+            name: 'member_idoverrideuser',
f7c668
+            associator: IPA.serial_associator,
f7c668
+            add_title: '@i18n:objects.group.add_idoverride_user',
f7c668
+            remove_title: '@i18n:objects.group.remove_idoverride_users',
f7c668
+            columns: [
f7c668
+                {
f7c668
+                    name: 'ipaanchoruuid',
f7c668
+                    label: '@i18n:objects.idoverrideuser.anchor_label',
f7c668
+                    link: false
f7c668
+                }
f7c668
+            ]
f7c668
         }
f7c668
     ],
f7c668
     standard_association_facets: true,
f7c668
diff --git a/install/ui/src/freeipa/idviews.js b/install/ui/src/freeipa/idviews.js
f7c668
index 35dc998c8..a4fca6205 100644
f7c668
--- a/install/ui/src/freeipa/idviews.js
f7c668
+++ b/install/ui/src/freeipa/idviews.js
f7c668
@@ -966,6 +966,58 @@ idviews.unapply_action = function(spec) {
f7c668
     return that;
f7c668
 };
f7c668
 
f7c668
+idviews.idoverrideuser_adder_dialog = function(spec) {
f7c668
+
f7c668
+    spec = spec || {};
f7c668
+
f7c668
+    var that = IPA.association_adder_dialog(spec);
f7c668
+
f7c668
+    that.base_search = that.search;
f7c668
+
f7c668
+    that.search = function() {
f7c668
+        // Search for users only in case a ID view is selected
f7c668
+        if (that.get_filter()) {
f7c668
+            that.base_search();
f7c668
+        }
f7c668
+    };
f7c668
+
f7c668
+    /**
f7c668
+     * Replace default text filter with a select box for filtering by ID view
f7c668
+     */
f7c668
+    that.get_filter_field = function(input_group) {
f7c668
+
f7c668
+        var filter_field = $('<select/>', {
f7c668
+            name: 'filter',
f7c668
+            'class': 'form-control',
f7c668
+            change: function(event) {
f7c668
+                that.search();
f7c668
+            }
f7c668
+        }).appendTo(input_group);
f7c668
+
f7c668
+        rpc.command({
f7c668
+            entity: 'idview',
f7c668
+            method: 'find',
f7c668
+            on_success: function(data) {
f7c668
+                var results = data.result;
f7c668
+
f7c668
+                for (var i=0; i
f7c668
+                    var result = results.result[i];
f7c668
+                    $('<option/>', {
f7c668
+                        text: result.cn[0],
f7c668
+                        value: result.cn[0]
f7c668
+                    }).appendTo(filter_field);
f7c668
+                }
f7c668
+
f7c668
+                that.search();
f7c668
+            }
f7c668
+        }).execute();
f7c668
+
f7c668
+        return filter_field;
f7c668
+    };
f7c668
+
f7c668
+    return that;
f7c668
+};
f7c668
+
f7c668
 /**
f7c668
  * ID View entity specification object
f7c668
  * @member idviews
f7c668
@@ -993,6 +1045,7 @@ idviews.register = function() {
f7c668
     var f = reg.facet;
f7c668
     var a = reg.action;
f7c668
     var w = reg.widget;
f7c668
+    var ad = reg.association_adder_dialog;
f7c668
 
f7c668
     e.register({type: 'idview', spec: idviews.spec});
f7c668
     e.register({
f7c668
@@ -1012,6 +1065,11 @@ idviews.register = function() {
f7c668
 
f7c668
     w.register('idviews_certs', idviews.idviews_certs_widget);
f7c668
     w.register('cert_textarea', idviews.cert_textarea_widget);
f7c668
+
f7c668
+    ad.register({
f7c668
+        type: 'idoverrideuser',
f7c668
+        factory: idviews.idoverrideuser_adder_dialog
f7c668
+    });
f7c668
 };
f7c668
 
f7c668
 phases.on('registration', idviews.register);
f7c668
diff --git a/ipaserver/plugins/internal.py b/ipaserver/plugins/internal.py
f7c668
index 5f2b1fdc2..7622e65dc 100644
f7c668
--- a/ipaserver/plugins/internal.py
f7c668
+++ b/ipaserver/plugins/internal.py
f7c668
@@ -835,6 +835,9 @@ class i18n_messages(Command):
f7c668
                     "Remove users from member managers for user group "
f7c668
                     "'${primary_key}'"
f7c668
                 ),
f7c668
+                "add_idoverride_user": _(
f7c668
+                    "Add user ID override into user group '${primary_key}'"
f7c668
+                ),
f7c668
                 "details": _("Group Settings"),
f7c668
                 "external": _("External"),
f7c668
                 "groups": _("Groups"),
f7c668
@@ -868,6 +871,9 @@ class i18n_messages(Command):
f7c668
                 "remove_users": _(
f7c668
                     "Remove users from user group '${primary_key}'"
f7c668
                 ),
f7c668
+                "remove_idoverride_users": _(
f7c668
+                    "Remove user ID overrides from user group '${primary_key}'"
f7c668
+                ),
f7c668
                 "type": _("Group Type"),
f7c668
                 "user_groups": _("User Groups"),
f7c668
             },
f7c668
-- 
f7c668
2.26.2
f7c668
3ed92b
From f6c460aee8542d4d81cd9970d71051c240156973 Mon Sep 17 00:00:00 2001
3ed92b
From: Serhii Tsymbaliuk <stsymbal@redhat.com>
3ed92b
Date: Thu, 16 Jul 2020 18:52:24 +0200
3ed92b
Subject: [PATCH] WebUI: Fix error "unknown command
3ed92b
 'idoverrideuser_add_member'"
3ed92b
3ed92b
There was wrong IPA.associator class used for 'Groups' -> 'User ID overrides' association,
3ed92b
as a result a wrong command was sent to the server.
3ed92b
3ed92b
Ticket: https://pagure.io/freeipa/issue/8416
3ed92b
3ed92b
Signed-off-by: Serhii Tsymbaliuk <stsymbal@redhat.com>
3ed92b
Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
3ed92b
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
3ed92b
---
3ed92b
 install/ui/src/freeipa/group.js | 1 -
3ed92b
 1 file changed, 1 deletion(-)
3ed92b
3ed92b
diff --git a/install/ui/src/freeipa/group.js b/install/ui/src/freeipa/group.js
3ed92b
index 2984bd4b2..61c19a82f 100644
3ed92b
--- a/install/ui/src/freeipa/group.js
3ed92b
+++ b/install/ui/src/freeipa/group.js
3ed92b
@@ -209,7 +209,6 @@ return {
3ed92b
         {
3ed92b
             $type: 'association',
3ed92b
             name: 'member_idoverrideuser',
3ed92b
-            associator: IPA.serial_associator,
3ed92b
             add_title: '@i18n:objects.group.add_idoverride_user',
3ed92b
             remove_title: '@i18n:objects.group.remove_idoverride_users',
3ed92b
             columns: [
3ed92b
-- 
3ed92b
2.26.2
3ed92b
3ed92b
From e35739b7e9f6bb016b37abbd92bdaee71a59a288 Mon Sep 17 00:00:00 2001
3ed92b
From: Serhii Tsymbaliuk <stsymbal@redhat.com>
3ed92b
Date: Wed, 29 Jul 2020 09:41:36 +0200
3ed92b
Subject: [PATCH] WebUI tests: Add test case to cover user ID override feature
3ed92b
3ed92b
The test case includes adding an user ID override to Default Trust View
3ed92b
and adding the ID override to some IPA group.
3ed92b
3ed92b
Ticket: https://pagure.io/freeipa/issue/8416
3ed92b
3ed92b
Signed-off-by: Serhii Tsymbaliuk <stsymbal@redhat.com>
3ed92b
Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
3ed92b
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
3ed92b
---
3ed92b
 ipatests/test_webui/test_trust.py | 41 +++++++++++++++++++++++++++++++
3ed92b
 1 file changed, 41 insertions(+)
3ed92b
3ed92b
diff --git a/ipatests/test_webui/test_trust.py b/ipatests/test_webui/test_trust.py
3ed92b
index c04c2fcd8..605f8a2a7 100644
3ed92b
--- a/ipatests/test_webui/test_trust.py
3ed92b
+++ b/ipatests/test_webui/test_trust.py
3ed92b
@@ -21,6 +21,8 @@
3ed92b
 Trust tests
3ed92b
 """
3ed92b
 
3ed92b
+import ipatests.test_webui.data_group as group
3ed92b
+import ipatests.test_webui.data_idviews as idview
3ed92b
 from ipatests.test_webui.ui_driver import UI_driver
3ed92b
 from ipatests.test_webui.ui_driver import screenshot
3ed92b
 from ipatests.test_webui.task_range import range_tasks
3ed92b
@@ -29,6 +31,8 @@ import pytest
3ed92b
 ENTITY = 'trust'
3ed92b
 CONFIG_ENTITY = 'trustconfig'
3ed92b
 
3ed92b
+DEFAULT_TRUST_VIEW = 'Default Trust View'
3ed92b
+
3ed92b
 CONFIG_DATA = {
3ed92b
     'mod': [
3ed92b
         ['combobox', 'ipantfallbackprimarygroup', 'admins'],
3ed92b
@@ -164,3 +168,40 @@ class test_trust(trust_tasks):
3ed92b
 
3ed92b
         self.mod_record(CONFIG_ENTITY, CONFIG_DATA)
3ed92b
         self.mod_record(CONFIG_ENTITY, CONFIG_DATA2)
3ed92b
+
3ed92b
+    @screenshot
3ed92b
+    def test_group_member_idoverrideuser(self):
3ed92b
+
3ed92b
+        self.init_app()
3ed92b
+
3ed92b
+        # Create new trust
3ed92b
+        data = self.get_data()
3ed92b
+        self.add_record(ENTITY, data)
3ed92b
+
3ed92b
+        # Create an user ID override
3ed92b
+        ad_domain = self.config.get('ad_domain')
3ed92b
+        ad_admin = self.config.get('ad_admin')
3ed92b
+        idoverrideuser_pkey = '{}@{}'.format(ad_admin, ad_domain).lower()
3ed92b
+
3ed92b
+        self.navigate_to_record(DEFAULT_TRUST_VIEW, entity=idview.ENTITY)
3ed92b
+        self.add_record(idview.ENTITY, {
3ed92b
+            'pkey': idoverrideuser_pkey,
3ed92b
+            'add': [
3ed92b
+                ('textbox', 'ipaanchoruuid_default', idoverrideuser_pkey),
3ed92b
+            ],
3ed92b
+        }, facet='idoverrideuser')
3ed92b
+
3ed92b
+        # Create new group and add the user ID override there
3ed92b
+        self.navigate_to_entity(group.ENTITY)
3ed92b
+        self.add_record(group.ENTITY, group.DATA)
3ed92b
+        self.navigate_to_record(group.PKEY)
3ed92b
+        self.add_associations([idoverrideuser_pkey],
3ed92b
+                              facet='member_idoverrideuser', delete=True)
3ed92b
+
3ed92b
+        # Clean up data
3ed92b
+        self.navigate_to_entity(group.ENTITY)
3ed92b
+        self.delete_record(group.PKEY)
3ed92b
+        self.navigate_to_record(DEFAULT_TRUST_VIEW, entity=idview.ENTITY)
3ed92b
+        self.delete_record(idoverrideuser_pkey)
3ed92b
+        self.navigate_to_entity(ENTITY)
3ed92b
+        self.delete_record(ad_domain)
3ed92b
-- 
3ed92b
2.26.2
3ed92b