diff --git a/KeeAnywhere/KeeAnywhere.csproj b/KeeAnywhere/KeeAnywhere.csproj index 1833c02..b4ccadb 100644 --- a/KeeAnywhere/KeeAnywhere.csproj +++ b/KeeAnywhere/KeeAnywhere.csproj @@ -402,14 +402,6 @@ - - - - - - - - diff --git a/KeeAnywhere/StorageProviders/HubiC/HubiCAccount.cs b/KeeAnywhere/StorageProviders/HubiC/HubiCAccount.cs deleted file mode 100644 index 1ee558d..0000000 --- a/KeeAnywhere/StorageProviders/HubiC/HubiCAccount.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Runtime.Serialization; - -namespace KeeAnywhere.StorageProviders.HubiC -{ - [DataContract] - internal class HubiCAccount - { - [DataMember(Name="email")] - public string EMail { get; set; } - - [DataMember(Name = "firstname")] - public string FirstName { get; set; } - - [DataMember(Name = "lastname")] - public string LastName { get; set; } - } -} \ No newline at end of file diff --git a/KeeAnywhere/StorageProviders/HubiC/HubiCCredentials.cs b/KeeAnywhere/StorageProviders/HubiC/HubiCCredentials.cs deleted file mode 100644 index 3dc9000..0000000 --- a/KeeAnywhere/StorageProviders/HubiC/HubiCCredentials.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Runtime.Serialization; - -namespace KeeAnywhere.StorageProviders.HubiC -{ - [DataContract] - public class HubiCCredentials - { - [DataMember(Name = "token")] - public string Token { get; set; } - - [DataMember(Name = "endpoint")] - public string Endpoint { get; set; } - - [DataMember(Name = "expires")] - public DateTime Exprires { get; set; } - } -} \ No newline at end of file diff --git a/KeeAnywhere/StorageProviders/HubiC/HubiCHelper.cs b/KeeAnywhere/StorageProviders/HubiC/HubiCHelper.cs deleted file mode 100644 index 0e16759..0000000 --- a/KeeAnywhere/StorageProviders/HubiC/HubiCHelper.cs +++ /dev/null @@ -1,264 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using System.Threading.Tasks; -using KeeAnywhere.OAuth2; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace KeeAnywhere.StorageProviders.HubiC -{ - internal class HubiCHelper - { - /* - The consumer key and the secret key included here are dummy keys. - You should go to https://hubic.com/home/browser/developers/ to create your own application - and get your own keys. - - This is done to prevent bots from scraping the keys from the source code posted on the web. - - Every now and then an accidental checkin of keys may occur, but these are all dummy applications - created specifically for development that are deleted frequently and limited to the developer, - never the real production keys. - */ - - //TODO: Change API keys!!! - internal const string HubiCClientId = "dummy"; - internal const string HubiCClientSecret = "dummy"; - - public const string AuthorizationUri = "https://api.hubic.com/oauth/auth"; - public const string RedirectUri = "https://github.com/kyrodan/KeeAnywhere/"; - public const string TokenUri = "https://api.hubic.com/oauth/token"; - public const string AccountUri = "https://api.hubic.com/1.0/account"; - public const string AccountCredentialsUri = "https://api.hubic.com/1.0/account/credentials"; - - public static Uri GetAuthorizationUri() - { - var uriString = - string.Format( - "{0}?client_id={1}&redirect_uri={2}&response_type=code&scope=account.r,usage.r,credentials.r", - AuthorizationUri, HubiCClientId, Uri.EscapeUriString(RedirectUri)); - - return new Uri(uriString); - } - - //public static async Task GetAccessToken(string refreshToken) - //{ - // if (string.IsNullOrEmpty(refreshToken)) - // { - // throw new ArgumentNullException("refreshToken"); - // } - - // var httpClient = new HttpClient(); - // httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( - // "Basic", - // Convert.ToBase64String( - // Encoding.ASCII.GetBytes( - // string.Format("{0}:{1}", HubiCClientId, HubiCClientSecret)))); - - // var uri = string.Format("{0}?refresh_token={1}&grant_type=refresh_token", TokenUri, refreshToken); - - // try - // { - // var response = await httpClient.PostAsync(uri, null); - - // var bytes = await response.Content.ReadAsByteArrayAsync(); - // var raw = Encoding.UTF8.GetString(bytes); - // var token = JsonConvert.DeserializeObject(raw); - // return token; - // } - // finally - // { - // httpClient.Dispose(); - // } - //} - - public static async Task GetAccountAsync(string accessToken) - { - if (string.IsNullOrEmpty(accessToken)) - { - throw new ArgumentNullException("accessToken"); - } - - var httpClient = GetHttpClient(accessToken); - try - { - var response = await httpClient.GetAsync(AccountUri); - - var bytes = await response.Content.ReadAsByteArrayAsync(); - var raw = Encoding.UTF8.GetString(bytes); - var account = JsonConvert.DeserializeObject(raw); - return account; - } - finally - { - httpClient.Dispose(); - } - } - - public static async Task GetCredentialsAsync(string accessToken) - { - if (string.IsNullOrEmpty(accessToken)) - { - throw new ArgumentNullException("accessToken"); - } - - var httpClient = GetHttpClient(accessToken); - try - { - var response = await httpClient.GetAsync(AccountCredentialsUri); - - var bytes = await response.Content.ReadAsByteArrayAsync(); - var raw = Encoding.UTF8.GetString(bytes); - var credentials = JsonConvert.DeserializeObject(raw); - return credentials; - } - finally - { - httpClient.Dispose(); - } - } - - private static HttpClient GetHttpClient(string accessToken) - { - var httpClient = ProxyTools.CreateHttpClient(); - httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); - httpClient.DefaultRequestHeaders.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json")); - httpClient.DefaultRequestHeaders.AcceptCharset.Add(new StringWithQualityHeaderValue("utf-8")); - return httpClient; - } - - public static async Task ProcessCodeFlowAsync(string code) - { - if (string.IsNullOrEmpty(code)) - { - throw new ArgumentNullException("code"); - } - - var httpClient = ProxyTools.CreateHttpClient(); - try - { - var parameters = new Dictionary - { - {"code", code}, - {"grant_type", "authorization_code"}, - {"client_id", HubiCClientId}, - {"client_secret", HubiCClientSecret} - }; - - if (!string.IsNullOrEmpty(RedirectUri)) - { - parameters["redirect_uri"] = RedirectUri; - } - - var content = new FormUrlEncodedContent(parameters); - var response = await httpClient.PostAsync(TokenUri, content); - - var raw = await response.Content.ReadAsStringAsync(); - var json = JObject.Parse(raw); - - return new OAuth2Token( - json["access_token"].ToString(), - json["token_type"].ToString(), - json["expires_in"].Value(), - json["refresh_token"].ToString()); - } - finally - { - httpClient.Dispose(); - } - } - - public static async Task GetAccessTokenAsync(string refreshToken) - { - if (string.IsNullOrEmpty(refreshToken)) - { - throw new ArgumentNullException("refreshToken"); - } - - var httpClient = ProxyTools.CreateHttpClient(); - try - { - var parameters = new Dictionary - { - {"refresh_token", refreshToken}, - {"grant_type", "refresh_token"}, - {"client_id", HubiCClientId}, - {"client_secret", HubiCClientSecret} - }; - - var content = new FormUrlEncodedContent(parameters); - var response = await httpClient.PostAsync(TokenUri, content); - - var raw = await response.Content.ReadAsStringAsync(); - var json = JObject.Parse(raw); - - return new OAuth2Token( - json["access_token"].ToString(), - json["token_type"].ToString(), - json["expires_in"].Value()); - } - finally - { - httpClient.Dispose(); - } - } - - public static OAuth2Token GetAccessTokenFromFragment(Uri redirectedUri) - { - if (redirectedUri == null) - { - throw new ArgumentNullException("redirectedUri"); - } - - var fragment = redirectedUri.Fragment; - if (string.IsNullOrWhiteSpace(fragment)) - { - throw new ArgumentException("The supplied uri doesn't contain a fragment", "redirectedUri"); - } - - fragment = fragment.TrimStart('#'); - - string accessToken = null; - string expiresIn = null; - string scope = null; - string uid = null; - string state = null; - string tokenType = null; - - foreach (var pair in fragment.Split('&')) - { - var elements = pair.Split('='); - if (elements.Length != 2) - { - continue; - } - - switch (elements[0]) - { - case "access_token": - accessToken = Uri.UnescapeDataString(elements[1]); - break; - case "expires_in": - expiresIn = Uri.UnescapeDataString(elements[1]); - break; - case "scope": - scope = Uri.UnescapeDataString(elements[1]); - break; - case "state": - state = Uri.UnescapeDataString(elements[1]); - break; - case "token_type": - tokenType = Uri.UnescapeDataString(elements[1]); - break; - default: - throw new ArgumentException("Unexpected values in fragment", "redirectedUri"); - } - } - - return new OAuth2Token(accessToken, tokenType, expiresIn != null ? int.Parse(expiresIn) : (int?) null); - } - } -} \ No newline at end of file diff --git a/KeeAnywhere/StorageProviders/HubiC/HubiCStorageConfigurator.cs b/KeeAnywhere/StorageProviders/HubiC/HubiCStorageConfigurator.cs deleted file mode 100644 index 3a42204..0000000 --- a/KeeAnywhere/StorageProviders/HubiC/HubiCStorageConfigurator.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using System.Threading.Tasks; -using KeeAnywhere.Configuration; -using KeeAnywhere.OAuth2; - -namespace KeeAnywhere.StorageProviders.HubiC -{ - public class HubiCStorageConfigurator : IStorageConfigurator , IOAuth2Provider - { - private OAuth2Token _token; - - public async Task CreateAccount() - { - var isOk = OAuth2Flow.TryAuthenticate(this); - - if (!isOk) return null; - - var hubicAccount = await HubiCHelper.GetAccountAsync(_token.AccessToken); - - var account = new AccountConfiguration() - { - Type = StorageType.HubiC, - Id = hubicAccount.EMail, - Name = string.Format("{0} {1}", hubicAccount.FirstName, hubicAccount.LastName), - Secret = _token.RefreshToken, - }; - - return account; - } - - public async Task Initialize() - { - this.AuthorizationUrl = HubiCHelper.GetAuthorizationUri(); - this.RedirectionUrl = new Uri(HubiCHelper.RedirectUri); - } - - public bool CanClaim(Uri uri, string documentTitle) - { - return uri.ToString().StartsWith(this.RedirectionUrl.ToString(), StringComparison.OrdinalIgnoreCase); - } - - public async Task Claim(Uri uri, string documentTitle) - { - //_token = HubiCHelper.GetAccessTokenFromFragment(uri); - - string code = null; - - foreach (var pair in uri.Query.TrimStart('?').Split('&')) - { - var elements = pair.Split('='); - if (elements.Length != 2) - { - continue; - } - - switch (elements[0]) - { - case "code": - code = Uri.UnescapeDataString(elements[1]); - break; - } - } - - if (code == null) return false; - - _token = await HubiCHelper.ProcessCodeFlowAsync(code); - - return _token != null; - } - - public Uri PreAuthorizationUrl { get { return null; } } - public Uri AuthorizationUrl { get; protected set; } - public Uri RedirectionUrl { get; protected set; } - public string FriendlyProviderName { get { return "hubiC"; } } - } -} \ No newline at end of file diff --git a/KeeAnywhere/StorageProviders/HubiC/HubiCStorageProvider.cs b/KeeAnywhere/StorageProviders/HubiC/HubiCStorageProvider.cs deleted file mode 100644 index 17660fc..0000000 --- a/KeeAnywhere/StorageProviders/HubiC/HubiCStorageProvider.cs +++ /dev/null @@ -1,163 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using KeeAnywhere.Configuration; - -namespace KeeAnywhere.StorageProviders.HubiC -{ - public class HubiCStorageProvider : IStorageProvider - { - private readonly AccountConfiguration _account; - private SwiftClient _client; - private string _defaultContainer; - - public HubiCStorageProvider(AccountConfiguration account) - { - if (account == null) throw new ArgumentNullException("account"); - this._account = account; - } - - public async Task Load(string path) - { - if (path == null) throw new ArgumentNullException("path"); - - var container = await GetDefaultContainer(); - - var client = await GetClient(); - var normalizedPath = path.StartsWith("/") ? path.Remove(0, 1) : path; - - var stream = await client.DownloadObject(container, normalizedPath); - - return stream; - } - - public async Task Save(Stream stream, string path) - { - if (stream == null) throw new ArgumentNullException("stream"); - if (path == null) throw new ArgumentNullException("path"); - - var container = await GetDefaultContainer(); - - var client = await GetClient(); - var normalizedPath = path.StartsWith("/") ? path.Remove(0, 1) : path; - var folderName = CloudPath.GetDirectoryName(normalizedPath); - - var folder = await client.GetObjects(container, folderName); - if (folder == null || !folder.Any()) - throw new InvalidOperationException(string.Format("Folder does not exist: {0}", folderName)); - - var isOk = await client.UploadObject(container, normalizedPath, stream); - - if (!isOk) - throw new InvalidOperationException("Save to HubiC failed."); - } - - public async Task Copy(string sourcePath, string destPath) - { - var container = await GetDefaultContainer(); - - var client = await GetClient(); - var normalizedSourcePath = sourcePath.StartsWith("/") ? sourcePath.Remove(0, 1) : sourcePath; - var normalizedDestPath = destPath.StartsWith("/") ? destPath.Remove(0, 1) : destPath; - - var isOk = await client.CopyObject(container, normalizedSourcePath, container, normalizedDestPath); - - if (!isOk) - throw new InvalidOperationException("HubiC: Copy failed."); - } - - public async Task Delete(string path) - { - var container = await GetDefaultContainer(); - - var client = await GetClient(); - var normalizedPath = path.StartsWith("/") ? path.Remove(0, 1) : path; - - var isOk = await client.DeleteObject(container, normalizedPath); - - if (!isOk) - throw new InvalidOperationException("HubiC: Delete failed."); - } - - public async Task GetRootItem() - { - var container = await GetDefaultContainer(); - - return new StorageProviderItem { - Id = "/", - Name = "/", - Type = StorageProviderItemType.Folder - }; - } - - public async Task> GetChildrenByParentItem(StorageProviderItem parent) - { - var client = await GetClient(); - var container = await GetDefaultContainer(); - var objects = await client.GetObjects(container, parent.Id); - - var ret = objects.Select(_ => new StorageProviderItem - { - Type = - _.ContentType == "application/directory" - ? StorageProviderItemType.Folder - : StorageProviderItemType.File, - Name = NormalizeName(_.Name), - Id = _.Name, - ParentReferenceId = parent.Id, - LastModifiedDateTime = _.LastModified - }); - - return ret.ToArray(); - } - - public async Task> GetChildrenByParentPath(string path) - { - return await GetChildrenByParentItem(new StorageProviderItem {Id = path}); - } - - public bool IsFilenameValid(string filename) - { - if (string.IsNullOrEmpty(filename)) return false; - - char[] invalidChars = { '/', '\\' }; - return filename.All(c => c >= 32 && !invalidChars.Contains(c)); - } - - protected string NormalizeName(string path) - { - var ret = path.EndsWith("/") ? path.Remove(path.Length - 1, 1) : path; - - var posOfLastSlash = ret.LastIndexOf("/", StringComparison.InvariantCultureIgnoreCase); - - return posOfLastSlash >= 0 ? ret.Substring(posOfLastSlash + 1) : ret; - } - - protected async Task GetClient() - { - if (_client != null) return _client; - - var token = await HubiCHelper.GetAccessTokenAsync(_account.Secret); - var credentials = await HubiCHelper.GetCredentialsAsync(token.AccessToken); - _client = new SwiftClient(credentials); - - return _client; - } - - protected async Task GetDefaultContainer() - { - if (_defaultContainer != null) return _defaultContainer; - - var client = await GetClient(); - var containers = await client.GetContainers(); - var container = - containers.Single(_ => _.Name.Equals("default", StringComparison.InvariantCultureIgnoreCase)); - - _defaultContainer = container.Name; - - return _defaultContainer; - } - } -} \ No newline at end of file diff --git a/KeeAnywhere/StorageProviders/HubiC/SwiftClient.cs b/KeeAnywhere/StorageProviders/HubiC/SwiftClient.cs deleted file mode 100644 index 35f4968..0000000 --- a/KeeAnywhere/StorageProviders/HubiC/SwiftClient.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace KeeAnywhere.StorageProviders.HubiC -{ - public class SwiftClient - { - private readonly HubiCCredentials _credentials; - - public SwiftClient(HubiCCredentials credentials) - { - if (credentials == null) throw new ArgumentNullException("credentials"); - _credentials = credentials; - } - - private HttpClient GetClient() - { - var client = ProxyTools.CreateHttpClient(); - - client.DefaultRequestHeaders.Add("X-Auth-Token", _credentials.Token); - client.DefaultRequestHeaders.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json")); - client.DefaultRequestHeaders.AcceptCharset.Add(new StringWithQualityHeaderValue("utf-8")); - - return client; - } - - public async Task> GetContainers() - { - var client = GetClient(); - var response = await client.GetAsync(_credentials.Endpoint); - - var bytes = await response.Content.ReadAsByteArrayAsync(); - var raw = Encoding.UTF8.GetString(bytes); - var containers = JsonConvert.DeserializeObject>(raw); - - return containers; - } - - public async Task> GetObjects(string container, string path) - { - if (container == null) throw new ArgumentNullException("container"); - - var uri = _credentials.Endpoint + "/" + container + "?delimiter=/"; - if (!string.IsNullOrEmpty(path) && path != "/") - { - if (!path.EndsWith("/")) - path += "/"; - - uri += "&prefix=" + path; - } - - var client = GetClient(); - var response = await client.GetAsync(uri); - var bytes = await response.Content.ReadAsByteArrayAsync(); - var raw = Encoding.UTF8.GetString(bytes); - var objects = JsonConvert.DeserializeObject>(raw); - - return objects.Where(_ => string.IsNullOrEmpty(_.VirtualSubDirectory)).ToArray(); - } - - public async Task DownloadObject(string container, string path) - { - if (container == null) throw new ArgumentNullException("container"); - if (path == null) throw new ArgumentNullException("path"); - - var uri = _credentials.Endpoint + "/" + container + "/" + path; - var client = GetClient(); - var stream = await client.GetStreamAsync(uri); - - return stream; - } - - public async Task UploadObject(string container, string path, Stream stream) - { - if (container == null) throw new ArgumentNullException("container"); - if (path == null) throw new ArgumentNullException("path"); - if (stream == null) throw new ArgumentNullException("stream"); - - var uri = _credentials.Endpoint + "/" + container + "/" + path; - var client = GetClient(); - - var content = new StreamContent(stream); - var response = await client.PutAsync(uri, content); - - return response.IsSuccessStatusCode; - } - - public async Task DeleteObject(string container, string path) - { - if (container == null) throw new ArgumentNullException("container"); - if (path == null) throw new ArgumentNullException("path"); - - var uri = _credentials.Endpoint + "/" + container + "/" + path; - var client = GetClient(); - var response = await client.DeleteAsync(uri); - - return response.IsSuccessStatusCode; - } - - public async Task CopyObject(string sourceContainer, string sourcePath, string destContainer, string destPath) - { - if (sourceContainer == null) throw new ArgumentNullException("sourceContainer"); - if (sourcePath == null) throw new ArgumentNullException("sourcePath"); - if (destContainer == null) throw new ArgumentNullException("destContainer"); - if (destPath == null) throw new ArgumentNullException("destPath"); - - var uri = _credentials.Endpoint + "/" + destContainer + "/" + destPath; - var source = "/" + sourceContainer + "/" + sourcePath; - var client = GetClient(); - - var request = new HttpRequestMessage(HttpMethod.Put, uri); - request.Headers.Add("X-Copy-From", source); - - var response = await client.SendAsync(request); - - return response.IsSuccessStatusCode; - } - - } -} diff --git a/KeeAnywhere/StorageProviders/HubiC/SwiftContainer.cs b/KeeAnywhere/StorageProviders/HubiC/SwiftContainer.cs deleted file mode 100644 index 64523d8..0000000 --- a/KeeAnywhere/StorageProviders/HubiC/SwiftContainer.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Runtime.Serialization; - -namespace KeeAnywhere.StorageProviders.HubiC -{ - [DataContract] - public class SwiftContainer - { - [DataMember(Name = "name")] - public string Name { get; set; } - - [DataMember(Name = "count")] - public int Count { get; set; } - - [DataMember(Name = "bytes")] - public ulong Bytes { get; set; } - } -} \ No newline at end of file diff --git a/KeeAnywhere/StorageProviders/HubiC/SwiftObject.cs b/KeeAnywhere/StorageProviders/HubiC/SwiftObject.cs deleted file mode 100644 index aa17b97..0000000 --- a/KeeAnywhere/StorageProviders/HubiC/SwiftObject.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Runtime.Serialization; - -namespace KeeAnywhere.StorageProviders.HubiC -{ - [DataContract] - public class SwiftObject - { - [DataMember(Name = "name")] - public string Name { get; set; } - - [DataMember(Name = "content_type")] - public string ContentType { get; set; } - - [DataMember(Name = "bytes")] - public ulong Bytes { get; set; } - - [DataMember(Name = "last_modified")] - public DateTime LastModified { get; set; } - - [DataMember(Name = "hash")] - public string Hash { get; set; } - - [DataMember(Name = "subdir")] - public string VirtualSubDirectory { get; set; } - } -} \ No newline at end of file diff --git a/KeeAnywhere/StorageProviders/StorageRegistry.cs b/KeeAnywhere/StorageProviders/StorageRegistry.cs index 2f5d708..b44cb8b 100644 --- a/KeeAnywhere/StorageProviders/StorageRegistry.cs +++ b/KeeAnywhere/StorageProviders/StorageRegistry.cs @@ -7,7 +7,6 @@ using KeeAnywhere.StorageProviders.GoogleCloudPlatform; using KeeAnywhere.StorageProviders.GoogleDrive; using KeeAnywhere.StorageProviders.HiDrive; -using KeeAnywhere.StorageProviders.HubiC; using KeeAnywhere.StorageProviders.OneDrive; using KeePassLib.Native; @@ -30,7 +29,6 @@ static StorageRegistry() d.Add(new StorageDescriptor(StorageType.GoogleCloudStorage, "Google Cloud Storage", "gs", account => new GoogleCloudStorageProvider(account), () => new GoogleCloudStorageConfigurator(), PluginResources.GoogleCloudStorage_16x16)); d.Add(new StorageDescriptor(StorageType.GoogleDrive, "Google Drive", "gdrive", account => new GoogleDriveStorageProvider(account), () => new GoogleDriveStorageConfigurator(), PluginResources.GoogleDrive_16x16)); d.Add(new StorageDescriptor(StorageType.HiDrive, "HiDrive", "hidrive", account => new HiDriveStorageProvider(account), () => new HiDriveStorageConfigurator(), PluginResources.HiDrive_16x16)); - if (!isUnix) d.Add(new StorageDescriptor(StorageType.HubiC, "hubiC", "hubic", account => new HubiCStorageProvider(account), () => new HubiCStorageConfigurator(), PluginResources.HubiC_16x16)); d.Add(new StorageDescriptor(StorageType.OneDrive, "OneDrive", "onedrive", account => new OneDriveStorageProvider(account), () => new OneDriveStorageConfigurator(), PluginResources.OneDrive_16x16)); Descriptors = d.ToArray();