From 0a1f0e58d08823803d18a4127cddefaed8fea812 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Sun, 19 Aug 2012 21:37:54 -0400 Subject: [PATCH] gdm: Add network login hint Different networks have different user identifers. This can be confusing to the user, so to make it clearer, we try to provide a hint. https://bugzilla.gnome.org/show_bug.cgi?id=681975 --- js/Makefile.am | 1 + js/gdm/realmd.js | 139 +++++++++++++++++++++++++++++++++++++++++++++++ js/gdm/util.js | 31 ++++++++++- 3 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 js/gdm/realmd.js diff --git a/js/Makefile.am b/js/Makefile.am index b5bda7918..92e0e5993 100644 --- a/js/Makefile.am +++ b/js/Makefile.am @@ -20,6 +20,7 @@ nobase_dist_js_DATA = \ gdm/fingerprint.js \ gdm/loginDialog.js \ gdm/powerMenu.js \ + gdm/realmd.js \ gdm/util.js \ extensionPrefs/main.js \ misc/config.js \ diff --git a/js/gdm/realmd.js b/js/gdm/realmd.js new file mode 100644 index 000000000..e64b0b27b --- /dev/null +++ b/js/gdm/realmd.js @@ -0,0 +1,139 @@ +// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- + +const Gio = imports.gi.Gio; +const Lang = imports.lang; +const Shell = imports.gi.Shell; +const Signals = imports.signals; + +const ProviderIface = + + + + + + + + + +; +const Provider = Gio.DBusProxy.makeProxyWrapper(ProviderIface); + +const ServiceIface = + + + + + + + + + + + +; +const Service = Gio.DBusProxy.makeProxyWrapper(ServiceIface); + +const RealmIface = + + + + + + + + + + + + + + + + +; +const Realm = Gio.DBusProxy.makeProxyWrapper(RealmIface); + +const Manager = new Lang.Class({ + Name: 'Manager', + + _init: function(parentActor) { + this._aggregateProvider = Provider(Gio.DBus.system, + 'org.freedesktop.realmd', + '/org/freedesktop/realmd', + Lang.bind(this, this._reloadRealms)) + this._realms = {}; + + this._aggregateProvider.connect('g-properties-changed', + Lang.bind(this, function(proxy, properties) { + if ('Realms' in properties.deep_unpack()) + this._reloadRealms(); + })); + }, + + _reloadRealms: function() { + let realmPaths = this._aggregateProvider.Realms; + + if (!realmPaths) + return; + + for (let i = 0; i < realmPaths.length; i++) { + let realm = Realm(Gio.DBus.system, + 'org.freedesktop.realmd', + realmPaths[i], + Lang.bind(this, this._onRealmLoaded)); + } + }, + + _reloadRealm: function(realm) { + if (!realm.Configured) { + if (this._realms[realm.get_object_path()]) + delete this._realms[realm.get_object_path()]; + + return; + } + + this._realms[realm.get_object_path()] = realm; + + this._updateLoginFormat(); + }, + + _onRealmLoaded: function(realm, error) { + if (error) + return; + + this._reloadRealm(realm); + + realm.connect('g-properties-changed', + Lang.bind(this, function(proxy, properties) { + if ('Configured' in properties.deep_unpack()) + this._reloadRealm(); + })); + }, + + _updateLoginFormat: function() { + let newLoginFormat; + + for (let realmPath in this._realms) { + let realm = this._realms[realmPath]; + if (realm.LoginFormats && realm.LoginFormats.length > 0) { + newLoginFormat = realm.LoginFormats[0]; + break; + } + } + + if (this._loginFormat != newLoginFormat) { + this._loginFormat = newLoginFormat; + this.emit('login-format-changed', newLoginFormat); + } + }, + + get loginFormat() { + if (this._loginFormat !== undefined) + return this._loginFormat; + + this._updateLoginFormat(); + + return this._loginFormat; + } +}); +Signals.addSignalMethods(Manager.prototype) diff --git a/js/gdm/util.js b/js/gdm/util.js index 3224539c7..83b0fe078 100644 --- a/js/gdm/util.js +++ b/js/gdm/util.js @@ -6,6 +6,7 @@ const Signals = imports.signals; const Batch = imports.gdm.batch; const Fprint = imports.gdm.fingerprint; +const Realmd = imports.gdm.realmd; const Main = imports.ui.main; const Params = imports.misc.params; const Tweener = imports.ui.tweener; @@ -82,6 +83,8 @@ const ShellUserVerifier = new Lang.Class({ this._fprintManager = new Fprint.FprintManager(); this._checkForFingerprintReader(); + + this._realmManager = new Realmd.Manager(); }, begin: function(userName, hold) { @@ -228,11 +231,30 @@ const ShellUserVerifier = new Lang.Class({ Main.notifyError(problem); }, + _showRealmLoginHint: function() { + if (this._realmManager.loginFormat) { + let hint = this._realmManager.loginFormat; + + hint = hint.replace(/%U/g, 'user'); + hint = hint.replace(/%D/g, 'DOMAIN'); + hint = hint.replace(/%[^UD]/g, ''); + + // Translators: this message is shown below the username entry field + // to clue the user in on how to login to the local network realm + this.emit('show-login-hint', + _("(e.g., user or %s)").format(hint)); + } + }, + _onInfoQuery: function(client, serviceName, question) { // We only expect questions to come from the main auth service if (serviceName != PASSWORD_SERVICE_NAME) return; + this._showRealmLoginHint(); + this._realmLoginHintSignalId = this._realmManager.connect('login-format-changed', + Lang.bind(this, this._showRealmLoginHint)); + this.emit('ask-question', serviceName, question, ''); }, @@ -263,8 +285,13 @@ const ShellUserVerifier = new Lang.Class({ // password authentication a chance to succeed if (serviceName == PASSWORD_SERVICE_NAME) { this.emit('verification-failed'); - } else if (serviceName == FINGERPRINT_SERVICE_NAME) { - this.emit('hide-login-hint'); + } + + this.emit('hide-login-hint'); + + if (this._realmLoginHintSignalId) { + this._realmManager.disconnect(this._realmLoginHintSignalId); + this._realmLoginHintSignalId = 0; } }, });