diff --git a/GreenshotPlugin/Controls/OAuthLoginForm.Designer.cs b/GreenshotPlugin/Controls/OAuthLoginForm.Designer.cs
new file mode 100644
index 000000000..45e4de037
--- /dev/null
+++ b/GreenshotPlugin/Controls/OAuthLoginForm.Designer.cs
@@ -0,0 +1,95 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+namespace GreenshotPlugin.Controls {
+ partial class OAuthLoginForm {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null)) {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent() {
+ this.browser = new System.Windows.Forms.WebBrowser();
+ this.addressTextBox = new System.Windows.Forms.TextBox();
+ this.SuspendLayout();
+ //
+ // browser
+ //
+ this.browser.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.browser.Location = new System.Drawing.Point(0, 26);
+ this.browser.MinimumSize = new System.Drawing.Size(20, 20);
+ this.browser.Name = "browser";
+ this.browser.Size = new System.Drawing.Size(864, 561);
+ this.browser.TabIndex = 0;
+ this.browser.Navigating += new System.Windows.Forms.WebBrowserNavigatingEventHandler(this.webBrowser1_Navigating);
+ this.browser.Navigated += new System.Windows.Forms.WebBrowserNavigatedEventHandler(this.browser_Navigated);
+ //
+ // addressTextBox
+ //
+ this.addressTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.addressTextBox.Location = new System.Drawing.Point(7, 2);
+ this.addressTextBox.Name = "addressTextBox";
+ this.addressTextBox.Size = new System.Drawing.Size(840, 20);
+ this.addressTextBox.TabIndex = 1;
+ this.addressTextBox.TabStop = false;
+ this.addressTextBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.addressTextBox_KeyPress);
+ //
+ // LoginForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(864, 587);
+ this.Controls.Add(this.addressTextBox);
+ this.Controls.Add(this.browser);
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "LoginForm";
+ this.ShowInTaskbar = false;
+ this.ResumeLayout(false);
+ this.PerformLayout();
+ }
+
+ #endregion
+
+ private System.Windows.Forms.WebBrowser browser;
+ private System.Windows.Forms.TextBox addressTextBox;
+ }
+}
diff --git a/GreenshotPlugin/Controls/OAuthLoginForm.cs b/GreenshotPlugin/Controls/OAuthLoginForm.cs
new file mode 100644
index 000000000..7a7e76297
--- /dev/null
+++ b/GreenshotPlugin/Controls/OAuthLoginForm.cs
@@ -0,0 +1,97 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Web;
+using System.Collections.Specialized;
+using GreenshotPlugin.Core;
+
+namespace GreenshotPlugin.Controls {
+ ///
+ /// The OAuthLoginForm is used to allow the user to authorize Greenshot with an "Oauth" application
+ ///
+ public partial class OAuthLoginForm : Form {
+ private OAuthHelper _oauth;
+ private String _token;
+ private String _verifier;
+ private String _tokenSecret;
+
+ public String Token {
+ get {
+ return _token;
+ }
+ }
+
+ public String Verifier {
+ get {
+ return _verifier;
+ }
+ }
+
+ public String TokenSecret {
+ get {
+ return _tokenSecret;
+ }
+ }
+
+ public OAuthLoginForm(OAuthHelper o, string browserTitle) {
+ _oauth = o;
+ _token = null;
+ InitializeComponent();
+ this.Icon = GreenshotPlugin.Core.GreenshotResources.getGreenshotIcon();
+ this.Text = browserTitle;
+ this.addressTextBox.Text = o.AuthorizationLink;
+ _token = _oauth.Token;
+ _tokenSecret = _oauth.TokenSecret;
+ browser.Navigate(new Uri(_oauth.AuthorizationLink));
+ }
+
+ private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e) {
+ this.addressTextBox.Text = e.Url.ToString();
+ }
+
+ private void browser_Navigated(object sender, WebBrowserNavigatedEventArgs e) {
+ if (browser.Url.ToString().Contains(_oauth.CallbackUrl)) {
+ string queryParams = e.Url.Query;
+ if (queryParams.Length > 0) {
+ //Store the Token and Token Secret
+ NameValueCollection qs = NetworkHelper.ParseQueryString(queryParams);
+ if (qs["oauth_token"] != null) {
+ _token = qs["oauth_token"];
+ }
+ if (qs["oauth_verifier"] != null) {
+ _verifier = qs["oauth_verifier"];
+ }
+ }
+ this.Close();
+ }
+ }
+
+ private void addressTextBox_KeyPress(object sender, KeyPressEventArgs e) {
+ //Cancel the key press so the user can't enter a new url
+ e.Handled = true;
+ }
+ }
+}
diff --git a/GreenshotPlugin/Core/OAuthHelper.cs b/GreenshotPlugin/Core/OAuthHelper.cs
new file mode 100644
index 000000000..cc16550d2
--- /dev/null
+++ b/GreenshotPlugin/Core/OAuthHelper.cs
@@ -0,0 +1,594 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+using System;
+using System.Security.Cryptography;
+using System.Collections.Generic;
+using System.Text;
+using System.Net;
+using System.Collections.Specialized;
+using System.IO;
+using System.Text.RegularExpressions;
+using GreenshotPlugin.Controls;
+
+namespace GreenshotPlugin.Core {
+ public class OAuthHelper {
+
+ ///
+ /// Provides a predefined set of algorithms that are supported officially by the protocol
+ ///
+ protected enum SignatureTypes {
+ HMACSHA1,
+ PLAINTEXT,
+ RSASHA1
+ }
+
+ ///
+ /// Provides an internal structure to sort the query parameter
+ ///
+ protected class QueryParameter {
+ private string name = null;
+ private string value = null;
+
+ public QueryParameter(string name, string value)
+ {
+ this.name = name;
+ this.value = value;
+ }
+
+ public string Name
+ {
+ get { return name; }
+ }
+
+ public string Value
+ {
+ get { return value; }
+ }
+ }
+
+ ///
+ /// Comparer class used to perform the sorting of the query parameters
+ ///
+ protected class QueryParameterComparer : IComparer {
+
+ #region IComparer Members
+
+ public int Compare(QueryParameter x, QueryParameter y) {
+ if (x.Name == y.Name) {
+ return string.Compare(x.Value, y.Value);
+ } else {
+ return string.Compare(x.Name, y.Name);
+ }
+ }
+
+ #endregion
+ }
+
+ protected const string OAuthVersion = "1.0";
+ protected const string OAuthParameterPrefix = "oauth_";
+
+ //
+ // List of know and used oauth parameters' names
+ //
+ protected const string OAuthConsumerKeyKey = "oauth_consumer_key";
+ protected const string OAuthCallbackKey = "oauth_callback";
+ protected const string OAuthVersionKey = "oauth_version";
+ protected const string OAuthSignatureMethodKey = "oauth_signature_method";
+ protected const string OAuthSignatureKey = "oauth_signature";
+ protected const string OAuthTimestampKey = "oauth_timestamp";
+ protected const string OAuthNonceKey = "oauth_nonce";
+ protected const string OAuthTokenKey = "oauth_token";
+ protected const string oAauthVerifier = "oauth_verifier";
+ protected const string OAuthTokenSecretKey = "oauth_token_secret";
+
+ protected const string HMACSHA1SignatureType = "HMAC-SHA1";
+ protected const string PlainTextSignatureType = "PLAINTEXT";
+ protected const string RSASHA1SignatureType = "RSA-SHA1";
+
+ public enum Method { GET, POST, PUT, DELETE };
+ private string _userAgent = "Greenshot";
+ private string _callbackUrl = "http://getgreenshot.org";
+
+ #region PublicPropertiies
+ public string ConsumerKey { get; set; }
+ public string ConsumerSecret { get; set; }
+ public string UserAgent { get { return _userAgent; } set { _userAgent = value; } }
+ public string RequestTokenUrl { get; set; }
+ public string AuthorizeUrl { get; set; }
+ public string AccessTokenUrl { get; set; }
+ public string CallbackUrl { get { return _callbackUrl;} set { _callbackUrl = value; } }
+ public string Token { get; set; }
+ public string TokenSecret { get; set; }
+ #endregion
+
+ protected Random random = new Random();
+
+ private string oauth_verifier;
+ public string Verifier { get { return oauth_verifier; } set { oauth_verifier = value; } }
+
+
+ protected const string unreservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
+
+ ///
+ /// Helper function to compute a hash value
+ ///
+ /// The hashing algorithm used. If that algorithm needs some initialization, like HMAC and its derivatives, they should be initialized prior to passing it to this function
+ /// The data to hash
+ /// a Base64 string of the hash value
+ private string ComputeHash(HashAlgorithm hashAlgorithm, string data) {
+ if (hashAlgorithm == null) {
+ throw new ArgumentNullException("hashAlgorithm");
+ }
+
+ if (string.IsNullOrEmpty(data)) {
+ throw new ArgumentNullException("data");
+ }
+
+ byte[] dataBuffer = System.Text.Encoding.ASCII.GetBytes(data);
+ byte[] hashBytes = hashAlgorithm.ComputeHash(dataBuffer);
+
+ return Convert.ToBase64String(hashBytes);
+ }
+
+ ///
+ /// Internal function to cut out all non oauth query string parameters (all parameters not begining with "oauth_")
+ ///
+ /// The query string part of the Url
+ /// A list of QueryParameter each containing the parameter name and value
+ private List GetQueryParameters(string parameters) {
+ if (parameters.StartsWith("?")) {
+ parameters = parameters.Remove(0, 1);
+ }
+
+ List result = new List();
+
+ if (!string.IsNullOrEmpty(parameters)) {
+ string[] p = parameters.Split('&');
+ foreach (string s in p) {
+ if (!string.IsNullOrEmpty(s) && !s.StartsWith(OAuthParameterPrefix)) {
+ if (s.IndexOf('=') > -1) {
+ string[] temp = s.Split('=');
+ result.Add(new QueryParameter(temp[0], temp[1]));
+ } else {
+ result.Add(new QueryParameter(s, string.Empty));
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ ///
+ /// This is a different Url Encode implementation since the default .NET one outputs the percent encoding in lower case.
+ /// While this is not a problem with the percent encoding spec, it is used in upper case throughout OAuth
+ ///
+ /// The value to Url encode
+ /// Returns a Url encoded string
+ public static string UrlEncodeSpecial(string value) {
+ StringBuilder result = new StringBuilder();
+
+ foreach (char symbol in value) {
+ if (unreservedChars.IndexOf(symbol) != -1) {
+ result.Append(symbol);
+ } else {
+ result.Append('%' + String.Format("{0:X2}", (int)symbol));
+ }
+ }
+
+ return result.ToString();
+ }
+
+ ///
+ /// Normalizes the request parameters according to the spec
+ ///
+ /// The list of parameters already sorted
+ /// a string representing the normalized parameters
+ protected string NormalizeRequestParameters(IList parameters) {
+ StringBuilder sb = new StringBuilder();
+ QueryParameter p = null;
+ for (int i = 0; i < parameters.Count; i++) {
+ p = parameters[i];
+ sb.AppendFormat("{0}={1}", p.Name, p.Value);
+
+ if (i < parameters.Count - 1) {
+ sb.Append("&");
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ ///
+ /// Generate the signature base that is used to produce the signature
+ ///
+ /// The full url that needs to be signed including its non OAuth url parameters
+ /// The consumer key
+ /// The token, if available. If not available pass null or an empty string
+ /// The token secret, if available. If not available pass null or an empty string
+ /// The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)
+ /// The signature type. To use the default values use OAuthBase.SignatureTypes.
+ /// The signature base
+ protected string GenerateSignatureBase(Uri url, string consumerKey, string token, string tokenSecret, string httpMethod, string timeStamp, string nonce, string callback, string signatureType, out string normalizedUrl, out string normalizedRequestParameters) {
+ if (token == null) {
+ token = string.Empty;
+ }
+
+ if (tokenSecret == null) {
+ tokenSecret = string.Empty;
+ }
+
+ if (string.IsNullOrEmpty(consumerKey)) {
+ throw new ArgumentNullException("consumerKey");
+ }
+
+ if (string.IsNullOrEmpty(httpMethod)) {
+ throw new ArgumentNullException("httpMethod");
+ }
+
+ if (string.IsNullOrEmpty(signatureType)) {
+ throw new ArgumentNullException("signatureType");
+ }
+
+ normalizedUrl = null;
+ normalizedRequestParameters = null;
+
+ List parameters = GetQueryParameters(url.Query);
+ parameters.Add(new QueryParameter(OAuthVersionKey, OAuthVersion));
+ parameters.Add(new QueryParameter(OAuthNonceKey, nonce));
+ parameters.Add(new QueryParameter(OAuthTimestampKey, timeStamp));
+ parameters.Add(new QueryParameter(OAuthSignatureMethodKey, signatureType));
+ parameters.Add(new QueryParameter(OAuthConsumerKeyKey, consumerKey));
+
+ //TODO: Make this less of a hack
+ if (!string.IsNullOrEmpty(callback)) {
+ parameters.Add(new QueryParameter(OAuthCallbackKey, UrlEncodeSpecial(callback)));
+ }
+
+ if (!string.IsNullOrEmpty(token)) {
+ parameters.Add(new QueryParameter(OAuthTokenKey, token));
+ }
+
+ if (!string.IsNullOrEmpty(oauth_verifier)) {
+ parameters.Add(new QueryParameter(oAauthVerifier, oauth_verifier));
+ }
+
+
+ parameters.Sort(new QueryParameterComparer());
+
+
+ normalizedUrl = string.Format("{0}://{1}", url.Scheme, url.Host);
+ if (!((url.Scheme == "http" && url.Port == 80) || (url.Scheme == "https" && url.Port == 443))) {
+ normalizedUrl += ":" + url.Port;
+ }
+ normalizedUrl += url.AbsolutePath;
+ normalizedRequestParameters = NormalizeRequestParameters(parameters);
+
+ StringBuilder signatureBase = new StringBuilder();
+ signatureBase.AppendFormat("{0}&", httpMethod.ToUpper());
+ signatureBase.AppendFormat("{0}&", UrlEncodeSpecial(normalizedUrl));
+ signatureBase.AppendFormat("{0}", UrlEncodeSpecial(normalizedRequestParameters));
+
+ return signatureBase.ToString();
+ }
+
+ ///
+ /// Generate the signature value based on the given signature base and hash algorithm
+ ///
+ /// The signature based as produced by the GenerateSignatureBase method or by any other means
+ /// The hash algorithm used to perform the hashing. If the hashing algorithm requires initialization or a key it should be set prior to calling this method
+ /// A base64 string of the hash value
+ protected string GenerateSignatureUsingHash(string signatureBase, HashAlgorithm hash) {
+ return ComputeHash(hash, signatureBase);
+ }
+
+ ///
+ /// Generates a signature using the HMAC-SHA1 algorithm
+ ///
+ /// The full url that needs to be signed including its non OAuth url parameters
+ /// The consumer key
+ /// The consumer seceret
+ /// The token, if available. If not available pass null or an empty string
+ /// The token secret, if available. If not available pass null or an empty string
+ /// The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)
+ /// A base64 string of the hash value
+ protected string GenerateSignature(Uri url, string consumerKey, string consumerSecret, string token, string tokenSecret, string httpMethod, string timeStamp, string nonce, string callback, out string normalizedUrl, out string normalizedRequestParameters) {
+ return GenerateSignature(url, consumerKey, consumerSecret, token, tokenSecret, httpMethod, timeStamp, nonce, callback, SignatureTypes.HMACSHA1, out normalizedUrl, out normalizedRequestParameters);
+ }
+
+ ///
+ /// Generates a signature using the specified signatureType
+ ///
+ /// The full url that needs to be signed including its non OAuth url parameters
+ /// The consumer key
+ /// The consumer seceret
+ /// The token, if available. If not available pass null or an empty string
+ /// The token secret, if available. If not available pass null or an empty string
+ /// The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)
+ /// The type of signature to use
+ /// A base64 string of the hash value
+ protected string GenerateSignature(Uri url, string consumerKey, string consumerSecret, string token, string tokenSecret, string httpMethod, string timeStamp, string nonce, string callback, SignatureTypes signatureType, out string normalizedUrl, out string normalizedRequestParameters) {
+ normalizedUrl = null;
+ normalizedRequestParameters = null;
+
+ switch (signatureType) {
+ case SignatureTypes.PLAINTEXT:
+ return NetworkHelper.UrlEncode(string.Format("{0}&{1}", consumerSecret, tokenSecret));
+ case SignatureTypes.HMACSHA1:
+ string signatureBase = GenerateSignatureBase(url, consumerKey, token, tokenSecret, httpMethod, timeStamp, nonce, callback, HMACSHA1SignatureType, out normalizedUrl, out normalizedRequestParameters);
+ HMACSHA1 hmacsha1 = new HMACSHA1();
+ hmacsha1.Key = Encoding.ASCII.GetBytes(string.Format("{0}&{1}", UrlEncodeSpecial(consumerSecret), string.IsNullOrEmpty(tokenSecret) ? "" : UrlEncodeSpecial(tokenSecret)));
+
+ return GenerateSignatureUsingHash(signatureBase, hmacsha1);
+ case SignatureTypes.RSASHA1:
+ throw new NotImplementedException();
+ default:
+ throw new ArgumentException("Unknown signature type", "signatureType");
+ }
+ }
+
+ ///
+ /// Generate the timestamp for the signature
+ ///
+ ///
+
+ protected virtual string GenerateTimeStamp() {
+ // Default implementation of UNIX time of the current UTC time
+ TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
+ return Convert.ToInt64(ts.TotalSeconds).ToString();
+ }
+
+ /*
+ public virtual string GenerateTimeStamp() {
+ // Default implementation of UNIX time of the current UTC time
+ TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
+ string timeStamp = ts.TotalSeconds.ToString();
+ timeStamp = timeStamp.Substring(0, timeStamp.IndexOf(","));
+ return Convert.ToInt64(timeStamp).ToString();
+ }*/
+
+ ///
+ /// Generate a nonce
+ ///
+ ///
+ protected virtual string GenerateNonce() {
+ // Just a simple implementation of a random number between 123400 and 9999999
+ return random.Next(123400, 9999999).ToString();
+ }
+
+ ///
+ /// Get the request token using the consumer key and secret. Also initializes tokensecret
+ ///
+ /// The request token.
+ public String getRequestToken() {
+ string ret = null;
+ string response = oAuthWebRequest(Method.POST, RequestTokenUrl, String.Empty);
+ if (response.Length > 0) {
+ NameValueCollection qs = NetworkHelper.ParseQueryString(response);
+ if (qs["oauth_token"] != null) {
+ this.Token = qs["oauth_token"];
+ this.TokenSecret = qs["oauth_token_secret"];
+ ret = this.Token;
+ }
+ }
+ return ret;
+ }
+
+ ///
+ /// Authorize the token by showing the dialog
+ ///
+ /// The request token.
+ public String authorizeToken(string browserTitle) {
+ if (string.IsNullOrEmpty(Token)) {
+ Exception e = new Exception("The request token is not set");
+ throw e;
+ }
+
+ OAuthLoginForm oAuthLoginForm = new OAuthLoginForm(this, browserTitle);
+ oAuthLoginForm.ShowDialog();
+ Token = oAuthLoginForm.Token;
+ Verifier = oAuthLoginForm.Verifier;
+ if (!string.IsNullOrEmpty(Verifier)) {
+ return Token;
+ } else {
+ return null;
+ }
+ }
+
+ ///
+ /// Get the access token
+ ///
+ /// The access token.
+ public String getAccessToken() {
+ if (string.IsNullOrEmpty(Token) || string.IsNullOrEmpty(Verifier)) {
+ Exception e = new Exception("The request token and verifier were not set");
+ throw e;
+ }
+
+ string response = oAuthWebRequest(Method.POST, AccessTokenUrl, string.Empty);
+
+ if (response.Length > 0) {
+ NameValueCollection qs = NetworkHelper.ParseQueryString(response);
+ if (qs["oauth_token"] != null) {
+ this.Token = qs["oauth_token"];
+ }
+ if (qs["oauth_token_secret"] != null) {
+ this.TokenSecret = qs["oauth_token_secret"];
+ }
+ }
+
+ return Token;
+ }
+
+ ///
+ /// Get the link to the authorization page for this application.
+ ///
+ /// The url with a valid request token, or a null string.
+ public string AuthorizationLink {
+ get {
+ return AuthorizeUrl + "?oauth_token=" + this.Token;
+ }
+ }
+
+ ///
+ /// Submit a web request using oAuth.
+ ///
+ /// GET or POST
+ /// The full url, including the querystring.
+ /// Data to post (querystring format)
+ /// The web server response.
+ public string oAuthWebRequest(Method method, string url, string postData) {
+ string outUrl = "";
+ string querystring = "";
+ string ret = "";
+
+ //Setup postData for signing.
+ //Add the postData to the querystring.
+ if (method == Method.POST) {
+ if (postData.Length > 0) {
+ //Decode the parameters and re-encode using the oAuth UrlEncode method.
+ NameValueCollection qs = NetworkHelper.ParseQueryString(postData);
+ postData = "";
+ foreach (string key in qs.AllKeys) {
+ if (postData.Length > 0) {
+ postData += "&";
+ }
+ qs[key] = NetworkHelper.UrlDecode(qs[key]);
+ qs[key] = UrlEncodeSpecial(qs[key]);
+ postData += key + "=" + qs[key];
+
+ }
+ if (url.IndexOf("?") > 0) {
+ url += "&";
+ } else {
+ url += "?";
+ }
+ url += postData;
+ }
+ }
+
+ Uri uri = new Uri(url);
+
+ string nonce = this.GenerateNonce();
+ string timeStamp = this.GenerateTimeStamp();
+
+ string callback = "";
+ if (url.ToString().Contains(RequestTokenUrl)) {
+ callback = _callbackUrl;
+ }
+
+ //Generate Signature
+ string sig = this.GenerateSignature(uri,
+ this.ConsumerKey,
+ this.ConsumerSecret,
+ this.Token,
+ this.TokenSecret,
+ method.ToString(),
+ timeStamp,
+ nonce,
+ callback,
+ out outUrl,
+ out querystring);
+
+
+ querystring += "&oauth_signature=" + NetworkHelper.UrlEncode(sig);
+
+ //Convert the querystring to postData
+ if (method == Method.POST) {
+ postData = querystring;
+ querystring = "";
+ }
+
+ if (querystring.Length > 0) {
+ outUrl += "?";
+ }
+
+ if (method == Method.POST || method == Method.GET) {
+ ret = WebRequest(method, outUrl + querystring, postData);
+ }
+
+ return ret;
+ }
+
+ ///
+ /// Web Request Wrapper
+ ///
+ /// Http Method
+ /// Full url to the web resource
+ /// Data to post in querystring format
+ /// The web server response.
+ protected string WebRequest(Method method, string url, string postData) {
+ HttpWebRequest webRequest = null;
+ StreamWriter requestWriter = null;
+ string responseData = "";
+
+ webRequest = (HttpWebRequest)NetworkHelper.CreateWebRequest(url);
+ webRequest.Method = method.ToString();
+ webRequest.ServicePoint.Expect100Continue = false;
+ webRequest.UserAgent = _userAgent;
+ webRequest.Timeout = 20000;
+
+ if (method == Method.POST) {
+ webRequest.ContentType = "application/x-www-form-urlencoded";
+
+ requestWriter = new StreamWriter(webRequest.GetRequestStream());
+ try {
+ requestWriter.Write(postData);
+ } catch {
+ throw;
+ } finally {
+ requestWriter.Close();
+ requestWriter = null;
+ }
+ }
+
+ responseData = WebResponseGet(webRequest);
+
+ webRequest = null;
+
+ return responseData;
+
+ }
+
+ ///
+ /// Process the web response.
+ ///
+ /// The request object.
+ /// The response data.
+ protected string WebResponseGet(HttpWebRequest webRequest) {
+ StreamReader responseReader = null;
+ string responseData = "";
+
+ try {
+ responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());
+ responseData = responseReader.ReadToEnd();
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ webRequest.GetResponse().GetResponseStream().Close();
+ responseReader.Close();
+ responseReader = null;
+ }
+
+ return responseData;
+ }
+ }
+}
diff --git a/GreenshotPlugin/GreenshotPlugin.csproj b/GreenshotPlugin/GreenshotPlugin.csproj
index 927b0c15b..9dd0700e8 100644
--- a/GreenshotPlugin/GreenshotPlugin.csproj
+++ b/GreenshotPlugin/GreenshotPlugin.csproj
@@ -226,6 +226,10 @@
Component
+
+
+ OAuthLoginForm.cs
+
PleaseWaitForm.cs
@@ -252,6 +256,7 @@
+