From ceedc3f7ecb1300ed5bfaf5db8ef1b1450c6288e Mon Sep 17 00:00:00 2001 From: Pavel Vomacka Date: Wed, 22 Mar 2017 16:54:33 +0100 Subject: [PATCH] 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 Reviewed-By: Petr Vobornik Reviewed-By: Alexander Bokovoy --- .../ui/src/freeipa/Application_controller.js | 52 +++++++++++++++---- install/ui/src/freeipa/idviews.js | 21 +++++++- install/ui/src/freeipa/ipa.js | 47 +++++++++++------ .../ui/src/freeipa/navigation/menu_spec.js | 10 ++++ install/ui/src/freeipa/otptoken.js | 2 +- install/ui/src/freeipa/user.js | 5 +- ipaserver/plugins/internal.py | 1 + 7 files changed, 108 insertions(+), 30 deletions(-) diff --git a/install/ui/src/freeipa/Application_controller.js b/install/ui/src/freeipa/Application_controller.js index d809c1f26..5eb4e7a51 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) { /** @@ -156,7 +157,7 @@ define([ /** * Turns off one item in user dropdown menu and remove its listener. * @param {string} name of the user menu item which should be disabled - * @param {Object} listener disable this listener + * @param {Object} listener disable di */ disable_user_menu_item: function(name, listener) { this.app_widget.disable_user_menu_item(name); @@ -179,16 +180,22 @@ 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', + this.on_passwd_reset_listener); + } 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); @@ -232,10 +239,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; @@ -255,13 +261,39 @@ 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 (whoami.data.cn) { + fullname = whoami.data.cn[0]; + } else if (whoami.data.displayname) { + fullname = whoami.data.displayname[0]; + } else if (whoami.data.gecos) { + fullname = whoami.data.gecos[0]; + } else if (whoami.data.krbprincipalname) { + fullname = whoami.data.krbprincipalname[0]; + } else if (whoami.data.ipaoriginaluid) { + fullname = whoami.data.ipaoriginaluid[0]; + } + this.app_widget.set('fullname', fullname); }, on_profile: function() { - routing.navigate(['entity', 'user', 'details', [IPA.whoami.uid[0]]]); + routing.navigate(['entity', IPA.whoami.metadata.object, 'details', + IPA.whoami.metadata.arguments]); }, on_logout: function(event) { diff --git a/install/ui/src/freeipa/idviews.js b/install/ui/src/freeipa/idviews.js index f383ab3be..d9133a13c 100644 --- a/install/ui/src/freeipa/idviews.js +++ b/install/ui/src/freeipa/idviews.js @@ -452,6 +452,21 @@ 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.label = '@i18n:objects.idoverrideuser.profile'; + facet.actions = []; + facet.header_actions = []; + facet.disable_breadcrumb = true; + + return spec; +}; + /** * @extends IPA.cert.certs_widget */ @@ -948,7 +963,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 0ddbd0744..2538001c9 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,33 @@ 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() { + var options = data.options || []; + $.extend(options, {all: true}); + return 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(); } }); }; @@ -616,7 +631,7 @@ IPA.update_password_expiration = function() { var now, expires, notify_days, diff, message, container, notify; - expires = rpc.extract_objects(IPA.whoami.krbpasswordexpiration); + expires = rpc.extract_objects(IPA.whoami.data.krbpasswordexpiration); expires = expires ? datetime.parse(expires[0]) : null; notify_days = IPA.server_config.ipapwdexpadvnotify; @@ -650,13 +665,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 4f78e4bf9..9329694c1 100644 --- a/install/ui/src/freeipa/navigation/menu_spec.js +++ b/install/ui/src/freeipa/navigation/menu_spec.js @@ -353,5 +353,15 @@ nav.self_service = { ] }; +nav.ad_self_service = { + name: 'ad_self_service', + items: [ + { + entity: 'idoverrideuser', + label: 'Profile' + } + ] +}; + return nav; }); diff --git a/install/ui/src/freeipa/otptoken.js b/install/ui/src/freeipa/otptoken.js index caa7a8552..1f6f20d80 100644 --- a/install/ui/src/freeipa/otptoken.js +++ b/install/ui/src/freeipa/otptoken.js @@ -361,7 +361,7 @@ otptoken.adder_dialog = function(spec) { var command = that.entity_adder_dialog_create_add_command(record); if (that.self_service) { - command.set_option('ipatokenowner', IPA.whoami.uid[0]); + command.set_option('ipatokenowner', IPA.whoami.data.uid[0]); } return command; }; diff --git a/install/ui/src/freeipa/user.js b/install/ui/src/freeipa/user.js index 4bb04488b..6b2bf196c 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'); } diff --git a/ipaserver/plugins/internal.py b/ipaserver/plugins/internal.py index 9fa1b6de8..6feefa594 100644 --- a/ipaserver/plugins/internal.py +++ b/ipaserver/plugins/internal.py @@ -625,6 +625,7 @@ class i18n_messages(Command): "anchor_label": _("User to override"), "anchor_tooltip": _("Enter trusted or IPA user login. Note: search doesn't list users from trusted domains."), "anchor_tooltip_ad": _("Enter trusted user login."), + "profile": _("Profile"), }, "idoverridegroup": { "anchor_label": _("Group to override"),