diff options
Diffstat (limited to 'plugins/shotwell-publishing/FlickrPublishing.vala')
-rw-r--r-- | plugins/shotwell-publishing/FlickrPublishing.vala | 219 |
1 files changed, 13 insertions, 206 deletions
diff --git a/plugins/shotwell-publishing/FlickrPublishing.vala b/plugins/shotwell-publishing/FlickrPublishing.vala index 24b2b61..5a80284 100644 --- a/plugins/shotwell-publishing/FlickrPublishing.vala +++ b/plugins/shotwell-publishing/FlickrPublishing.vala @@ -59,7 +59,6 @@ internal const string SERVICE_NAME = "Flickr"; internal const string ENDPOINT_URL = "https://api.flickr.com/services/rest"; internal const int ORIGINAL_SIZE = -1; internal const string EXPIRED_SESSION_ERROR_CODE = "98"; -internal const string ENCODE_RFC_3986_EXTRA = "!*'();:@&=+$,/?%#[] \\"; internal enum UserKind { PRO, @@ -96,7 +95,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 +106,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(ENDPOINT_URL); this.parameters = new PublishingParameters(); this.authenticator = Publishing.Authenticator.Factory.get_instance().create("flickr", host); @@ -445,37 +444,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,35 +494,22 @@ 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 class UploadTransaction : Publishing.RESTSupport.OAuth1.UploadTransaction { private PublishingParameters parameters; - private 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"); + base(session, publishable, "https://api.flickr.com/services/upload"); this.parameters = parameters; - this.session = session; - this.auth_header_fields = new Publishing.RESTSupport.Argument[0]; - - add_authorization_header_field("oauth_nonce", session.get_oauth_nonce()); - add_authorization_header_field("oauth_signature_method", "HMAC-SHA1"); - add_authorization_header_field("oauth_version", "1.0"); - add_authorization_header_field("oauth_callback", "oob"); - add_authorization_header_field("oauth_timestamp", session.get_oauth_timestamp()); - add_authorization_header_field("oauth_consumer_key", session.get_consumer_key()); - add_authorization_header_field("oauth_token", session.get_access_phase_token()); - + add_argument("is_public", ("%d".printf(parameters.visibility_specification.everyone_level))); add_argument("is_friend", ("%d".printf(parameters.visibility_specification.friends_level))); add_argument("is_family", ("%d".printf(parameters.visibility_specification.family_level))); @@ -573,162 +529,13 @@ private class UploadTransaction : Publishing.RESTSupport.UploadTransaction { set_binary_disposition_table(disposition_table); } - - public void add_authorization_header_field(string key, string value) { - 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 "; - - for (int i = 0; i < auth_header_fields.length; i++) { - result += auth_header_fields[i].key; - result += "="; - result += ("\"" + auth_header_fields[i].value + "\""); - - if (i < auth_header_fields.length - 1) - result += ", "; - } - - return result; - } - + public override void execute() throws Spit.Publishing.PublishingError { - session.sign_transaction(this); - - string authorization_header = get_authorization_header_string(); - - debug("executing upload transaction: authorization header string = '%s'", - authorization_header); - add_header("Authorization", authorization_header); - + this.authorize(); base.execute(); } } -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 +738,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 +816,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()); } } |