[polari/wip/fmuellner/server-password: 4/4] roomList: Allow users to provide a server password



commit e1a821742d04457f29ba0bde042dacfb340cab9b
Author: Florian Müllner <fmuellner gnome org>
Date:   Fri Oct 23 15:56:36 2015 +0200

    roomList: Allow users to provide a server password
    
    Now that we support password authentication, allow the user to enter the
    server password in the header popover on authentication errors instead of
    merely pointing out the error.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=709824

 data/resources/room-list-header.ui |   21 +++++++++++++++++++++
 src/application.js                 |    2 ++
 src/chatroomManager.js             |   20 ++++++++++++++++++++
 src/roomList.js                    |   25 +++++++++++++++++++++++--
 4 files changed, 66 insertions(+), 2 deletions(-)
---
diff --git a/data/resources/room-list-header.ui b/data/resources/room-list-header.ui
index 658029f..75ae288 100644
--- a/data/resources/room-list-header.ui
+++ b/data/resources/room-list-header.ui
@@ -50,6 +50,15 @@
               </packing>
             </child>
             <child>
+              <object class="GtkImage">
+                <property name="icon-name">dialog-password-symbolic</property>
+                <property name="visible">True</property>
+              </object>
+              <packing>
+                <property name="name">auth</property>
+              </packing>
+            </child>
+            <child>
               <object class="GtkBox">
                 <property name="visible">True</property>
               </object>
@@ -101,6 +110,18 @@
           </object>
         </child>
         <child>
+          <object class="GtkEntry" id="popoverPassword">
+            <property name="visible" bind-source="popoverTitle"
+                      bind-property="visible" bind-flags="invert-boolean"/>
+            <property name="visibility">False</property>
+            <property name="can-default">True</property>
+            <property name="activates-default">True</property>
+            <property name="margin-top">6</property>
+            <property name="margin-start">6</property>
+            <property name="margin-end">6</property>
+          </object>
+        </child>
+        <child>
           <object class="GtkSeparator">
             <property name="visible">True</property>
             <property name="margin-top">6</property>
diff --git a/src/application.js b/src/application.js
index 40b4a0a..1754fe9 100644
--- a/src/application.js
+++ b/src/application.js
@@ -77,6 +77,8 @@ const Application = new Lang.Class({
             activate: Lang.bind(this, this._onLeaveCurrentRoom),
             create_hook: Lang.bind(this, this._leaveRoomCreateHook),
             accels: ['<Primary>w'] },
+          { name: 'authenticate-account',
+            parameter_type: GLib.VariantType.new('(os)') },
           { name: 'reconnect-account',
             parameter_type: GLib.VariantType.new('o') },
           { name: 'user-list',
diff --git a/src/chatroomManager.js b/src/chatroomManager.js
index ad9ea4f..f0f3178 100644
--- a/src/chatroomManager.js
+++ b/src/chatroomManager.js
@@ -170,6 +170,9 @@ const _ChatroomManager = new Lang.Class({
         let reconnectAction = this._app.lookup_action('reconnect-account');
         reconnectAction.connect('activate', Lang.bind(this, this._onReconnectAccountActivated));
 
+        let authAction = this._app.lookup_action('authenticate-account');
+        authAction.connect('activate', Lang.bind(this, this._onAuthenticateAccountActivated));
+
         this._client = new Client(am, this);
 
         let filters = [];
@@ -267,6 +270,23 @@ const _ChatroomManager = new Lang.Class({
         this._restoreSavedChannels(account);
     },
 
+    _onAuthenticateAccountActivated: function(action, parameter) {
+        let [accountPath, password] = parameter.deep_unpack();
+        let factory = Tp.AccountManager.dup().get_factory();
+        let account = factory.ensure_account(accountPath, []);
+
+        let prompt = new GLib.Variant('b', password.length > 0);
+        let params = GLib.Variant.new('a{sv}', { 'password-prompt': prompt });
+        account.update_parameters_vardict_async(params, [],
+            Lang.bind(this, function(a, res) {
+                a.update_parameters_vardict_finish(res);
+                Utils.storeAccountPassword(a, password, Lang.bind(this,
+                    function() {
+                        this._restoreSavedChannels(a);
+                    }));
+            }));
+    },
+
     _onJoinActivated: function(action, parameter) {
         let [accountPath, channelName, time] = parameter.deep_unpack();
         let factory = Tp.AccountManager.dup().get_factory();
diff --git a/src/roomList.js b/src/roomList.js
index 56f19dc..992f161 100644
--- a/src/roomList.js
+++ b/src/roomList.js
@@ -168,6 +168,7 @@ const RoomListHeader = new Lang.Class({
                        'iconStack',
                        'popoverStatus',
                        'popoverTitle',
+                       'popoverPassword',
                        'popoverReconnect',
                        'popoverRemove',
                        'popoverProperties',
@@ -182,13 +183,28 @@ const RoomListHeader = new Lang.Class({
 
         this.parent(params);
 
+        this.popover.set_default_widget(this._popoverPassword);
         this.popover.connect('notify::visible', _onPopoverVisibleChanged);
+        this.popover.connect('closed', Lang.bind(this,
+            function() {
+                this._popoverPassword.text = '';
+            }));
 
         let target = new GLib.Variant('o', this._account.get_object_path());
         this._popoverReconnect.action_target = target;
         this._popoverRemove.action_target = target;
         this._popoverProperties.action_target = target;
 
+        this._popoverPassword.connect('activate', Lang.bind(this,
+            function() {
+                let action = this._app.lookup_action('authenticate-account');
+                let password = this._popoverPassword.text;
+                let accountPath = this._account.get_object_path();
+                let param = new GLib.Variant('(os)', [accountPath, password]);
+                action.activate(param);
+                this.popover.hide();
+            }));
+
         let displayNameChangedId =
             this._account.connect('notify::display-name',
                                   Lang.bind(this, this._onDisplayNameChanged));
@@ -236,17 +252,22 @@ const RoomListHeader = new Lang.Class({
     _onConnectionStatusChanged: function() {
         let status = this._account.connection_status;
         let reason = this._account.connection_status_reason;
+        let authError = Tp.error_get_dbus_name(Tp.Error.AUTHENTICATION_FAILED);
         let isError = (status == Tp.ConnectionStatus.DISCONNECTED &&
                        reason != Tp.ConnectionStatusReason.REQUESTED);
+        let isAuth = isError && this._account.connection_error == authError;
+
         let child = 'none';
         if (status == Tp.ConnectionStatus.CONNECTING) {
             if (this._networkMonitor.network_available)
                 child = 'connecting';
         } else if (isError) {
-            child = 'error';
+            child = isAuth ? 'auth' : 'error';
         }
+
         this._iconStack.visible_child_name = child;
         this._spinner.active = (child == 'connecting');
+        this._popoverTitle.visible = !isAuth;
 
         this._popoverTitle.use_markup = isError;
         this._popoverStatus.use_markup = !isError;
@@ -305,7 +326,7 @@ const RoomListHeader = new Lang.Class({
                 return _("Could not connect to %s in a safe way.").format(this._account.display_name);
 
             case Tp.error_get_dbus_name(Tp.Error.AUTHENTICATION_FAILED):
-                return _("Could not connect to %s. Authentication 
failed.").format(this._account.display_name);
+                return _("%s requires a password.").format(this._account.display_name);
 
             case Tp.error_get_dbus_name(Tp.Error.CONNECTION_FAILED):
             case Tp.error_get_dbus_name(Tp.Error.CONNECTION_LOST):


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