mirror of
https://github.com/greenshot/greenshot
synced 2025-07-14 17:13:44 -07:00
Reused new OAuth 2 code for the Box plug-in, this was possible by adding the embedded browser. Also refactored code to be more readable, and have more reuse. Fixed problems with Picasa upload and pressing cancel on the PleaseWaitForm. [skip ci]
This commit is contained in:
parent
9d7299e5ea
commit
1f80d56b10
16 changed files with 408 additions and 277 deletions
|
@ -31,7 +31,7 @@ namespace Greenshot.Forms {
|
|||
// The InitializeComponent() call is required for Windows Forms designer support.
|
||||
//
|
||||
InitializeComponent();
|
||||
BringToFront = true;
|
||||
ToFront = true;
|
||||
}
|
||||
|
||||
public BugReportForm(string bugText) : this() {
|
||||
|
|
|
@ -177,7 +177,7 @@ namespace Greenshot.Forms {
|
|||
ResumeLayout();
|
||||
|
||||
// Fix missing focus
|
||||
BringToFront = true;
|
||||
ToFront = true;
|
||||
TopMost = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,22 @@
|
|||
/*
|
||||
* Created by SharpDevelop.
|
||||
* User: jens
|
||||
* Date: 09.04.2012
|
||||
* Time: 19:24
|
||||
* Greenshot - a free and open source screenshot tool
|
||||
* Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
|
||||
*
|
||||
* To change this template use Tools | Options | Coding | Edit Standard Headers.
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using GreenshotPlugin.Core;
|
||||
|
@ -28,7 +40,7 @@ namespace Greenshot.Help
|
|||
}
|
||||
|
||||
public static void LoadHelp() {
|
||||
string uri = findOnlineHelpUrl(Language.CurrentLanguage);
|
||||
string uri = FindOnlineHelpUrl(Language.CurrentLanguage);
|
||||
if(uri == null) {
|
||||
uri = Language.HelpFilePath;
|
||||
}
|
||||
|
@ -36,7 +48,7 @@ namespace Greenshot.Help
|
|||
}
|
||||
|
||||
/// <returns>URL of help file in selected ietf, or (if not present) default ietf, or null (if not present, too. probably indicating that there is no internet connection)</returns>
|
||||
private static string findOnlineHelpUrl(string currentIETF) {
|
||||
private static string FindOnlineHelpUrl(string currentIETF) {
|
||||
string ret = null;
|
||||
|
||||
string extHelpUrlForCurrrentIETF = EXT_HELP_URL;
|
||||
|
@ -45,12 +57,12 @@ namespace Greenshot.Help
|
|||
extHelpUrlForCurrrentIETF += currentIETF.ToLower() + "/";
|
||||
}
|
||||
|
||||
HttpStatusCode? httpStatusCode = getHttpStatus(extHelpUrlForCurrrentIETF);
|
||||
HttpStatusCode? httpStatusCode = GetHttpStatus(extHelpUrlForCurrrentIETF);
|
||||
if(httpStatusCode == HttpStatusCode.OK) {
|
||||
ret = extHelpUrlForCurrrentIETF;
|
||||
} else if(httpStatusCode != null && !extHelpUrlForCurrrentIETF.Equals(EXT_HELP_URL)) {
|
||||
LOG.DebugFormat("Localized online help not found at {0}, will try {1} as fallback", extHelpUrlForCurrrentIETF, EXT_HELP_URL);
|
||||
httpStatusCode = getHttpStatus(EXT_HELP_URL);
|
||||
httpStatusCode = GetHttpStatus(EXT_HELP_URL);
|
||||
if(httpStatusCode == HttpStatusCode.OK) {
|
||||
ret = EXT_HELP_URL;
|
||||
} else {
|
||||
|
@ -68,9 +80,9 @@ namespace Greenshot.Help
|
|||
/// </summary>
|
||||
/// <param name="url">URL for which the HTTP status is to be checked</param>
|
||||
/// <returns>An HTTP status code, or null if there is none (probably indicating that there is no internet connection available</returns>
|
||||
private static HttpStatusCode? getHttpStatus(string url) {
|
||||
private static HttpStatusCode? GetHttpStatus(string url) {
|
||||
try {
|
||||
HttpWebRequest req = (HttpWebRequest)NetworkHelper.CreateWebRequest(url);
|
||||
HttpWebRequest req = NetworkHelper.CreateWebRequest(url);
|
||||
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
|
||||
return res.StatusCode;
|
||||
} catch(WebException e) {
|
||||
|
|
|
@ -18,9 +18,11 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Windows.Forms;
|
||||
using Greenshot.IniFile;
|
||||
using GreenshotPlugin.Core;
|
||||
using System;
|
||||
|
||||
namespace GreenshotBoxPlugin {
|
||||
/// <summary>
|
||||
|
@ -38,10 +40,43 @@ namespace GreenshotBoxPlugin {
|
|||
public bool AfterUploadLinkToClipBoard;
|
||||
|
||||
[IniProperty("UseSharedLink", Description = "Use the shared link, instead of the private, on the clipboard", DefaultValue = "True")]
|
||||
public bool UseSharedLink;
|
||||
public bool UseSharedLink {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
[IniProperty("FolderId", Description = "Folder ID to upload to, only change if you know what you are doing!", DefaultValue = "0")]
|
||||
public string FolderId {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[IniProperty("BoxToken", Description = "Token.", DefaultValue = "")]
|
||||
public string BoxToken;
|
||||
[IniProperty("AddFilename", Description = "Is the filename passed on to Box", DefaultValue = "False")]
|
||||
public bool AddFilename {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[IniProperty("RefreshToken", Description = "Box authorization refresh Token", Encrypted = true)]
|
||||
public string RefreshToken {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not stored
|
||||
/// </summary>
|
||||
public string AccessToken {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not stored
|
||||
/// </summary>
|
||||
public DateTimeOffset AccessTokenExpires {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A form for token
|
||||
|
|
|
@ -18,16 +18,14 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
|
||||
using Greenshot.IniFile;
|
||||
using GreenshotPlugin.Core;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using Greenshot.IniFile;
|
||||
using GreenshotPlugin.Controls;
|
||||
using GreenshotPlugin.Core;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using System.Text;
|
||||
|
||||
namespace GreenshotBoxPlugin {
|
||||
|
||||
|
@ -37,101 +35,24 @@ namespace GreenshotBoxPlugin {
|
|||
public static class BoxUtils {
|
||||
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(BoxUtils));
|
||||
private static readonly BoxConfiguration Config = IniConfig.GetIniSection<BoxConfiguration>();
|
||||
private const string RedirectUri = "https://www.box.com/home/";
|
||||
private const string UploadFileUri = "https://upload.box.com/api/2.0/files/content";
|
||||
private const string AuthorizeUri = "https://www.box.com/api/oauth2/authorize";
|
||||
private const string TokenUri = "https://www.box.com/api/oauth2/token";
|
||||
private const string FilesUri = "https://www.box.com/api/2.0/files/{0}";
|
||||
|
||||
private static bool Authorize() {
|
||||
string authorizeUrl = string.Format("{0}?client_id={1}&response_type=code&state=dropboxplugin&redirect_uri={2}", AuthorizeUri, BoxCredentials.ClientId, RedirectUri);
|
||||
|
||||
OAuthLoginForm loginForm = new OAuthLoginForm("Box Authorize", new Size(1060, 600), authorizeUrl, RedirectUri);
|
||||
loginForm.ShowDialog();
|
||||
if (!loginForm.isOk) {
|
||||
return false;
|
||||
}
|
||||
var callbackParameters = loginForm.CallbackParameters;
|
||||
if (callbackParameters == null || !callbackParameters.ContainsKey("code")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
string authorizationResponse = PostAndReturn(new Uri(TokenUri), string.Format("grant_type=authorization_code&code={0}&client_id={1}&client_secret={2}", callbackParameters["code"], BoxCredentials.ClientId, BoxCredentials.ClientSecret));
|
||||
var authorization = JsonSerializer.Deserialize<Authorization>(authorizationResponse);
|
||||
|
||||
Config.BoxToken = authorization.AccessToken;
|
||||
IniConfig.Save();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Download a url response as string
|
||||
/// </summary>
|
||||
/// <param name="url">An Uri to specify the download location</param>
|
||||
/// <param name="postMessage"></param>
|
||||
/// <returns>string with the file content</returns>
|
||||
public static string PostAndReturn(Uri url, string postMessage) {
|
||||
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(url);
|
||||
webRequest.Method = "POST";
|
||||
webRequest.KeepAlive = true;
|
||||
webRequest.Credentials = CredentialCache.DefaultCredentials;
|
||||
webRequest.ContentType = "application/x-www-form-urlencoded";
|
||||
byte[] data = Encoding.UTF8.GetBytes(postMessage);
|
||||
using (var requestStream = webRequest.GetRequestStream()) {
|
||||
requestStream.Write(data, 0, data.Length);
|
||||
}
|
||||
return NetworkHelper.GetResponse(webRequest);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Upload parameters by post
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="parameters"></param>
|
||||
/// <returns>response</returns>
|
||||
public static string HttpPost(string url, IDictionary<string, object> parameters) {
|
||||
var webRequest = (HttpWebRequest)NetworkHelper.CreateWebRequest(url);
|
||||
webRequest.Method = "POST";
|
||||
webRequest.KeepAlive = true;
|
||||
webRequest.Credentials = CredentialCache.DefaultCredentials;
|
||||
webRequest.Headers.Add("Authorization", "Bearer " + Config.BoxToken);
|
||||
NetworkHelper.WriteMultipartFormData(webRequest, parameters);
|
||||
|
||||
return NetworkHelper.GetResponse(webRequest);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Upload file by PUT
|
||||
/// Put string
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="content"></param>
|
||||
/// <param name="settings">OAuth2Settings</param>
|
||||
/// <returns>response</returns>
|
||||
public static string HttpPut(string url, string content) {
|
||||
var webRequest = (HttpWebRequest)NetworkHelper.CreateWebRequest(url);
|
||||
webRequest.Method = "PUT";
|
||||
webRequest.KeepAlive = true;
|
||||
webRequest.Credentials = CredentialCache.DefaultCredentials;
|
||||
webRequest.Headers.Add("Authorization", "Bearer " + Config.BoxToken);
|
||||
public static string HttpPut(string url, string content, OAuth2Settings settings) {
|
||||
var webRequest= OAuth2Helper.CreateOAuth2WebRequest(HTTPMethod.PUT, url, settings);
|
||||
|
||||
byte[] data = Encoding.UTF8.GetBytes(content);
|
||||
using (var requestStream = webRequest.GetRequestStream()) {
|
||||
requestStream.Write(data, 0, data.Length);
|
||||
}
|
||||
return NetworkHelper.GetResponse(webRequest);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get REST request
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns>response</returns>
|
||||
public static string HttpGet(string url) {
|
||||
var webRequest = (HttpWebRequest)NetworkHelper.CreateWebRequest(url);
|
||||
webRequest.Method = "GET";
|
||||
webRequest.KeepAlive = true;
|
||||
webRequest.Credentials = CredentialCache.DefaultCredentials;
|
||||
webRequest.Headers.Add("Authorization", "Bearer " + Config.BoxToken);
|
||||
return NetworkHelper.GetResponse(webRequest);
|
||||
return NetworkHelper.GetResponseAsString(webRequest);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -143,45 +64,53 @@ namespace GreenshotBoxPlugin {
|
|||
/// <param name="filename">Filename of box upload</param>
|
||||
/// <returns>url to uploaded image</returns>
|
||||
public static string UploadToBox(SurfaceContainer image, string title, string filename) {
|
||||
while (true) {
|
||||
const string folderId = "0";
|
||||
if (string.IsNullOrEmpty(Config.BoxToken)) {
|
||||
if (!Authorize()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill the OAuth2Settings
|
||||
OAuth2Settings settings = new OAuth2Settings();
|
||||
|
||||
settings.AuthUrlPattern = "https://www.box.com/api/oauth2/authorize?client_id={ClientId}&response_type={response_type}&state{State}&redirect_uri={RedirectUrl}";
|
||||
settings.TokenUrlPattern = "https://www.box.com/api/oauth2/token";
|
||||
settings.CloudServiceName = "Box";
|
||||
settings.ClientId = BoxCredentials.ClientId;
|
||||
settings.ClientSecret = BoxCredentials.ClientSecret;
|
||||
settings.RedirectUrl = "https://www.box.com/home/";
|
||||
settings.BrowserSize = new Size(1060, 600);
|
||||
settings.AuthorizeMode = OAuth2AuthorizeMode.EmbeddedBrowser;
|
||||
|
||||
// Copy the settings from the config, which is kept in memory and on the disk
|
||||
settings.RefreshToken = Config.RefreshToken;
|
||||
settings.AccessToken = Config.AccessToken;
|
||||
settings.AccessTokenExpires = Config.AccessTokenExpires;
|
||||
|
||||
try {
|
||||
var webRequest = OAuth2Helper.CreateOAuth2WebRequest(HTTPMethod.POST, FilesUri, settings);
|
||||
IDictionary<string, object> parameters = new Dictionary<string, object>();
|
||||
parameters.Add("filename", image);
|
||||
parameters.Add("parent_id", folderId);
|
||||
|
||||
var response = "";
|
||||
try {
|
||||
response = HttpPost(UploadFileUri, parameters);
|
||||
} catch (WebException ex) {
|
||||
if (ex.Status == WebExceptionStatus.ProtocolError) {
|
||||
Config.BoxToken = null;
|
||||
continue;
|
||||
}
|
||||
if (Config.AddFilename) {
|
||||
parameters.Add("filename", image);
|
||||
}
|
||||
parameters.Add("parent_id", Config.FolderId);
|
||||
|
||||
NetworkHelper.WriteMultipartFormData(webRequest, parameters);
|
||||
|
||||
var response = NetworkHelper.GetResponseAsString(webRequest);
|
||||
|
||||
LOG.DebugFormat("Box response: {0}", response);
|
||||
|
||||
// Check if the token is wrong
|
||||
if ("wrong auth token".Equals(response)) {
|
||||
Config.BoxToken = null;
|
||||
IniConfig.Save();
|
||||
continue;
|
||||
}
|
||||
var upload = JsonSerializer.Deserialize<Upload>(response);
|
||||
if (upload == null || upload.Entries == null || upload.Entries.Count == 0) return null;
|
||||
|
||||
if (Config.UseSharedLink) {
|
||||
string filesResponse = HttpPut(string.Format(FilesUri, upload.Entries[0].Id), "{\"shared_link\": {\"access\": \"open\"}}");
|
||||
string filesResponse = HttpPut(string.Format(FilesUri, upload.Entries[0].Id), "{\"shared_link\": {\"access\": \"open\"}}", settings);
|
||||
var file = JsonSerializer.Deserialize<FileEntry>(filesResponse);
|
||||
return file.SharedLink.Url;
|
||||
}
|
||||
return string.Format("http://www.box.com/files/0/f/0/1/f_{0}", upload.Entries[0].Id);
|
||||
} finally {
|
||||
// Copy the settings back to the config, so they are stored.
|
||||
Config.RefreshToken = settings.RefreshToken;
|
||||
Config.AccessToken = settings.AccessToken;
|
||||
Config.AccessTokenExpires = settings.AccessTokenExpires;
|
||||
Config.IsDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,8 +122,7 @@ namespace GreenshotImgurPlugin {
|
|||
if (config.AnonymousAccess) {
|
||||
// add key, we only use the other parameters for the AnonymousAccess
|
||||
otherParameters.Add("key", IMGUR_ANONYMOUS_API_KEY);
|
||||
HttpWebRequest webRequest = (HttpWebRequest)NetworkHelper.CreateWebRequest(config.ImgurApiUrl + "/upload.xml?" + NetworkHelper.GenerateQueryParameters(otherParameters));
|
||||
webRequest.Method = "POST";
|
||||
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(config.ImgurApiUrl + "/upload.xml?" + NetworkHelper.GenerateQueryParameters(otherParameters), HTTPMethod.POST);
|
||||
webRequest.ContentType = "image/" + outputSettings.Format.ToString();
|
||||
webRequest.ServicePoint.Expect100Continue = false;
|
||||
|
||||
|
@ -194,8 +193,7 @@ namespace GreenshotImgurPlugin {
|
|||
return;
|
||||
}
|
||||
LOG.InfoFormat("Retrieving Imgur image for {0} with url {1}", imgurInfo.Hash, imgurInfo.SmallSquare);
|
||||
HttpWebRequest webRequest = (HttpWebRequest)NetworkHelper.CreateWebRequest(imgurInfo.SmallSquare);
|
||||
webRequest.Method = "GET";
|
||||
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(imgurInfo.SmallSquare, HTTPMethod.GET);
|
||||
webRequest.ServicePoint.Expect100Continue = false;
|
||||
SetClientId(webRequest);
|
||||
using (WebResponse response = webRequest.GetResponse()) {
|
||||
|
@ -215,8 +213,7 @@ namespace GreenshotImgurPlugin {
|
|||
public static ImgurInfo RetrieveImgurInfo(string hash, string deleteHash) {
|
||||
string url = config.ImgurApiUrl + "/image/" + hash;
|
||||
LOG.InfoFormat("Retrieving Imgur info for {0} with url {1}", hash, url);
|
||||
HttpWebRequest webRequest = (HttpWebRequest)NetworkHelper.CreateWebRequest(url);
|
||||
webRequest.Method = "GET";
|
||||
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(url, HTTPMethod.GET);
|
||||
webRequest.ServicePoint.Expect100Continue = false;
|
||||
SetClientId(webRequest);
|
||||
string responseString;
|
||||
|
@ -250,10 +247,7 @@ namespace GreenshotImgurPlugin {
|
|||
|
||||
try {
|
||||
string url = config.ImgurApiUrl + "/delete/" + imgurInfo.DeleteHash;
|
||||
HttpWebRequest webRequest = (HttpWebRequest)NetworkHelper.CreateWebRequest(url);
|
||||
|
||||
//webRequest.Method = "DELETE";
|
||||
webRequest.Method = "GET";
|
||||
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(url, HTTPMethod.GET);
|
||||
webRequest.ServicePoint.Expect100Continue = false;
|
||||
SetClientId(webRequest);
|
||||
string responseString;
|
||||
|
|
|
@ -37,12 +37,6 @@ namespace GreenshotPicasaPlugin {
|
|||
[IniProperty("AfterUploadLinkToClipBoard", Description = "After upload send Picasa link to clipboard.", DefaultValue = "true")]
|
||||
public bool AfterUploadLinkToClipBoard;
|
||||
|
||||
[IniProperty("RefreshToken", Description = "Picasa refresh Token", Encrypted = true)]
|
||||
public string RefreshToken {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[IniProperty("AddFilename", Description = "Is the filename passed on to Picasa", DefaultValue = "False")]
|
||||
public bool AddFilename {
|
||||
get;
|
||||
|
@ -61,6 +55,12 @@ namespace GreenshotPicasaPlugin {
|
|||
set;
|
||||
}
|
||||
|
||||
[IniProperty("RefreshToken", Description = "Picasa authorization refresh Token", Encrypted = true)]
|
||||
public string RefreshToken {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not stored
|
||||
/// </summary>
|
||||
|
|
|
@ -50,10 +50,12 @@ namespace GreenshotPicasaPlugin {
|
|||
OAuth2Settings settings = new OAuth2Settings();
|
||||
settings.AuthUrlPattern = AuthUrl;
|
||||
settings.TokenUrlPattern = TokenUrl;
|
||||
settings.CloudServiceName = "Picasa";
|
||||
settings.AdditionalAttributes.Add("response_type", "code");
|
||||
settings.AdditionalAttributes.Add("scope", PicasaScope);
|
||||
settings.ClientId = PicasaCredentials.ClientId;
|
||||
settings.ClientSecret = PicasaCredentials.ClientSecret;
|
||||
settings.AuthorizeMode = OAuth2AuthorizeMode.LocalServer;
|
||||
|
||||
// Copy the settings from the config, which is kept in memory and on the disk
|
||||
settings.RefreshToken = Config.RefreshToken;
|
||||
|
@ -61,27 +63,14 @@ namespace GreenshotPicasaPlugin {
|
|||
settings.AccessTokenExpires = Config.AccessTokenExpires;
|
||||
|
||||
try {
|
||||
// Get Refresh / Access token
|
||||
if (string.IsNullOrEmpty(settings.RefreshToken)) {
|
||||
OAuth2Helper.AuthenticateViaLocalServer(settings);
|
||||
}
|
||||
|
||||
if (settings.IsAccessTokenExpired) {
|
||||
OAuth2Helper.GenerateAccessToken(settings);
|
||||
}
|
||||
|
||||
var webRequest = (HttpWebRequest)NetworkHelper.CreateWebRequest(string.Format(UploadUrl, Config.UploadUser, Config.UploadAlbum));
|
||||
webRequest.Method = "POST";
|
||||
webRequest.KeepAlive = true;
|
||||
webRequest.Credentials = CredentialCache.DefaultCredentials;
|
||||
OAuth2Helper.AddOAuth2Credentials(webRequest, settings);
|
||||
var webRequest = OAuth2Helper.CreateOAuth2WebRequest(HTTPMethod.POST, string.Format(UploadUrl, Config.UploadUser, Config.UploadAlbum), settings);
|
||||
if (Config.AddFilename) {
|
||||
webRequest.Headers.Add("Slug", NetworkHelper.EscapeDataString(filename));
|
||||
}
|
||||
SurfaceContainer container = new SurfaceContainer(surfaceToUpload, outputSettings, filename);
|
||||
container.Upload(webRequest);
|
||||
|
||||
string response = NetworkHelper.GetResponse(webRequest);
|
||||
string response = NetworkHelper.GetResponseAsString(webRequest);
|
||||
|
||||
return ParseResponse(response);
|
||||
} finally {
|
||||
|
@ -89,6 +78,7 @@ namespace GreenshotPicasaPlugin {
|
|||
Config.RefreshToken = settings.RefreshToken;
|
||||
Config.AccessToken = settings.AccessToken;
|
||||
Config.AccessTokenExpires = settings.AccessTokenExpires;
|
||||
Config.IsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace GreenshotPlugin.Controls {
|
|||
/// <summary>
|
||||
/// When this is set, the form will be brought to the foreground as soon as it is shown.
|
||||
/// </summary>
|
||||
protected bool BringToFront {
|
||||
protected bool ToFront {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ namespace GreenshotPlugin.Controls {
|
|||
/// <param name="e">EventArgs</param>
|
||||
protected override void OnShown(EventArgs e) {
|
||||
base.OnShown(e);
|
||||
if (BringToFront) {
|
||||
if (ToFront) {
|
||||
WindowDetails.ToForeground(Handle);
|
||||
}
|
||||
}
|
||||
|
|
44
GreenshotPlugin/Controls/OAuthLoginForm.Designer.cs
generated
44
GreenshotPlugin/Controls/OAuthLoginForm.Designer.cs
generated
|
@ -44,37 +44,37 @@ namespace GreenshotPlugin.Controls {
|
|||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.addressTextBox = new System.Windows.Forms.TextBox();
|
||||
this.browser = new ExtendedWebBrowser();
|
||||
this._addressTextBox = new System.Windows.Forms.TextBox();
|
||||
this._browser = new ExtendedWebBrowser();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// addressTextBox
|
||||
// _addressTextBox
|
||||
//
|
||||
this.addressTextBox.Cursor = System.Windows.Forms.Cursors.Arrow;
|
||||
this.addressTextBox.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.addressTextBox.Enabled = false;
|
||||
this.addressTextBox.Location = new System.Drawing.Point(0, 0);
|
||||
this.addressTextBox.Name = "addressTextBox";
|
||||
this.addressTextBox.Size = new System.Drawing.Size(595, 20);
|
||||
this.addressTextBox.TabIndex = 3;
|
||||
this.addressTextBox.TabStop = false;
|
||||
this._addressTextBox.Cursor = System.Windows.Forms.Cursors.Arrow;
|
||||
this._addressTextBox.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this._addressTextBox.Enabled = false;
|
||||
this._addressTextBox.Location = new System.Drawing.Point(0, 0);
|
||||
this._addressTextBox.Name = "addressTextBox";
|
||||
this._addressTextBox.Size = new System.Drawing.Size(595, 20);
|
||||
this._addressTextBox.TabIndex = 3;
|
||||
this._addressTextBox.TabStop = false;
|
||||
//
|
||||
// browser
|
||||
// _browser
|
||||
//
|
||||
this.browser.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.browser.Location = new System.Drawing.Point(0, 20);
|
||||
this.browser.MinimumSize = new System.Drawing.Size(100, 100);
|
||||
this.browser.Name = "browser";
|
||||
this.browser.Size = new System.Drawing.Size(595, 295);
|
||||
this.browser.TabIndex = 4;
|
||||
this._browser.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this._browser.Location = new System.Drawing.Point(0, 20);
|
||||
this._browser.MinimumSize = new System.Drawing.Size(100, 100);
|
||||
this._browser.Name = "browser";
|
||||
this._browser.Size = new System.Drawing.Size(595, 295);
|
||||
this._browser.TabIndex = 4;
|
||||
//
|
||||
// OAuthLoginForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(595, 315);
|
||||
this.Controls.Add(this.browser);
|
||||
this.Controls.Add(this.addressTextBox);
|
||||
this.Controls.Add(this._browser);
|
||||
this.Controls.Add(this._addressTextBox);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "OAuthLoginForm";
|
||||
|
@ -85,8 +85,8 @@ namespace GreenshotPlugin.Controls {
|
|||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TextBox addressTextBox;
|
||||
private ExtendedWebBrowser browser;
|
||||
private System.Windows.Forms.TextBox _addressTextBox;
|
||||
private ExtendedWebBrowser _browser;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,31 +35,33 @@ namespace GreenshotPlugin.Controls {
|
|||
/// </summary>
|
||||
public partial class OAuthLoginForm : Form {
|
||||
private static readonly ILog LOG = LogManager.GetLogger(typeof(OAuthLoginForm));
|
||||
private string callbackUrl = null;
|
||||
private IDictionary<string, string> callbackParameters = null;
|
||||
private string _callbackUrl = null;
|
||||
private IDictionary<string, string> _callbackParameters = null;
|
||||
|
||||
public IDictionary<string, string> CallbackParameters {
|
||||
get { return callbackParameters; }
|
||||
get {
|
||||
return _callbackParameters;
|
||||
}
|
||||
}
|
||||
|
||||
public bool isOk {
|
||||
public bool IsOk {
|
||||
get {
|
||||
return DialogResult == DialogResult.OK;
|
||||
}
|
||||
}
|
||||
|
||||
public OAuthLoginForm(string browserTitle, Size size, string authorizationLink, string callbackUrl) {
|
||||
this.callbackUrl = callbackUrl;
|
||||
_callbackUrl = callbackUrl;
|
||||
InitializeComponent();
|
||||
ClientSize = size;
|
||||
Icon = GreenshotResources.getGreenshotIcon();
|
||||
Text = browserTitle;
|
||||
addressTextBox.Text = authorizationLink;
|
||||
_addressTextBox.Text = authorizationLink;
|
||||
|
||||
// The script errors are suppressed by using the ExtendedWebBrowser
|
||||
browser.ScriptErrorsSuppressed = false;
|
||||
browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(browser_DocumentCompleted);
|
||||
browser.Navigate(new Uri(authorizationLink));
|
||||
_browser.ScriptErrorsSuppressed = false;
|
||||
_browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(Browser_DocumentCompleted);
|
||||
_browser.Navigate(new Uri(authorizationLink));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -71,33 +73,24 @@ namespace GreenshotPlugin.Controls {
|
|||
WindowDetails.ToForeground(Handle);
|
||||
}
|
||||
|
||||
private void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) {
|
||||
LOG.DebugFormat("document completed with url: {0}", browser.Url);
|
||||
checkUrl();
|
||||
}
|
||||
private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e) {
|
||||
LOG.DebugFormat("Navigating to url: {0}", browser.Url);
|
||||
addressTextBox.Text = e.Url.ToString();
|
||||
private void Browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) {
|
||||
LOG.DebugFormat("document completed with url: {0}", _browser.Url);
|
||||
CheckUrl();
|
||||
}
|
||||
|
||||
private void browser_Navigated(object sender, WebBrowserNavigatedEventArgs e) {
|
||||
LOG.DebugFormat("Navigated to url: {0}", browser.Url);
|
||||
checkUrl();
|
||||
}
|
||||
|
||||
private void checkUrl() {
|
||||
if (browser.Url.ToString().StartsWith(callbackUrl)) {
|
||||
string queryParams = browser.Url.Query;
|
||||
private void CheckUrl() {
|
||||
if (_browser.Url.ToString().StartsWith(_callbackUrl)) {
|
||||
string queryParams = _browser.Url.Query;
|
||||
if (queryParams.Length > 0) {
|
||||
queryParams = NetworkHelper.UrlDecode(queryParams);
|
||||
//Store the Token and Token Secret
|
||||
callbackParameters = NetworkHelper.ParseQueryString(queryParams);
|
||||
_callbackParameters = NetworkHelper.ParseQueryString(queryParams);
|
||||
}
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
}
|
||||
|
||||
private void addressTextBox_KeyPress(object sender, KeyPressEventArgs e) {
|
||||
private void AddressTextBox_KeyPress(object sender, KeyPressEventArgs e) {
|
||||
//Cancel the key press so the user can't enter a new url
|
||||
e.Handled = true;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace GreenshotPlugin.Controls {
|
|||
trackBarJpegQuality.Value = Settings.JPGQuality;
|
||||
textBoxJpegQuality.Enabled = OutputFormat.jpg.Equals(outputSettings.Format);
|
||||
textBoxJpegQuality.Text = Settings.JPGQuality.ToString();
|
||||
BringToFront = true;
|
||||
ToFront = true;
|
||||
}
|
||||
|
||||
void Button_okClick(object sender, EventArgs e) {
|
||||
|
|
|
@ -33,6 +33,17 @@ using System.Text;
|
|||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace GreenshotPlugin.Core {
|
||||
/// <summary>
|
||||
/// HTTP Method to make sure we have the correct method
|
||||
/// </summary>
|
||||
public enum HTTPMethod {
|
||||
GET,
|
||||
POST,
|
||||
PUT,
|
||||
DELETE,
|
||||
HEAD
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Description of NetworkHelper.
|
||||
/// </summary>
|
||||
|
@ -55,10 +66,7 @@ namespace GreenshotPlugin.Core {
|
|||
/// <returns>string with the file content</returns>
|
||||
public static string GetAsString(Uri uri) {
|
||||
HttpWebRequest webRequest = CreateWebRequest(uri);
|
||||
webRequest.Method = "GET";
|
||||
webRequest.KeepAlive = true;
|
||||
webRequest.Credentials = CredentialCache.DefaultCredentials;
|
||||
return GetResponse(webRequest);
|
||||
return GetResponseAsString(CreateWebRequest(uri));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -143,14 +151,36 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to create a web request, eventually with proxy
|
||||
/// Helper method to create a web request with a lot of default settings
|
||||
/// </summary>
|
||||
/// <param name="uri">string with uri to connect to</param>
|
||||
/// <returns>WebRequest</returns>
|
||||
public static HttpWebRequest CreateWebRequest(string uri) {
|
||||
return CreateWebRequest(new Uri(uri));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to create a web request with a lot of default settings
|
||||
/// </summary>
|
||||
/// <param name="uri">string with uri to connect to</param>
|
||||
/// /// <param name="method">Method to use</param>
|
||||
/// <returns>WebRequest</returns>
|
||||
public static HttpWebRequest CreateWebRequest(string uri, HTTPMethod method) {
|
||||
return CreateWebRequest(new Uri(uri), method);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to create a web request with a lot of default settings
|
||||
/// </summary>
|
||||
/// <param name="uri">Uri with uri to connect to</param>
|
||||
/// <param name="method">Method to use</param>
|
||||
/// <returns>WebRequest</returns>
|
||||
public static HttpWebRequest CreateWebRequest(Uri uri, HTTPMethod method) {
|
||||
HttpWebRequest webRequest = CreateWebRequest(uri);
|
||||
webRequest.Method = method.ToString();
|
||||
return webRequest;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to create a web request, eventually with proxy
|
||||
/// </summary>
|
||||
|
@ -164,6 +194,10 @@ namespace GreenshotPlugin.Core {
|
|||
// BUG-1655: Fix that Greenshot always uses the default proxy even if the "use default proxy" checkbox is unset
|
||||
webRequest.Proxy = null;
|
||||
}
|
||||
// Make sure the default credentials are available
|
||||
webRequest.Credentials = CredentialCache.DefaultCredentials;
|
||||
|
||||
// Allow redirect, this is usually needed so that we don't get a problem when a service moves
|
||||
webRequest.AllowAutoRedirect = true;
|
||||
// Set default timeouts
|
||||
webRequest.Timeout = Config.WebRequestTimeout*1000;
|
||||
|
@ -365,7 +399,7 @@ namespace GreenshotPlugin.Core {
|
|||
using (var streamWriter = new StreamWriter(requestStream, Encoding.UTF8)) {
|
||||
streamWriter.Write(urlEncoded);
|
||||
}
|
||||
return GetResponse(webRequest);
|
||||
return GetResponseAsString(webRequest);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -388,7 +422,7 @@ namespace GreenshotPlugin.Core {
|
|||
/// <param name="webRequest">The request object.</param>
|
||||
/// <returns>The response data.</returns>
|
||||
/// TODO: This method should handle the StatusCode better!
|
||||
public static string GetResponse(HttpWebRequest webRequest) {
|
||||
public static string GetResponseAsString(HttpWebRequest webRequest) {
|
||||
string responseData = null;
|
||||
try {
|
||||
HttpWebResponse response = (HttpWebResponse) webRequest.GetResponse();
|
||||
|
@ -429,7 +463,7 @@ namespace GreenshotPlugin.Core {
|
|||
public static DateTime GetLastModified(Uri uri) {
|
||||
try {
|
||||
HttpWebRequest webRequest = CreateWebRequest(uri);
|
||||
webRequest.Method = "HEAD";
|
||||
webRequest.Method = HTTPMethod.HEAD.ToString();
|
||||
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
|
||||
LOG.DebugFormat("RSS feed was updated at {0}", webResponse.LastModified);
|
||||
return webResponse.LastModified;
|
||||
|
|
|
@ -46,9 +46,15 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used HTTP Method, this is for the OAuth 1.x protocol
|
||||
/// Specify the autorize mode that is used to get the token from the cloud service.
|
||||
/// </summary>
|
||||
public enum HTTPMethod { GET, POST, PUT, DELETE };
|
||||
public enum OAuth2AuthorizeMode {
|
||||
Unknown, // Will give an exception, caller needs to specify another value
|
||||
LocalServer, // Will specify a redirect URL to http://localhost:port/authorize, while having a HttpListener
|
||||
MonitorTitle, // Not implemented yet: Will monitor for title changes
|
||||
Pin, // Not implemented yet: Will ask the user to enter the shown PIN
|
||||
EmbeddedBrowser // Will open into an embedded _browser (OAuthLoginForm), and catch the redirect
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Settings for the OAuth 2 protocol
|
||||
|
@ -58,6 +64,28 @@ namespace GreenshotPlugin.Core {
|
|||
AdditionalAttributes = new Dictionary<string, string>();
|
||||
// Create a default state
|
||||
State = Guid.NewGuid().ToString();
|
||||
AuthorizeMode = OAuth2AuthorizeMode.Unknown;
|
||||
}
|
||||
|
||||
public OAuth2AuthorizeMode AuthorizeMode {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specify the name of the cloud service, so it can be used in window titles, logs etc
|
||||
/// </summary>
|
||||
public string CloudServiceName {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specify the size of the embedded Browser, if using this
|
||||
/// </summary>
|
||||
public Size BrowserSize {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -242,7 +270,7 @@ namespace GreenshotPlugin.Core {
|
|||
private readonly string _consumerKey;
|
||||
private readonly string _consumerSecret;
|
||||
|
||||
// default browser size
|
||||
// default _browser size
|
||||
private Size _browserSize = new Size(864, 587);
|
||||
private string _loginTitle = "Authorize Greenshot access";
|
||||
|
||||
|
@ -479,7 +507,7 @@ namespace GreenshotPlugin.Core {
|
|||
LOG.DebugFormat("Opening AuthorizationLink: {0}", AuthorizationLink);
|
||||
OAuthLoginForm oAuthLoginForm = new OAuthLoginForm(LoginTitle, BrowserSize, AuthorizationLink, CallbackUrl);
|
||||
oAuthLoginForm.ShowDialog();
|
||||
if (oAuthLoginForm.isOk) {
|
||||
if (oAuthLoginForm.IsOk) {
|
||||
if (oAuthLoginForm.CallbackParameters != null) {
|
||||
string tokenValue;
|
||||
if (oAuthLoginForm.CallbackParameters.TryGetValue(OAUTH_TOKEN_KEY, out tokenValue)) {
|
||||
|
@ -812,11 +840,9 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
}
|
||||
// Create webrequest
|
||||
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(requestURL);
|
||||
webRequest.Method = method.ToString();
|
||||
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(requestURL, method);
|
||||
webRequest.ServicePoint.Expect100Continue = false;
|
||||
webRequest.UserAgent = _userAgent;
|
||||
webRequest.Timeout = 100000;
|
||||
|
||||
if (UseHTTPHeadersForAuthorization && authHeader != null) {
|
||||
LOG.DebugFormat("Authorization: OAuth {0}", authHeader);
|
||||
|
@ -860,7 +886,7 @@ namespace GreenshotPlugin.Core {
|
|||
|
||||
string responseData;
|
||||
try {
|
||||
responseData = NetworkHelper.GetResponse(webRequest);
|
||||
responseData = NetworkHelper.GetResponseAsString(webRequest);
|
||||
LOG.DebugFormat("Response: {0}", responseData);
|
||||
} catch (Exception ex) {
|
||||
LOG.Error("Couldn't retrieve response: ", ex);
|
||||
|
@ -879,6 +905,7 @@ namespace GreenshotPlugin.Core {
|
|||
/// </summary>
|
||||
public class LocalServerCodeReceiver {
|
||||
private static readonly ILog LOG = LogManager.GetLogger(typeof(LocalServerCodeReceiver));
|
||||
private readonly ManualResetEvent _ready = new ManualResetEvent(true);
|
||||
|
||||
private string _loopbackCallback = "http://localhost:{0}/authorize/";
|
||||
/// <summary>
|
||||
|
@ -896,9 +923,9 @@ namespace GreenshotPlugin.Core {
|
|||
|
||||
private string _closePageResponse =
|
||||
@"<html>
|
||||
<head><title>OAuth 2.0 Authentication Token Received</title></head>
|
||||
<head><title>OAuth 2.0 Authentication CloudServiceName</title></head>
|
||||
<body>
|
||||
Greenshot received verification code. You can close this browser / tab if it is not closed itself...
|
||||
Greenshot received information from CloudServiceName. You can close this browser / tab if it is not closed itself...
|
||||
<script type='text/javascript'>
|
||||
window.setTimeout(function() {
|
||||
window.open('', '_self', '');
|
||||
|
@ -912,7 +939,8 @@ Greenshot received verification code. You can close this browser / tab if it is
|
|||
</html>";
|
||||
|
||||
/// <summary>
|
||||
/// HTML code to to return the browser, default it will try to close the browser / tab, this won't always work.
|
||||
/// HTML code to to return the _browser, default it will try to close the _browser / tab, this won't always work.
|
||||
/// You can use CloudServiceName where you want to show the CloudServiceName from your OAuth2 settings
|
||||
/// </summary>
|
||||
public string ClosePageResponse {
|
||||
get {
|
||||
|
@ -937,6 +965,11 @@ Greenshot received verification code. You can close this browser / tab if it is
|
|||
}
|
||||
}
|
||||
|
||||
private string _cloudServiceName;
|
||||
|
||||
private IDictionary<string, string> _returnValues = new Dictionary<string, string>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The OAuth code receiver
|
||||
/// </summary>
|
||||
|
@ -945,6 +978,7 @@ Greenshot received verification code. You can close this browser / tab if it is
|
|||
public IDictionary<string, string> ReceiveCode(OAuth2Settings oauth2Settings) {
|
||||
// Set the redirect URL on the settings
|
||||
oauth2Settings.RedirectUrl = RedirectUri;
|
||||
_cloudServiceName = oauth2Settings.CloudServiceName;
|
||||
using (var listener = new HttpListener()) {
|
||||
listener.Prefixes.Add(oauth2Settings.RedirectUrl);
|
||||
try {
|
||||
|
@ -956,31 +990,67 @@ Greenshot received verification code. You can close this browser / tab if it is
|
|||
Process.Start(authorizationUrl);
|
||||
|
||||
// Wait to get the authorization code response.
|
||||
var context = listener.GetContext();
|
||||
try {
|
||||
NameValueCollection nameValueCollection = context.Request.QueryString;
|
||||
var context = listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener);
|
||||
_ready.Reset();
|
||||
|
||||
// Write a "close" response.
|
||||
using (var writer = new StreamWriter(context.Response.OutputStream)) {
|
||||
writer.WriteLine(ClosePageResponse);
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
// Create a new response URL with a dictionary that contains all the response query parameters.
|
||||
IDictionary<string, string> returnValues = new Dictionary<string, string>();
|
||||
foreach (var name in nameValueCollection.AllKeys) {
|
||||
if (!returnValues.ContainsKey(name)) {
|
||||
returnValues.Add(name, nameValueCollection[name]);
|
||||
}
|
||||
}
|
||||
return returnValues;
|
||||
} finally {
|
||||
context.Response.OutputStream.Close();
|
||||
while (!context.AsyncWaitHandle.WaitOne(1000, true)) {
|
||||
LOG.Debug("Waiting for response");
|
||||
}
|
||||
} catch (Exception) {
|
||||
// Make sure we can clean up, also if the thead is aborted
|
||||
_ready.Set();
|
||||
throw;
|
||||
} finally {
|
||||
_ready.WaitOne();
|
||||
listener.Close();
|
||||
}
|
||||
}
|
||||
return _returnValues;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle a connection async, this allows us to break the waiting
|
||||
/// </summary>
|
||||
/// <param name="result">IAsyncResult</param>
|
||||
private void ListenerCallback(IAsyncResult result) {
|
||||
HttpListener listener = (HttpListener)result.AsyncState;
|
||||
|
||||
//If not listening return immediately as this method is called one last time after Close()
|
||||
if (!listener.IsListening) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use EndGetContext to complete the asynchronous operation.
|
||||
HttpListenerContext context = listener.EndGetContext(result);
|
||||
|
||||
|
||||
// Handle request
|
||||
HttpListenerRequest request = context.Request;
|
||||
try {
|
||||
NameValueCollection nameValueCollection = request.QueryString;
|
||||
|
||||
// Get response object.
|
||||
using (HttpListenerResponse response = context.Response) {
|
||||
// Write a "close" response.
|
||||
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(ClosePageResponse.Replace("CloudServiceName", _cloudServiceName));
|
||||
// Write to response stream.
|
||||
response.ContentLength64 = buffer.Length;
|
||||
using (var stream = response.OutputStream) {
|
||||
stream.Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new response URL with a dictionary that contains all the response query parameters.
|
||||
foreach (var name in nameValueCollection.AllKeys) {
|
||||
if (!_returnValues.ContainsKey(name)) {
|
||||
_returnValues.Add(name, nameValueCollection[name]);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
context.Response.OutputStream.Close();
|
||||
throw;
|
||||
}
|
||||
_ready.Set();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1002,23 +1072,6 @@ Greenshot received verification code. You can close this browser / tab if it is
|
|||
/// Code to simplify OAuth 2
|
||||
/// </summary>
|
||||
public static class OAuth2Helper {
|
||||
/// <summary>
|
||||
/// Upload parameters by post
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="parameters">Form-Url-Parameters</param>
|
||||
/// <param name="settings">OAuth2Settings</param>
|
||||
/// <returns>response</returns>
|
||||
public static string HttpPost(string url, IDictionary<string, object> parameters, OAuth2Settings settings) {
|
||||
HttpWebRequest webRequest = (HttpWebRequest)NetworkHelper.CreateWebRequest(url);
|
||||
webRequest.Method = "POST";
|
||||
webRequest.KeepAlive = true;
|
||||
webRequest.Credentials = CredentialCache.DefaultCredentials;
|
||||
|
||||
AddOAuth2Credentials(webRequest, settings);
|
||||
return NetworkHelper.UploadFormUrlEncoded(webRequest, parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate an OAuth 2 Token by using the supplied code
|
||||
/// </summary>
|
||||
|
@ -1033,7 +1086,8 @@ Greenshot received verification code. You can close this browser / tab if it is
|
|||
data.Add("client_secret", settings.ClientSecret);
|
||||
data.Add("grant_type", "authorization_code");
|
||||
|
||||
string accessTokenJsonResult = HttpPost(settings.FormattedTokenUrl, data, settings);
|
||||
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(settings.FormattedTokenUrl, HTTPMethod.POST);
|
||||
string accessTokenJsonResult = NetworkHelper.UploadFormUrlEncoded(webRequest, data);
|
||||
IDictionary<string, object> refreshTokenResult = JSONHelper.JsonDecode(accessTokenJsonResult);
|
||||
// gives as described here: https://developers.google.com/identity/protocols/OAuth2InstalledApp
|
||||
// "access_token":"1/fFAGRNJru1FTz70BzhT3Zg",
|
||||
|
@ -1061,7 +1115,9 @@ Greenshot received verification code. You can close this browser / tab if it is
|
|||
data.Add("client_secret", settings.ClientSecret);
|
||||
data.Add("grant_type", "refresh_token");
|
||||
|
||||
string accessTokenJsonResult = HttpPost(settings.FormattedTokenUrl, data, settings);
|
||||
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(settings.FormattedTokenUrl, HTTPMethod.POST);
|
||||
string accessTokenJsonResult = NetworkHelper.UploadFormUrlEncoded(webRequest, data);
|
||||
|
||||
// gives as described here: https://developers.google.com/identity/protocols/OAuth2InstalledApp
|
||||
// "access_token":"1/fFAGRNJru1FTz70BzhT3Zg",
|
||||
// "expires_in":3920,
|
||||
|
@ -1076,26 +1132,78 @@ Greenshot received verification code. You can close this browser / tab if it is
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Authenticate via a local server by using the LocalServerCodeReceiver
|
||||
/// If this works, immediately generate a refresh token afterwards, otherwise this throws an exception
|
||||
/// Authenticate by using the mode specified in the settings
|
||||
/// </summary>
|
||||
/// <param name="settings">OAuth2Settings</param>
|
||||
/// <returns>false if it was canceled, true if it worked, exception if not</returns>
|
||||
public static bool Authenticate(OAuth2Settings settings) {
|
||||
bool completed = true;
|
||||
switch (settings.AuthorizeMode) {
|
||||
case OAuth2AuthorizeMode.LocalServer:
|
||||
completed = AuthenticateViaLocalServer(settings);
|
||||
break;
|
||||
case OAuth2AuthorizeMode.EmbeddedBrowser:
|
||||
completed = AuthenticateViaEmbeddedBrowser(settings);
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException(string.Format("Authorize mode '{0}' is not 'yet' implemented.", settings.AuthorizeMode));
|
||||
}
|
||||
return completed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Authenticate via an embedded browser
|
||||
/// If this works, return the code
|
||||
/// </summary>
|
||||
/// <param name="settings">OAuth2Settings with the Auth / Token url etc</param>
|
||||
public static void AuthenticateViaLocalServer(OAuth2Settings settings) {
|
||||
/// <returns>true if completed, false if canceled</returns>
|
||||
private static bool AuthenticateViaEmbeddedBrowser(OAuth2Settings settings) {
|
||||
if (string.IsNullOrEmpty(settings.CloudServiceName)) {
|
||||
throw new ArgumentNullException("CloudServiceName");
|
||||
}
|
||||
if (settings.BrowserSize == Size.Empty) {
|
||||
throw new ArgumentNullException("BrowserSize");
|
||||
}
|
||||
OAuthLoginForm loginForm = new OAuthLoginForm(string.Format("Authorize {0}", settings.CloudServiceName), settings.BrowserSize, settings.FormattedAuthUrl, settings.RedirectUrl);
|
||||
loginForm.ShowDialog();
|
||||
if (loginForm.IsOk) {
|
||||
string code;
|
||||
if (loginForm.CallbackParameters.TryGetValue("code", out code) && !string.IsNullOrEmpty(code)) {
|
||||
GenerateRefreshToken(code, settings);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Authenticate via a local server by using the LocalServerCodeReceiver
|
||||
/// If this works, return the code
|
||||
/// </summary>
|
||||
/// <param name="settings">OAuth2Settings with the Auth / Token url etc</param>
|
||||
/// <returns>true if completed</returns>
|
||||
private static bool AuthenticateViaLocalServer(OAuth2Settings settings) {
|
||||
var codeReceiver = new LocalServerCodeReceiver();
|
||||
IDictionary<string, string> result = codeReceiver.ReceiveCode(settings);
|
||||
|
||||
string code;
|
||||
if (result.TryGetValue("code", out code)) {
|
||||
if (result.TryGetValue("code", out code) && !string.IsNullOrEmpty(code)) {
|
||||
GenerateRefreshToken(code, settings);
|
||||
return true;
|
||||
}
|
||||
string error;
|
||||
if (result.TryGetValue("error", out error)) {
|
||||
string errorDescription;
|
||||
if (result.TryGetValue("error_description", out errorDescription)) {
|
||||
throw new Exception(errorDescription);
|
||||
}
|
||||
if ("access_denied" == error) {
|
||||
throw new UnauthorizedAccessException("Access denied");
|
||||
} else {
|
||||
throw new Exception(error);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1108,5 +1216,38 @@ Greenshot received verification code. You can close this browser / tab if it is
|
|||
webRequest.Headers.Add("Authorization", "Bearer " + settings.AccessToken);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check and authenticate or refresh tokens
|
||||
/// </summary>
|
||||
/// <param name="settings">OAuth2Settings</param>
|
||||
public static void CheckAndAuthenticateOrRefresh(OAuth2Settings settings) {
|
||||
// Get Refresh / Access token
|
||||
if (string.IsNullOrEmpty(settings.RefreshToken)) {
|
||||
if (!OAuth2Helper.Authenticate(settings)) {
|
||||
throw new Exception("Authentication cancelled");
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.IsAccessTokenExpired) {
|
||||
OAuth2Helper.GenerateAccessToken(settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// CreateWebRequest ready for OAuth 2 access
|
||||
/// </summary>
|
||||
/// <param name="method">HTTPMethod</param>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="settings">OAuth2Settings</param>
|
||||
/// <returns>HttpWebRequest</returns>
|
||||
public static HttpWebRequest CreateOAuth2WebRequest(HTTPMethod method, string url, OAuth2Settings settings) {
|
||||
CheckAndAuthenticateOrRefresh(settings);
|
||||
|
||||
HttpWebRequest webRequest = (HttpWebRequest)NetworkHelper.CreateWebRequest(url, method);
|
||||
OAuth2Helper.AddOAuth2Credentials(webRequest, settings);
|
||||
return webRequest;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
@ -113,10 +114,9 @@ namespace GreenshotPlugin.Core {
|
|||
/// </summary>
|
||||
/// <returns>Dictionary<string, Dictionary<string, RssFile>> with files and their RssFile "description"</returns>
|
||||
public static Dictionary<string, Dictionary<string, SourceforgeFile>> readRSS() {
|
||||
HttpWebRequest webRequest;
|
||||
XmlDocument rssDoc = new XmlDocument();
|
||||
try {
|
||||
webRequest = (HttpWebRequest)NetworkHelper.CreateWebRequest(RSSFEED);
|
||||
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(RSSFEED);
|
||||
XmlTextReader rssReader = new XmlTextReader(webRequest.GetResponse().GetResponseStream());
|
||||
|
||||
// Load the XML content into a XmlDocument
|
||||
|
|
|
@ -58,7 +58,10 @@ namespace Greenshot.IniFile {
|
|||
/// <summary>
|
||||
/// Flag to specify if values have been changed
|
||||
/// </summary>
|
||||
public bool IsDirty = false;
|
||||
public bool IsDirty {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Supply values we can't put as defaults
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue