[gnome-shell] gdm: Add network login hint



commit 0a1f0e58d08823803d18a4127cddefaed8fea812
Author: Ray Strode <rstrode redhat com>
Date:   Sun Aug 19 21:37:54 2012 -0400

    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(-)
---
diff --git a/js/Makefile.am b/js/Makefile.am
index b5bda79..92e0e59 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 0000000..e64b0b2
--- /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 = <interface name='org.freedesktop.realmd.Provider'>
+    <property name="Name" type="s" access="read"/>
+    <property name="Version" type="s" access="read"/>
+    <property name="Realms" type="ao" access="read"/>
+    <method name="Discover">
+        <arg name="string" type="s" direction="in"/>
+        <arg name="options" type="a{sv}" direction="in"/>
+        <arg name="relevance" type="i" direction="out"/>
+        <arg name="realm" type="ao" direction="out"/>
+    </method>
+</interface>;
+const Provider = Gio.DBusProxy.makeProxyWrapper(ProviderIface);
+
+const ServiceIface = <interface name="org.freedesktop.realmd.Service">
+    <method name="Cancel">
+        <arg name="operation" type="s" direction="in"/>
+    </method>
+    <method name="Release" />
+    <method name="SetLocale">
+        <arg name="locale" type="s" direction="in"/>
+    </method>
+    <signal name="Diagnostics">
+        <arg name="data" type="s"/>
+        <arg name="operation" type="s"/>
+    </signal>
+</interface>;
+const Service = Gio.DBusProxy.makeProxyWrapper(ServiceIface);
+
+const RealmIface = <interface name="org.freedesktop.realmd.Realm">
+    <property name="Name" type="s" access="read"/>
+    <property name="Configured" type="s" access="read"/>
+    <property name="Details" type="a(ss)" access="read"/>
+    <property name="LoginFormats" type="as" access="read"/>
+    <property name="LoginPolicy" type="s" access="read"/>
+    <property name="PermittedLogins" type="as" access="read"/>
+    <property name="SupportedInterfaces" type="as" access="read"/>
+    <method name="ChangeLoginPolicy">
+        <arg name="login_policy" type="s" direction="in"/>
+        <arg name="permitted_add" type="as" direction="in"/>
+        <arg name="permitted_remove" type="as" direction="in"/>
+        <arg name="options" type="a{sv}" direction="in"/>
+    </method>
+    <method name="Deconfigure">
+        <arg name="options" type="a{sv}" direction="in"/>
+    </method>
+</interface>;
+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 3224539..83b0fe0 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;
         }
     },
 });



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]