URL: https://github.com/freeipa/freeipa/pull/639
Author: pvomacka
 Title: #639: WebUI: Login for AD Users
Action: opened

PR body:
"""
Allows login as AD user. AD Users has its own menu specification as there is 
visible only its profile and list of active IPA users. 

https://pagure.io/freeipa/issue/3242
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/639/head:pr639
git checkout pr639
From 79a2dbfd1459ff4f1e95cbc547625222efa6beb1 Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvoma...@redhat.com>
Date: Wed, 22 Mar 2017 16:39:21 +0100
Subject: [PATCH 1/3] WebUI: check principals in lowercase

WebUI checks whether principal name of logged user and principal name
in each command is equal. As KDC for our principals is case insensitive
- it does make sense to switch this check also into case insensitive.
So both principals are reformated to lower case and then
compared.

Part of: https://pagure.io/freeipa/issue/3242
---
 install/ui/src/freeipa/rpc.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/install/ui/src/freeipa/rpc.js b/install/ui/src/freeipa/rpc.js
index 7ae1b64..1880f8d 100644
--- a/install/ui/src/freeipa/rpc.js
+++ b/install/ui/src/freeipa/rpc.js
@@ -389,7 +389,8 @@ rpc.command = function(spec) {
             } else if (IPA.version && data.version && IPA.version !== data.version) {
                 window.location.reload();
 
-            } else if (IPA.principal && data.principal && IPA.principal !== data.principal) {
+            } else if (IPA.principal && data.principal &&
+                IPA.principal.toLowerCase() !== data.principal.toLowerCase()) {
                 window.location.reload();
 
             } else if (data.error) {

From 6660dd17632190c534e5aa0844d1fbf18f90964b Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvoma...@redhat.com>
Date: Wed, 22 Mar 2017 16:48:36 +0100
Subject: [PATCH 2/3] WebUI: add method for disabling item in user dropdown
 menu

AD user can do only several things. One of those which are not
allowed is to reset password to itself. Therefore we need to be
able to turn of a item in dropdown menu. In our case
'Password reset' item. Function which disable menu item and detach
the listener on click from the item specified by its name was added.

Part of: https://pagure.io/freeipa/issue/3242
---
 install/ui/src/freeipa/Application_controller.js | 40 ++++++++++++++++++++----
 install/ui/src/freeipa/widgets/App.js            |  4 +++
 2 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/install/ui/src/freeipa/Application_controller.js b/install/ui/src/freeipa/Application_controller.js
index 32add5f..6c7da8b 100644
--- a/install/ui/src/freeipa/Application_controller.js
+++ b/install/ui/src/freeipa/Application_controller.js
@@ -69,6 +69,16 @@ define([
         facet_changing: false,
 
         /**
+         * Listeners for user menu items
+         */
+         on_profile_listener: null,
+         on_passwd_reset_listener: null,
+         on_logout_listener: null,
+         on_item_select_listener: null,
+         on_configuration_listerer: null,
+         on_about_listener: null,
+
+        /**
          * Currently displayed facet
          *
          */
@@ -109,12 +119,7 @@ define([
                 }
             };
 
-            on(this.app_widget.menu_widget, 'item-select', this.on_menu_click.bind(this));
-            on(this.app_widget, 'profile-click', this.on_profile.bind(this));
-            on(this.app_widget, 'logout-click', this.on_logout.bind(this));
-            on(this.app_widget, 'password-reset-click', this.on_password_reset.bind(this));
-            on(this.app_widget, 'configuration-click', this.on_configuration.bind(this));
-            on(this.app_widget, 'about-click', this.on_about.bind(this));
+            this.register_user_menu_listeners();
 
             on(this.router, 'facet-show', this.on_facet_show.bind(this));
             on(this.router, 'facet-change', this.on_facet_change.bind(this));
@@ -133,6 +138,29 @@ define([
             IPA.opened_dialogs.start_handling(this);
         },
 
+        register_user_menu_listeners: function() {
+            this.on_profile_listener = on(this.app_widget, 'profile-click',
+                    this.on_profile.bind(this));
+            this.on_passwd_reset_listener = on(this.app_widget,
+                    'password-reset-click', this.on_password_reset.bind(this));
+            this.on_logout_listener = on(this.app_widget, 'logout-click',
+                    this.on_logout.bind(this));
+            this.on_item_select_listener = on(this.app_widget.menu_widget,
+                    'item-select', this.on_menu_click.bind(this));
+            this.on_configuration_listerer = on(this.app_widget,
+                    'configuration-click', this.on_configuration.bind(this));
+            this.on_about_listener = on(this.app_widget,
+                    'about-click', this.on_about.bind(this));
+        },
+
+        /**
+         * Turns off one item in user dropdown menu and remove its listener.
+         */
+        disable_user_menu_item: function(name) {
+            this.app_widget.disable_user_menu_item(name);
+            this.on_passwd_reset_listener.remove();
+        },
+
         /**
          * Gets:
          *  * metadata
diff --git a/install/ui/src/freeipa/widgets/App.js b/install/ui/src/freeipa/widgets/App.js
index 68b78c7..95bc9b2 100644
--- a/install/ui/src/freeipa/widgets/App.js
+++ b/install/ui/src/freeipa/widgets/App.js
@@ -222,6 +222,10 @@ define(['dojo/_base/declare',
             }
         },
 
+        disable_user_menu_item: function(name) {
+            this.user_menu.disable_item(name);
+        },
+
         on_menu_item_click: function(item) {
             this.collapse_menu();
         },

From 32983c5178c0919e7a42536fa5d0bc5d0560b9c6 Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvoma...@redhat.com>
Date: Wed, 22 Mar 2017 16:54:33 +0100
Subject: [PATCH 3/3] WebUI: Add support for login for AD users

After login, method user-find --whoami was called which cannot be
called for AD users. That method was replaced by ipa whoami command
and sequential command according to result of ipa whoami. AD user
can now be logged in.

AD users have new menu definition which contains only list of IPA
users and profile page of AD user - "User ID Override".

This commit also fixes several places where IPA.whoami object was
used, because its structure was also changed. It now contains two
objects. First one is stored in 'metadata' property and stores
result from ipa whoami (type of object, command which should be
called for showing detailed data about currently logged entity, etc).
The second one is stored in 'data' property which stores result of
_show command for currently logged entity.

https://pagure.io/freeipa/issue/3242
---
 install/ui/src/freeipa/Application_controller.js | 46 +++++++++++++++++++-----
 install/ui/src/freeipa/idviews.js                | 20 ++++++++++-
 install/ui/src/freeipa/ipa.js                    | 44 +++++++++++++++--------
 install/ui/src/freeipa/navigation/menu_spec.js   |  8 +++++
 install/ui/src/freeipa/user.js                   |  5 +--
 5 files changed, 96 insertions(+), 27 deletions(-)

diff --git a/install/ui/src/freeipa/Application_controller.js b/install/ui/src/freeipa/Application_controller.js
index 6c7da8b..25ec03a 100644
--- a/install/ui/src/freeipa/Application_controller.js
+++ b/install/ui/src/freeipa/Application_controller.js
@@ -31,6 +31,7 @@ define([
         './widgets/App',
         './widgets/FacetContainer',
         './ipa',
+        './rpc',
         './reg',
         './config',
         './widget',
@@ -41,7 +42,7 @@ define([
         './plugins/load_page'
        ],
        function(declare, array, Deferred, on, topic, query, dom_class, auth,
-            JSON, App_widget, FacetContainer, IPA, reg, config, widget_mod,
+            JSON, App_widget, FacetContainer, IPA, rpc, reg, config, widget_mod,
             Menu, Router, routing, menu_spec) {
 
     /**
@@ -177,16 +178,21 @@ define([
          */
         choose_profile: function() {
 
-            // TODO: change IPA.whoami.cn[0] to something readable
-            this.update_logged_in(true, IPA.whoami.cn[0]);
+            this.update_logged_in(true);
             var selfservice = this.is_selfservice();
 
 
             this.app_widget.menu_widget.ignore_changes = true;
 
             if (selfservice) {
-                this.menu.name = menu_spec.self_service.name;
-                this.menu.add_items(menu_spec.self_service.items);
+                if (this.is_aduser_selfservice()) {
+                    this.menu.name = menu_spec.ad_self_service.name;
+                    this.menu.add_items(menu_spec.ad_self_service.items);
+                    this.disable_user_menu_item('password_reset');
+                } else {
+                    this.menu.name = menu_spec.self_service.name;
+                    this.menu.add_items(menu_spec.self_service.items);
+                }
             } else {
                 this.menu.name = menu_spec.admin.name;
                 this.menu.add_items(menu_spec.admin.items);
@@ -230,10 +236,9 @@ define([
         },
 
         is_selfservice: function() {
-            var whoami = IPA.whoami;
+            var whoami = IPA.whoami.data;
             var self_service = true;
 
-
             if (whoami.hasOwnProperty('memberof_group') &&
                 whoami.memberof_group.indexOf('admins') !== -1) {
                 self_service = false;
@@ -253,13 +258,36 @@ define([
             return self_service;
         },
 
-        update_logged_in: function(logged_in, fullname) {
+        is_aduser_selfservice: function() {
+            var selfservice = IPA.whoami.metadata.object === 'idoverrideuser';
+            // quite ugly, needed for users and iduseroverride to hide breadcrumb
+            IPA.is_aduser_selfservice = selfservice;
+
+            return selfservice;
+        },
+
+        update_logged_in: function(logged_in) {
             this.app_widget.set('logged', logged_in);
+
+            var whoami = IPA.whoami;
+            var fullname = '';
+            var entity = whoami.metadata.object;
+
+            if (entity === 'user') fullname = whoami.data.krbprincipalname[0];
+            else if (entity === 'idoverrideuser')
+                fullname = whoami.data.ipaoriginaluid[0];
             this.app_widget.set('fullname', fullname);
         },
 
         on_profile: function() {
-            routing.navigate(['entity', 'user', 'details', [IPA.whoami.uid[0]]]);
+            var entity = IPA.whoami.metadata.object;
+            if (entity === 'idoverrideuser') {
+                routing.navigate(['entity', 'idoverrideuser', 'details',
+                    [IPA.whoami.metadata.arguments[0],
+                    IPA.whoami.metadata.arguments[1]]]);
+            } else {
+                routing.navigate(['entity', 'user', 'details', [IPA.whoami.data.uid[0]]]);
+            }
         },
 
         on_logout: function(event) {
diff --git a/install/ui/src/freeipa/idviews.js b/install/ui/src/freeipa/idviews.js
index f383ab3..13cdeb9 100644
--- a/install/ui/src/freeipa/idviews.js
+++ b/install/ui/src/freeipa/idviews.js
@@ -452,6 +452,20 @@ idviews.id_override_user_details_facet = function(spec) {
     return that;
 };
 
+
+idviews.aduser_idoverrideuser_pre_op = function(spec, context) {
+    spec = spec || [];
+
+    if (!IPA.is_aduser_selfservice) return spec;
+
+    var facet = spec.facets[0];
+    facet.actions = [];
+    facet.header_actions = [];
+    facet.disable_breadcrumb = true;
+
+    return spec;
+};
+
 /**
  * @extends IPA.cert.certs_widget
  */
@@ -948,7 +962,11 @@ idviews.register = function() {
     var w = reg.widget;
 
     e.register({type: 'idview', spec: idviews.spec});
-    e.register({type: 'idoverrideuser', spec: idviews.idoverrideuser_spec});
+    e.register({
+        type: 'idoverrideuser',
+        spec: idviews.idoverrideuser_spec,
+        pre_ops: [idviews.aduser_idoverrideuser_pre_op]
+    });
     e.register({type: 'idoverridegroup', spec: idviews.idoverridegroup_spec});
     f.copy('attribute', 'idview_appliedtohosts', {
         factory: idviews.appliedtohosts_facet
diff --git a/install/ui/src/freeipa/ipa.js b/install/ui/src/freeipa/ipa.js
index 0ddbd07..15325ef 100644
--- a/install/ui/src/freeipa/ipa.js
+++ b/install/ui/src/freeipa/ipa.js
@@ -86,7 +86,8 @@ var IPA = function () {
     /**
      * User information
      *
-     * - output of ipa user-find --whoami
+     * - output of ipa whoami in that.whoami.metadata and then object_show method
+     * in that.whoami.data
      */
     that.whoami = {};
 
@@ -263,19 +264,32 @@ var IPA = function () {
      */
     that.get_whoami_command = function(batch) {
         return rpc.command({
-            entity: 'user',
-            method: 'find',
-            options: {
-                whoami: true,
-                all: true
-            },
+            method: 'whoami',
             on_success: function(data, text_status, xhr) {
-                that.whoami = batch ? data.result[0] : data.result.result[0];
-                var cn = that.whoami.krbcanonicalname;
-                if (cn) that.principal = cn[0];
-                if (!that.principal) {
-                    that.principal = that.whoami.krbprincipalname[0];
-                }
+                that.whoami.metadata = data;
+
+                rpc.command({
+                    method: data.details || data.command,
+                    args: data.arguments,
+                    options: function() {
+                        $.extend(data.options, {all: true});
+                        return data.options;
+                    }(),
+                    on_success: function(data, text_status, xhr) {
+                        that.whoami.data = false ? data.result[0] : data.result.result;
+                        var entity = that.whoami.metadata.object;
+
+                        if (entity === 'user') {
+                            var cn = that.whoami.data.krbcanonicalname;
+                            if (cn) that.principal = cn[0];
+                            if (!that.principal) {
+                                that.principal = that.whoami.data.krbprincipalname[0];
+                            }
+                        } else if (entity === 'idoverrideuser') {
+                            that.principal = that.whoami.data.ipaoriginaluid[0];
+                        }
+                    }
+                }).execute();
             }
         });
     };
@@ -650,13 +664,13 @@ IPA.update_password_expiration = function() {
 IPA.password_selfservice = function() {
     var reset_dialog = builder.build('dialog', {
         $type: 'user_password',
-        args: [IPA.whoami.uid[0]]
+        args: [IPA.whoami.data.uid[0]]
     });
     reset_dialog.succeeded.attach(function() {
         var command = IPA.get_whoami_command();
         var orig_on_success = command.on_success;
         command.on_success = function(data, text_status, xhr) {
-            orig_on_success.call(this, data, text_status, xhr);
+            orig_on_success.call(this, data.result, text_status, xhr);
             IPA.update_password_expiration();
         };
         command.execute();
diff --git a/install/ui/src/freeipa/navigation/menu_spec.js b/install/ui/src/freeipa/navigation/menu_spec.js
index 4f78e4b..4ae9517 100644
--- a/install/ui/src/freeipa/navigation/menu_spec.js
+++ b/install/ui/src/freeipa/navigation/menu_spec.js
@@ -353,5 +353,13 @@ nav.self_service = {
     ]
 };
 
+nav.ad_self_service = {
+    name: 'ad_self_service',
+    items: [
+        { entity: 'user' },
+        { entity: 'idoverrideuser' }
+    ]
+};
+
 return nav;
 });
diff --git a/install/ui/src/freeipa/user.js b/install/ui/src/freeipa/user.js
index 4bb0448..6b2bf19 100644
--- a/install/ui/src/freeipa/user.js
+++ b/install/ui/src/freeipa/user.js
@@ -735,7 +735,7 @@ IPA.user.password_dialog = function(spec) {
     var that = dialogs.command_dialog(spec);
 
     that.is_self_service = function() {
-        var self_service = that.args[0] === IPA.whoami.uid[0];
+        var self_service = that.args[0] === IPA.whoami.data.uid[0];
         return self_service;
     };
 
@@ -895,7 +895,8 @@ IPA.user.self_service_other_user_evaluator = function(spec) {
         that.state = [];
 
         var value = that.adapter.load(data);
-        if (IPA.is_selfservice && IPA.whoami.uid[0] !== value[0]) {
+        if (IPA.is_aduser_selfservice ||
+            (IPA.is_selfservice && IPA.whoami.data.uid[0] !== value[0])) {
             that.state.push('self-service-other');
         }
 
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to