[geary/wip/714650-login-denied] First work to differentiate btwn login denied and login failed



commit 21257c723f390199732fe8a9f421d607fcefc976
Author: Jim Nelson <jim yorba org>
Date:   Fri Aug 29 12:19:03 2014 -0700

    First work to differentiate btwn login denied and login failed

 src/client/application/geary-controller.vala       |    4 +-
 src/engine/api/geary-account.vala                  |    4 +-
 src/engine/imap-db/outbox/smtp-outbox-folder.vala  |    2 +-
 .../imap-engine/imap-engine-generic-account.vala   |   10 +++---
 src/engine/imap/api/imap-account.vala              |    8 ++--
 src/engine/imap/imap-error.vala                    |    4 ++
 src/engine/imap/response/imap-capabilities.vala    |    1 +
 .../transport/imap-client-session-manager.vala     |   10 +++++-
 src/engine/imap/transport/imap-client-session.vala |   30 ++++++++++++++++---
 9 files changed, 52 insertions(+), 21 deletions(-)
---
diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala
index 990b548..8e40589 100644
--- a/src/client/application/geary-controller.vala
+++ b/src/client/application/geary-controller.vala
@@ -889,8 +889,8 @@ public class GearyController : Geary.BaseObject {
                 // TODO
             break;
             
-            case Geary.Account.Problem.RECV_EMAIL_LOGIN_FAILED:
-            case Geary.Account.Problem.SEND_EMAIL_LOGIN_FAILED:
+            case Geary.Account.Problem.RECV_EMAIL_LOGIN_DENIED:
+            case Geary.Account.Problem.SEND_EMAIL_LOGIN_DENIED:
                 // At this point, we've prompted them for the password and
                 // they've hit cancel, so there's not much for us to do here.
                 close_account(account);
diff --git a/src/engine/api/geary-account.vala b/src/engine/api/geary-account.vala
index a144566..4ed52c1 100644
--- a/src/engine/api/geary-account.vala
+++ b/src/engine/api/geary-account.vala
@@ -6,8 +6,8 @@
 
 public interface Geary.Account : BaseObject {
     public enum Problem {
-        RECV_EMAIL_LOGIN_FAILED,
-        SEND_EMAIL_LOGIN_FAILED,
+        RECV_EMAIL_LOGIN_DENIED,
+        SEND_EMAIL_LOGIN_DENIED,
         HOST_UNREACHABLE,
         NETWORK_UNAVAILABLE,
         DATABASE_FAILURE,
diff --git a/src/engine/imap-db/outbox/smtp-outbox-folder.vala 
b/src/engine/imap-db/outbox/smtp-outbox-folder.vala
index 745967b..044f93f 100644
--- a/src/engine/imap-db/outbox/smtp-outbox-folder.vala
+++ b/src/engine/imap-db/outbox/smtp-outbox-folder.vala
@@ -252,7 +252,7 @@ private class Geary.SmtpOutboxFolder : Geary.AbstractLocalFolder, Geary.FolderSu
                     }
                     
                     if (report)
-                        report_problem(Geary.Account.Problem.SEND_EMAIL_LOGIN_FAILED, send_err);
+                        report_problem(Geary.Account.Problem.SEND_EMAIL_LOGIN_DENIED, send_err);
                 } else if (send_err is TlsError) {
                     // up to application to be aware of problem via Geary.Engine, but do nap and
                     // try later
diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala 
b/src/engine/imap-engine/imap-engine-generic-account.vala
index 92fef95..ff4f7b5 100644
--- a/src/engine/imap-engine/imap-engine-generic-account.vala
+++ b/src/engine/imap-engine/imap-engine-generic-account.vala
@@ -32,7 +32,7 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
         this.remote = remote;
         this.local = local;
         
-        this.remote.login_failed.connect(on_login_failed);
+        this.remote.login_denied.connect(on_login_denied);
         this.local.email_sent.connect(on_email_sent);
         
         search_upgrade_monitor = local.search_index_monitor;
@@ -843,15 +843,15 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
         return yield local.get_containing_folders_async(ids, cancellable);
     }
     
-    private void on_login_failed(Geary.Credentials? credentials) {
+    private void on_login_denied(Geary.Credentials? credentials) {
         if (awaiting_credentials)
             return; // We're already asking for the password.
         
         awaiting_credentials = true;
-        do_login_failed_async.begin(credentials, () => { awaiting_credentials = false; });
+        do_login_denied_async.begin(credentials, () => { awaiting_credentials = false; });
     }
     
-    private async void do_login_failed_async(Geary.Credentials? credentials) {
+    private async void do_login_denied_async(Geary.Credentials? credentials) {
         try {
             if (yield information.fetch_passwords_async(ServiceFlag.IMAP, true))
                 return;
@@ -859,7 +859,7 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
             debug("Error prompting for IMAP password: %s", e.message);
         }
         
-        notify_report_problem(Geary.Account.Problem.RECV_EMAIL_LOGIN_FAILED, null);
+        notify_report_problem(Geary.Account.Problem.RECV_EMAIL_LOGIN_DENIED, null);
     }
 }
 
diff --git a/src/engine/imap/api/imap-account.vala b/src/engine/imap/api/imap-account.vala
index 2bff719..287daa5 100644
--- a/src/engine/imap/api/imap-account.vala
+++ b/src/engine/imap/api/imap-account.vala
@@ -35,14 +35,14 @@ private class Geary.Imap.Account : BaseObject {
     private Gee.List<ServerData>? server_data_collector = null;
     private Imap.MailboxSpecifier? inbox_specifier = null;
     
-    public signal void login_failed(Geary.Credentials cred);
+    public signal void login_denied(Geary.Credentials cred);
     
     public Account(Geary.AccountInformation account_information) {
         name = "IMAP Account for %s".printf(account_information.imap_credentials.to_string());
         this.account_information = account_information;
         this.session_mgr = new ClientSessionManager(account_information);
         
-        session_mgr.login_failed.connect(on_login_failed);
+        session_mgr.login_denied.connect(on_login_denied);
     }
     
     private void check_open() throws Error {
@@ -506,8 +506,8 @@ private class Geary.Imap.Account : BaseObject {
             (path != null) ? path.to_string() : "root", session_mgr.to_string());
     }
     
-    private void on_login_failed() {
-        login_failed(account_information.imap_credentials);
+    private void on_login_denied() {
+        login_denied(account_information.imap_credentials);
     }
     
     public string to_string() {
diff --git a/src/engine/imap/imap-error.vala b/src/engine/imap/imap-error.vala
index c88cc32..da8d797 100644
--- a/src/engine/imap/imap-error.vala
+++ b/src/engine/imap/imap-error.vala
@@ -52,5 +52,9 @@ public errordomain Geary.ImapError {
      * This indicates a local time out, not one reported by the server.
      */
     TIMED_OUT,
+    /**
+     * Operation is currently unavailable.
+     */
+    UNAVAILABLE
 }
 
diff --git a/src/engine/imap/response/imap-capabilities.vala b/src/engine/imap/response/imap-capabilities.vala
index f74dd25..1c58f31 100644
--- a/src/engine/imap/response/imap-capabilities.vala
+++ b/src/engine/imap/response/imap-capabilities.vala
@@ -12,6 +12,7 @@ public class Geary.Imap.Capabilities : Geary.GenericCapabilities {
     public const string DEFLATE_SETTING = "DEFLATE";
     public const string UIDPLUS = "UIDPLUS";
     public const string SPECIAL_USE = "SPECIAL-USE";
+    public const string LOGIN_DISABLED = "LOGINDISABLED";
     
     public const string NAME_SEPARATOR = "=";
     public const string? VALUE_SEPARATOR = null;
diff --git a/src/engine/imap/transport/imap-client-session-manager.vala 
b/src/engine/imap/transport/imap-client-session-manager.vala
index c821d64..d6716d0 100644
--- a/src/engine/imap/transport/imap-client-session-manager.vala
+++ b/src/engine/imap/transport/imap-client-session-manager.vala
@@ -53,7 +53,7 @@ public class Geary.Imap.ClientSessionManager : BaseObject {
     private bool untrusted_host = false;
     private uint authorized_session_error_retry_timeout_id = 0;
     
-    public signal void login_failed();
+    public signal void login_denied();
     
     public ClientSessionManager(AccountInformation account_information) {
         this.account_information = account_information;
@@ -396,9 +396,13 @@ public class Geary.Imap.ClientSessionManager : BaseObject {
     }
     
     private void on_login_failed(ClientSession session) {
+        session.disconnect_async.begin();
+    }
+    
+    private void on_login_denied(ClientSession session) {
         authentication_failed = true;
         
-        login_failed();
+        login_denied();
         
         session.disconnect_async.begin();
     }
@@ -409,6 +413,7 @@ public class Geary.Imap.ClientSessionManager : BaseObject {
         
         // See create_new_authorized_session() for why the "disconnected" signal is not subscribed
         // to here (but *is* unsubscribed to in remove_session())
+        session.login_denied.connect(on_login_denied);
         session.login_failed.connect(on_login_failed);
     }
     
@@ -423,6 +428,7 @@ public class Geary.Imap.ClientSessionManager : BaseObject {
         bool removed = sessions.remove(session);
         if (removed) {
             session.disconnected.disconnect(on_disconnected);
+            session.login_denied.disconnect(on_login_denied);
             session.login_failed.disconnect(on_login_failed);
         }
         
diff --git a/src/engine/imap/transport/imap-client-session.vala 
b/src/engine/imap/transport/imap-client-session.vala
index ec45b41..b2ae925 100644
--- a/src/engine/imap/transport/imap-client-session.vala
+++ b/src/engine/imap/transport/imap-client-session.vala
@@ -190,6 +190,8 @@ public class Geary.Imap.ClientSession : BaseObject {
     
     public signal void logged_out();
     
+    public signal void login_denied();
+    
     public signal void login_failed();
     
     public signal void disconnected(DisconnectReason reason);
@@ -652,10 +654,14 @@ public class Geary.Imap.ClientSession : BaseObject {
     public async StatusResponse login_async(Geary.Credentials credentials, Cancellable? cancellable = null)
         throws Error {
         if (!credentials.is_complete()) {
-            login_failed();
+            login_denied();
+            
             throw new ImapError.UNAUTHENTICATED("No credentials provided for account: %s", 
credentials.to_string());
         }
         
+        if (capabilities.has_capability(Capabilities.LOGIN_DISABLED))
+            throw new ImapError.UNAVAILABLE("LOGIN not allowed with %s", to_string());
+        
         LoginCommand cmd = new LoginCommand(credentials.user, credentials.pass);
         
         MachineParams params = new MachineParams(cmd);
@@ -726,9 +732,17 @@ public class Geary.Imap.ClientSession : BaseObject {
         
         // Login after STARTTLS
         StatusResponse login_resp = yield login_async(credentials, cancellable);
-        if (login_resp.status != Status.OK) {
-            throw new ImapError.UNAUTHENTICATED("Unable to login to %s with supplied credentials",
-                to_string());
+        switch (login_resp.status) {
+            case Status.OK:
+                // fallthrough
+            break;
+            
+            case Status.NO:
+                throw new ImapError.UNAUTHENTICATED("Login denied to %s with supplied credentials",
+                    to_string());
+            
+            default:
+                throw new ImapError.SERVER_ERROR("Login to %s failed", to_string());
         }
         
         // if new capabilities not offered after login, get them now
@@ -785,8 +799,14 @@ public class Geary.Imap.ClientSession : BaseObject {
                 
                 return State.AUTHORIZED;
             
+            case Status.NO:
+                debug("[%s] LOGIN denied: %s", to_string(), completion_response.to_string());
+                fsm.do_post_transition(() => { login_denied(); });
+                
+                return State.NOAUTH;
+            
             default:
-                debug("[%s] Unable to LOGIN: %s", to_string(), completion_response.to_string());
+                debug("[%s] LOGIN failed: %s", to_string(), completion_response.to_string());
                 fsm.do_post_transition(() => { login_failed(); });
                 
                 return State.NOAUTH;


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