mirror of
https://github.com/ShareX/ShareX.git
synced 2024-10-02 18:26:27 +13:00
Merge pull request #3316 from SupSuper/onedrive-api
Update OneDrive Uploader to Microsoft Graph API
This commit is contained in:
commit
a0255f95a6
10 changed files with 307 additions and 67 deletions
|
@ -424,5 +424,13 @@ public static string RemoveQuery(string url)
|
|||
|
||||
return url;
|
||||
}
|
||||
|
||||
public static string BuildUri(string root, string path, string query = null)
|
||||
{
|
||||
UriBuilder builder = new UriBuilder(root);
|
||||
builder.Path = path;
|
||||
builder.Query = query;
|
||||
return builder.Uri.AbsoluteUri;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -290,6 +290,78 @@ protected UploadResult SendRequestFile(string url, Stream data, string fileName,
|
|||
return result;
|
||||
}
|
||||
|
||||
protected UploadResult SendRequestBytes(string url, Stream data, string fileName, long contentPosition = 0, long contentLength = -1, Dictionary<string, string> args = null,
|
||||
NameValueCollection headers = null, CookieCollection cookies = null, ResponseType responseType = ResponseType.Text, HttpMethod method = HttpMethod.PUT)
|
||||
{
|
||||
UploadResult result = new UploadResult();
|
||||
|
||||
IsUploading = true;
|
||||
StopUploadRequested = false;
|
||||
|
||||
try
|
||||
{
|
||||
url = URLHelpers.CreateQuery(url, args);
|
||||
|
||||
if (contentLength == -1)
|
||||
{
|
||||
contentLength = data.Length;
|
||||
}
|
||||
contentLength = Math.Min(contentLength, data.Length - contentPosition);
|
||||
|
||||
string contentType = Helpers.GetMimeType(fileName);
|
||||
|
||||
if (headers == null)
|
||||
{
|
||||
headers = new NameValueCollection();
|
||||
}
|
||||
long startByte = contentPosition;
|
||||
long endByte = startByte + contentLength - 1;
|
||||
long dataLength = data.Length;
|
||||
headers.Add("Content-Range", $"bytes {startByte}-{endByte}/{dataLength}");
|
||||
|
||||
HttpWebRequest request = PrepareWebRequest(method, url, headers, cookies, contentType, contentLength);
|
||||
|
||||
using (Stream requestStream = request.GetRequestStream())
|
||||
{
|
||||
if (!TransferData(data, requestStream, contentPosition, contentLength))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
using (WebResponse response = request.GetResponse())
|
||||
{
|
||||
result.Response = ResponseToString(response, responseType);
|
||||
}
|
||||
|
||||
result.IsSuccess = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (!StopUploadRequested)
|
||||
{
|
||||
string response = AddWebError(e, url);
|
||||
|
||||
if (ReturnResponseOnError && e is WebException)
|
||||
{
|
||||
result.Response = response;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
currentRequest = null;
|
||||
IsUploading = false;
|
||||
|
||||
if (VerboseLogs && !string.IsNullOrEmpty(VerboseLogsPath))
|
||||
{
|
||||
WriteVerboseLog(url, args, headers, result.Response);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private HttpWebResponse GetResponse(HttpMethod method, string url, Stream data = null, string contentType = null, Dictionary<string, string> args = null,
|
||||
NameValueCollection headers = null, CookieCollection cookies = null)
|
||||
{
|
||||
|
@ -397,21 +469,34 @@ private HttpWebRequest PrepareWebRequest(HttpMethod method, string url, NameValu
|
|||
return request;
|
||||
}
|
||||
|
||||
protected bool TransferData(Stream dataStream, Stream requestStream)
|
||||
protected bool TransferData(Stream dataStream, Stream requestStream, long dataPosition = 0, long dataLength = -1)
|
||||
{
|
||||
if (dataPosition >= dataStream.Length)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (dataStream.CanSeek)
|
||||
{
|
||||
dataStream.Position = 0;
|
||||
dataStream.Position = dataPosition;
|
||||
}
|
||||
|
||||
ProgressManager progress = new ProgressManager(dataStream.Length);
|
||||
int length = (int)Math.Min(BufferSize, dataStream.Length);
|
||||
if (dataLength == -1)
|
||||
{
|
||||
dataLength = dataStream.Length;
|
||||
}
|
||||
dataLength = Math.Min(dataLength, dataStream.Length - dataPosition);
|
||||
|
||||
ProgressManager progress = new ProgressManager(dataStream.Length, dataPosition);
|
||||
int length = (int)Math.Min(BufferSize, dataLength);
|
||||
byte[] buffer = new byte[length];
|
||||
int bytesRead;
|
||||
|
||||
long bytesRemaining = dataLength;
|
||||
while (!StopUploadRequested && (bytesRead = dataStream.Read(buffer, 0, length)) > 0)
|
||||
{
|
||||
requestStream.Write(buffer, 0, bytesRead);
|
||||
bytesRemaining -= bytesRead;
|
||||
length = (int)Math.Min(buffer.Length, bytesRemaining);
|
||||
|
||||
if (AllowReportProgress && progress.UpdateProgress(bytesRead))
|
||||
{
|
||||
|
|
|
@ -27,6 +27,7 @@ You should have received a copy of the GNU General Public License
|
|||
using ShareX.HelpersLib;
|
||||
using ShareX.UploadersLib.Properties;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
|
@ -42,14 +43,14 @@ public class OneDriveFileUploaderService : FileUploaderService
|
|||
|
||||
public override bool CheckConfig(UploadersConfig config)
|
||||
{
|
||||
return OAuth2Info.CheckOAuth(config.OneDriveOAuth2Info);
|
||||
return OAuth2Info.CheckOAuth(config.OneDriveV2OAuth2Info);
|
||||
}
|
||||
|
||||
public override GenericUploader CreateUploader(UploadersConfig config, TaskReferenceHelper taskInfo)
|
||||
{
|
||||
return new OneDrive(config.OneDriveOAuth2Info)
|
||||
return new OneDrive(config.OneDriveV2OAuth2Info)
|
||||
{
|
||||
FolderID = config.OneDriveSelectedFolder.id,
|
||||
FolderID = config.OneDriveV2SelectedFolder.id,
|
||||
AutoCreateShareableLink = config.OneDriveAutoCreateShareableLink
|
||||
};
|
||||
}
|
||||
|
@ -59,13 +60,17 @@ public override GenericUploader CreateUploader(UploadersConfig config, TaskRefer
|
|||
|
||||
public sealed class OneDrive : FileUploader, IOAuth2
|
||||
{
|
||||
private const string AuthorizationEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize";
|
||||
private const string TokenEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
|
||||
private const int MaxSegmentSize = 64 * 1024 * 1024; // 64 MiB
|
||||
|
||||
public OAuth2Info AuthInfo { get; set; }
|
||||
public string FolderID { get; set; }
|
||||
public bool AutoCreateShareableLink { get; set; }
|
||||
|
||||
public static OneDriveFileInfo RootFolder = new OneDriveFileInfo
|
||||
{
|
||||
id = "me/skydrive",
|
||||
id = "", // empty defaults to root
|
||||
name = Resources.OneDrive_RootFolder_Root_folder
|
||||
};
|
||||
|
||||
|
@ -78,11 +83,16 @@ public string GetAuthorizationURL()
|
|||
{
|
||||
Dictionary<string, string> args = new Dictionary<string, string>();
|
||||
args.Add("client_id", AuthInfo.Client_ID);
|
||||
args.Add("scope", "wl.offline_access wl.skydrive_update");
|
||||
args.Add("scope", "offline_access files.readwrite");
|
||||
args.Add("response_type", "code");
|
||||
args.Add("redirect_uri", Links.URL_CALLBACK);
|
||||
if (AuthInfo.Proof != null)
|
||||
{
|
||||
args.Add("code_challenge", AuthInfo.Proof.CodeChallenge);
|
||||
args.Add("code_challenge_method", AuthInfo.Proof.ChallengeMethod);
|
||||
}
|
||||
|
||||
return URLHelpers.CreateQuery("https://login.live.com/oauth20_authorize.srf", args);
|
||||
return URLHelpers.CreateQuery(AuthorizationEndpoint, args);
|
||||
}
|
||||
|
||||
public bool GetAccessToken(string code)
|
||||
|
@ -93,8 +103,12 @@ public bool GetAccessToken(string code)
|
|||
args.Add("client_secret", AuthInfo.Client_Secret);
|
||||
args.Add("code", code);
|
||||
args.Add("grant_type", "authorization_code");
|
||||
if (AuthInfo.Proof != null)
|
||||
{
|
||||
args.Add("code_verifier", AuthInfo.Proof.CodeVerifier);
|
||||
}
|
||||
|
||||
string response = SendRequestURLEncoded(HttpMethod.POST, "https://login.live.com/oauth20_token.srf", args);
|
||||
string response = SendRequestURLEncoded(HttpMethod.POST, TokenEndpoint, args);
|
||||
|
||||
if (!string.IsNullOrEmpty(response))
|
||||
{
|
||||
|
@ -117,12 +131,11 @@ public bool RefreshAccessToken()
|
|||
{
|
||||
Dictionary<string, string> args = new Dictionary<string, string>();
|
||||
args.Add("client_id", AuthInfo.Client_ID);
|
||||
args.Add("redirect_uri", Links.URL_CALLBACK);
|
||||
args.Add("client_secret", AuthInfo.Client_Secret);
|
||||
args.Add("refresh_token", AuthInfo.Token.refresh_token);
|
||||
args.Add("grant_type", "refresh_token");
|
||||
|
||||
string response = SendRequestURLEncoded(HttpMethod.POST, "https://login.live.com/oauth20_token.srf", args);
|
||||
string response = SendRequestURLEncoded(HttpMethod.POST, TokenEndpoint, args);
|
||||
|
||||
if (!string.IsNullOrEmpty(response))
|
||||
{
|
||||
|
@ -161,29 +174,79 @@ public bool CheckAuthorization()
|
|||
return true;
|
||||
}
|
||||
|
||||
private NameValueCollection GetAuthHeaders()
|
||||
{
|
||||
NameValueCollection headers = new NameValueCollection();
|
||||
headers.Add("Authorization", "Bearer " + AuthInfo.Token.access_token);
|
||||
return headers;
|
||||
}
|
||||
|
||||
private string GetFolderUrl(string folderID)
|
||||
{
|
||||
string folderPath;
|
||||
|
||||
if (!string.IsNullOrEmpty(folderID))
|
||||
{
|
||||
folderPath = URLHelpers.CombineURL("me/drive/items", folderID);
|
||||
}
|
||||
else
|
||||
{
|
||||
folderPath = "me/drive/root";
|
||||
}
|
||||
|
||||
return folderPath;
|
||||
}
|
||||
|
||||
private string CreateSession(string fileName)
|
||||
{
|
||||
string json = JsonConvert.SerializeObject(new
|
||||
{
|
||||
item = new Dictionary<string, string>
|
||||
{
|
||||
{ "name", fileName },
|
||||
{ "@microsoft.graph.conflictBehavior", "replace" }
|
||||
}
|
||||
});
|
||||
|
||||
string folderPath = GetFolderUrl(FolderID);
|
||||
|
||||
string url = URLHelpers.BuildUri("https://graph.microsoft.com", $"/v1.0/{folderPath}:/{fileName}:/createUploadSession");
|
||||
|
||||
string response = SendRequest(HttpMethod.POST, url, json, ContentTypeJSON, headers: GetAuthHeaders());
|
||||
|
||||
OneDriveUploadSession session = JsonConvert.DeserializeObject<OneDriveUploadSession>(response);
|
||||
|
||||
if (session != null)
|
||||
{
|
||||
return session.uploadUrl;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override UploadResult Upload(Stream stream, string fileName)
|
||||
{
|
||||
if (!CheckAuthorization()) return null;
|
||||
|
||||
Dictionary<string, string> args = new Dictionary<string, string>();
|
||||
args.Add("access_token", AuthInfo.Token.access_token);
|
||||
args.Add("overwrite", "true");
|
||||
args.Add("downsize_photo_uploads", "false");
|
||||
string sessionUrl = CreateSession(fileName);
|
||||
long position = 0;
|
||||
UploadResult result = new UploadResult();
|
||||
|
||||
string folderPath;
|
||||
|
||||
if (!string.IsNullOrEmpty(FolderID))
|
||||
do
|
||||
{
|
||||
folderPath = URLHelpers.CombineURL(FolderID, "files");
|
||||
}
|
||||
else
|
||||
{
|
||||
folderPath = "me/skydrive/files";
|
||||
}
|
||||
result = SendRequestBytes(sessionUrl, stream, fileName, position, MaxSegmentSize);
|
||||
|
||||
string url = URLHelpers.CreateQuery(URLHelpers.CombineURL("https://apis.live.net/v5.0", folderPath), args);
|
||||
|
||||
UploadResult result = SendRequestFile(url, stream, fileName);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
position += MaxSegmentSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
SendRequest(HttpMethod.DELETE, sessionUrl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (position < stream.Length);
|
||||
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
|
@ -191,11 +254,13 @@ public override UploadResult Upload(Stream stream, string fileName)
|
|||
|
||||
if (AutoCreateShareableLink)
|
||||
{
|
||||
AllowReportProgress = false;
|
||||
|
||||
result.URL = CreateShareableLink(uploadInfo.id);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.URL = uploadInfo.source;
|
||||
result.URL = uploadInfo.webUrl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,9 +269,6 @@ public override UploadResult Upload(Stream stream, string fileName)
|
|||
|
||||
public string CreateShareableLink(string id, OneDriveLinkType linkType = OneDriveLinkType.Read)
|
||||
{
|
||||
Dictionary<string, string> args = new Dictionary<string, string>();
|
||||
args.Add("access_token", AuthInfo.Token.access_token);
|
||||
|
||||
string linkTypeValue;
|
||||
|
||||
switch (linkType)
|
||||
|
@ -216,39 +278,46 @@ public string CreateShareableLink(string id, OneDriveLinkType linkType = OneDriv
|
|||
break;
|
||||
default:
|
||||
case OneDriveLinkType.Read:
|
||||
linkTypeValue = "shared_read_link";
|
||||
linkTypeValue = "view";
|
||||
break;
|
||||
case OneDriveLinkType.Edit:
|
||||
linkTypeValue = "shared_edit_link";
|
||||
linkTypeValue = "edit";
|
||||
break;
|
||||
}
|
||||
|
||||
string response = SendRequest(HttpMethod.GET, $"https://apis.live.net/v5.0/{id}/{linkTypeValue}", args);
|
||||
|
||||
OneDriveShareableLinkInfo shareableLinkInfo = JsonConvert.DeserializeObject<OneDriveShareableLinkInfo>(response);
|
||||
|
||||
if (shareableLinkInfo != null)
|
||||
string json = JsonConvert.SerializeObject(new
|
||||
{
|
||||
return shareableLinkInfo.link;
|
||||
type = linkTypeValue
|
||||
});
|
||||
|
||||
string response = SendRequest(HttpMethod.POST, $"https://graph.microsoft.com/v1.0/me/drive/items/{id}/createLink", json, ContentTypeJSON,
|
||||
headers: GetAuthHeaders());
|
||||
|
||||
OneDrivePermission permissionInfo = JsonConvert.DeserializeObject<OneDrivePermission>(response);
|
||||
|
||||
if (permissionInfo != null && permissionInfo.link != null)
|
||||
{
|
||||
return permissionInfo.link.webUrl;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public OneDrivePathInfo GetPathInfo(string path)
|
||||
public OneDriveFileList GetPathInfo(string id)
|
||||
{
|
||||
if (!CheckAuthorization()) return null;
|
||||
|
||||
string folderPath = GetFolderUrl(id);
|
||||
|
||||
Dictionary<string, string> args = new Dictionary<string, string>();
|
||||
args.Add("access_token", AuthInfo.Token.access_token);
|
||||
args.Add("select", "id,name");
|
||||
args.Add("filter", "folder ne null");
|
||||
|
||||
if (!path.EndsWith("files")) path += "/files";
|
||||
|
||||
string response = SendRequest(HttpMethod.GET, URLHelpers.CombineURL("https://apis.live.net/v5.0", path), args);
|
||||
string response = SendRequest(HttpMethod.GET, $"https://graph.microsoft.com/v1.0/{folderPath}/children", args, GetAuthHeaders());
|
||||
|
||||
if (response != null)
|
||||
{
|
||||
OneDrivePathInfo pathInfo = JsonConvert.DeserializeObject<OneDrivePathInfo>(response);
|
||||
OneDriveFileList pathInfo = JsonConvert.DeserializeObject<OneDriveFileList>(response);
|
||||
return pathInfo;
|
||||
}
|
||||
|
||||
|
@ -260,17 +329,29 @@ public class OneDriveFileInfo
|
|||
{
|
||||
public string id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string source { get; set; }
|
||||
public string webUrl { get; set; }
|
||||
}
|
||||
|
||||
public class OneDriveShareableLinkInfo
|
||||
public class OneDrivePermission
|
||||
{
|
||||
public string link { get; set; }
|
||||
public OneDriveShareableLink link { get; set; }
|
||||
}
|
||||
|
||||
public class OneDrivePathInfo
|
||||
public class OneDriveShareableLink
|
||||
{
|
||||
public OneDriveFileInfo[] data { get; set; }
|
||||
public string webUrl { get; set; }
|
||||
public string webHtml { get; set; }
|
||||
}
|
||||
|
||||
public class OneDriveFileList
|
||||
{
|
||||
public OneDriveFileInfo[] value { get; set; }
|
||||
}
|
||||
|
||||
public class OneDriveUploadSession
|
||||
{
|
||||
public string uploadUrl { get; set; }
|
||||
public string[] nextExpectedRanges { get; set; }
|
||||
}
|
||||
|
||||
public enum OneDriveLinkType
|
||||
|
|
|
@ -395,7 +395,7 @@ public void LoadSettings()
|
|||
tvOneDrive.Nodes.Clear();
|
||||
OneDriveAddFolder(OneDrive.RootFolder, null);
|
||||
|
||||
if (OAuth2Info.CheckOAuth(Config.OneDriveOAuth2Info))
|
||||
if (OAuth2Info.CheckOAuth(Config.OneDriveV2OAuth2Info))
|
||||
{
|
||||
oAuth2OneDrive.Status = OAuthLoginStatus.LoginSuccessful;
|
||||
|
||||
|
@ -403,7 +403,7 @@ public void LoadSettings()
|
|||
}
|
||||
|
||||
cbOneDriveCreateShareableLink.Checked = Config.OneDriveAutoCreateShareableLink;
|
||||
lblOneDriveFolderID.Text = Resources.UploadersConfigForm_LoadSettings_Selected_folder_ + " " + Config.OneDriveSelectedFolder.name;
|
||||
lblOneDriveFolderID.Text = Resources.UploadersConfigForm_LoadSettings_Selected_folder_ + " " + Config.OneDriveV2SelectedFolder.name;
|
||||
tvOneDrive.CollapseAll();
|
||||
|
||||
#endregion OneDrive
|
||||
|
@ -1750,7 +1750,7 @@ private void oAuth2OneDrive_RefreshButtonClicked()
|
|||
|
||||
private void oAuth2OneDrive_ClearButtonClicked()
|
||||
{
|
||||
Config.OneDriveOAuth2Info = null;
|
||||
Config.OneDriveV2OAuth2Info = null;
|
||||
}
|
||||
|
||||
private void cbOneDriveCreateShareableLink_CheckedChanged(object sender, EventArgs e)
|
||||
|
@ -1764,7 +1764,7 @@ private void tvOneDrive_AfterSelect(object sender, TreeViewEventArgs e)
|
|||
if (file != null)
|
||||
{
|
||||
lblOneDriveFolderID.Text = Resources.UploadersConfigForm_LoadSettings_Selected_folder_ + " " + file.name;
|
||||
Config.OneDriveSelectedFolder = file;
|
||||
Config.OneDriveV2SelectedFolder = file;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -711,11 +711,12 @@ public void OneDriveAuthOpen()
|
|||
try
|
||||
{
|
||||
OAuth2Info oauth = new OAuth2Info(APIKeys.OneDriveClientID, APIKeys.OneDriveClientSecret);
|
||||
oauth.Proof = new OAuth2ProofKey(OAuth2ChallengeMethod.SHA256);
|
||||
string url = new OneDrive(oauth).GetAuthorizationURL();
|
||||
|
||||
if (!string.IsNullOrEmpty(url))
|
||||
{
|
||||
Config.OneDriveOAuth2Info = oauth;
|
||||
Config.OneDriveV2OAuth2Info = oauth;
|
||||
URLHelpers.OpenURL(url);
|
||||
DebugHelper.WriteLine("OneDriveAuthOpen - Authorization URL is opened: " + url);
|
||||
}
|
||||
|
@ -734,9 +735,9 @@ public void OneDriveAuthComplete(string code)
|
|||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(code) && Config.OneDriveOAuth2Info != null)
|
||||
if (!string.IsNullOrEmpty(code) && Config.OneDriveV2OAuth2Info != null)
|
||||
{
|
||||
bool result = new OneDrive(Config.OneDriveOAuth2Info).GetAccessToken(code);
|
||||
bool result = new OneDrive(Config.OneDriveV2OAuth2Info).GetAccessToken(code);
|
||||
|
||||
if (result)
|
||||
{
|
||||
|
@ -763,9 +764,9 @@ public void OneDriveAuthRefresh()
|
|||
{
|
||||
try
|
||||
{
|
||||
if (OAuth2Info.CheckOAuth(Config.OneDriveOAuth2Info))
|
||||
if (OAuth2Info.CheckOAuth(Config.OneDriveV2OAuth2Info))
|
||||
{
|
||||
bool result = new OneDrive(Config.OneDriveOAuth2Info).RefreshAccessToken();
|
||||
bool result = new OneDrive(Config.OneDriveV2OAuth2Info).RefreshAccessToken();
|
||||
|
||||
if (result)
|
||||
{
|
||||
|
@ -790,10 +791,10 @@ public void OneDriveAuthRefresh()
|
|||
public void OneDriveListFolders(OneDriveFileInfo fileEntry, TreeNode tnParent)
|
||||
{
|
||||
Application.DoEvents();
|
||||
OneDrive oneDrive = new OneDrive(Config.OneDriveOAuth2Info);
|
||||
OneDrivePathInfo oneDrivePathInfo = oneDrive.GetPathInfo(fileEntry.id);
|
||||
OneDrive oneDrive = new OneDrive(Config.OneDriveV2OAuth2Info);
|
||||
OneDriveFileList oneDrivePathInfo = oneDrive.GetPathInfo(fileEntry.id);
|
||||
tnParent.Nodes.Clear();
|
||||
foreach (OneDriveFileInfo folder in oneDrivePathInfo.data.Where(x => x.id.StartsWith("folder.")))
|
||||
foreach (OneDriveFileInfo folder in oneDrivePathInfo.value)
|
||||
{
|
||||
OneDriveAddFolder(folder, tnParent);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ public class OAuth2Info
|
|||
public string Client_ID { get; set; }
|
||||
public string Client_Secret { get; set; }
|
||||
public OAuth2Token Token { get; set; }
|
||||
public OAuth2ProofKey Proof { get; set; }
|
||||
|
||||
public OAuth2Info(string client_id, string client_secret)
|
||||
{
|
||||
|
|
62
ShareX.UploadersLib/Helpers/OAuth/OAuth2ProofKey.cs
Normal file
62
ShareX.UploadersLib/Helpers/OAuth/OAuth2ProofKey.cs
Normal file
|
@ -0,0 +1,62 @@
|
|||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace ShareX.UploadersLib
|
||||
{
|
||||
public enum OAuth2ChallengeMethod
|
||||
{
|
||||
Plain, SHA256
|
||||
}
|
||||
|
||||
public class OAuth2ProofKey
|
||||
{
|
||||
public string CodeVerifier { get; private set; }
|
||||
public string CodeChallenge { get; private set; }
|
||||
private OAuth2ChallengeMethod Method;
|
||||
public string ChallengeMethod
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (Method)
|
||||
{
|
||||
case OAuth2ChallengeMethod.Plain: return "plain";
|
||||
case OAuth2ChallengeMethod.SHA256: return "S256";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public OAuth2ProofKey(OAuth2ChallengeMethod method)
|
||||
{
|
||||
Method = method;
|
||||
|
||||
var buffer = new byte[32];
|
||||
|
||||
using (var rng = new RNGCryptoServiceProvider())
|
||||
{
|
||||
rng.GetBytes(buffer);
|
||||
}
|
||||
CodeVerifier = CleanBase64(buffer);
|
||||
CodeChallenge = CodeVerifier;
|
||||
|
||||
if (Method == OAuth2ChallengeMethod.SHA256)
|
||||
{
|
||||
using (var sha = SHA256.Create())
|
||||
{
|
||||
sha.ComputeHash(Encoding.UTF8.GetBytes(CodeVerifier));
|
||||
CodeChallenge = CleanBase64(sha.Hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string CleanBase64(byte[] buffer)
|
||||
{
|
||||
var sb = new StringBuilder(Convert.ToBase64String(buffer));
|
||||
sb.Replace('+', '-');
|
||||
sb.Replace('/', '_');
|
||||
sb.Replace("=", "");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -60,9 +60,10 @@ public TimeSpan Remaining
|
|||
private long speedTest;
|
||||
private FixedSizedQueue<double> averageSpeed = new FixedSizedQueue<double>(10);
|
||||
|
||||
public ProgressManager(long length)
|
||||
public ProgressManager(long length, long position = 0)
|
||||
{
|
||||
Length = length;
|
||||
Position = position;
|
||||
startTimer.Start();
|
||||
smoothTimer.Start();
|
||||
}
|
||||
|
|
|
@ -243,6 +243,7 @@
|
|||
<Compile Include="Helpers\EscapeHelper.cs" />
|
||||
<Compile Include="Helpers\GoogleOAuth2.cs" />
|
||||
<Compile Include="Helpers\OAuth\IOAuthBase.cs" />
|
||||
<Compile Include="Helpers\OAuth\OAuth2ProofKey.cs" />
|
||||
<Compile Include="Helpers\SSLBypassHelper.cs" />
|
||||
<Compile Include="BaseServices\URLSharingService.cs" />
|
||||
<Compile Include="OtherServices\OCRSpace.cs" />
|
||||
|
|
|
@ -179,8 +179,8 @@ public class UploadersConfig : SettingsBase<UploadersConfig>
|
|||
|
||||
#region OneDrive
|
||||
|
||||
public OAuth2Info OneDriveOAuth2Info = null;
|
||||
public OneDriveFileInfo OneDriveSelectedFolder = OneDrive.RootFolder;
|
||||
public OAuth2Info OneDriveV2OAuth2Info = null;
|
||||
public OneDriveFileInfo OneDriveV2SelectedFolder = OneDrive.RootFolder;
|
||||
public bool OneDriveAutoCreateShareableLink = true;
|
||||
|
||||
#endregion OneDrive
|
||||
|
|
Loading…
Reference in a new issue