[geary] Use email address rather than username in keyring: Bug #714689



commit 8ce52b5924d858803d9011cf209ad5d066cbd1c6
Author: Simon Lipp <bugs-gnome simon lipp name>
Date:   Thu Aug 21 12:42:38 2014 -0700

    Use email address rather than username in keyring: Bug #714689
    
    Since different email accounts can have the same username, use the
    full email address for the keyring to prevent collisions.  This patch
    will also migrate both username-based keys and the very early one-pw
    keys (from 0.1).

 src/client/application/secret-mediator.vala    |   69 +++++++++++++++++++-----
 src/engine/api/geary-account-information.vala  |   20 ++++----
 src/engine/api/geary-credentials-mediator.vala |    9 ++-
 3 files changed, 72 insertions(+), 26 deletions(-)
---
diff --git a/src/client/application/secret-mediator.vala b/src/client/application/secret-mediator.vala
index 9210b7c..b06224d 100644
--- a/src/client/application/secret-mediator.vala
+++ b/src/client/application/secret-mediator.vala
@@ -20,45 +20,88 @@ public class SecretMediator : Geary.CredentialsMediator, Object {
                 assert_not_reached();
         }
     }
+
+    private Geary.Credentials get_credentials(Geary.CredentialsMediator.Service service, 
Geary.AccountInformation account_information) {
+        switch (service) {
+            case Service.IMAP:
+                return account_information.imap_credentials;
+
+            case Service.SMTP:
+                return account_information.smtp_credentials;
+
+            default:
+                assert_not_reached();
+        }
+    }
+
+    private async string? migrate_old_password(string old_key, string new_key, Cancellable? cancellable)
+        throws Error {
+        string? password = yield Secret.password_lookup(Secret.SCHEMA_COMPAT_NETWORK, cancellable,
+            "user", old_key);
+        if (password != null) {
+            bool result = yield Secret.password_store(Secret.SCHEMA_COMPAT_NETWORK,
+                null, new_key, password, cancellable, "user", new_key);
+            if (result)
+                yield Secret.password_clear(Secret.SCHEMA_COMPAT_NETWORK, cancellable, "user", old_key);
+        }
+        
+        return password;
+    }
     
     public virtual async string? get_password_async(
-        Geary.CredentialsMediator.Service service, string username, Cancellable? cancellable = null)
+        Geary.CredentialsMediator.Service service, Geary.AccountInformation account_information, 
Cancellable? cancellable = null)
         throws Error {
+        string key_name = get_key_name(service, account_information.email);
         string? password = yield Secret.password_lookup(Secret.SCHEMA_COMPAT_NETWORK, cancellable,
-            "user", get_key_name(service, username));
+            "user", key_name);
         
+        // fallback to the old keyring key string for upgrading users
         if (password == null) {
-            // fallback to the old keyring key string for upgrading users
-            password = yield Secret.password_lookup(Secret.SCHEMA_COMPAT_NETWORK, cancellable,
-                "user", OLD_GEARY_USERNAME_PREFIX + username);
+            Geary.Credentials creds = get_credentials(service, account_information);
+            
+            // <= 0.6
+            password = yield migrate_old_password(get_key_name(service, creds.user),
+                key_name, cancellable);
+            
+            // 0.1
+            if (password == null) {
+                password = yield migrate_old_password(OLD_GEARY_USERNAME_PREFIX + creds.user,
+                    key_name, cancellable);
+            }
         }
         
         if (password == null)
-            debug("Unable to fetch password in libsecret keyring for user: %s", username);
+            debug("Unable to fetch password in libsecret keyring for %s", account_information.email);
         
         return password;
     }
     
     public virtual async void set_password_async(
-        Geary.CredentialsMediator.Service service, Geary.Credentials credentials,
+        Geary.CredentialsMediator.Service service, Geary.AccountInformation account_information,
         Cancellable? cancellable = null) throws Error {
-        string key_name = get_key_name(service, credentials.user);
+        string key_name = get_key_name(service, account_information.email);
+        Geary.Credentials credentials = get_credentials(service, account_information);
         
         bool result = yield Secret.password_store(Secret.SCHEMA_COMPAT_NETWORK,
             null, key_name, credentials.pass, cancellable, "user", key_name);
-        
         if (!result)
-            debug("Unable to store password in libsecret keyring: %s", result.to_string());
+            debug("Unable to store password for \"%s\" in libsecret keyring", key_name);
     }
     
     public virtual async void clear_password_async(
-        Geary.CredentialsMediator.Service service, string username, Cancellable? cancellable = null)
+        Geary.CredentialsMediator.Service service, Geary.AccountInformation account_information, 
Cancellable? cancellable = null)
         throws Error {
         // delete new-style and old-style locations
+        Geary.Credentials credentials = get_credentials(service, account_information);
+        // new-style
+        yield Secret.password_clear(Secret.SCHEMA_COMPAT_NETWORK, cancellable, "user",
+            get_key_name(service, account_information.email));
+        // <= 0.6
         yield Secret.password_clear(Secret.SCHEMA_COMPAT_NETWORK, cancellable, "user",
-            get_key_name(service, username));
+            get_key_name(service, credentials.user));
+        // 0.1
         yield Secret.password_clear(Secret.SCHEMA_COMPAT_NETWORK, cancellable, "user",
-            OLD_GEARY_USERNAME_PREFIX + username);
+            OLD_GEARY_USERNAME_PREFIX + credentials.user);
     }
     
     public virtual async bool prompt_passwords_async(Geary.CredentialsMediator.ServiceFlag services,
diff --git a/src/engine/api/geary-account-information.vala b/src/engine/api/geary-account-information.vala
index 793df1b..c00dbb8 100644
--- a/src/engine/api/geary-account-information.vala
+++ b/src/engine/api/geary-account-information.vala
@@ -293,13 +293,13 @@ public class Geary.AccountInformation : BaseObject {
             // Delete the current password(s).
             if (services.has_imap()) {
                 yield Geary.Engine.instance.authentication_mediator.clear_password_async(
-                    CredentialsMediator.Service.IMAP, email);
+                    CredentialsMediator.Service.IMAP, this);
                 
                 if (imap_credentials != null)
                     imap_credentials.pass = null;
             } else if (services.has_smtp()) {
                 yield Geary.Engine.instance.authentication_mediator.clear_password_async(
-                    CredentialsMediator.Service.SMTP, email);
+                    CredentialsMediator.Service.SMTP, this);
                 
                 if (smtp_credentials != null)
                     smtp_credentials.pass = null;
@@ -361,7 +361,7 @@ public class Geary.AccountInformation : BaseObject {
         
         if (services.has_imap()) {
             string? imap_password = yield mediator.get_password_async(
-                CredentialsMediator.Service.IMAP, imap_credentials.user);
+                CredentialsMediator.Service.IMAP, this);
             
             if (imap_password != null)
                 set_imap_password(imap_password);
@@ -371,7 +371,7 @@ public class Geary.AccountInformation : BaseObject {
         
         if (services.has_smtp() && smtp_credentials != null) {
             string? smtp_password = yield mediator.get_password_async(
-                CredentialsMediator.Service.SMTP, smtp_credentials.user);
+                CredentialsMediator.Service.SMTP, this);
             
             if (smtp_password != null)
                 set_smtp_password(smtp_password);
@@ -433,20 +433,20 @@ public class Geary.AccountInformation : BaseObject {
         if (services.has_imap()) {
             if (imap_remember_password) {
                 yield mediator.set_password_async(
-                    CredentialsMediator.Service.IMAP, imap_credentials);
+                    CredentialsMediator.Service.IMAP, this);
             } else {
                 yield mediator.clear_password_async(
-                    CredentialsMediator.Service.IMAP, imap_credentials.user);
+                    CredentialsMediator.Service.IMAP, this);
             }
         }
         
         if (services.has_smtp() && smtp_credentials != null) {
             if (smtp_remember_password) {
                 yield mediator.set_password_async(
-                    CredentialsMediator.Service.SMTP, smtp_credentials);
+                    CredentialsMediator.Service.SMTP, this);
             } else {
                 yield mediator.clear_password_async(
-                    CredentialsMediator.Service.SMTP, smtp_credentials.user);
+                    CredentialsMediator.Service.SMTP, this);
             }
         }
     }
@@ -655,7 +655,7 @@ public class Geary.AccountInformation : BaseObject {
         try {
             if (services.has_imap()) {
                 yield mediator.clear_password_async(
-                    CredentialsMediator.Service.IMAP, imap_credentials.user);
+                    CredentialsMediator.Service.IMAP, this);
             }
         } catch (Error e) {
             return_error = e;
@@ -664,7 +664,7 @@ public class Geary.AccountInformation : BaseObject {
         try {
             if (services.has_smtp() && smtp_credentials != null) {
                 yield mediator.clear_password_async(
-                    CredentialsMediator.Service.SMTP, smtp_credentials.user);
+                    CredentialsMediator.Service.SMTP, this);
             }
         } catch (Error e) {
             return_error = e;
diff --git a/src/engine/api/geary-credentials-mediator.vala b/src/engine/api/geary-credentials-mediator.vala
index cdce5a2..fa6b683 100644
--- a/src/engine/api/geary-credentials-mediator.vala
+++ b/src/engine/api/geary-credentials-mediator.vala
@@ -29,7 +29,8 @@ public interface Geary.CredentialsMediator : Object {
      * service.  Return null if the password wasn't in the key store, or the
      * password if it was.
      */
-    public abstract async string? get_password_async(Service service, string username,
+    public abstract async string? get_password_async(Service service,
+        AccountInformation account_information,
         Cancellable? cancellable = null) throws Error;
     
     /**
@@ -37,14 +38,16 @@ public interface Geary.CredentialsMediator : Object {
      * for the given service.
      */
     public abstract async void set_password_async(Service service,
-        Geary.Credentials credentials, Cancellable? cancellable = null) throws Error;
+        AccountInformation account_information,
+        Cancellable? cancellable = null) throws Error;
     
     /**
      * Deletes the key store's password entry for the given credentials for the
      * given service.  Do nothing (and do *not* throw an error) if the
      * credentials weren't in the key store.
      */
-    public abstract async void clear_password_async(Service service, string username,
+    public abstract async void clear_password_async(Service service,
+        AccountInformation account_information,
         Cancellable? cancellable = null) throws Error;
     
     /**


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