[shotwell] publising: Bind secrets to the shotwell profile



commit e9aef49850c5ce83e852d06dd491ad2144fbf0cd
Author: Jens Georg <mail jensge org>
Date:   Tue Dec 22 09:35:06 2020 +0100

    publising: Bind secrets to the shotwell profile
    
    So if you log out in one profile, the saved credentials are still
    available in another

 .../shotwell/GoogleAuthenticator.vala              | 18 ++++--
 .../shotwell/OAuth1Authenticator.vala              | 65 ++++++++++++----------
 .../GalleryConnector.vala                          | 11 +++-
 .../RajcePublishing.vala                           | 11 +++-
 plugins/shotwell-publishing/PiwigoPublishing.vala  | 11 +++-
 src/plugins/PublishingInterfaces.vala              |  2 +
 src/publishing/PublishingPluginHost.vala           |  4 ++
 7 files changed, 82 insertions(+), 40 deletions(-)
---
diff --git a/plugins/authenticator/shotwell/GoogleAuthenticator.vala 
b/plugins/authenticator/shotwell/GoogleAuthenticator.vala
index a5c139a5..a0a0bf99 100644
--- a/plugins/authenticator/shotwell/GoogleAuthenticator.vala
+++ b/plugins/authenticator/shotwell/GoogleAuthenticator.vala
@@ -7,6 +7,7 @@ namespace Publishing.Authenticator.Shotwell.Google {
     private const string OAUTH_CLIENT_SECRET = "pwpzZ7W1TCcD5uIfYCu8sM7x";
     private const string OAUTH_CALLBACK_URI = REVERSE_CLIENT_ID + ":/auth-callback";
 
+    private const string SCHEMA_KEY_PROFILE_ID = "shotwell-profile-id";
     private const string SCHEMA_KEY_ACCOUNTNAME = "accountname";
 
     private class WebAuthenticationPane : Common.WebAuthenticationPane {
@@ -135,16 +136,18 @@ namespace Publishing.Authenticator.Shotwell.Google {
             this.scope = scope;
             this.session = new Session();
             this.welcome_message = welcome_message;
-            this.schema = new Secret.Schema (PASSWORD_SCHEME, Secret.SchemaFlags.NONE,
-                                             SCHEMA_KEY_ACCOUNTNAME, Secret.SchemaAttributeType.STRING,
-                                             "scope", Secret.SchemaAttributeType.STRING);
+            this.schema = new Secret.Schema(PASSWORD_SCHEME, Secret.SchemaFlags.NONE,
+                SCHEMA_KEY_PROFILE_ID, Secret.SchemaAttributeType.STRING,
+                SCHEMA_KEY_ACCOUNTNAME, Secret.SchemaAttributeType.STRING,
+                "scope", Secret.SchemaAttributeType.STRING);
         }
 
         public void authenticate() {
             string? refresh_token = null;
             try {
                 refresh_token = Secret.password_lookup_sync(this.schema, null,
-                                                            SCHEMA_KEY_ACCOUNTNAME, this.accountname, 
"scope", this.scope);
+                    SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+                    SCHEMA_KEY_ACCOUNTNAME, this.accountname, "scope", this.scope);
             } catch (Error err) {
                 critical("Failed to lookup refresh_token from password store: %s", err.message);
             }
@@ -176,7 +179,8 @@ namespace Publishing.Authenticator.Shotwell.Google {
             session.deauthenticate();
             try {
                 Secret.password_clear_sync(this.schema, null,
-                                           SCHEMA_KEY_ACCOUNTNAME, this.accountname, "scope", this.scope);
+                    SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+                    SCHEMA_KEY_ACCOUNTNAME, this.accountname, "scope", this.scope);
             } catch (Error err) {
                 critical("Failed to remove password for scope %s: %s", this.scope, err.message);
             }
@@ -398,6 +402,7 @@ namespace Publishing.Authenticator.Shotwell.Google {
                 Secret.password_store_sync(this.schema, Secret.COLLECTION_DEFAULT,
                     "Shotwell publishing (Google account scope %s@%s)".printf(this.accountname, this.scope),
                     session.refresh_token, null,
+                    SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
                     SCHEMA_KEY_ACCOUNTNAME, this.accountname, "scope", this.scope);
             } catch (Error err) {
                 critical("Failed to look up password for scope %s: %s", this.scope, err.message);
@@ -451,7 +456,8 @@ namespace Publishing.Authenticator.Shotwell.Google {
                 // Refresh token invalid, starting over
                 try {
                     Secret.password_clear_sync(this.schema, null,
-                            SCHEMA_KEY_ACCOUNTNAME, this.accountname, "scope", this.scope);
+                        SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+                        SCHEMA_KEY_ACCOUNTNAME, this.accountname, "scope", this.scope);
                 } catch (Error err) {
                     critical("Failed to remove password for accountname@scope %s@%s: %s", this.accountname, 
this.scope, err.message);
                 }
diff --git a/plugins/authenticator/shotwell/OAuth1Authenticator.vala 
b/plugins/authenticator/shotwell/OAuth1Authenticator.vala
index a2b4cbb1..e79c6fd6 100644
--- a/plugins/authenticator/shotwell/OAuth1Authenticator.vala
+++ b/plugins/authenticator/shotwell/OAuth1Authenticator.vala
@@ -16,6 +16,7 @@ namespace Publishing.Authenticator.Shotwell.OAuth1 {
         private const string SECRET_TYPE_AUTH_TOKEN = "auth-token";
         private const string SECRET_TYPE_AUTH_TOKEN_SECRET = "auth-token-secret";
         private const string SCHEMA_KEY_ACCOUNTNAME = "accountname";
+        private const string SCHEMA_KEY_PROFILE_ID = "shotwell-profile-id";
         private string service = null;
         private string accountname = "default";
 
@@ -23,9 +24,10 @@ namespace Publishing.Authenticator.Shotwell.OAuth1 {
             base();
             this.host = host;
             this.service = service;
-            this.schema = new Secret.Schema ("org.gnome.Shotwell." + service, Secret.SchemaFlags.NONE,
-                                             SCHEMA_KEY_ACCOUNTNAME, Secret.SchemaAttributeType.STRING,
-                                             "type", Secret.SchemaAttributeType.STRING);
+            this.schema = new Secret.Schema("org.gnome.Shotwell." + service, Secret.SchemaFlags.NONE,
+                SCHEMA_KEY_PROFILE_ID, Secret.SchemaAttributeType.STRING,
+                SCHEMA_KEY_ACCOUNTNAME, Secret.SchemaAttributeType.STRING,
+                "type", Secret.SchemaAttributeType.STRING);
 
             params = new GLib.HashTable<string, Variant>(str_hash, str_equal);
             params.insert("ConsumerKey", api_key);
@@ -62,6 +64,7 @@ namespace Publishing.Authenticator.Shotwell.OAuth1 {
             set_persistent_access_phase_token_secret(null);
             set_persistent_access_phase_username(null);
         }
+
         protected bool is_persistent_session_valid() {
             return (get_persistent_access_phase_username() != null &&
                     get_persistent_access_phase_token() != null &&
@@ -71,7 +74,8 @@ namespace Publishing.Authenticator.Shotwell.OAuth1 {
         protected string? get_persistent_access_phase_username() {
             try {
                 return Secret.password_lookup_sync(this.schema, null,
-                            SCHEMA_KEY_ACCOUNTNAME, this.accountname, "type", SECRET_TYPE_USERNAME);
+                    SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+                    SCHEMA_KEY_ACCOUNTNAME, this.accountname, "type", SECRET_TYPE_USERNAME);
             } catch (Error err) {
                 critical("Failed to lookup username from password store: %s", err.message);
                 return null;
@@ -82,13 +86,15 @@ namespace Publishing.Authenticator.Shotwell.OAuth1 {
             try {
                 if (username == null || username == "") {
                     Secret.password_clear_sync(this.schema, null,
-                                               SCHEMA_KEY_ACCOUNTNAME, this.accountname,
-                                               "type", SECRET_TYPE_USERNAME);
+                        SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+                        SCHEMA_KEY_ACCOUNTNAME, this.accountname,
+                        "type", SECRET_TYPE_USERNAME);
                 } else {
                     Secret.password_store_sync(this.schema, Secret.COLLECTION_DEFAULT,
-                                               "Shotwell publishing (%s@%s)".printf(this.accountname, 
this.service),
-                                               username, null,
-                                               SCHEMA_KEY_ACCOUNTNAME, this.accountname, "type", 
SECRET_TYPE_USERNAME);
+                        "Shotwell publishing (%s@%s)".printf(this.accountname, this.service),
+                        username, null,
+                        SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+                        SCHEMA_KEY_ACCOUNTNAME, this.accountname, "type", SECRET_TYPE_USERNAME);
                 }
             } catch (Error err) {
                 critical("Failed to store username in store: %s", err.message);
@@ -98,8 +104,9 @@ namespace Publishing.Authenticator.Shotwell.OAuth1 {
         protected string? get_persistent_access_phase_token() {
             try {
                 return Secret.password_lookup_sync(this.schema, null,
-                                                   SCHEMA_KEY_ACCOUNTNAME, this.accountname,
-                                                   "type", SECRET_TYPE_AUTH_TOKEN);
+                    SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+                    SCHEMA_KEY_ACCOUNTNAME, this.accountname,
+                    "type", SECRET_TYPE_AUTH_TOKEN);
             } catch (Error err) {
                 critical("Failed to lookup auth-token from password store: %s", err.message);
                 return null;
@@ -110,14 +117,16 @@ namespace Publishing.Authenticator.Shotwell.OAuth1 {
             try {
                 if (token == null || token == "") {
                     Secret.password_clear_sync(this.schema, null,
-                                               SCHEMA_KEY_ACCOUNTNAME, this.accountname,
-                                               "type", SECRET_TYPE_AUTH_TOKEN);
+                        SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+                        SCHEMA_KEY_ACCOUNTNAME, this.accountname,
+                        "type", SECRET_TYPE_AUTH_TOKEN);
                 } else {
                     Secret.password_store_sync(this.schema, Secret.COLLECTION_DEFAULT,
-                                               "Shotwell publishing (%s@%s)".printf(this.accountname, 
this.service),
-                                               token, null,
-                                               SCHEMA_KEY_ACCOUNTNAME, this.accountname,
-                                               "type", SECRET_TYPE_AUTH_TOKEN);
+                        "Shotwell publishing (%s@%s)".printf(this.accountname, this.service),
+                        token, null,
+                        SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+                        SCHEMA_KEY_ACCOUNTNAME, this.accountname,
+                        "type", SECRET_TYPE_AUTH_TOKEN);
                 }
             } catch (Error err) {
                 critical("Failed to store auth-token store: %s", err.message);
@@ -127,8 +136,9 @@ namespace Publishing.Authenticator.Shotwell.OAuth1 {
         protected string? get_persistent_access_phase_token_secret() {
             try {
                 return Secret.password_lookup_sync(this.schema, null,
-                        SCHEMA_KEY_ACCOUNTNAME, this.accountname,
-                        "type", SECRET_TYPE_AUTH_TOKEN_SECRET);
+                    SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+                    SCHEMA_KEY_ACCOUNTNAME, this.accountname,
+                    "type", SECRET_TYPE_AUTH_TOKEN_SECRET);
             } catch (Error err) {
                 critical("Failed to lookup auth-token-secret from password store: %s", err.message);
                 return null;
@@ -139,21 +149,22 @@ namespace Publishing.Authenticator.Shotwell.OAuth1 {
             try {
                 if (secret == null || secret == "") {
                     Secret.password_clear_sync(this.schema, null,
-                                               SCHEMA_KEY_ACCOUNTNAME, this.accountname,
-                                               "type", SECRET_TYPE_AUTH_TOKEN_SECRET);
+                        SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+                        SCHEMA_KEY_ACCOUNTNAME, this.accountname,
+                        "type", SECRET_TYPE_AUTH_TOKEN_SECRET);
                 } else {
                     Secret.password_store_sync(this.schema, Secret.COLLECTION_DEFAULT,
-                                               "Shotwell publishing (%s@%s)".printf(this.accountname, 
this.service),
-                                               secret, null,
-                                               SCHEMA_KEY_ACCOUNTNAME, this.accountname,
-                                               "type", SECRET_TYPE_AUTH_TOKEN_SECRET);
+                        "Shotwell publishing (%s@%s)".printf(this.accountname, this.service),
+                        secret, null,
+                        SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+                        SCHEMA_KEY_ACCOUNTNAME, this.accountname,
+                        "type", SECRET_TYPE_AUTH_TOKEN_SECRET);
                 }
             } catch (Error err) {
                 critical("Failed to store auth-token-secret store: %s", err.message);
             }
         }
 
-
         protected void on_session_authenticated() {
             params.insert("AuthToken", session.get_access_phase_token());
             params.insert("AuthTokenSecret", session.get_access_phase_token_secret());
@@ -166,7 +177,5 @@ namespace Publishing.Authenticator.Shotwell.OAuth1 {
 
             this.authenticated();
         }
-
     }
-
 }
diff --git a/plugins/shotwell-publishing-extras/GalleryConnector.vala 
b/plugins/shotwell-publishing-extras/GalleryConnector.vala
index e5e9abe0..44b7caec 100644
--- a/plugins/shotwell-publishing-extras/GalleryConnector.vala
+++ b/plugins/shotwell-publishing-extras/GalleryConnector.vala
@@ -800,6 +800,7 @@ private class GalleryUploadTransaction :
 
 public class GalleryPublisher : Spit.Publishing.Publisher, GLib.Object {
     private const string PASSWORD_SCHEME = "org.gnome.Shotwell.Gallery3";
+    private const string SCHEMA_KEY_PROFILE_ID = "shotwell-profile-id";
     private const string BAD_FILE_MSG = _("\n\nThe file ā€œ%sā€ may not be supported by or may be too large for 
this instance of Gallery3.");
     private const string BAD_MOVIE_MSG = _("\nNote that Gallery3 only supports the video types that 
Flowplayer does.");
 
@@ -820,6 +821,7 @@ public class GalleryPublisher : Spit.Publishing.Publisher, GLib.Object {
         this.host = host;
         this.session = new Session();
         this.schema = new Secret.Schema (PASSWORD_SCHEME, Secret.SchemaFlags.NONE,
+                                        SCHEMA_KEY_PROFILE_ID, Secret.SchemaAttributeType.STRING,
                                         "url", Secret.SchemaAttributeType.STRING,
                                         "user", Secret.SchemaAttributeType.STRING);
     }
@@ -882,7 +884,9 @@ public class GalleryPublisher : Spit.Publishing.Publisher, GLib.Object {
         var url = get_gallery_url();
 
         try {
-            return Secret.password_lookup_sync(this.schema, null, "url", url, "user", user);
+            return Secret.password_lookup_sync(this.schema, null,
+                            SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+            "url", url, "user", user);
         } catch (Error err) {
             critical ("Failed to get api key for %s@%s: %s", user, url, err.message);
         }
@@ -895,12 +899,15 @@ public class GalleryPublisher : Spit.Publishing.Publisher, GLib.Object {
         var url = get_gallery_url();
         try {
             if (key == null | key == "") {
-                Secret.password_clear_sync(this.schema, null, "url", url, "user", user);
+                Secret.password_clear_sync(this.schema, null,
+                            SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+                "url", url, "user", user);
             } else {
                 Secret.password_store_sync(this.schema, Secret.COLLECTION_DEFAULT,
                                            "Shotwell publishing (Gallery3 account %s@%s)".printf(user, url),
                                            key,
                                            null,
+                            SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
                                            "url", url, "user", user);
             }
         } catch (Error err) {
diff --git a/plugins/shotwell-publishing-extras/RajcePublishing.vala 
b/plugins/shotwell-publishing-extras/RajcePublishing.vala
index f4f8b73e..4b733f5e 100644
--- a/plugins/shotwell-publishing-extras/RajcePublishing.vala
+++ b/plugins/shotwell-publishing-extras/RajcePublishing.vala
@@ -66,6 +66,7 @@ namespace Publishing.Rajce
 public class RajcePublisher : Spit.Publishing.Publisher, GLib.Object
 {
     private const string PASSWORD_SCHEME = "org.gnome.Shotwell.Rajce";
+    private const string SCHEMA_KEY_PROFILE_ID = "shotwell-profile-id";
     private Spit.Publishing.PluginHost host = null;
     private Spit.Publishing.ProgressCallback progress_reporter = null;
     private Spit.Publishing.Service service = null;
@@ -94,6 +95,7 @@ public class RajcePublisher : Spit.Publishing.Publisher, GLib.Object
             media_type |= p.get_media_type();
 
         this.schema = new Secret.Schema(PASSWORD_SCHEME, Secret.SchemaFlags.NONE,
+                                        SCHEMA_KEY_PROFILE_ID, Secret.SchemaAttributeType.STRING,
                                         "user", Secret.SchemaAttributeType.STRING);
     }
     
@@ -151,7 +153,9 @@ public class RajcePublisher : Spit.Publishing.Publisher, GLib.Object
             return null;
 
         try {
-            return Secret.password_lookup_sync(this.schema, null, "user", user);
+            return Secret.password_lookup_sync(this.schema, null,
+                            SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+            "user", user);
         } catch (Error err) {
             critical("Failed to get token for user %s: %s", user, err.message);
         }
@@ -166,12 +170,15 @@ public class RajcePublisher : Spit.Publishing.Publisher, GLib.Object
 
         try {
             if (token == null || token == "") {
-                Secret.password_clear_sync(this.schema, null, "user", user);
+                Secret.password_clear_sync(this.schema, null,
+                            SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+                "user", user);
             } else {
                 Secret.password_store_sync(this.schema, Secret.COLLECTION_DEFAULT,
                                            "Shotwell publishing (Rajce user %s)".printf(user),
                                            token,
                                            null,
+                            SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
                                            "user", user);
             }
         } catch (Error err) {
diff --git a/plugins/shotwell-publishing/PiwigoPublishing.vala 
b/plugins/shotwell-publishing/PiwigoPublishing.vala
index 3cbbf1fd..1502cf25 100644
--- a/plugins/shotwell-publishing/PiwigoPublishing.vala
+++ b/plugins/shotwell-publishing/PiwigoPublishing.vala
@@ -125,6 +125,7 @@ internal class PublishingParameters {
 
 public class PiwigoPublisher : Spit.Publishing.Publisher, GLib.Object {
     private const string PASSWORD_SCHEME = "org.gnome.Shotwell.Piwigo";
+    private const string SCHEMA_KEY_PROFILE_ID = "shotwell-profile-id";
 
     private Spit.Publishing.Service service;
     private Spit.Publishing.PluginHost host;
@@ -143,6 +144,7 @@ public class PiwigoPublisher : Spit.Publishing.Publisher, GLib.Object {
         this.host = host;
         session = new Session();
         this.schema = new Secret.Schema (PASSWORD_SCHEME, Secret.SchemaFlags.NONE,
+                                         SCHEMA_KEY_PROFILE_ID, Secret.SchemaAttributeType.STRING,
                                          "url", Secret.SchemaAttributeType.STRING,
                                          "user", Secret.SchemaAttributeType.STRING);
     }
@@ -212,7 +214,9 @@ public class PiwigoPublisher : Spit.Publishing.Publisher, GLib.Object {
     public string? get_persistent_password(string? url, string? user) {
         if (url != null && user != null) {
             try {
-                var pw = Secret.password_lookup_sync(this.schema, null, "url", url, "user", user);
+                var pw = Secret.password_lookup_sync(this.schema, null,
+                            SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+                "url", url, "user", user);
 
                 return pw;
             } catch (Error err) {
@@ -229,12 +233,15 @@ public class PiwigoPublisher : Spit.Publishing.Publisher, GLib.Object {
         try {
             if (password == null) {
                 // remove
-                Secret.password_clear_sync(this.schema, null, "url", url, "user", user);
+                Secret.password_clear_sync(this.schema, null,
+                            SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
+                "url", url, "user", user);
             } else {
                 Secret.password_store_sync(this.schema, Secret.COLLECTION_DEFAULT,
                         "Shotwell publishing (Piwigo account %s@%s)".printf(user, url),
                         password,
                         null,
+                            SCHEMA_KEY_PROFILE_ID, host.get_current_profile_id(),
                         "url", url, "user", user);
             }
         } catch (Error err) {
diff --git a/src/plugins/PublishingInterfaces.vala b/src/plugins/PublishingInterfaces.vala
index a2728e58..4ac5754f 100644
--- a/src/plugins/PublishingInterfaces.vala
+++ b/src/plugins/PublishingInterfaces.vala
@@ -268,6 +268,8 @@ public interface PluginHost : GLib.Object, Spit.HostInterface {
         CANCEL = 1
     }
 
+    public abstract string get_current_profile_id();
+
     /**
      * Notifies the user that an unrecoverable publishing error has occurred and halts
      * the publishing process.
diff --git a/src/publishing/PublishingPluginHost.vala b/src/publishing/PublishingPluginHost.vala
index ca935ab3..22f6c34d 100644
--- a/src/publishing/PublishingPluginHost.vala
+++ b/src/publishing/PublishingPluginHost.vala
@@ -32,6 +32,10 @@ public class ConcretePublishingHost : Plugins.StandardHostInterface,
         
         this.active_publisher = service.create_publisher(this);
     }
+
+    public string get_current_profile_id() {
+        return Shotwell.ProfileManager.get_instance().id();
+    }
     
     private void on_login_clicked() {
         if (current_login_callback != null)


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