[polari] roomList: Allow users to provide a server password



commit 17f4efa8a603496768ee231d9a2910b6f10e6f0f
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 28cbaba..62ff472 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..b270193 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() {
+                        a.reconnect_async(null);
+                    }));
+            }));
+    },
+
     _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 7157095..1942c68 100644
--- a/src/roomList.js
+++ b/src/roomList.js
@@ -142,6 +142,7 @@ const RoomListHeader = new Lang.Class({
                        'iconStack',
                        'popoverStatus',
                        'popoverTitle',
+                       'popoverPassword',
                        'popoverReconnect',
                        'popoverRemove',
                        'popoverProperties',
@@ -156,13 +157,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));
@@ -210,17 +226,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;
@@ -279,7 +300,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]