[gitg] Re-authenticate after authentication failure



commit 795c4f17fe0e93f5e06dae05480cfa4f3677e543
Author: Jesse van den Kieboom <jessevdk gmail com>
Date:   Thu Dec 25 11:41:00 2014 +0100

    Re-authenticate after authentication failure

 libgitg/gitg-authentication-dialog.vala         |   29 +++++++++++++++-
 libgitg/gitg-credentials-manager.vala           |   31 ++---------------
 libgitg/gitg-remote.vala                        |   41 ++++++++++++++++++-----
 libgitg/resources/gitg-authentication-dialog.ui |   32 ++++++++++++++---
 4 files changed, 89 insertions(+), 44 deletions(-)
---
diff --git a/libgitg/gitg-authentication-dialog.vala b/libgitg/gitg-authentication-dialog.vala
index eef47dc..6468904 100644
--- a/libgitg/gitg-authentication-dialog.vala
+++ b/libgitg/gitg-authentication-dialog.vala
@@ -33,6 +33,9 @@ public class AuthenticationDialog : Gtk.Dialog
        [GtkChild ( name = "label_title" )]
        private Gtk.Label d_label_title;
 
+       [GtkChild ( name = "label_failed" )]
+       private Gtk.Label d_label_failed;
+
        [GtkChild ( name = "entry_username" )]
        private Gtk.Entry d_entry_username;
 
@@ -45,7 +48,17 @@ public class AuthenticationDialog : Gtk.Dialog
        [GtkChild ( name = "radio_button_session" )]
        private Gtk.RadioButton d_radio_button_session;
 
-       public AuthenticationDialog(string url, string? username)
+       [GtkChild ( name = "radio_button_forever" )]
+       private Gtk.RadioButton d_radio_button_forever;
+
+       private static AuthenticationLifeTime s_last_lifetime;
+
+       static construct
+       {
+               s_last_lifetime = AuthenticationLifeTime.SESSION;
+       }
+
+       public AuthenticationDialog(string url, string? username, bool failed)
        {
                Object(use_header_bar: 1);
 
@@ -54,12 +67,26 @@ public class AuthenticationDialog : Gtk.Dialog
                /* Translators: %s will be replaced with a URL indicating the resource
                   for which the authentication is required. */
                d_label_title.label = _("Password required for %s").printf(url);
+               d_label_failed.visible = failed;
 
                if (username != null)
                {
                        d_entry_username.text = username;
                        d_entry_password.grab_focus();
                }
+
+               switch (s_last_lifetime)
+               {
+                       case AuthenticationLifeTime.FORGET:
+                               d_radio_button_forget.active = true;
+                               break;
+                       case AuthenticationLifeTime.SESSION:
+                               d_radio_button_session.active = true;
+                               break;
+                       case AuthenticationLifeTime.FOREVER:
+                               d_radio_button_forever.active = true;
+                               break;
+               }
        }
 
        public string username
diff --git a/libgitg/gitg-credentials-manager.vala b/libgitg/gitg-credentials-manager.vala
index a80cadb..db2d8c1 100644
--- a/libgitg/gitg-credentials-manager.vala
+++ b/libgitg/gitg-credentials-manager.vala
@@ -27,29 +27,9 @@ public errordomain CredentialsError
 
 public class CredentialsManager
 {
-       class CredSshInteractive : Ggit.CredSshInteractive
-       {
-               private weak Remote d_remote;
-
-               public CredSshInteractive(Remote remote, string username) throws Error
-               {
-                       Object(username: username);
-
-                       d_remote = remote;
-
-                       ((Initable)this).init(null);
-               }
-
-               protected override void prompt(Ggit.CredSshInteractivePrompt[] prompts)
-               {
-                       // TODO
-               }
-       }
-
        private weak Remote d_remote;
        private Gtk.Window d_window;
        private Gee.HashMap<string, string>? d_usermap;
-
        private static Secret.Schema s_secret_schema;
 
        static construct
@@ -106,7 +86,7 @@ public class CredentialsManager
                AuthenticationLifeTime lifetime = AuthenticationLifeTime.FORGET;
 
                Idle.add(() => {
-                       var d = new AuthenticationDialog(url, username);
+                       var d = new AuthenticationDialog(url, username, d_remote.authentication_error != 
null);
                        d.set_transient_for(d_window);
 
                        response = (Gtk.ResponseType)d.run();
@@ -164,7 +144,6 @@ public class CredentialsManager
                attributes["host"] = host;
                attributes["user"] = newusername;
 
-
                // Save secret
                if (lifetime != AuthenticationLifeTime.FORGET)
                {
@@ -233,7 +212,7 @@ public class CredentialsManager
                        user = username;
                }
 
-               if (user != null)
+               if (user != null && d_remote.authentication_error == null)
                {
                        string? secret = null;
 
@@ -270,14 +249,10 @@ public class CredentialsManager
                                      string?       username,
                                      Ggit.Credtype allowed_types) throws Error
        {
-               if ((allowed_types & Ggit.Credtype.SSH_KEY) != 0)
+               if (d_remote.authentication_error != null && (allowed_types & Ggit.Credtype.SSH_KEY) != 0)
                {
                        return new Ggit.CredSshKeyFromAgent(username);
                }
-               else if ((allowed_types & Ggit.Credtype.SSH_INTERACTIVE) != 0)
-               {
-                       return new CredSshInteractive(d_remote, username);
-               }
                else if ((allowed_types & Ggit.Credtype.USERPASS_PLAINTEXT) != 0)
                {
                        return query_user_pass(url, username);
diff --git a/libgitg/gitg-remote.vala b/libgitg/gitg-remote.vala
index df7763c..b04f1a9 100644
--- a/libgitg/gitg-remote.vala
+++ b/libgitg/gitg-remote.vala
@@ -39,6 +39,12 @@ public errordomain RemoteError
 public class Remote : Ggit.Remote
 {
        private RemoteState d_state;
+       private Error? d_authentication_error;
+
+       public Error authentication_error
+       {
+               get { return d_authentication_error; }
+       }
 
        public RemoteState state
        {
@@ -69,6 +75,7 @@ public class Remote : Ggit.Remote
                        else
                        {
                                state = RemoteState.CONNECTED;
+                               d_authentication_error = null;
                        }
                }
                else
@@ -95,16 +102,32 @@ public class Remote : Ggit.Remote
 
                state = RemoteState.CONNECTING;
 
-               try
+               while (true)
                {
-                       yield Async.thread(() => {
-                               base.connect(direction);
-                       });
-               }
-               catch (Error e)
-               {
-                       update_state();
-                       throw e;
+                       try
+                       {
+                               yield Async.thread(() => {
+                                       base.connect(direction);
+                               });
+                       }
+                       catch (Error e)
+                       {
+                               // NOTE: need to check the message for now in case of failed
+                               // http auth.
+                               if (e.message == "Unexpected HTTP status code: 401")
+                               {
+                                       d_authentication_error = e;
+                                       continue;
+                               }
+                               else
+                               {
+                                       update_state();
+                                       throw e;
+                               }
+                       }
+
+                       d_authentication_error = null;
+                       break;
                }
 
                update_state();
diff --git a/libgitg/resources/gitg-authentication-dialog.ui b/libgitg/resources/gitg-authentication-dialog.ui
index 5ce69e0..7cdc802 100644
--- a/libgitg/resources/gitg-authentication-dialog.ui
+++ b/libgitg/resources/gitg-authentication-dialog.ui
@@ -49,7 +49,7 @@
               <packing>
                 <property name="left_attach">0</property>
                 <property name="top_attach">0</property>
-                <property name="height">4</property>
+                <property name="height">5</property>
               </packing>
             </child>
             <child>
@@ -68,6 +68,26 @@
               </packing>
             </child>
             <child>
+              <object class="GtkLabel" id="label_failed">
+                <property name="visible">False</property>
+                <property name="can_focus">False</property>
+                <property name="halign">fill</property>
+                <property name="wrap">True</property>
+                <property name="label" translatable="yes">The previous attempt to authenticate has failed, 
please provide your user name and password and try again.</property>
+                <property name="margin_top">12</property>
+                <property name="margin_bottom">12</property>
+                <property name="max_width_chars">0</property>
+                <attributes>
+                  <attribute name="style" value="italic"/>
+                </attributes>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">1</property>
+                <property name="width">2</property>
+              </packing>
+            </child>
+            <child>
               <object class="GtkLabel" id="label_username">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
@@ -78,7 +98,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="top_attach">1</property>
+                <property name="top_attach">2</property>
               </packing>
             </child>
             <child>
@@ -92,7 +112,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="top_attach">2</property>
+                <property name="top_attach">3</property>
               </packing>
             </child>
             <child>
@@ -105,7 +125,7 @@
               </object>
               <packing>
                 <property name="left_attach">2</property>
-                <property name="top_attach">1</property>
+                <property name="top_attach">2</property>
               </packing>
             </child>
             <child>
@@ -120,7 +140,7 @@
               </object>
               <packing>
                 <property name="left_attach">2</property>
-                <property name="top_attach">2</property>
+                <property name="top_attach">3</property>
               </packing>
             </child>
             <child>
@@ -184,7 +204,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="top_attach">3</property>
+                <property name="top_attach">4</property>
                 <property name="width">2</property>
               </packing>
             </child>


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