[shotwell] Move OAuth1 code into common library



commit 3d44027404c19eb1f97c17f4f106a99876ba848f
Author: Jens Georg <mail jensge org>
Date:   Wed Nov 8 23:43:21 2017 +0100

    Move OAuth1 code into common library

 .../shotwell/FlickrPublishingAuthenticator.vala    |    8 +-
 .../shotwell/OAuth1Authenticator.vala              |  177 +-------------------
 .../shotwell/TumblrAuthenticator.vala              |    4 +-
 plugins/common/RESTSupport.vala                    |  175 +++++++++++++++++++
 plugins/shotwell-publishing/FlickrPublishing.vala  |  172 +------------------
 plugins/shotwell-publishing/TumblrPublishing.vala  |  178 +-------------------
 6 files changed, 201 insertions(+), 513 deletions(-)
---
diff --git a/plugins/authenticator/shotwell/FlickrPublishingAuthenticator.vala 
b/plugins/authenticator/shotwell/FlickrPublishingAuthenticator.vala
index 111c772..387392f 100644
--- a/plugins/authenticator/shotwell/FlickrPublishingAuthenticator.vala
+++ b/plugins/authenticator/shotwell/FlickrPublishingAuthenticator.vala
@@ -14,16 +14,16 @@ namespace Publishing.Authenticator.Shotwell.Flickr {
     internal const string SERVICE_WELCOME_MESSAGE =
         _("You are not currently logged into Flickr.\n\nClick Log in to log into Flickr in your Web browser. 
You will have to authorize Shotwell Connect to link to your Flickr account.");
 
-    internal class AuthenticationRequestTransaction : OAuth1.Transaction {
-        public AuthenticationRequestTransaction(OAuth1.Session session) {
+    internal class AuthenticationRequestTransaction : Publishing.RESTSupport.OAuth1.Transaction {
+        public AuthenticationRequestTransaction(Publishing.RESTSupport.OAuth1.Session session) {
             base.with_uri(session, "https://www.flickr.com/services/oauth/request_token";,
                     Publishing.RESTSupport.HttpMethod.GET);
             add_argument("oauth_callback", "oob");
         }
     }
 
-    internal class AccessTokenFetchTransaction : OAuth1.Transaction {
-        public AccessTokenFetchTransaction(OAuth1.Session session, string user_verifier) {
+    internal class AccessTokenFetchTransaction : Publishing.RESTSupport.OAuth1.Transaction {
+        public AccessTokenFetchTransaction(Publishing.RESTSupport.OAuth1.Session session, string 
user_verifier) {
             base.with_uri(session, "https://www.flickr.com/services/oauth/access_token";,
                     Publishing.RESTSupport.HttpMethod.GET);
             add_argument("oauth_verifier", user_verifier);
diff --git a/plugins/authenticator/shotwell/OAuth1Authenticator.vala 
b/plugins/authenticator/shotwell/OAuth1Authenticator.vala
index 62988ec..399b66f 100644
--- a/plugins/authenticator/shotwell/OAuth1Authenticator.vala
+++ b/plugins/authenticator/shotwell/OAuth1Authenticator.vala
@@ -6,182 +6,10 @@
  */
 
 namespace Publishing.Authenticator.Shotwell.OAuth1 {
-    internal const string ENCODE_RFC_3986_EXTRA = "!*'();:@&=+$,/?%#[] \\";
-
-    internal class Session : Publishing.RESTSupport.Session {
-        private string? request_phase_token = null;
-        private string? request_phase_token_secret = null;
-        private string? access_phase_token = null;
-        private string? access_phase_token_secret = null;
-        private string? username = null;
-        private string? consumer_key = null;
-        private string? consumer_secret = null;
-
-        public Session() {
-            base();
-        }
-
-        public override bool is_authenticated() {
-            return (access_phase_token != null && access_phase_token_secret != null &&
-                    username != null);
-        }
-
-        public void authenticate_from_persistent_credentials(string token, string secret,
-                string username) {
-            this.access_phase_token = token;
-            this.access_phase_token_secret = secret;
-            this.username = username;
-
-            this.authenticated();
-        }
-
-        public void deauthenticate() {
-            access_phase_token = null;
-            access_phase_token_secret = null;
-            username = null;
-        }
-
-        public void set_api_credentials(string consumer_key, string consumer_secret) {
-            this.consumer_key = consumer_key;
-            this.consumer_secret = consumer_secret;
-        }
-
-        public void sign_transaction(Publishing.RESTSupport.Transaction txn) {
-            string http_method = txn.get_method().to_string();
-
-            debug("signing transaction with parameters:");
-            debug("HTTP method = " + http_method);
-
-            Publishing.RESTSupport.Argument[] base_string_arguments = txn.get_arguments();
-
-            Publishing.RESTSupport.Argument[] sorted_args =
-                Publishing.RESTSupport.Argument.sort(base_string_arguments);
-
-            string arguments_string = "";
-            for (int i = 0; i < sorted_args.length; i++) {
-                arguments_string += (sorted_args[i].key + "=" + sorted_args[i].value);
-                if (i < sorted_args.length - 1)
-                    arguments_string += "&";
-            }
-
-            string? signing_key = null;
-            if (access_phase_token_secret != null) {
-                debug("access phase token secret available; using it as signing key");
-
-                signing_key = consumer_secret + "&" + access_phase_token_secret;
-            } else if (request_phase_token_secret != null) {
-                debug("request phase token secret available; using it as signing key");
-
-                signing_key = consumer_secret + "&" + request_phase_token_secret;
-            } else {
-                debug("neither access phase nor request phase token secrets available; using API " +
-                        "key as signing key");
-
-                signing_key = consumer_secret + "&";
-            }
-
-            string signature_base_string = http_method + "&" + Soup.URI.encode(
-                    txn.get_endpoint_url(), ENCODE_RFC_3986_EXTRA) + "&" +
-                Soup.URI.encode(arguments_string, ENCODE_RFC_3986_EXTRA);
-
-            debug("signature base string = '%s'", signature_base_string);
-
-            debug("signing key = '%s'", signing_key);
-
-            // compute the signature
-            string signature = RESTSupport.hmac_sha1(signing_key, signature_base_string);
-            signature = Soup.URI.encode(signature, ENCODE_RFC_3986_EXTRA);
-
-            debug("signature = '%s'", signature);
-
-            txn.add_argument("oauth_signature", signature);
-        }
-
-        public void set_request_phase_credentials(string token, string secret) {
-            this.request_phase_token = token;
-            this.request_phase_token_secret = secret;
-        }
-
-        public void set_access_phase_credentials(string token, string secret, string username) {
-            this.access_phase_token = token;
-            this.access_phase_token_secret = secret;
-            this.username = username;
-
-            authenticated();
-        }
-
-        public string get_oauth_nonce() {
-            TimeVal currtime = TimeVal();
-            currtime.get_current_time();
-
-            return Checksum.compute_for_string(ChecksumType.MD5, currtime.tv_sec.to_string() +
-                    currtime.tv_usec.to_string());
-        }
-
-        public string get_oauth_timestamp() {
-            return GLib.get_real_time().to_string().substring(0, 10);
-        }
-
-        public string get_consumer_key() {
-            assert(consumer_key != null);
-            return consumer_key;
-        }
-
-        public string get_request_phase_token() {
-            assert(request_phase_token != null);
-            return request_phase_token;
-        }
-
-        public string get_access_phase_token() {
-            assert(access_phase_token != null);
-            return access_phase_token;
-        }
-
-        public string get_access_phase_token_secret() {
-            assert(access_phase_token_secret != null);
-            return access_phase_token_secret;
-        }
-
-        public string get_username() {
-            assert(is_authenticated());
-            return username;
-        }
-    }
-
-    internal class Transaction : Publishing.RESTSupport.Transaction {
-        public Transaction(Session session, Publishing.RESTSupport.HttpMethod method =
-                Publishing.RESTSupport.HttpMethod.POST) {
-            base(session, method);
-            setup_arguments();
-        }
-
-        public Transaction.with_uri(Session session, string uri,
-                Publishing.RESTSupport.HttpMethod method = Publishing.RESTSupport.HttpMethod.POST) {
-            base.with_endpoint_url(session, uri, method);
-            setup_arguments();
-        }
-
-        private void setup_arguments() {
-            var session = (Session) get_parent_session();
-
-            add_argument("oauth_nonce", session.get_oauth_nonce());
-            add_argument("oauth_signature_method", "HMAC-SHA1");
-            add_argument("oauth_version", "1.0");
-            add_argument("oauth_timestamp", session.get_oauth_timestamp());
-            add_argument("oauth_consumer_key", session.get_consumer_key());
-        }
-
-
-        public override void execute() throws Spit.Publishing.PublishingError {
-            ((Session) get_parent_session()).sign_transaction(this);
-
-            base.execute();
-        }
-    }
 
     internal abstract class Authenticator : GLib.Object, Spit.Publishing.Authenticator {
         protected GLib.HashTable<string, Variant> params;
-        protected Session session;
+        protected Publishing.RESTSupport.OAuth1.Session session;
         protected Spit.Publishing.PluginHost host;
 
         public Authenticator(string api_key, string api_secret, Spit.Publishing.PluginHost host) {
@@ -192,7 +20,7 @@ namespace Publishing.Authenticator.Shotwell.OAuth1 {
             params.insert("ConsumerKey", api_key);
             params.insert("ConsumerSecret", api_secret);
 
-            session = new Session();
+            session = new Publishing.RESTSupport.OAuth1.Session();
             session.set_api_credentials(api_key, api_secret);
             session.authenticated.connect(on_session_authenticated);
         }
@@ -219,7 +47,6 @@ namespace Publishing.Authenticator.Shotwell.OAuth1 {
             set_persistent_access_phase_token_secret("");
             set_persistent_access_phase_username("");
         }
-
         protected bool is_persistent_session_valid() {
             return (get_persistent_access_phase_username() != null &&
                     get_persistent_access_phase_token() != null &&
diff --git a/plugins/authenticator/shotwell/TumblrAuthenticator.vala 
b/plugins/authenticator/shotwell/TumblrAuthenticator.vala
index 5d2c847..35fdce9 100644
--- a/plugins/authenticator/shotwell/TumblrAuthenticator.vala
+++ b/plugins/authenticator/shotwell/TumblrAuthenticator.vala
@@ -115,8 +115,8 @@ namespace Publishing.Authenticator.Shotwell.Tumblr {
         }
     }
 
-    internal class AccessTokenFetchTransaction : OAuth1.Transaction {
-        public AccessTokenFetchTransaction(OAuth1.Session session, string username, string password) {
+    internal class AccessTokenFetchTransaction : Publishing.RESTSupport.OAuth1.Transaction {
+        public AccessTokenFetchTransaction(Publishing.RESTSupport.OAuth1.Session session, string username, 
string password) {
             base.with_uri(session, "https://www.tumblr.com/oauth/access_token";,
                     Publishing.RESTSupport.HttpMethod.POST);
             add_argument("x_auth_username", Soup.URI.encode(username, ENCODE_RFC_3986_EXTRA));
diff --git a/plugins/common/RESTSupport.vala b/plugins/common/RESTSupport.vala
index f06473c..5820d8f 100644
--- a/plugins/common/RESTSupport.vala
+++ b/plugins/common/RESTSupport.vala
@@ -858,5 +858,180 @@ public abstract class GooglePublisher : Object, Spit.Publishing.Publisher {
     }
 }
 
+namespace OAuth1 {
+    internal const string ENCODE_RFC_3986_EXTRA = "!*'();:@&=+$,/?%#[] \\";
+
+    public class Session : Publishing.RESTSupport.Session {
+        private string? request_phase_token = null;
+        private string? request_phase_token_secret = null;
+        private string? access_phase_token = null;
+        private string? access_phase_token_secret = null;
+        private string? username = null;
+        private string? consumer_key = null;
+        private string? consumer_secret = null;
+
+        public Session() {
+            base();
+        }
+
+        public override bool is_authenticated() {
+            return (access_phase_token != null && access_phase_token_secret != null &&
+                    username != null);
+        }
+
+        public void authenticate_from_persistent_credentials(string token, string secret,
+                string username) {
+            this.access_phase_token = token;
+            this.access_phase_token_secret = secret;
+            this.username = username;
+
+            this.authenticated();
+        }
+
+        public void deauthenticate() {
+            access_phase_token = null;
+            access_phase_token_secret = null;
+            username = null;
+        }
+
+        public void set_api_credentials(string consumer_key, string consumer_secret) {
+            this.consumer_key = consumer_key;
+            this.consumer_secret = consumer_secret;
+        }
+
+        public void sign_transaction(Publishing.RESTSupport.Transaction txn) {
+            string http_method = txn.get_method().to_string();
+
+            debug("signing transaction with parameters:");
+            debug("HTTP method = " + http_method);
+
+            Publishing.RESTSupport.Argument[] base_string_arguments = txn.get_arguments();
+
+            Publishing.RESTSupport.Argument[] sorted_args =
+                Publishing.RESTSupport.Argument.sort(base_string_arguments);
+
+            string arguments_string = "";
+            for (int i = 0; i < sorted_args.length; i++) {
+                arguments_string += (sorted_args[i].key + "=" + sorted_args[i].value);
+                if (i < sorted_args.length - 1)
+                    arguments_string += "&";
+            }
+
+            string? signing_key = null;
+            if (access_phase_token_secret != null) {
+                debug("access phase token secret available; using it as signing key");
+
+                signing_key = consumer_secret + "&" + access_phase_token_secret;
+            } else if (request_phase_token_secret != null) {
+                debug("request phase token secret available; using it as signing key");
+
+                signing_key = consumer_secret + "&" + request_phase_token_secret;
+            } else {
+                debug("neither access phase nor request phase token secrets available; using API " +
+                        "key as signing key");
+
+                signing_key = consumer_secret + "&";
+            }
+
+            string signature_base_string = http_method + "&" + Soup.URI.encode(
+                    txn.get_endpoint_url(), ENCODE_RFC_3986_EXTRA) + "&" +
+                Soup.URI.encode(arguments_string, ENCODE_RFC_3986_EXTRA);
+
+            debug("signature base string = '%s'", signature_base_string);
+
+            debug("signing key = '%s'", signing_key);
+
+            // compute the signature
+            string signature = RESTSupport.hmac_sha1(signing_key, signature_base_string);
+            signature = Soup.URI.encode(signature, ENCODE_RFC_3986_EXTRA);
+
+            debug("signature = '%s'", signature);
+
+            txn.add_argument("oauth_signature", signature);
+        }
+
+        public void set_request_phase_credentials(string token, string secret) {
+            this.request_phase_token = token;
+            this.request_phase_token_secret = secret;
+        }
+
+        public void set_access_phase_credentials(string token, string secret, string username) {
+            this.access_phase_token = token;
+            this.access_phase_token_secret = secret;
+            this.username = username;
+
+            authenticated();
+        }
+
+        public string get_oauth_nonce() {
+            TimeVal currtime = TimeVal();
+            currtime.get_current_time();
+
+            return Checksum.compute_for_string(ChecksumType.MD5, currtime.tv_sec.to_string() +
+                    currtime.tv_usec.to_string());
+        }
+
+        public string get_oauth_timestamp() {
+            return GLib.get_real_time().to_string().substring(0, 10);
+        }
+
+        public string get_consumer_key() {
+            assert(consumer_key != null);
+            return consumer_key;
+        }
+
+        public string get_request_phase_token() {
+            assert(request_phase_token != null);
+            return request_phase_token;
+        }
+
+        public string get_access_phase_token() {
+            assert(access_phase_token != null);
+            return access_phase_token;
+        }
+
+        public string get_access_phase_token_secret() {
+            assert(access_phase_token_secret != null);
+            return access_phase_token_secret;
+        }
+
+        public string get_username() {
+            assert(is_authenticated());
+            return username;
+        }
+    }
+
+    public class Transaction : Publishing.RESTSupport.Transaction {
+        public Transaction(Session session, Publishing.RESTSupport.HttpMethod method =
+                Publishing.RESTSupport.HttpMethod.POST) {
+            base(session, method);
+            setup_arguments();
+        }
+
+        public Transaction.with_uri(Session session, string uri,
+                Publishing.RESTSupport.HttpMethod method = Publishing.RESTSupport.HttpMethod.POST) {
+            base.with_endpoint_url(session, uri, method);
+            setup_arguments();
+        }
+
+        private void setup_arguments() {
+            var session = (Session) get_parent_session();
+
+            add_argument("oauth_nonce", session.get_oauth_nonce());
+            add_argument("oauth_signature_method", "HMAC-SHA1");
+            add_argument("oauth_version", "1.0");
+            add_argument("oauth_timestamp", session.get_oauth_timestamp());
+            add_argument("oauth_consumer_key", session.get_consumer_key());
+        }
+
+
+        public override void execute() throws Spit.Publishing.PublishingError {
+            ((Session) get_parent_session()).sign_transaction(this);
+
+            base.execute();
+        }
+    }
+}
+
 }
 
diff --git a/plugins/shotwell-publishing/FlickrPublishing.vala 
b/plugins/shotwell-publishing/FlickrPublishing.vala
index 24b2b61..4ef642e 100644
--- a/plugins/shotwell-publishing/FlickrPublishing.vala
+++ b/plugins/shotwell-publishing/FlickrPublishing.vala
@@ -96,7 +96,7 @@ public class FlickrPublisher : Spit.Publishing.Publisher, GLib.Object {
     private Spit.Publishing.ProgressCallback progress_reporter = null;
     private bool running = false;
     private bool was_started = false;
-    private Session session = null;
+    private Publishing.RESTSupport.OAuth1.Session session = null;
     private PublishingOptionsPane publishing_options_pane = null;
     private Spit.Publishing.Authenticator authenticator = null;
    
@@ -107,7 +107,7 @@ public class FlickrPublisher : Spit.Publishing.Publisher, GLib.Object {
         debug("FlickrPublisher instantiated.");
         this.service = service;
         this.host = host;
-        this.session = new Session();
+        this.session = new Publishing.RESTSupport.OAuth1.Session();
         this.parameters = new PublishingParameters();
         this.authenticator = Publishing.Authenticator.Factory.get_instance().create("flickr", host);
 
@@ -445,37 +445,7 @@ public class FlickrPublisher : Spit.Publishing.Publisher, GLib.Object {
     }
 }
 
-internal class Transaction : Publishing.RESTSupport.Transaction {
-    public Transaction(Session session, Publishing.RESTSupport.HttpMethod method =
-        Publishing.RESTSupport.HttpMethod.POST) {
-        base(session, method);
-        
-        add_argument("oauth_nonce", session.get_oauth_nonce());
-        add_argument("oauth_signature_method", "HMAC-SHA1");
-        add_argument("oauth_version", "1.0");
-        add_argument("oauth_callback", "oob");
-        add_argument("oauth_timestamp", session.get_oauth_timestamp());
-        add_argument("oauth_consumer_key", session.get_consumer_key());
-    }
-    
-    public Transaction.with_uri(Session session, string uri,
-        Publishing.RESTSupport.HttpMethod method = Publishing.RESTSupport.HttpMethod.POST) {
-        base.with_endpoint_url(session, uri, method);
-
-        add_argument("oauth_nonce", session.get_oauth_nonce());
-        add_argument("oauth_signature_method", "HMAC-SHA1");
-        add_argument("oauth_version", "1.0");
-        add_argument("oauth_callback", "oob");
-        add_argument("oauth_timestamp", session.get_oauth_timestamp());
-        add_argument("oauth_consumer_key", session.get_consumer_key());
-    }
-
-    public override void execute() throws Spit.Publishing.PublishingError {
-        ((Session) get_parent_session()).sign_transaction(this);
-        
-        base.execute();
-    }
-
+namespace Transaction {
     public static string? validate_xml(Publishing.RESTSupport.XmlDocument doc) {
         Xml.Node* root = doc.get_root_node();
         string? status = root->get_prop("stat");
@@ -525,20 +495,19 @@ internal class Transaction : Publishing.RESTSupport.Transaction {
     }
 }
 
-internal class AccountInfoFetchTransaction : Transaction {
-    public AccountInfoFetchTransaction(Session session) {
+internal class AccountInfoFetchTransaction : Publishing.RESTSupport.OAuth1.Transaction {
+    public AccountInfoFetchTransaction(Publishing.RESTSupport.OAuth1.Session session) {
         base(session, Publishing.RESTSupport.HttpMethod.GET);
         add_argument("method", "flickr.people.getUploadStatus");
-        add_argument("oauth_token", session.get_access_phase_token());
     }
 }
 
 private class UploadTransaction : Publishing.RESTSupport.UploadTransaction {
     private PublishingParameters parameters;
-    private Session session;
+    private Publishing.RESTSupport.OAuth1.Session session;
     private Publishing.RESTSupport.Argument[] auth_header_fields;
 
-    public UploadTransaction(Session session, PublishingParameters parameters,
+    public UploadTransaction(Publishing.RESTSupport.OAuth1.Session session, PublishingParameters parameters,
         Spit.Publishing.Publishable publishable) {
         base.with_endpoint_url(session, publishable, "https://api.flickr.com/services/upload";);
 
@@ -578,10 +547,6 @@ private class UploadTransaction : Publishing.RESTSupport.UploadTransaction {
         auth_header_fields += new Publishing.RESTSupport.Argument(key, value);
     }
     
-    public Publishing.RESTSupport.Argument[] get_authorization_header_fields() {
-        return auth_header_fields;
-    }
-    
     public string get_authorization_header_string() {
         string result = "OAuth ";
         
@@ -610,125 +575,6 @@ private class UploadTransaction : Publishing.RESTSupport.UploadTransaction {
     }
 }
 
-internal class Session : Publishing.RESTSupport.Session {
-    private string? access_phase_token = null;
-    private string? access_phase_token_secret = null;
-    private string? username = null;
-    private string? consumer_key = null;
-    private string? consumer_secret = null;
-
-    public Session() {
-        base(ENDPOINT_URL);
-    }
-
-    public override bool is_authenticated() {
-        return (access_phase_token != null && access_phase_token_secret != null &&
-            username != null);
-    }
-
-    public void set_api_credentials(string consumer_key, string consumer_secret) {
-        this.consumer_key = consumer_key;
-        this.consumer_secret = consumer_secret;
-    }
-    
-    public void sign_transaction(Publishing.RESTSupport.Transaction txn) {
-        string http_method = txn.get_method().to_string();
-        
-        debug("signing transaction with parameters:");
-        debug("HTTP method = " + http_method);
-
-        Publishing.RESTSupport.Argument[] base_string_arguments = txn.get_arguments();
-
-        UploadTransaction? upload_txn = txn as UploadTransaction;
-        if (upload_txn != null) {
-            debug("this transaction is an UploadTransaction; including Authorization header " +
-                "fields in signature base string");
-            
-            Publishing.RESTSupport.Argument[] auth_header_args =
-                upload_txn.get_authorization_header_fields();
-
-            foreach (Publishing.RESTSupport.Argument arg in auth_header_args)
-                base_string_arguments += arg;
-        }
-        
-        Publishing.RESTSupport.Argument[] sorted_args =
-            Publishing.RESTSupport.Argument.sort(base_string_arguments);
-        
-        string arguments_string = "";
-        for (int i = 0; i < sorted_args.length; i++) {
-            arguments_string += (sorted_args[i].key + "=" + sorted_args[i].value);
-            if (i < sorted_args.length - 1)
-                arguments_string += "&";
-        }
-
-        string? signing_key = null;
-        if (access_phase_token_secret != null) {
-            debug("access phase token secret available; using it as signing key");
-
-            signing_key = consumer_secret + "&" + access_phase_token_secret;
-        } else {
-            debug("neither access phase nor request phase token secrets available; using API " +
-                "key as signing key");
-
-            signing_key = consumer_secret + "&";
-        }
-        
-        string signature_base_string = http_method + "&" + Soup.URI.encode(
-            txn.get_endpoint_url(), ENCODE_RFC_3986_EXTRA) + "&" +
-            Soup.URI.encode(arguments_string, ENCODE_RFC_3986_EXTRA);
-
-        debug("signature base string = '%s'", signature_base_string);
-        
-        debug("signing key = '%s'", signing_key);
-
-        // compute the signature
-        string signature = RESTSupport.hmac_sha1(signing_key, signature_base_string);
-        signature = Soup.URI.encode(signature, ENCODE_RFC_3986_EXTRA);
-
-        debug("signature = '%s'", signature);
-
-        if (upload_txn != null)
-            upload_txn.add_authorization_header_field("oauth_signature", signature);
-        else
-            txn.add_argument("oauth_signature", signature);
-    }
-    
-    public void set_access_phase_credentials(string token, string secret, string username) {
-        this.access_phase_token = token;
-        this.access_phase_token_secret = secret;
-        this.username = username;
-        
-        authenticated();
-    }
-
-    public string get_oauth_nonce() {
-        TimeVal currtime = TimeVal();
-        currtime.get_current_time();
-        
-        return Checksum.compute_for_string(ChecksumType.MD5, currtime.tv_sec.to_string() +
-            currtime.tv_usec.to_string());
-    }
-    
-    public string get_oauth_timestamp() {
-        return GLib.get_real_time().to_string().substring(0, 10);
-    }
-
-    public string get_consumer_key() {
-        assert(consumer_key != null);
-        return consumer_key;
-    }
-
-    public string get_access_phase_token() {
-        assert(access_phase_token != null);
-        return access_phase_token;
-    }
-    
-    public string get_username() {
-        assert(is_authenticated());
-        return username;
-    }
-}
-
 internal class PublishingOptionsPane : Spit.Publishing.DialogPane, GLib.Object {
     private class SizeEntry {
         public string title;
@@ -931,7 +777,7 @@ internal class Uploader : Publishing.RESTSupport.BatchUploader {
     private PublishingParameters parameters;
     private bool strip_metadata;
 
-    public Uploader(Session session, Spit.Publishing.Publishable[] publishables,
+    public Uploader(Publishing.RESTSupport.OAuth1.Session session, Spit.Publishing.Publishable[] 
publishables,
         PublishingParameters parameters, bool strip_metadata) {
         base(session, publishables);
         
@@ -1009,7 +855,7 @@ internal class Uploader : Publishing.RESTSupport.BatchUploader {
     protected override Publishing.RESTSupport.Transaction create_transaction(
         Spit.Publishing.Publishable publishable) {
         preprocess_publishable(get_current_publishable());
-        return new UploadTransaction((Session) get_session(), parameters,
+        return new UploadTransaction((Publishing.RESTSupport.OAuth1.Session) get_session(), parameters,
             get_current_publishable());
     }
 }
diff --git a/plugins/shotwell-publishing/TumblrPublishing.vala 
b/plugins/shotwell-publishing/TumblrPublishing.vala
index 1ab0b70..074635f 100644
--- a/plugins/shotwell-publishing/TumblrPublishing.vala
+++ b/plugins/shotwell-publishing/TumblrPublishing.vala
@@ -89,7 +89,7 @@ public class TumblrPublisher : Spit.Publishing.Publisher, GLib.Object {
     private Spit.Publishing.ProgressCallback progress_reporter = null;
     private bool running = false;
     private bool was_started = false;
-    private Session session = null;
+    private Publishing.RESTSupport.OAuth1.Session session = null;
     private PublishingOptionsPane publishing_options_pane = null;
     private SizeEntry[] sizes = null;
     private BlogEntry[] blogs = null;
@@ -123,7 +123,7 @@ public class TumblrPublisher : Spit.Publishing.Publisher, GLib.Object {
         debug("TumblrPublisher instantiated.");
         this.service = service;
         this.host = host;
-        this.session = new Session();
+        this.session = new Publishing.RESTSupport.OAuth1.Session();
         this.sizes = this.create_sizes();
         this.blogs = this.create_blogs();
 
@@ -187,7 +187,7 @@ public class TumblrPublisher : Spit.Publishing.Publisher, GLib.Object {
         params.lookup_extended("AuthToken", null, out auth_token);
         params.lookup_extended("AuthTokenSecret", null, out auth_token_secret);
         session.set_access_phase_credentials(auth_token.get_string(),
-                auth_token_secret.get_string());
+                auth_token_secret.get_string(), "");
 
 
         do_get_blogs();
@@ -567,44 +567,15 @@ internal class PublishingOptionsPane : Spit.Publishing.DialogPane, GLib.Object {
     }
 }
 
-internal class Transaction : Publishing.RESTSupport.Transaction {
-    public Transaction(Session session, Publishing.RESTSupport.HttpMethod method =
-            Publishing.RESTSupport.HttpMethod.POST) {
-        base(session, method);
-
-    }
-
-    public Transaction.with_uri(Session session, string uri,
-            Publishing.RESTSupport.HttpMethod method = Publishing.RESTSupport.HttpMethod.POST) {
-        base.with_endpoint_url(session, uri, method);
-
-        add_argument("oauth_nonce", session.get_oauth_nonce());
-        add_argument("oauth_signature_method", "HMAC-SHA1");
-        add_argument("oauth_version", "1.0");
-        add_argument("oauth_timestamp", session.get_oauth_timestamp());
-        add_argument("oauth_consumer_key", session.get_consumer_key());
-        if (session.get_access_phase_token() != null) {
-            add_argument("oauth_token", session.get_access_phase_token());
-        }
-    }
-
-    public override void execute() throws Spit.Publishing.PublishingError {
-        ((Session) get_parent_session()).sign_transaction(this);
-
-        base.execute();
-    }
-
-}
-
-internal class UserInfoFetchTransaction : Transaction {
-    public UserInfoFetchTransaction(Session session) {
+internal class UserInfoFetchTransaction : Publishing.RESTSupport.OAuth1.Transaction {
+    public UserInfoFetchTransaction(Publishing.RESTSupport.OAuth1.Session session) {
         base.with_uri(session, "https://api.tumblr.com/v2/user/info";,
             Publishing.RESTSupport.HttpMethod.POST);
     }
 }
 
 internal class UploadTransaction : Publishing.RESTSupport.UploadTransaction {
-    private Session session;
+    private Publishing.RESTSupport.OAuth1.Session session;
     private Publishing.RESTSupport.Argument[] auth_header_fields;
 
 
@@ -626,7 +597,7 @@ internal class UploadTransaction : Publishing.RESTSupport.UploadTransaction {
     }
 
 
-    public UploadTransaction(Session session,Spit.Publishing.Publishable publishable, string blog_url)  {
+    public UploadTransaction(Publishing.RESTSupport.OAuth1.Session session,Spit.Publishing.Publishable 
publishable, string blog_url)  {
                debug("Init upload transaction");
         base.with_endpoint_url(session, 
publishable,"https://api.tumblr.com/v2/blog/%s/post".printf(blog_url) );
         this.session = session;
@@ -639,10 +610,6 @@ internal class UploadTransaction : Publishing.RESTSupport.UploadTransaction {
         auth_header_fields += new Publishing.RESTSupport.Argument(key, value);
     }
 
-    public Publishing.RESTSupport.Argument[] get_authorization_header_fields() {
-        return auth_header_fields;
-    }
-
     public string get_authorization_header_string() {
         string result = "OAuth ";
 
@@ -732,7 +699,7 @@ internal class UploadTransaction : Publishing.RESTSupport.UploadTransaction {
 
 internal class Uploader : Publishing.RESTSupport.BatchUploader {
        private string blog_url = "";
-    public Uploader(Session session, Spit.Publishing.Publishable[] publishables, string blog_url) {
+    public Uploader(Publishing.RESTSupport.OAuth1.Session session, Spit.Publishing.Publishable[] 
publishables, string blog_url) {
         base(session, publishables);
                this.blog_url=blog_url;
 
@@ -742,138 +709,11 @@ internal class Uploader : Publishing.RESTSupport.BatchUploader {
     protected override Publishing.RESTSupport.Transaction create_transaction(
         Spit.Publishing.Publishable publishable) {
                debug("Create upload transaction");
-        return new UploadTransaction((Session) get_session(), get_current_publishable(), this.blog_url);
+        return new UploadTransaction((Publishing.RESTSupport.OAuth1.Session) get_session(), 
get_current_publishable(), this.blog_url);
 
     }
 }
 
-/**
- * Session class that keeps track of the authentication status and of the
- * user token tumblr.
- */
-internal class Session : Publishing.RESTSupport.Session {
-    private string? access_phase_token = null;
-    private string? access_phase_token_secret = null;
-    private string? consumer_key = null;
-    private string? consumer_secret = null;
-
-    public Session() {
-        base(ENDPOINT_URL);
-    }
-
-    public override bool is_authenticated() {
-        return (access_phase_token != null && access_phase_token_secret != null);
-    }
-
-    public void deauthenticate() {
-        access_phase_token = null;
-        access_phase_token_secret = null;
-    }
-
-    public void set_api_credentials(string consumer_key, string consumer_secret) {
-        this.consumer_key = consumer_key;
-        this.consumer_secret = consumer_secret;
-    }
-
-    public string get_consumer_key() {
-        return this.consumer_key;
-    }
-
-
-    public void set_access_phase_credentials(string token, string secret) {
-        this.access_phase_token = token;
-        this.access_phase_token_secret = secret;
-    }
-
-    public void sign_transaction(Publishing.RESTSupport.Transaction txn) {
-        string http_method = txn.get_method().to_string();
-
-        debug("signing transaction with parameters:");
-        debug("HTTP method = " + http_method);
-               string? signing_key = null;
-        if (access_phase_token_secret != null) {
-            debug("access phase token secret available; using it as signing key");
-
-            signing_key = this.consumer_secret + "&" + this.get_access_phase_token_secret();
-        } else {
-            debug("Access phase token secret not available; using API " +
-                "key as signing key");
-
-            signing_key = this.consumer_secret + "&";
-        }
-
-
-        Publishing.RESTSupport.Argument[] base_string_arguments = txn.get_arguments();
-
-        UploadTransaction? upload_txn = txn as UploadTransaction;
-        if (upload_txn != null) {
-            debug("this transaction is an UploadTransaction; including Authorization header " +
-                "fields in signature base string");
-
-            Publishing.RESTSupport.Argument[] auth_header_args =
-                upload_txn.get_authorization_header_fields();
-
-            foreach (Publishing.RESTSupport.Argument arg in auth_header_args)
-                base_string_arguments += arg;
-        }
-
-        Publishing.RESTSupport.Argument[] sorted_args =
-            Publishing.RESTSupport.Argument.sort(base_string_arguments);
-
-        string arguments_string = "";
-        for (int i = 0; i < sorted_args.length; i++) {
-            arguments_string += (sorted_args[i].key + "=" + sorted_args[i].value);
-            if (i < sorted_args.length - 1)
-                arguments_string += "&";
-        }
-
-
-        string signature_base_string = http_method + "&" + Soup.URI.encode(
-            txn.get_endpoint_url(), ENCODE_RFC_3986_EXTRA) + "&" +
-            Soup.URI.encode(arguments_string, ENCODE_RFC_3986_EXTRA);
-
-        debug("signature base string = '%s'", signature_base_string);
-        debug("signing key = '%s'", signing_key);
-
-        // compute the signature
-        string signature = Publishing.RESTSupport.hmac_sha1(signing_key, signature_base_string);
-        debug("signature = '%s'", signature);
-        signature = Soup.URI.encode(signature, ENCODE_RFC_3986_EXTRA);
-
-        debug("signature after RFC encode = '%s'", signature);
-
-        if (upload_txn != null)
-            upload_txn.add_authorization_header_field("oauth_signature", signature);
-        else
-            txn.add_argument("oauth_signature", signature);
-
-
-    }
-
-    public string get_access_phase_token() {
-        return access_phase_token;
-    }
-
-
-    public string get_access_phase_token_secret() {
-        return access_phase_token_secret;
-    }
-
-    public string get_oauth_nonce() {
-        TimeVal currtime = TimeVal();
-        currtime.get_current_time();
-
-        return Checksum.compute_for_string(ChecksumType.MD5, currtime.tv_sec.to_string() +
-            currtime.tv_usec.to_string());
-    }
-
-    public string get_oauth_timestamp() {
-        return GLib.get_real_time().to_string().substring(0, 10);
-    }
-
-}
-
-
 } //class TumblrPublisher
 
 } //namespace Publishing.Tumblr



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