From 3c8acd8f84772a0bfdde75c3d59d635193e03ae3 Mon Sep 17 00:00:00 2001 From: Rosario Pulella Date: Tue, 16 Feb 2021 11:06:58 -0500 Subject: [PATCH] Remove services and related --- .../Core/AuthenticationResult.cs | 27 - .../Core/AuthenticationResultStatus.cs | 27 - .../Core/DataProviderBase.cs | 91 --- .../Core/DataProviderBase{TConfig,TSchema}.cs | 37 - .../Core/ExtensionMethods.cs | 35 - .../Core/IAuthenticationBroker.cs | 26 - .../Core/IDataService{T,U,V}.cs | 32 - .../Core/IPasswordManager.cs | 32 - .../Core/ISignatureManager.cs | 21 - .../Core/IStorageManager.cs | 29 - .../Core/PasswordCredential.cs | 22 - .../Exceptions/ConfigNullException.cs | 43 -- .../ConfigParameterNullException.cs | 43 -- .../OAuthKeysNotPresentException.cs | 43 -- .../Exceptions/OAuthKeysRevokedException.cs | 43 -- .../Exceptions/ParserNullException.cs | 43 -- .../Exceptions/RequestFailedException.cs | 55 -- .../Exceptions/TooManyRequestsException.cs | 43 -- .../Exceptions/UserNotFoundException.cs | 43 -- .../Microsoft.Toolkit.Services.csproj | 53 -- .../OAuth/OAuthEncoder.cs | 78 -- .../OAuth/OAuthParameter.cs | 65 -- .../OAuth/OAuthUriExtensions.cs | 62 -- .../NetFrameworkAuthenticationBroker.cs | 81 -- .../NetFrameworkPasswordManager.cs | 70 -- .../NetFrameworkSignatureManager.cs | 40 - .../NetFrameworkStorageManager.cs | 57 -- .../PasswordManagerNativeMethods.cs | 161 ---- .../NETFramework/PopupForm.Designer.cs | 67 -- .../NETFramework/PopupForm.cs | 77 -- .../NETFramework/PopupWPF.xaml | 13 - .../NETFramework/PopupWPF.xaml.cs | 83 --- .../Uwp/UwpAuthenticationBroker.cs | 44 -- .../Uwp/UwpPasswordManager.cs | 67 -- .../Uwp/UwpSignatureManager.cs | 37 - .../PlatformSpecific/Uwp/UwpStorageManager.cs | 40 - .../Microsoft.Toolkit.Services.rd.xml | 6 - .../Services/LinkedIn/LinkedInConstants.cs | 22 - .../Services/LinkedIn/LinkedInContent.cs | 32 - .../Services/LinkedIn/LinkedInDataConfig.cs | 17 - .../Services/LinkedIn/LinkedInDataProvider.cs | 334 --------- .../Services/LinkedIn/LinkedInOAuthTokens.cs | 37 - .../Services/LinkedIn/LinkedInParser.cs | 48 -- .../Services/LinkedIn/LinkedInPermissions.cs | 54 -- .../Services/LinkedIn/LinkedInProfile.cs | 67 -- .../LinkedIn/LinkedInProfileRequest.cs | 17 - .../Services/LinkedIn/LinkedInService.cs | 276 ------- .../Services/LinkedIn/LinkedInShareRequest.cs | 27 - .../LinkedIn/LinkedInShareResponse.cs | 22 - .../LinkedIn/LinkedInShareVisibility.cs | 25 - .../Services/LinkedIn/LinkedInVisibility.cs | 58 -- .../MicrosoftTranslator/AzureAuthToken.cs | 114 --- .../MicrosoftTranslator/DetectedLanguage.cs | 41 - .../DetectedLanguageBase.cs | 48 -- .../DetectedLanguageResponse.cs | 36 - .../MicrosoftTranslator/ErrorResponse.cs | 28 - .../MicrosoftTranslator/ITranslatorService.cs | 372 --------- .../MicrosoftTranslator/ServiceLanguage.cs | 58 -- .../MicrosoftTranslator/Translation.cs | 34 - .../TranslationResponse.cs | 46 -- .../MicrosoftTranslator/TranslatorService.cs | 261 ------- .../TranslatorServiceException.cs | 24 - .../Services/Twitter/ITwitterResult.cs | 13 - .../Services/Twitter/Tweet.cs | 213 ------ .../Services/Twitter/TweetParser.cs | 30 - .../Services/Twitter/TwitterCoordinates.cs | 28 - .../Twitter/TwitterCoordinatesConverter.cs | 115 --- .../Services/Twitter/TwitterDataConfig.cs | 22 - .../Services/Twitter/TwitterDataProvider.cs | 705 ------------------ .../Services/Twitter/TwitterDirectMessage.cs | 103 --- .../Services/Twitter/TwitterEntities.cs | 57 -- .../Services/Twitter/TwitterError.cs | 26 - .../Services/Twitter/TwitterErrors.cs | 20 - .../Services/Twitter/TwitterException.cs | 19 - .../Services/Twitter/TwitterExtended.cs | 20 - .../Twitter/TwitterExtendedEntities.cs | 20 - .../Services/Twitter/TwitterGeoData.cs | 87 --- .../Services/Twitter/TwitterHashtag.cs | 26 - .../Services/Twitter/TwitterMedia.cs | 86 --- .../Twitter/TwitterMediaAdditionalInfo.cs | 38 - .../Services/Twitter/TwitterMediaSizeData.cs | 32 - .../Services/Twitter/TwitterMediaSizes.cs | 38 - .../Services/Twitter/TwitterMediaVideoInfo.cs | 32 - .../Twitter/TwitterMediaVideoVariants.cs | 32 - .../Services/Twitter/TwitterOAuthRequest.cs | 168 ----- .../Twitter/TwitterOAuthRequestBuilder.cs | 251 ------- .../Twitter/TwitterOAuthRequestExtensions.cs | 33 - .../Services/Twitter/TwitterOAuthTokenType.cs | 37 - .../Services/Twitter/TwitterOAuthTokens.cs | 47 -- .../Services/Twitter/TwitterParser.cs | 41 - .../Services/Twitter/TwitterPlace.cs | 62 -- .../Twitter/TwitterPlaceBoundingBox.cs | 45 -- .../Services/Twitter/TwitterPoll.cs | 53 -- .../Services/Twitter/TwitterPollOptions.cs | 26 - .../Services/Twitter/TwitterQueryType.cs | 32 - .../Services/Twitter/TwitterSearchParser.cs | 33 - .../Services/Twitter/TwitterSearchResult.cs | 17 - .../Services/Twitter/TwitterService.cs | 440 ----------- .../Services/Twitter/TwitterStatus.cs | 112 --- .../Twitter/TwitterStreamCallbacks.cs | 24 - .../Twitter/TwitterStreamDeletedEvent.cs | 28 - .../Services/Twitter/TwitterStreamEvent.cs | 66 -- .../Twitter/TwitterStreamEventType.cs | 115 --- .../Services/Twitter/TwitterSymbol.cs | 26 - .../Services/Twitter/TwitterUrl.cs | 44 -- .../Services/Twitter/TwitterUrlUnwound.cs | 38 - .../Services/Twitter/TwitterUser.cs | 207 ----- .../Services/Twitter/TwitterUserMention.cs | 20 - .../Twitter/TwitterUserStreamParser.cs | 72 -- .../Services/Weibo/WeiboDataConfig.cs | 22 - .../Services/Weibo/WeiboDataProvider.cs | 452 ----------- .../Services/Weibo/WeiboError.cs | 26 - .../Services/Weibo/WeiboException.cs | 19 - .../Services/Weibo/WeiboGeoInfo.cs | 37 - .../Services/Weibo/WeiboImage.cs | 32 - .../Services/Weibo/WeiboOAuthRequest.cs | 182 ----- .../Weibo/WeiboOAuthRequestExtensions.cs | 33 - .../Services/Weibo/WeiboOAuthTokens.cs | 32 - .../Services/Weibo/WeiboParser.cs | 41 - .../Services/Weibo/WeiboQueryType.cs | 28 - .../Services/Weibo/WeiboService.cs | 285 ------- .../Services/Weibo/WeiboStatus.cs | 143 ---- .../Services/Weibo/WeiboStatusParser.cs | 41 - .../Services/Weibo/WeiboUser.cs | 92 --- .../Microsoft.Toolkit.Uwp.SampleApp.csproj | 43 -- .../LinkedIn Service/LinkedInCode.bind | 16 - .../LinkedIn Service/LinkedInLogo.png | Bin 1661 -> 0 bytes .../LinkedIn Service/LinkedInPage.xaml | 142 ---- .../LinkedIn Service/LinkedInPage.xaml.cs | 99 --- .../MicrosoftTranslatorCode.bind | 16 - .../MicrosoftTranslatorPage.xaml | 48 -- .../MicrosoftTranslatorPage.xaml.cs | 91 --- .../TranslatorService.png | Bin 2191 -> 0 bytes .../OneDrive Service/OneDriveLogo.png | Bin 2266 -> 0 bytes .../Twitter Service/TwitterCode.bind | 60 -- .../Twitter Service/TwitterLogo.png | Bin 2050 -> 0 bytes .../Twitter Service/TwitterPage.xaml | 441 ----------- .../Twitter Service/TwitterPage.xaml.cs | 313 -------- .../TwitterTemplateSelector.cs | 49 -- .../SamplePages/Twitter Service/icon.png | Bin 2895 -> 0 bytes .../SamplePages/Weibo Service/WeiboCode.bind | 21 - .../SamplePages/Weibo Service/WeiboLogo.png | Bin 4239 -> 0 bytes .../SamplePages/Weibo Service/WeiboPage.xaml | 242 ------ .../Weibo Service/WeiboPage.xaml.cs | 175 ----- .../SamplePages/samples.json | 45 -- .../Microsoft.Toolkit.Services/MainPage.xaml | 21 - .../MainPage.xaml.cs | 29 - SmokeTests/SmokeTests.proj | 1 - UITests/UITests.App/UITests.App.csproj | 4 - UnitTests/UnitTests.UWP/UnitTests.UWP.csproj | 6 +- Windows Community Toolkit.sln | 24 +- 151 files changed, 2 insertions(+), 11082 deletions(-) delete mode 100644 Microsoft.Toolkit.Services/Core/AuthenticationResult.cs delete mode 100644 Microsoft.Toolkit.Services/Core/AuthenticationResultStatus.cs delete mode 100644 Microsoft.Toolkit.Services/Core/DataProviderBase.cs delete mode 100644 Microsoft.Toolkit.Services/Core/DataProviderBase{TConfig,TSchema}.cs delete mode 100644 Microsoft.Toolkit.Services/Core/ExtensionMethods.cs delete mode 100644 Microsoft.Toolkit.Services/Core/IAuthenticationBroker.cs delete mode 100644 Microsoft.Toolkit.Services/Core/IDataService{T,U,V}.cs delete mode 100644 Microsoft.Toolkit.Services/Core/IPasswordManager.cs delete mode 100644 Microsoft.Toolkit.Services/Core/ISignatureManager.cs delete mode 100644 Microsoft.Toolkit.Services/Core/IStorageManager.cs delete mode 100644 Microsoft.Toolkit.Services/Core/PasswordCredential.cs delete mode 100644 Microsoft.Toolkit.Services/Exceptions/ConfigNullException.cs delete mode 100644 Microsoft.Toolkit.Services/Exceptions/ConfigParameterNullException.cs delete mode 100644 Microsoft.Toolkit.Services/Exceptions/OAuthKeysNotPresentException.cs delete mode 100644 Microsoft.Toolkit.Services/Exceptions/OAuthKeysRevokedException.cs delete mode 100644 Microsoft.Toolkit.Services/Exceptions/ParserNullException.cs delete mode 100644 Microsoft.Toolkit.Services/Exceptions/RequestFailedException.cs delete mode 100644 Microsoft.Toolkit.Services/Exceptions/TooManyRequestsException.cs delete mode 100644 Microsoft.Toolkit.Services/Exceptions/UserNotFoundException.cs delete mode 100644 Microsoft.Toolkit.Services/Microsoft.Toolkit.Services.csproj delete mode 100644 Microsoft.Toolkit.Services/OAuth/OAuthEncoder.cs delete mode 100644 Microsoft.Toolkit.Services/OAuth/OAuthParameter.cs delete mode 100644 Microsoft.Toolkit.Services/OAuth/OAuthUriExtensions.cs delete mode 100644 Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/NetFrameworkAuthenticationBroker.cs delete mode 100644 Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/NetFrameworkPasswordManager.cs delete mode 100644 Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/NetFrameworkSignatureManager.cs delete mode 100644 Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/NetFrameworkStorageManager.cs delete mode 100644 Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PasswordManagerNativeMethods.cs delete mode 100644 Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PopupForm.Designer.cs delete mode 100644 Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PopupForm.cs delete mode 100644 Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PopupWPF.xaml delete mode 100644 Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PopupWPF.xaml.cs delete mode 100644 Microsoft.Toolkit.Services/PlatformSpecific/Uwp/UwpAuthenticationBroker.cs delete mode 100644 Microsoft.Toolkit.Services/PlatformSpecific/Uwp/UwpPasswordManager.cs delete mode 100644 Microsoft.Toolkit.Services/PlatformSpecific/Uwp/UwpSignatureManager.cs delete mode 100644 Microsoft.Toolkit.Services/PlatformSpecific/Uwp/UwpStorageManager.cs delete mode 100644 Microsoft.Toolkit.Services/Properties/Microsoft.Toolkit.Services.rd.xml delete mode 100644 Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInConstants.cs delete mode 100644 Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInContent.cs delete mode 100644 Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInDataConfig.cs delete mode 100644 Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInDataProvider.cs delete mode 100644 Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInOAuthTokens.cs delete mode 100644 Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInParser.cs delete mode 100644 Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInPermissions.cs delete mode 100644 Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInProfile.cs delete mode 100644 Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInProfileRequest.cs delete mode 100644 Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInService.cs delete mode 100644 Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInShareRequest.cs delete mode 100644 Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInShareResponse.cs delete mode 100644 Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInShareVisibility.cs delete mode 100644 Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInVisibility.cs delete mode 100644 Microsoft.Toolkit.Services/Services/MicrosoftTranslator/AzureAuthToken.cs delete mode 100644 Microsoft.Toolkit.Services/Services/MicrosoftTranslator/DetectedLanguage.cs delete mode 100644 Microsoft.Toolkit.Services/Services/MicrosoftTranslator/DetectedLanguageBase.cs delete mode 100644 Microsoft.Toolkit.Services/Services/MicrosoftTranslator/DetectedLanguageResponse.cs delete mode 100644 Microsoft.Toolkit.Services/Services/MicrosoftTranslator/ErrorResponse.cs delete mode 100644 Microsoft.Toolkit.Services/Services/MicrosoftTranslator/ITranslatorService.cs delete mode 100644 Microsoft.Toolkit.Services/Services/MicrosoftTranslator/ServiceLanguage.cs delete mode 100644 Microsoft.Toolkit.Services/Services/MicrosoftTranslator/Translation.cs delete mode 100644 Microsoft.Toolkit.Services/Services/MicrosoftTranslator/TranslationResponse.cs delete mode 100644 Microsoft.Toolkit.Services/Services/MicrosoftTranslator/TranslatorService.cs delete mode 100644 Microsoft.Toolkit.Services/Services/MicrosoftTranslator/TranslatorServiceException.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/ITwitterResult.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/Tweet.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TweetParser.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterCoordinates.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterCoordinatesConverter.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterDataConfig.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterDataProvider.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterDirectMessage.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterEntities.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterError.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterErrors.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterException.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterExtended.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterExtendedEntities.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterGeoData.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterHashtag.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterMedia.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaAdditionalInfo.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaSizeData.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaSizes.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaVideoInfo.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaVideoVariants.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthRequest.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthRequestBuilder.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthRequestExtensions.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthTokenType.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthTokens.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterParser.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterPlace.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterPlaceBoundingBox.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterPoll.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterPollOptions.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterQueryType.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterSearchParser.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterSearchResult.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterService.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterStatus.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterStreamCallbacks.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterStreamDeletedEvent.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterStreamEvent.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterStreamEventType.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterSymbol.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterUrl.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterUrlUnwound.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterUser.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterUserMention.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Twitter/TwitterUserStreamParser.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Weibo/WeiboDataConfig.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Weibo/WeiboDataProvider.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Weibo/WeiboError.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Weibo/WeiboException.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Weibo/WeiboGeoInfo.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Weibo/WeiboImage.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Weibo/WeiboOAuthRequest.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Weibo/WeiboOAuthRequestExtensions.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Weibo/WeiboOAuthTokens.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Weibo/WeiboParser.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Weibo/WeiboQueryType.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Weibo/WeiboService.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Weibo/WeiboStatus.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Weibo/WeiboStatusParser.cs delete mode 100644 Microsoft.Toolkit.Services/Services/Weibo/WeiboUser.cs delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/LinkedIn Service/LinkedInCode.bind delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/LinkedIn Service/LinkedInLogo.png delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/LinkedIn Service/LinkedInPage.xaml delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/LinkedIn Service/LinkedInPage.xaml.cs delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Microsoft Translator Service/MicrosoftTranslatorCode.bind delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Microsoft Translator Service/MicrosoftTranslatorPage.xaml delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Microsoft Translator Service/MicrosoftTranslatorPage.xaml.cs delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Microsoft Translator Service/TranslatorService.png delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/OneDrive Service/OneDriveLogo.png delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Twitter Service/TwitterCode.bind delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Twitter Service/TwitterLogo.png delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Twitter Service/TwitterPage.xaml delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Twitter Service/TwitterPage.xaml.cs delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Twitter Service/TwitterTemplateSelector.cs delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Twitter Service/icon.png delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Weibo Service/WeiboCode.bind delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Weibo Service/WeiboLogo.png delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Weibo Service/WeiboPage.xaml delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Weibo Service/WeiboPage.xaml.cs delete mode 100644 SmokeTests/Microsoft.Toolkit.Services/MainPage.xaml delete mode 100644 SmokeTests/Microsoft.Toolkit.Services/MainPage.xaml.cs diff --git a/Microsoft.Toolkit.Services/Core/AuthenticationResult.cs b/Microsoft.Toolkit.Services/Core/AuthenticationResult.cs deleted file mode 100644 index 0378093c0..000000000 --- a/Microsoft.Toolkit.Services/Core/AuthenticationResult.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.Core -{ - /// - /// AuthenticationResult class, parameters: ResponseErrorDetail(uint), ResponseData(string) and ResponseStatus(AuthenticationResultStatus) - /// - public class AuthenticationResult - { - /// - /// Gets or sets the authentication error detail - /// - public uint ResponseErrorDetail { get; set; } - - /// - /// Gets or sets the authentication result data - /// - public string ResponseData { get; set; } - - /// - /// Gets or sets the authentication status, could be UserCancel, ErrorHttp and Success. - /// - public AuthenticationResultStatus ResponseStatus { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Core/AuthenticationResultStatus.cs b/Microsoft.Toolkit.Services/Core/AuthenticationResultStatus.cs deleted file mode 100644 index 439caceff..000000000 --- a/Microsoft.Toolkit.Services/Core/AuthenticationResultStatus.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.Core -{ - /// - /// Contains the status of the authentication operation - /// - public enum AuthenticationResultStatus - { - /// - /// The operation succeeded, and the response data is available. - /// - Success, - - /// - /// The operation was canceled by the user - /// - UserCancel, - - /// - /// The operation failed because a specific HTTP error was returned, for example 404 - /// - ErrorHttp - } -} diff --git a/Microsoft.Toolkit.Services/Core/DataProviderBase.cs b/Microsoft.Toolkit.Services/Core/DataProviderBase.cs deleted file mode 100644 index ff8f320af..000000000 --- a/Microsoft.Toolkit.Services/Core/DataProviderBase.cs +++ /dev/null @@ -1,91 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Threading.Tasks; - -namespace Microsoft.Toolkit.Services -{ - /// - /// Base class for data providers in this library. - /// - /// Query configuration type for given provider. - public abstract class DataProviderBase - { - /// - /// Initializes a new instance of the class. - /// - public DataProviderBase() - { - } - - /// - /// Load data from provider endpoint. - /// - /// Strong typed object to parse the response items into. - /// Query configuration. - /// Upper record limit. - /// The zero-based index of the page that corresponds to the items to retrieve. - /// Parser to use for results. - /// Strong typed list of results. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an async method, so nesting generic types is necessary.")] - public async Task> LoadDataAsync(TConfig config, int maxRecords, int pageIndex, Parsers.IParser parser) - where TSchema : Parsers.SchemaBase - { - if (config == null) - { - throw new ConfigNullException(); - } - - if (parser == null) - { - throw new ParserNullException(); - } - - ValidateConfig(config); - - var result = await GetDataAsync(config, maxRecords, pageIndex, parser); - if (result != null) - { - return result - .Take(maxRecords) - .ToList(); - } - - return Array.Empty(); - } - - private static HttpClient httpClient; - - /// - /// Gets or sets static instance of HttpClient. - /// - public static HttpClient HttpClient - { - get { return httpClient ?? (httpClient = new HttpClient()); } - set { httpClient = value; } - } - - /// - /// Derived classes will have to implement this method to return provider data - /// - /// Configuration to use - /// Maximum number of records to return - /// The zero-based index of the page that corresponds to the items to retrieve. - /// Parser to use - /// Schema defining data returned - /// List of data - protected abstract Task> GetDataAsync(TConfig config, int maxRecords, int pageIndex, Parsers.IParser parser) - where TSchema : Parsers.SchemaBase; - - /// - /// Method provided by derived class to validate specified configuration - /// - /// Configuration to validate - protected abstract void ValidateConfig(TConfig config); - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Core/DataProviderBase{TConfig,TSchema}.cs b/Microsoft.Toolkit.Services/Core/DataProviderBase{TConfig,TSchema}.cs deleted file mode 100644 index 4115623aa..000000000 --- a/Microsoft.Toolkit.Services/Core/DataProviderBase{TConfig,TSchema}.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Microsoft.Toolkit.Services -{ - /// - /// Base class for data providers in this library. - /// - /// Strong typed query configuration object. - /// Strong typed object to parse the response items into. - public abstract class DataProviderBase : DataProviderBase - where TSchema : Parsers.SchemaBase - { - /// - /// Load data from provider endpoint. - /// - /// Query configuration. - /// Upper record limit. - /// The zero-based index of the page that corresponds to the items to retrieve. - /// List of strong typed objects. - public Task> LoadDataAsync(TConfig config, int maxRecords = 20, int pageIndex = 0) - { - return LoadDataAsync(config, maxRecords, pageIndex, GetDefaultParser(config)); - } - - /// - /// Default parser abstract method. - /// - /// Query configuration object. - /// Strong typed default parser. - protected abstract Parsers.IParser GetDefaultParser(TConfig config); - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Core/ExtensionMethods.cs b/Microsoft.Toolkit.Services/Core/ExtensionMethods.cs deleted file mode 100644 index 49124ac62..000000000 --- a/Microsoft.Toolkit.Services/Core/ExtensionMethods.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Reflection; - -namespace Microsoft.Toolkit.Services -{ - /// - /// This class offers general purpose methods. - /// - internal static class ExtensionMethods - { - /// - /// Converts between enumeration value and string value. - /// - /// Enumeration. - /// Returns string value. - private static string GetStringValue(Enum value) - { - string output = null; - Type type = value.GetType(); - - FieldInfo fi = type.GetRuntimeField(value.ToString()); - Parsers.Core.StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof(Parsers.Core.StringValueAttribute), false) as Parsers.Core.StringValueAttribute[]; - if (attrs != null && attrs.Length > 0) - { - output = attrs[0].Value; - } - - return output; - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Core/IAuthenticationBroker.cs b/Microsoft.Toolkit.Services/Core/IAuthenticationBroker.cs deleted file mode 100644 index 1c56147e7..000000000 --- a/Microsoft.Toolkit.Services/Core/IAuthenticationBroker.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.Toolkit.Services.Core -{ - /// - /// This gets an Uri value. - /// - public interface IAuthenticationBroker - { - /// - /// Returns the authentication status, it could be UserCancel, ErrorHttp and Success. - /// - /// Authorization base url - /// LinkedInOAuthTokens callbackUri - /// Returns a status - Task Authenticate(Uri requestUri, Uri callbackUri); - } -} diff --git a/Microsoft.Toolkit.Services/Core/IDataService{T,U,V}.cs b/Microsoft.Toolkit.Services/Core/IDataService{T,U,V}.cs deleted file mode 100644 index c24144b82..000000000 --- a/Microsoft.Toolkit.Services/Core/IDataService{T,U,V}.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Microsoft.Toolkit.Services -{ - /// - /// Generic interface that all deployed service providers implement. - /// - /// Reference to underlying data service provider. - /// Strongly-typed schema for data returned in list query. - /// Configuration type specifying query parameters. - public interface IDataService - { - /// - /// Gets the underlying data service provider. - /// - T Provider { get; } - - /// - /// Makes a request for a list of data from the given service provider. - /// - /// Describes the query on the list data request. - /// Specifies an upper limit to the number of records returned. - /// The zero-based index of the page that corresponds to the items to retrieve. - /// Returns a strongly typed list of results from the service. - Task> RequestAsync(V config, int maxRecords, int pageIndex = 0); - } -} diff --git a/Microsoft.Toolkit.Services/Core/IPasswordManager.cs b/Microsoft.Toolkit.Services/Core/IPasswordManager.cs deleted file mode 100644 index 33aff9706..000000000 --- a/Microsoft.Toolkit.Services/Core/IPasswordManager.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.Core -{ - /// - /// This interface gets a PasswordCredential, store the credential and remove the key. - /// - public interface IPasswordManager - { - /// - /// Gets the user credentials. - /// - /// Receive the storage key user and the access token - /// Returns user credential. - PasswordCredential Get(string key); - - /// - /// Store users credential. - /// - /// Resource - /// Username and password. - void Store(string resource, PasswordCredential credential); - - /// - /// Remove users credential. - /// - /// Credential unique key - void Remove(string key); - } -} diff --git a/Microsoft.Toolkit.Services/Core/ISignatureManager.cs b/Microsoft.Toolkit.Services/Core/ISignatureManager.cs deleted file mode 100644 index d35af9d20..000000000 --- a/Microsoft.Toolkit.Services/Core/ISignatureManager.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.Core -{ - /// - /// Provides platform specific logic to sign request for OAuth communication - /// - public interface ISignatureManager - { - /// - /// Generate request signature - /// - /// String to sign - /// Secret to use to sign - /// If true append & to the base string - /// The signed baseString to use in the OAuth requests - string GetSignature(string baseString, string secret, bool append = false); - } -} diff --git a/Microsoft.Toolkit.Services/Core/IStorageManager.cs b/Microsoft.Toolkit.Services/Core/IStorageManager.cs deleted file mode 100644 index eab9f81ff..000000000 --- a/Microsoft.Toolkit.Services/Core/IStorageManager.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Threading.Tasks; - -namespace Microsoft.Toolkit.Services.Core -{ - /// - /// This interface store the key value - /// - public interface IStorageManager - { - /// - /// Gets the key value - /// - /// Token value - /// Returns a string value - Task GetAsync(string key); - - /// - /// Sets the key value - /// - /// Token key - /// String value - /// A representing the asynchronous operation. - Task SetAsync(string key, string value); - } -} diff --git a/Microsoft.Toolkit.Services/Core/PasswordCredential.cs b/Microsoft.Toolkit.Services/Core/PasswordCredential.cs deleted file mode 100644 index 67bb96641..000000000 --- a/Microsoft.Toolkit.Services/Core/PasswordCredential.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.Core -{ - /// - /// PasswordCredential class composed of UserName and Password, both strings. - /// - public class PasswordCredential - { - /// - /// Gets or sets the username from login form - /// - public string UserName { get; set; } - - /// - /// Gets or sets the password from login form - /// - public string Password { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Exceptions/ConfigNullException.cs b/Microsoft.Toolkit.Services/Exceptions/ConfigNullException.cs deleted file mode 100644 index f32b19b73..000000000 --- a/Microsoft.Toolkit.Services/Exceptions/ConfigNullException.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Microsoft.Toolkit.Services -{ - /// - /// Exception for null Config. - /// - public class ConfigNullException : Exception - { - /// - /// Initializes a new instance of the class. - /// Default constructor. - /// - public ConfigNullException() - { - } - - /// - /// Initializes a new instance of the class. - /// Constructor accepting additional message string. - /// - /// Additional error information. - public ConfigNullException(string message) - : base(message) - { - } - - /// - /// Initializes a new instance of the class. - /// Constructor accepting additional message string and inner exception - /// - /// Additional error information. - /// Reference to inner exception. - public ConfigNullException(string message, Exception innerException) - : base(message, innerException) - { - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Exceptions/ConfigParameterNullException.cs b/Microsoft.Toolkit.Services/Exceptions/ConfigParameterNullException.cs deleted file mode 100644 index 8a4f1cddd..000000000 --- a/Microsoft.Toolkit.Services/Exceptions/ConfigParameterNullException.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Microsoft.Toolkit.Services -{ - /// - /// Exception for config parameter being null. - /// - public class ConfigParameterNullException : Exception - { - /// - /// Initializes a new instance of the class. - /// Default constructor. - /// - public ConfigParameterNullException() - { - } - - /// - /// Initializes a new instance of the class. - /// Accepts parameter name. - /// - /// Name of the parameter. - public ConfigParameterNullException(string parameter) - : base(string.Format("The parameter '{0}' in config is null.", parameter)) - { - } - - /// - /// Initializes a new instance of the class. - /// Accepts parameter name and inner exception. - /// - /// Name of the parameter. - /// Reference to the inner exception. - public ConfigParameterNullException(string message, Exception innerException) - : base(message, innerException) - { - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Exceptions/OAuthKeysNotPresentException.cs b/Microsoft.Toolkit.Services/Exceptions/OAuthKeysNotPresentException.cs deleted file mode 100644 index 06b13dfe3..000000000 --- a/Microsoft.Toolkit.Services/Exceptions/OAuthKeysNotPresentException.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Microsoft.Toolkit.Services -{ - /// - /// Exception for no OAuth keys being present. - /// - public class OAuthKeysNotPresentException : Exception - { - /// - /// Initializes a new instance of the class. - /// Default constructor. - /// - public OAuthKeysNotPresentException() - { - } - - /// - /// Initializes a new instance of the class. - /// Constructor with information on missing key. - /// - /// Name of the missing key. - public OAuthKeysNotPresentException(string key) - : base(string.Format("Open Authentication Key '{0}' not present", key)) - { - } - - /// - /// Initializes a new instance of the class. - /// Constructor with additional message and inner exception. - /// - /// Additional exception message. - /// Reference to inner exception. - public OAuthKeysNotPresentException(string message, Exception innerException) - : base(message, innerException) - { - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Exceptions/OAuthKeysRevokedException.cs b/Microsoft.Toolkit.Services/Exceptions/OAuthKeysRevokedException.cs deleted file mode 100644 index f9126448a..000000000 --- a/Microsoft.Toolkit.Services/Exceptions/OAuthKeysRevokedException.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Microsoft.Toolkit.Services -{ - /// - /// Exception for revoked OAuth keys. - /// - public class OAuthKeysRevokedException : Exception - { - /// - /// Initializes a new instance of the class. - /// Default constructor. - /// - public OAuthKeysRevokedException() - { - } - - /// - /// Initializes a new instance of the class. - /// Constructor with additional message. - /// - /// Additional message - public OAuthKeysRevokedException(string message) - : base(message) - { - } - - /// - /// Initializes a new instance of the class. - /// Constructor with additional message and inner exception. - /// - /// Additional message. - /// Reference to inner exception. - public OAuthKeysRevokedException(string message, Exception innerException) - : base(message, innerException) - { - } - } -} diff --git a/Microsoft.Toolkit.Services/Exceptions/ParserNullException.cs b/Microsoft.Toolkit.Services/Exceptions/ParserNullException.cs deleted file mode 100644 index 24da1f64e..000000000 --- a/Microsoft.Toolkit.Services/Exceptions/ParserNullException.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Microsoft.Toolkit.Services -{ - /// - /// Exception for null Parser. - /// - public class ParserNullException : Exception - { - /// - /// Initializes a new instance of the class. - /// Default constructor. - /// - public ParserNullException() - { - } - - /// - /// Initializes a new instance of the class. - /// Constructor with additional message. - /// - /// Additional message - public ParserNullException(string message) - : base(message) - { - } - - /// - /// Initializes a new instance of the class. - /// Constructor with additional message and inner exception. - /// - /// Additional message. - /// Reference to inner exception. - public ParserNullException(string message, Exception innerException) - : base(message, innerException) - { - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Exceptions/RequestFailedException.cs b/Microsoft.Toolkit.Services/Exceptions/RequestFailedException.cs deleted file mode 100644 index 6bfd16057..000000000 --- a/Microsoft.Toolkit.Services/Exceptions/RequestFailedException.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Net; - -namespace Microsoft.Toolkit.Services -{ - /// - /// Exception for failed requests. - /// - public class RequestFailedException : Exception - { - /// - /// Initializes a new instance of the class. - /// Default constructor. - /// - public RequestFailedException() - { - } - - /// - /// Initializes a new instance of the class. - /// Constructor with additional message. - /// - /// Additional message. - public RequestFailedException(string message) - : base(message) - { - } - - /// - /// Initializes a new instance of the class. - /// Constructor with status code and reason for request failure. - /// - /// Failure status code. - /// Failure reason. - public RequestFailedException(HttpStatusCode statusCode, string reason) - : base(string.Format("Request failed with status code {0} and reason '{1}'", (int)statusCode, reason)) - { - } - - /// - /// Initializes a new instance of the class. - /// Constructor with additional message and inner exception. - /// - /// Additional message. - /// Reference to inner exception. - public RequestFailedException(string message, Exception innerException) - : base(message, innerException) - { - } - } -} diff --git a/Microsoft.Toolkit.Services/Exceptions/TooManyRequestsException.cs b/Microsoft.Toolkit.Services/Exceptions/TooManyRequestsException.cs deleted file mode 100644 index 7b66c23d5..000000000 --- a/Microsoft.Toolkit.Services/Exceptions/TooManyRequestsException.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Microsoft.Toolkit.Services -{ - /// - /// Exception for too many requests. - /// - public class TooManyRequestsException : Exception - { - /// - /// Initializes a new instance of the class. - /// Default constructor. - /// - public TooManyRequestsException() - { - } - - /// - /// Initializes a new instance of the class. - /// Constructor with additional message. - /// - /// Additional message. - public TooManyRequestsException(string message) - : base(message) - { - } - - /// - /// Initializes a new instance of the class. - /// Constructor with additional message and reference to inner exception. - /// - /// Additional message. - /// Reference to inner exception. - public TooManyRequestsException(string message, Exception innerException) - : base(message, innerException) - { - } - } -} diff --git a/Microsoft.Toolkit.Services/Exceptions/UserNotFoundException.cs b/Microsoft.Toolkit.Services/Exceptions/UserNotFoundException.cs deleted file mode 100644 index afa74efc9..000000000 --- a/Microsoft.Toolkit.Services/Exceptions/UserNotFoundException.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Microsoft.Toolkit.Services -{ - /// - /// Exception for user not found. - /// - public class UserNotFoundException : Exception - { - /// - /// Initializes a new instance of the class. - /// Default constructor. - /// - public UserNotFoundException() - { - } - - /// - /// Initializes a new instance of the class. - /// Constructor with screen/user name information. - /// - /// Name of user not found. - public UserNotFoundException(string screenName) - : base("User " + screenName + " not found.") - { - } - - /// - /// Initializes a new instance of the class. - /// Constructor with screen/user name information and inner exception. - /// - /// Name of user not found. - /// Reference to inner exception. - public UserNotFoundException(string screenName, Exception innerException) - : base("User " + screenName + " not found.", innerException) - { - } - } -} diff --git a/Microsoft.Toolkit.Services/Microsoft.Toolkit.Services.csproj b/Microsoft.Toolkit.Services/Microsoft.Toolkit.Services.csproj deleted file mode 100644 index e1f1a13d6..000000000 --- a/Microsoft.Toolkit.Services/Microsoft.Toolkit.Services.csproj +++ /dev/null @@ -1,53 +0,0 @@ - - - - uap10.0.17763;netstandard2.0;NET462 - Windows Community Toolkit .NET Standard Services - - This .NET standard library enables access to different data sources such as Microsoft Graph, OneDrive, Twitter, Microsoft Translator, and LinkedIn. It is part of the Windows Community Toolkit. - - UWP Community Toolkit Windows Microsoft Graph OneDrive Twitter Translator LinkedIn service login OAuth - 8.0 - CS8002;CS0618 - false - - - - $(DefineConstants);WINRT - - - - true - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Microsoft.Toolkit.Services/OAuth/OAuthEncoder.cs b/Microsoft.Toolkit.Services/OAuth/OAuthEncoder.cs deleted file mode 100644 index d89876145..000000000 --- a/Microsoft.Toolkit.Services/OAuth/OAuthEncoder.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; - -#if WINRT -using Windows.Security.Cryptography; -using Windows.Security.Cryptography.Core; -using Windows.Storage.Streams; - -#endif -namespace Microsoft.Toolkit.Services.OAuth -{ - /// - /// OAuth Encoder. - /// - internal static class OAuthEncoder - { - /// - /// Url encode input string. - /// - /// Input string. - /// Encoded string. - public static string UrlEncode(string value) - { - if (string.IsNullOrEmpty(value)) - { - return string.Empty; - } - - var result = Uri.EscapeDataString(value); - - // UrlEncode escapes with lowercase characters (e.g. %2f) but oAuth needs %2F - result = Regex.Replace(result, "(%[0-9a-f][0-9a-f])", c => c.Value.ToUpper()); - - // these characters are not escaped by UrlEncode() but needed to be escaped - result = result - .Replace("(", "%28") - .Replace(")", "%29") - .Replace("$", "%24") - .Replace("!", "%21") - .Replace("*", "%2A") - .Replace("'", "%27"); - - // these characters are escaped by UrlEncode() but will fail if unescaped! - result = result.Replace("%7E", "~"); - - return result; - } - - /// - /// Encode list of parameters. - /// - /// List of parameters. - /// Encoded string of parameters. - public static string UrlEncode(IEnumerable parameters) - { - string rawUrl = string.Join("&", parameters.OrderBy(p => p.Key).Select(p => p.ToString()).ToArray()); - return UrlEncode(rawUrl); - } - -#if WINRT - public static string GenerateHash(string input, string key) - { - MacAlgorithmProvider mac = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha1); - IBuffer keyMaterial = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8); - CryptographicKey cryptoKey = mac.CreateKey(keyMaterial); - IBuffer hash = CryptographicEngine.Sign(cryptoKey, CryptographicBuffer.ConvertStringToBinary(input, BinaryStringEncoding.Utf8)); - return CryptographicBuffer.EncodeToBase64String(hash); - } -#endif - - } -} diff --git a/Microsoft.Toolkit.Services/OAuth/OAuthParameter.cs b/Microsoft.Toolkit.Services/OAuth/OAuthParameter.cs deleted file mode 100644 index be93787e9..000000000 --- a/Microsoft.Toolkit.Services/OAuth/OAuthParameter.cs +++ /dev/null @@ -1,65 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Globalization; - -namespace Microsoft.Toolkit.Services.OAuth -{ - /// - /// OAuth parameter. - /// - internal class OAuthParameter - { - /// - /// Gets or sets key property. - /// - public string Key { get; set; } - - /// - /// Gets or sets value property. - /// - public string Value { get; set; } - - /// - /// Initializes a new instance of the class. - /// Constructor accepting key and value. - /// - /// Key. - /// Value. - public OAuthParameter(string key, string value) - { - Key = key; - Value = value; - } - - /// - /// ToString override. - /// - /// String representation - public override string ToString() - { - return ToString(false); - } - - /// - /// Format key / value into string. - /// - /// Whether to create quotes in string. - /// Formatted string of key / value. - public string ToString(bool withQuotes) - { - string format; - if (withQuotes) - { - format = "{0}=\"{1}\""; - } - else - { - format = "{0}={1}"; - } - - return string.Format(CultureInfo.InvariantCulture, format, OAuthEncoder.UrlEncode(Key), OAuthEncoder.UrlEncode(Value)); - } - } -} diff --git a/Microsoft.Toolkit.Services/OAuth/OAuthUriExtensions.cs b/Microsoft.Toolkit.Services/OAuth/OAuthUriExtensions.cs deleted file mode 100644 index c26927999..000000000 --- a/Microsoft.Toolkit.Services/OAuth/OAuthUriExtensions.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; - -namespace Microsoft.Toolkit.Services.OAuth -{ - /// - /// OAuth Uri extensions. - /// - internal static class OAuthUriExtensions - { - /// - /// Get query parameters from Uri. - /// - /// Uri to process. - /// Dictionary of query parameters. - public static IDictionary GetQueryParams(this Uri uri) - { - var dict = uri.Query.Remove(0, 1).Split('&').ToDictionary(c => c.Split('=')[0], c => Uri.UnescapeDataString(c.Split('=')[1])); - return dict; - } - - /// - /// Get absolute Uri. - /// - /// Uri to process. - /// Uri without query string. - public static string AbsoluteWithoutQuery(this Uri uri) - { - if (string.IsNullOrEmpty(uri.Query)) - { - return uri.AbsoluteUri; - } - - return uri.AbsoluteUri.Replace(uri.Query, string.Empty); - } - - /// - /// Normalize the Uri into string. - /// - /// Uri to process. - /// Normalized string. - public static string Normalize(this Uri uri) - { - var result = new StringBuilder(string.Format(CultureInfo.InvariantCulture, "{0}://{1}", uri.Scheme, uri.Host)); - if (!((uri.Scheme == "http" && uri.Port == 80) || (uri.Scheme == "https" && uri.Port == 443))) - { - result.Append(string.Concat(":", uri.Port)); - } - - result.Append(uri.AbsolutePath); - - return result.ToString(); - } - } -} diff --git a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/NetFrameworkAuthenticationBroker.cs b/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/NetFrameworkAuthenticationBroker.cs deleted file mode 100644 index a182c8490..000000000 --- a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/NetFrameworkAuthenticationBroker.cs +++ /dev/null @@ -1,81 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Threading.Tasks; -using System.Windows; -using Microsoft.Toolkit.Services.Core; -using ApplicationForm = System.Windows.Forms.Application; - -namespace Microsoft.Toolkit.Services.PlatformSpecific.NetFramework -{ - internal class NetFrameworkAuthenticationBroker : IAuthenticationBroker - { - public Task Authenticate(Uri requestUri, Uri callbackUri) - { - int numberForms = ApplicationForm.OpenForms.Count; - if (numberForms > 0) - { - return this.AuthenticateForm(requestUri, callbackUri); - } - else if (Application.Current != null) - { - return this.AuthenticateWindow(requestUri, callbackUri); - } - else - { - // Your code shouldn't reach this exception. - throw new Exception("Cannot identify the current application. Please review your main app"); - } - } - - public async Task AuthenticateWindow(Uri requestUri, Uri callbackUri) - { - PopupWPF popupWindow; - var taskCompletionSource = new TaskCompletionSource(); - popupWindow = new PopupWPF(callbackUri); - popupWindow.Closed += (sender, e) => - { - taskCompletionSource.SetResult(HandleExit(popupWindow.ActualUrl)); - }; - - popupWindow.Show(); - popupWindow.NavigateTo(requestUri.AbsoluteUri); - return await taskCompletionSource.Task; - } - - public async Task AuthenticateForm(Uri requestUri, Uri callbackUri) - { - PopupForm popupForm; - var taskCompletionSource = new TaskCompletionSource(); - popupForm = new PopupForm(callbackUri); - popupForm.FormClosed += (sender, e) => - { - taskCompletionSource.SetResult(HandleExit(popupForm.ActualUrl)); - }; - - popupForm.Show(); - popupForm.NavigateTo(requestUri.AbsoluteUri); - return await taskCompletionSource.Task; - } - - private AuthenticationResult HandleExit(Uri actualUrl) - { - var result = new AuthenticationResult(); - if (actualUrl != null) - { - var query = System.Web.HttpUtility.ParseQueryString(actualUrl.Query); - - result.ResponseData = query.ToString(); - result.ResponseStatus = AuthenticationResultStatus.Success; - } - else - { - result.ResponseStatus = AuthenticationResultStatus.ErrorHttp; - } - - return result; - } - } -} diff --git a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/NetFrameworkPasswordManager.cs b/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/NetFrameworkPasswordManager.cs deleted file mode 100644 index bca8353a8..000000000 --- a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/NetFrameworkPasswordManager.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Runtime.InteropServices; -using System.Text; -using Microsoft.Toolkit.Services.Core; -using static Microsoft.Toolkit.Services.PlatformSpecific.NetFramework.PasswordManagerNativeMethods; - -namespace Microsoft.Toolkit.Services.PlatformSpecific.NetFramework -{ - internal class NetFrameworkPasswordManager : IPasswordManager - { - public void Store(string resource, PasswordCredential credential) - { - // Validations. - byte[] byteArray = Encoding.Unicode.GetBytes(credential.Password); - - // Go ahead with what we have are stuff it into the CredMan structures. - Credential cred = new Credential - { - TargetName = resource, - UserName = credential.UserName, - CredentialBlob = credential.Password, - CredentialBlobSize = (uint)byteArray.Length, - AttributeCount = 0, - Attributes = IntPtr.Zero, - Comment = null, - TargetAlias = null, - Type = CRED_TYPE.GENERIC, - Persist = CRED_PERSIST.LOCAL_MACHINE - }; - NativeCredential userCredential = NativeCredential.GetNativeCredential(cred); - - // Write the info into the CredMan storage. - bool written = CredWrite(ref userCredential, 0); - int lastError = Marshal.GetLastWin32Error(); - if (!written) - { - string message = "CredWrite failed with the error code " + lastError.ToString(); - throw new InvalidOperationException(message); - } - } - - public PasswordCredential Get(string key) - { - int lastError = Marshal.GetHRForLastWin32Error(); - - if (!CredRead(key, CRED_TYPE.GENERIC, 0, out var nCredPtr)) - { - return null; - } - - CriticalCredentialHandle credentialHandle = new CriticalCredentialHandle(nCredPtr); - - Credential credential = credentialHandle.GetCredential(); - return new PasswordCredential - { - UserName = credential.UserName, - Password = credential.CredentialBlob - }; - } - - public void Remove(string key) - { - CredDelete(key, CRED_TYPE.GENERIC, 0); - } - } -} diff --git a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/NetFrameworkSignatureManager.cs b/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/NetFrameworkSignatureManager.cs deleted file mode 100644 index 61dfd1c08..000000000 --- a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/NetFrameworkSignatureManager.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Cryptography; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Toolkit.Services.Core; - -namespace Microsoft.Toolkit.Services.PlatformSpecific.NetFramework -{ - internal class NetFrameworkSignatureManager : ISignatureManager - { - /// - /// Generate request signature. - /// - /// String to sign - /// Secret to use to sign - /// If true append & to the base string - /// Signature. - public string GetSignature(string baseString, string secret, bool append = false) - { - var key = append ? secret + "&" : secret; - - var baseStringByte = Encoding.UTF8.GetBytes(baseString); - var keyByte = Encoding.UTF8.GetBytes(key); - - using (HMACSHA1 hmac = new HMACSHA1(keyByte)) - { - hmac.Initialize(); - var hash = hmac.ComputeHash(baseStringByte); - string base64 = Convert.ToBase64String(hash); - return base64; - } - } - } -} diff --git a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/NetFrameworkStorageManager.cs b/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/NetFrameworkStorageManager.cs deleted file mode 100644 index c5a4b1868..000000000 --- a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/NetFrameworkStorageManager.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.IO.IsolatedStorage; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Toolkit.Services.Core; - -namespace Microsoft.Toolkit.Services.PlatformSpecific.NetFramework -{ - internal class NetFrameworkStorageManager : IStorageManager - { - private const string FileName = "credential_service_data.txt"; - private const char Separator = ':'; - - public async Task GetAsync(string key) - { - var isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null); - - using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream(FileName, FileMode.OpenOrCreate, isoStore)) - { - using (StreamReader reader = new StreamReader(isoStream)) - { - while (!reader.EndOfStream) - { - var line = (await reader.ReadLineAsync()).Split(Separator); - var currentKey = line.First(); - if (currentKey == key) - { - return line.Last(); - } - } - } - } - - return null; - } - - public Task SetAsync(string key, string value) - { - var isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null); - - using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream(FileName, FileMode.Append, isoStore)) - { - using (StreamWriter writer = new StreamWriter(isoStream)) - { - return writer.WriteLineAsync(string.Concat(key, Separator, value)); - } - } - } - } -} diff --git a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PasswordManagerNativeMethods.cs b/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PasswordManagerNativeMethods.cs deleted file mode 100644 index d4f9a993f..000000000 --- a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PasswordManagerNativeMethods.cs +++ /dev/null @@ -1,161 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Runtime.InteropServices; - -using Microsoft.Win32.SafeHandles; - -namespace Microsoft.Toolkit.Services.PlatformSpecific.NetFramework -{ - internal class PasswordManagerNativeMethods - { - [DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)] - internal static extern bool CredRead(string target, CRED_TYPE type, int reservedFlag, out IntPtr credentialPtr); - - [DllImport("Advapi32.dll", EntryPoint = "CredWriteW", CharSet = CharSet.Unicode, SetLastError = true)] - internal static extern bool CredWrite([In] ref NativeCredential userCredential, [In] uint flags); - - [DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)] - internal static extern bool CredFree([In] IntPtr cred); - - [DllImport("advapi32.dll", EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode)] - internal static extern bool CredDelete(string target, CRED_TYPE type, int flags); - - internal enum CRED_TYPE : uint - { - GENERIC = 1, - DOMAIN_PASSWORD = 2, - DOMAIN_CERTIFICATE = 3, - DOMAIN_VISIBLE_PASSWORD = 4, - GENERIC_CERTIFICATE = 5, - DOMAIN_EXTENDED = 6, - MAXIMUM = 7, // Maximum supported cred type - MAXIMUM_EX = MAXIMUM + 1000, // Allow new applications to run on old OSes - } - - internal enum CRED_PERSIST : uint - { - SESSION = 1, - LOCAL_MACHINE = 2, - ENTERPRISE = 3, - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct NativeCredential - { - internal uint Flags; - internal CRED_TYPE Type; - internal IntPtr TargetName; - internal IntPtr Comment; - internal System.Runtime.InteropServices.ComTypes.FILETIME LastWritten; - internal uint CredentialBlobSize; - internal IntPtr CredentialBlob; - internal uint Persist; - internal uint AttributeCount; - internal IntPtr Attributes; - internal IntPtr TargetAlias; - internal IntPtr UserName; - - /// - /// This method derives a NativeCredential instance from a given Credential instance. - /// - /// The managed Credential counterpart containing data to be stored. - /// A NativeCredential instance that is derived from the given Credential - /// instance. - internal static NativeCredential GetNativeCredential(Credential cred) - { - return new NativeCredential - { - AttributeCount = 0, - Attributes = IntPtr.Zero, - Comment = IntPtr.Zero, - TargetAlias = IntPtr.Zero, - Type = CRED_TYPE.GENERIC, - Persist = (uint)cred.Persist, - CredentialBlobSize = (uint)cred.CredentialBlobSize, - TargetName = Marshal.StringToCoTaskMemUni(cred.TargetName), - CredentialBlob = Marshal.StringToCoTaskMemUni(cred.CredentialBlob), - UserName = Marshal.StringToCoTaskMemUni(cred.UserName) - }; - } - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct Credential - { - internal uint Flags; - internal CRED_TYPE Type; - internal string TargetName; - internal string Comment; - internal System.Runtime.InteropServices.ComTypes.FILETIME LastWritten; - internal uint CredentialBlobSize; - internal string CredentialBlob; - internal CRED_PERSIST Persist; - internal uint AttributeCount; - internal IntPtr Attributes; - internal string TargetAlias; - internal string UserName; - } - - /// - /// Handle and create the credential. - /// - internal sealed class CriticalCredentialHandle : CriticalHandleZeroOrMinusOneIsInvalid - { - // Set the handle. - internal CriticalCredentialHandle(IntPtr preexistingHandle) - { - SetHandle(preexistingHandle); - } - - internal Credential GetCredential() - { - if (!IsInvalid) - { - // Get the Credential from the mem location - NativeCredential nativeCredential = (NativeCredential)Marshal.PtrToStructure(handle, typeof(NativeCredential)); - - // Create a managed Credential type and fill it with data from the native counterpart. - return new Credential - { - CredentialBlobSize = nativeCredential.CredentialBlobSize, - CredentialBlob = Marshal.PtrToStringUni(nativeCredential.CredentialBlob, (int)nativeCredential.CredentialBlobSize / 2), - UserName = Marshal.PtrToStringUni(nativeCredential.UserName), - TargetName = Marshal.PtrToStringUni(nativeCredential.TargetName), - TargetAlias = Marshal.PtrToStringUni(nativeCredential.TargetAlias), - Type = nativeCredential.Type, - Flags = nativeCredential.Flags, - Persist = (CRED_PERSIST)nativeCredential.Persist - }; - } - else - { - throw new InvalidOperationException("Invalid CriticalHandle!"); - } - } - - // Perform any specific actions to release the handle in the ReleaseHandle method. - // Often, you need to use PInvoke to make a call into the Win32 API to release the - // handle. In this case, however, we can use the Marshal class to release the unmanaged memory. - protected override bool ReleaseHandle() - { - // If the handle was set, free it. Return success. - if (!IsInvalid) - { - // NOTE: We should also ZERO out the memory allocated to the handle, before freeing it - // so there are no traces of the sensitive data left in memory. - CredFree(handle); - - // Mark the handle as invalid for future users. - SetHandleAsInvalid(); - return true; - } - - // Return false. - return false; - } - } - } -} diff --git a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PopupForm.Designer.cs b/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PopupForm.Designer.cs deleted file mode 100644 index 85562563d..000000000 --- a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PopupForm.Designer.cs +++ /dev/null @@ -1,67 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.PlatformSpecific.NetFramework -{ - - partial class PopupForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.webView1 = new Microsoft.Toolkit.Forms.UI.Controls.WebView(); - ((System.ComponentModel.ISupportInitialize)(this.webView1)).BeginInit(); - this.SuspendLayout(); - // - // webView1 - // - this.webView1.Dock = System.Windows.Forms.DockStyle.Fill; - this.webView1.Location = new System.Drawing.Point(0, 0); - this.webView1.MinimumSize = new System.Drawing.Size(20, 20); - this.webView1.Name = "webView1"; - this.webView1.Size = new System.Drawing.Size(800, 450); - this.webView1.TabIndex = 0; - // - // Form1 - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(800, 450); - this.Controls.Add(this.webView1); - this.Name = "Form1"; - this.Text = "Form1"; - ((System.ComponentModel.ISupportInitialize)(this.webView1)).EndInit(); - this.ResumeLayout(false); - - } - - #endregion - - private Microsoft.Toolkit.Forms.UI.Controls.WebView webView1; - } -} - diff --git a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PopupForm.cs b/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PopupForm.cs deleted file mode 100644 index 2c4e6a2ac..000000000 --- a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PopupForm.cs +++ /dev/null @@ -1,77 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace Microsoft.Toolkit.Services.PlatformSpecific.NetFramework -{ - /// - /// Service WebView for windows forms - /// - public partial class PopupForm : Form - { - private string initialHost; - private string callbackHost; - - /// - /// Gets or sets the current URL before closing the form - /// - public Uri ActualUrl { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// Uri callback url - public PopupForm(Uri callbackUrl) - { - InitializeComponent(); - webView1.NavigationStarting += (s, e) => WebViewNavigationStartingHandler(e.Uri); - callbackHost = GetTopLevelDomain(callbackUrl); - } - - private void WebViewNavigationStartingHandler(Uri uri) - { - var topLevelDomain = GetTopLevelDomain(uri); - if (initialHost != topLevelDomain && topLevelDomain == callbackHost) - { - ActualUrl = uri; - this.Close(); - } - } - - /// - /// Loads a given url in the WebView - /// - /// Url string to navigate to. - public void NavigateTo(string url) - { - initialHost = GetTopLevelDomain(url); - webView1.Navigate(url); - } - - private string GetTopLevelDomain(string url) - { - return GetTopLevelDomain(new Uri(url)); - } - - private string GetTopLevelDomain(Uri url) - { - var hostParts = url.Host.Split('.').Select(x => x.ToString()); - if (hostParts.Count() > 1) - { - return hostParts.ElementAt(1); - } - - return hostParts.ElementAt(0); - } - } -} diff --git a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PopupWPF.xaml b/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PopupWPF.xaml deleted file mode 100644 index 4783beba5..000000000 --- a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PopupWPF.xaml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - diff --git a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PopupWPF.xaml.cs b/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PopupWPF.xaml.cs deleted file mode 100644 index 75b958ca6..000000000 --- a/Microsoft.Toolkit.Services/PlatformSpecific/NETFramework/PopupWPF.xaml.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Forms; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; - -namespace Microsoft.Toolkit.Services.PlatformSpecific.NetFramework -{ - /// - /// Interaction logic for PopupWPF.xaml - /// - public partial class PopupWPF : Window - { - private string initialHost; - private string callbackHost; - - /// - /// Gets or sets the current URL before closing the form - /// - public Uri ActualUrl { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// Uri callback url - public PopupWPF(Uri callbackUrl) - { - InitializeComponent(); - - WebView1.NavigationStarting += (s, e) => WebViewNavigationStartingHandler(e.Uri); - callbackHost = GetTopLevelDomain(callbackUrl); - } - - private void WebViewNavigationStartingHandler(Uri uri) - { - var topLevelDomain = GetTopLevelDomain(uri); - if (initialHost != topLevelDomain && topLevelDomain == callbackHost) - { - ActualUrl = uri; - this.Close(); - } - } - - /// - /// Loads a given url in the WebView - /// - /// Url string to navigate to. - public void NavigateTo(string url) - { - initialHost = GetTopLevelDomain(url); - WebView1.Navigate(url); - } - - private string GetTopLevelDomain(string url) - { - return GetTopLevelDomain(new Uri(url)); - } - - private string GetTopLevelDomain(Uri url) - { - var hostParts = url.Host.Split('.').Select(x => x.ToString()); - if (hostParts.Count() > 1) - { - return hostParts.ElementAt(1); - } - - return hostParts.ElementAt(0); - } - } -} diff --git a/Microsoft.Toolkit.Services/PlatformSpecific/Uwp/UwpAuthenticationBroker.cs b/Microsoft.Toolkit.Services/PlatformSpecific/Uwp/UwpAuthenticationBroker.cs deleted file mode 100644 index 0d73af1c9..000000000 --- a/Microsoft.Toolkit.Services/PlatformSpecific/Uwp/UwpAuthenticationBroker.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Threading.Tasks; -using Microsoft.Toolkit.Services.Core; -using Windows.Security.Authentication.Web; - -namespace Microsoft.Toolkit.Services.PlatformSpecific.Uwp -{ - /// - /// Authentication Broker - /// - internal class UwpAuthenticationBroker : IAuthenticationBroker - { - /// - /// Authentication process - /// - /// Request Uri - /// Uri result - /// Returns login status - public async Task Authenticate(Uri requestUri, Uri callbackUri) - { - WebAuthenticationResult result = await WebAuthenticationBroker.AuthenticateAsync( - WebAuthenticationOptions.None, - requestUri, - callbackUri); - - switch (result.ResponseStatus) - { - case WebAuthenticationStatus.Success: - return new AuthenticationResult { ResponseData = result.ResponseData, ResponseStatus = AuthenticationResultStatus.Success }; - case WebAuthenticationStatus.UserCancel: - return new AuthenticationResult { ResponseData = result.ResponseData, ResponseStatus = AuthenticationResultStatus.UserCancel, ResponseErrorDetail = result.ResponseErrorDetail }; - case WebAuthenticationStatus.ErrorHttp: - return new AuthenticationResult { ResponseData = result.ResponseData, ResponseStatus = AuthenticationResultStatus.ErrorHttp, ResponseErrorDetail = result.ResponseErrorDetail }; - default: - // TODO: Change with correct name; - throw new ArgumentException("error"); - } - } - } -} diff --git a/Microsoft.Toolkit.Services/PlatformSpecific/Uwp/UwpPasswordManager.cs b/Microsoft.Toolkit.Services/PlatformSpecific/Uwp/UwpPasswordManager.cs deleted file mode 100644 index 4d7b3f77f..000000000 --- a/Microsoft.Toolkit.Services/PlatformSpecific/Uwp/UwpPasswordManager.cs +++ /dev/null @@ -1,67 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Linq; -using Microsoft.Toolkit.Services.Core; -using Windows.Security.Credentials; - -namespace Microsoft.Toolkit.Services.PlatformSpecific.Uwp -{ - /// - /// Password Manager - /// - internal class UwpPasswordManager : IPasswordManager - { - /// - /// Password vault used to store access tokens - /// - private readonly PasswordVault _vault; - - /// - /// Initializes a new instance of the class. - /// - public UwpPasswordManager() - { - _vault = new PasswordVault(); - } - - /// - public Toolkit.Services.Core.PasswordCredential Get(string key) - { - var credentials = RetrievePasswordCredential(key); - if (credentials == null) - { - return null; - } - - return new Toolkit.Services.Core.PasswordCredential { Password = credentials.Password, UserName = credentials.UserName }; - } - - private Windows.Security.Credentials.PasswordCredential RetrievePasswordCredential(string key) - { - var passwordCredentials = _vault.RetrieveAll(); - var temp = passwordCredentials.FirstOrDefault(c => c.Resource == key); - - if (temp == null) - { - return null; - } - - return _vault.Retrieve(temp.Resource, temp.UserName); - } - - /// - public void Remove(string key) - { - _vault.Remove(RetrievePasswordCredential(key)); - } - - /// - public void Store(string resource, Toolkit.Services.Core.PasswordCredential credentials) - { - var passwordCredential = new Windows.Security.Credentials.PasswordCredential(resource, credentials.UserName, credentials.Password); - _vault.Add(passwordCredential); - } - } -} diff --git a/Microsoft.Toolkit.Services/PlatformSpecific/Uwp/UwpSignatureManager.cs b/Microsoft.Toolkit.Services/PlatformSpecific/Uwp/UwpSignatureManager.cs deleted file mode 100644 index f25799503..000000000 --- a/Microsoft.Toolkit.Services/PlatformSpecific/Uwp/UwpSignatureManager.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.Toolkit.Services.Core; - -using Windows.Security.Cryptography; -using Windows.Security.Cryptography.Core; -using Windows.Storage.Streams; - -namespace Microsoft.Toolkit.Services.PlatformSpecific.Uwp -{ - /// - /// UWP specific signature generator using cryptographic library - /// - internal class UwpSignatureManager : ISignatureManager - { - /// - /// Generate request signature. - /// - /// String to sign - /// Secret to use to sign - /// If true append & to the base string - /// Signature. - public string GetSignature(string baseString, string secret, bool append = false) - { - var key = append ? secret + "&" : secret; - - IBuffer keyMaterial = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8); - MacAlgorithmProvider mac = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha1); - CryptographicKey cryptoKey = mac.CreateKey(keyMaterial); - IBuffer dataToBeSigned = CryptographicBuffer.ConvertStringToBinary(baseString, BinaryStringEncoding.Utf8); - IBuffer hash = CryptographicEngine.Sign(cryptoKey, dataToBeSigned); - return CryptographicBuffer.EncodeToBase64String(hash); - } - } -} diff --git a/Microsoft.Toolkit.Services/PlatformSpecific/Uwp/UwpStorageManager.cs b/Microsoft.Toolkit.Services/PlatformSpecific/Uwp/UwpStorageManager.cs deleted file mode 100644 index 9fbfc6be3..000000000 --- a/Microsoft.Toolkit.Services/PlatformSpecific/Uwp/UwpStorageManager.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Toolkit.Services.Core; -using Windows.Security.Credentials; -using Windows.Storage; - -namespace Microsoft.Toolkit.Services.PlatformSpecific.Uwp -{ - /// - /// UWP specific implementation for IStorageManager using ApplicationData and LocalSettings - /// - internal class UwpStorageManager : IStorageManager - { - /// - /// Read the storage to return the key if exists if not null; - /// - /// Key to lookup - /// Return string value if exists if not null - public Task GetAsync(string key) - { - return Task.FromResult(ApplicationData.Current.LocalSettings.Values[key]?.ToString()); - } - - /// - /// Save the value in the key inside the storage - /// - /// Key name in storage - /// Value associated to the storage - /// A representing the asynchronous operation. - public Task SetAsync(string key, string value) - { - ApplicationData.Current.LocalSettings.Values[key] = value; - return Task.CompletedTask; - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Properties/Microsoft.Toolkit.Services.rd.xml b/Microsoft.Toolkit.Services/Properties/Microsoft.Toolkit.Services.rd.xml deleted file mode 100644 index 9f5b9bd94..000000000 --- a/Microsoft.Toolkit.Services/Properties/Microsoft.Toolkit.Services.rd.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInConstants.cs b/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInConstants.cs deleted file mode 100644 index af8b06799..000000000 --- a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInConstants.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.LinkedIn -{ - /// - /// Constant strings for LinkedIn Service. - /// - public static class LinkedInConstants - { - /// - /// Storage key name for access token. - /// - public static readonly string STORAGEKEYACCESSTOKEN = "LinkedInAccessToken"; - - /// - /// Storage key name for user name. - /// - public static readonly string STORAGEKEYUSER = "LinkedInUser"; - } -} diff --git a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInContent.cs b/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInContent.cs deleted file mode 100644 index cafd0e456..000000000 --- a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInContent.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.LinkedIn -{ - /// - /// Strong type representation of Content. - /// - public class LinkedInContent - { - /// - /// Gets or sets title property. - /// - public string Title { get; set; } - - /// - /// Gets or sets description property. - /// - public string Description { get; set; } - - /// - /// Gets or sets submitted url property. - /// - public string SubmittedUrl { get; set; } - - /// - /// Gets or sets submitted image url property. - /// - public string SubmittedImageUrl { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInDataConfig.cs b/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInDataConfig.cs deleted file mode 100644 index 1bd294d35..000000000 --- a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInDataConfig.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.LinkedIn -{ - /// - /// Configuration object for specifying richer query information. - /// - public class LinkedInDataConfig - { - /// - /// Gets or sets the query string for filtering service results. - /// - public string Query { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInDataProvider.cs b/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInDataProvider.cs deleted file mode 100644 index b7977d0d0..000000000 --- a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInDataProvider.cs +++ /dev/null @@ -1,334 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Net.Http; -using System.Text; -using System.Text.Json; -using System.Threading.Tasks; -using Microsoft.Toolkit.Services.Core; - -#if WINRT -using Microsoft.Toolkit.Services.PlatformSpecific.Uwp; -#endif - -#if NET462 -using Microsoft.Toolkit.Services.PlatformSpecific.NetFramework; -#endif - -namespace Microsoft.Toolkit.Services.LinkedIn -{ - /// - /// Data Provider for connecting to LinkedIn service. - /// - public class LinkedInDataProvider - { - private const string _oAuthBaseUrl = "https://www.linkedin.com/uas/oauth2/"; - private const string _baseUrl = "https://api.linkedin.com/v1"; - - private static HttpClient client = new HttpClient(); - - /// - /// Gets or sets logged in user information. - /// - public string Username { get; set; } - - /// - /// Gets a value indicating whether the provider is already logged in - /// - public bool LoggedIn { get; private set; } - - /// - /// Gets or sets requiredPermissions property. - /// - public LinkedInPermissions RequiredPermissions { get; set; } - - private readonly IAuthenticationBroker _authentication; - private readonly IPasswordManager _passwordManager; - private readonly IStorageManager _storageManager; - - /// - /// Gets or sets tokens property. - /// - public LinkedInOAuthTokens Tokens { get; set; } - - /// - /// Initializes a new instance of the class. - /// Constructor. - /// - /// OAuth tokens for request. - /// Required permissions for the session. - /// Authentication result interface. - /// Password Manager interface, store the password. - /// Storage Manager interface. - public LinkedInDataProvider(LinkedInOAuthTokens tokens, LinkedInPermissions requiredPermissions, IAuthenticationBroker authentication, IPasswordManager passwordManager, IStorageManager storageManager) - { - if (string.IsNullOrEmpty(tokens.ClientSecret)) - { - throw new ArgumentException("Missing client secret key"); - } - - if (string.IsNullOrEmpty(tokens.ClientId)) - { - throw new ArgumentException("Missing client ID"); - } - - if (string.IsNullOrEmpty(tokens.CallbackUri)) - { - throw new ArgumentException("Missing callback uri"); - } - - // Check if its a valid combination of LinkedInPermissions - if ((~(int)LinkedInPermissionsHelpers.AllPermissions & (int)requiredPermissions) != 0) - { - throw new ArgumentException("Error retrieving required permissions"); - } - - Tokens = tokens; - RequiredPermissions = requiredPermissions; - _authentication = authentication ?? throw new ArgumentException("Invalid AuthenticationBroker"); - _storageManager = storageManager ?? throw new ArgumentException("Invalid StorageManager"); - _passwordManager = passwordManager ?? throw new ArgumentException("Invalid PasswordManager"); - } -#if WINRT - /// - /// Initializes a new instance of the class. - /// Constructor. - /// - /// OAuth tokens for request. - /// Required permissions for the session. - public LinkedInDataProvider(LinkedInOAuthTokens tokens, LinkedInPermissions requiredPermissions) - : this(tokens, requiredPermissions, new UwpAuthenticationBroker(), new UwpPasswordManager(), new UwpStorageManager()) - { - } -#endif - -#if NET462 - /// - /// Initializes a new instance of the class. - /// Constructor. - /// - /// OAuth tokens for request. - /// Required permissions for the session. - public LinkedInDataProvider(LinkedInOAuthTokens tokens, LinkedInPermissions requiredPermissions) - : this(tokens, requiredPermissions, new NetFrameworkAuthenticationBroker(), new NetFrameworkPasswordManager(), new NetFrameworkStorageManager()) - { - } -#endif - - /// - /// Log user in to LinkedIn. - /// - /// Boolean indicating login success. - public async Task LoginAsync() - { - var user = await _storageManager.GetAsync(LinkedInConstants.STORAGEKEYUSER); - var credential = _passwordManager.Get(LinkedInConstants.STORAGEKEYACCESSTOKEN); - if (!string.IsNullOrEmpty(user) && credential != null) - { - Tokens.AccessToken = credential.Password; - Username = user; - LoggedIn = true; - return true; - } - - string authorizeCode = await GetAuthorizeCodeAsync(Tokens, RequiredPermissions); - - if (!string.IsNullOrEmpty(authorizeCode)) - { - var accessToken = await GetAccessTokenAsync(Tokens, authorizeCode); - - if (!string.IsNullOrEmpty(accessToken)) - { - Tokens.AccessToken = accessToken; - - _passwordManager.Store(LinkedInConstants.STORAGEKEYACCESSTOKEN, new PasswordCredential { UserName = LinkedInConstants.STORAGEKEYUSER, Password = accessToken }); - await _storageManager.SetAsync(LinkedInConstants.STORAGEKEYUSER, LinkedInConstants.STORAGEKEYUSER); - return true; - } - } - - LoggedIn = false; - return false; - } - - /// - /// Log user out of LinkedIn. - /// - /// A representing the asynchronous operation. - public async Task LogoutAsync() - { - var credential = _passwordManager.Get(LinkedInConstants.STORAGEKEYACCESSTOKEN); - - if (credential != null) - { - _passwordManager.Remove(LinkedInConstants.STORAGEKEYACCESSTOKEN); - await _storageManager.SetAsync(LinkedInConstants.STORAGEKEYUSER, null); - } - - LoggedIn = false; - } - - /// - /// Wrapper around REST API for making data request. - /// - /// Schema to use - /// Query configuration. - /// Upper limit for records returned. - /// Index of paged results. - /// A comma separated string of required fields, which will have strongly typed representation in the model passed in. - /// Strongly typed list of results. - public async Task> GetDataAsync(LinkedInDataConfig config, int maxRecords, int startRecord = 0, string fields = "id") - { - var parser = new LinkedInParser(); - - var url = $"{_baseUrl}{config.Query}/~:({fields})?oauth2_access_token={Tokens.AccessToken}&format=json&count={maxRecords}&start={startRecord}"; - - using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(url)); - request.Headers.Connection.TryParseAdd("Keep-Alive"); - - using var response = await client.SendAsync(request).ConfigureAwait(false); - var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - - if (response.IsSuccessStatusCode && !string.IsNullOrEmpty(data)) - { - return parser.Parse(data); - } - - throw new RequestFailedException((System.Net.HttpStatusCode)response.StatusCode, data); - } - - /// - /// Share data to LinkedIn. - /// - /// Schema of data to share. - /// Type of response object. - /// Share request content. - /// Boolean indicating success or failure. - public async Task ShareDataAsync(T dataToShare) - { - var shareRequest = dataToShare as LinkedInShareRequest; - if (shareRequest != null) - { - LinkedInVisibility.ParseVisibilityStringToEnum(shareRequest.Visibility.Code); - - var requestParser = new LinkedInParser(); - - var url = $"{_baseUrl}/people/~/shares?oauth2_access_token={Tokens.AccessToken}&format=json"; - - using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, new Uri(url)); - request.Headers.Add("x-li-format", "json"); - var stringContent = requestParser.Parse(shareRequest); - request.Content = new StringContent(stringContent, Encoding.UTF8, "application/json"); - - using var response = await client.SendAsync(request).ConfigureAwait(false); - var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - - var responseParser = new LinkedInParser(); - - var listResults = responseParser.Parse(data) as List; - return listResults[0]; - } - - return default(U); - } - - /// - /// Check validity of configuration. - /// - /// Query configuration. - protected void ValidateConfig(LinkedInDataConfig config) - { - if (config?.Query == null) - { - throw new ConfigParameterNullException(nameof(config.Query)); - } - } - - private async Task GetAccessTokenAsync(LinkedInOAuthTokens tokens, string authorizeCode) - { - var url = $"{_oAuthBaseUrl}accessToken?grant_type=authorization_code" - + "&code=" + authorizeCode - + "&redirect_uri=" + Uri.EscapeDataString(tokens.CallbackUri) - + "&client_id=" + tokens.ClientId - + "&client_secret=" + tokens.ClientSecret; - - using var request = new HttpRequestMessage(HttpMethod.Post, new Uri(url)); - using var response = await client.SendAsync(request).ConfigureAwait(false); - using var jsonStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); - using var jsonDoc = await JsonDocument.ParseAsync(jsonStream).ConfigureAwait(false); - - var value = jsonDoc.RootElement.GetProperty("access_token"); - return value.GetString(); - } - - private async Task GetAuthorizeCodeAsync(LinkedInOAuthTokens tokens, LinkedInPermissions permissions) - { - string scopes = ConvertPermissionsToEncodedScopeString(permissions); - - var url = $"{_oAuthBaseUrl}authorization?response_type=code" - + "&client_id=" + tokens.ClientId - + "&state=STATE" - + "&redirect_uri=" + Uri.EscapeDataString(tokens.CallbackUri) - + "&" + scopes; - - var startUri = new Uri(url); - var endUri = new Uri(tokens.CallbackUri); - - var result = await _authentication.Authenticate(startUri, endUri); - switch (result.ResponseStatus) - { - case AuthenticationResultStatus.Success: - { - var response = result.ResponseData; - IDictionary dictionary = new Dictionary(); - var split = response.Split('?'); - foreach (var keyValue in split[split.Length - 1].Split('&')) - { - var keyValueSplit = keyValue.Split('='); - if (keyValueSplit.Length == 2) - { - dictionary.Add(keyValueSplit[0], keyValueSplit[1]); - } - } - - return dictionary["code"]; - } - - case AuthenticationResultStatus.ErrorHttp: - Debug.WriteLine("WAB failed, message={0}", result.ResponseErrorDetail.ToString()); - return string.Empty; - - case AuthenticationResultStatus.UserCancel: - Debug.WriteLine("WAB user aborted."); - return string.Empty; - } - - return string.Empty; - } - - private string ConvertPermissionsToEncodedScopeString(LinkedInPermissions requiredPermissions) - { - StringBuilder scope = new StringBuilder(); - - foreach (LinkedInPermissions value in Enum.GetValues(typeof(LinkedInPermissions))) - { - if ((requiredPermissions & value) != LinkedInPermissions.NotSet) - { - var name = value.ToString().ToLower(); - name = name.Replace("readwrite", "rw_"); - name = name.Replace("read", "r_"); - name = name.Replace("write", "w_"); - name = name.Replace("companyadmin", "company_admin"); - - scope.Append($"{name} "); - } - } - - return "scope=" + Uri.EscapeDataString(scope.ToString()); - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInOAuthTokens.cs b/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInOAuthTokens.cs deleted file mode 100644 index 0014425af..000000000 --- a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInOAuthTokens.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.LinkedIn -{ - /// - /// LinkedIn OAuth tokens. - /// - public class LinkedInOAuthTokens - { - /// - /// Gets or sets clientId. - /// - public string ClientId { get; set; } - - /// - /// Gets or sets clientSecret. - /// - public string ClientSecret { get; set; } - - /// - /// Gets or sets callback Uri. - /// - public string CallbackUri { get; set; } - - /// - /// Gets or sets access token. - /// - public string AccessToken { get; set; } - - /// - /// Gets or sets access token Secret. - /// - public string AccessTokenSecret { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInParser.cs b/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInParser.cs deleted file mode 100644 index 4e1457644..000000000 --- a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInParser.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; -using System.Text.Json; - -namespace Microsoft.Toolkit.Services.LinkedIn -{ - /// - /// Parse results into strong type. - /// - /// Type to parse into. - public class LinkedInParser - { - /// - /// Take string data and parse into strong data type. - /// - /// String data. - /// Returns strong type. - public IEnumerable Parse(string data) - { - List results; - - try - { - results = JsonSerializer.Deserialize>(data); - } - catch (JsonException) - { - T linkedInResult = JsonSerializer.Deserialize(data); - results = new List { linkedInResult }; - } - - return results; - } - - /// - /// Take strong type and return corresponding JSON string. - /// - /// Strong typed instance. - /// Returns string data. - public string Parse(T dataToShare) - { - return JsonSerializer.Serialize(dataToShare, typeof(T), new JsonSerializerOptions { IgnoreNullValues = true }); - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInPermissions.cs b/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInPermissions.cs deleted file mode 100644 index 6d2d2fe75..000000000 --- a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInPermissions.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Microsoft.Toolkit.Services.LinkedIn -{ - /// - /// List of user related data permissions - /// - [Flags] - public enum LinkedInPermissions - { - /// - /// Not set - /// - NotSet = 0, - - /// - /// Read - Basic profile (r_basicprofile) - /// - ReadBasicProfile = 1, - - /// - /// Read - Email Address (r_emailaddress) - /// - ReadEmailAddress = 2, - - /// - /// Read / Write - Company Admin (rw_company_admin) - /// - ReadWriteCompanyAdmin = 4, - - /// - /// Write - Share (w_share) - /// - WriteShare = 8 - } - -#pragma warning disable SA1649 // File name should match first type name - internal static class LinkedInPermissionsHelpers - { - /// - /// Internal AllPermissions for LinkedInPermissions, so we don't expose it. Keep it in sync with - /// - internal const LinkedInPermissions AllPermissions = - LinkedInPermissions.ReadBasicProfile | - LinkedInPermissions.ReadEmailAddress | - LinkedInPermissions.ReadWriteCompanyAdmin | - LinkedInPermissions.WriteShare; - } -#pragma warning restore SA1649 // File name should match first type name -} diff --git a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInProfile.cs b/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInProfile.cs deleted file mode 100644 index 84dc6f0ed..000000000 --- a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInProfile.cs +++ /dev/null @@ -1,67 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.LinkedIn -{ - /// - /// Strongly typed LinkedIn Basic Profile. More details here https://developer.linkedin.com/docs/fields/basic-profile. - /// - public partial class LinkedInProfile - { - /// - /// Gets a string description of the strongly typed properties in this model. - /// - public static string Fields => "first-name,last-name,headline,id,picture-url,site-standard-profile-request,num-connections,summary,public-profile-url"; - - /// - /// Gets or sets firstName property. - /// - public string FirstName { get; set; } - - /// - /// Gets or sets headline property. - /// - public string Headline { get; set; } - - /// - /// Gets or sets id property. - /// - public string Id { get; set; } - - /// - /// Gets or sets lastname property. - /// - public string LastName { get; set; } - - /// - /// Gets or sets picture-url property. - /// - public string PictureUrl { get; set; } - - /// - /// Gets or sets num-connections property. - /// - public string NumConnections { get; set; } - - /// - /// Gets or sets summary property. - /// - public string Summary { get; set; } - - /// - /// Gets or sets public-profile-url property. - /// - public string PublicProfileUrl { get; set; } - - /// - /// Gets or sets email-address property. Requires r_emailaddress permission. - /// - public string EmailAddress { get; set; } - - /// - /// Gets or sets siteStandardProfileRequest property. - /// - public LinkedInProfileRequest SiteStandardProfileRequest { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInProfileRequest.cs b/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInProfileRequest.cs deleted file mode 100644 index ac8e238c5..000000000 --- a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInProfileRequest.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.LinkedIn -{ - /// - /// Strongly typed SiteStandardProfileRequest class. - /// - public class LinkedInProfileRequest - { - /// - /// Gets or sets url property. - /// - public string Url { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInService.cs b/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInService.cs deleted file mode 100644 index 977419ebe..000000000 --- a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInService.cs +++ /dev/null @@ -1,276 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.Toolkit.Services.Core; -#if WINRT -using Microsoft.Toolkit.Services.PlatformSpecific.Uwp; -#endif - -#if NET462 -using Microsoft.Toolkit.Services.PlatformSpecific.NetFramework; -#endif - -namespace Microsoft.Toolkit.Services.LinkedIn -{ - /// - /// Class for connecting to LinkedIn. - /// - public class LinkedInService - { - /// - /// Private singleton field. - /// - private static LinkedInService _instance; - - /// - /// Gets public singleton property. - /// - public static LinkedInService Instance => _instance ?? (_instance = new LinkedInService()); - - private LinkedInDataProvider _provider; - - private LinkedInOAuthTokens _oAuthTokens; - - private LinkedInPermissions _requiredPermissions; - - private IAuthenticationBroker _authenticationBroker; - private IPasswordManager _passwordManager; - private IStorageManager _storageManager; - private bool _isInitialized = false; - - /// - /// Gets a reference to an instance of the underlying data provider. - /// - public LinkedInDataProvider Provider => _provider ?? (_provider = new LinkedInDataProvider(_oAuthTokens, _requiredPermissions, _authenticationBroker, _passwordManager, _storageManager)); - - private LinkedInService() - { - } - - /// - /// Log user in to LinkedIn. - /// - /// Returns success or failure of login attempt. - public Task LoginAsync() - { - if (!_isInitialized) - { - throw new InvalidOperationException("Initialized needs to be called first."); - } - - return Provider.LoginAsync(); - } - - /// - /// Share content to LinkedIn. - /// - /// Comment containing a Url. - /// Code for who to share with. - /// Boolean indicating success or failure. - public Task ShareActivityAsync(string commentContainingUrl, LinkedInShareVisibility visibilityCode = LinkedInShareVisibility.ConnectionsOnly) - { - var shareRequest = new LinkedInShareRequest - { - Comment = commentContainingUrl, - Visibility = new LinkedInVisibility { Code = LinkedInVisibility.ParseVisibilityEnumToString(visibilityCode) } - }; - - return ShareActivityAsync(shareRequest); - } - - /// - /// Share content to LinkedIn. - /// - /// Share request. - /// Boolean indicating success or failure. - public Task ShareActivityAsync(LinkedInShareRequest shareRequest) - { - return Provider.ShareDataAsync(shareRequest); - } - - /// - /// Log user out of LinkedIn. - /// - /// A representing the asynchronous operation. - public Task LogoutAsync() - { - _isInitialized = false; - return Provider.LogoutAsync(); - } - -#if WINRT - /// - /// Initialize underlying provider with relevant token information for UWP. - /// - /// Token instance. - /// Scope / permissions app requires user to sign up for. - /// Success or failure. - public bool Initialize(LinkedInOAuthTokens oAuthTokens, LinkedInPermissions requiredPermissions = LinkedInPermissions.NotSet) - { - return Initialize(oAuthTokens, new UwpAuthenticationBroker(), new UwpPasswordManager(), new UwpStorageManager(), requiredPermissions); - } - - /// - /// Initialize underlying provider with relevant token information. - /// - /// Client Id. - /// Client secret. - /// Callback URI. Has to match callback URI defined at www.linkedin.com/developer/apps/ (can be arbitrary). - /// Success or failure. - public bool Initialize(string clientId, string clientSecret, string callbackUri) - { - return Initialize(clientId, clientSecret, callbackUri, new UwpAuthenticationBroker(), new UwpPasswordManager(), new UwpStorageManager()); - } -#endif - -#if NET462 - /// - /// Initialize underlying provider with relevant token information for UWP. - /// - /// Token instance. - /// Scope / permissions app requires user to sign up for. - /// Success or failure. - public bool Initialize(LinkedInOAuthTokens oAuthTokens, LinkedInPermissions requiredPermissions = LinkedInPermissions.NotSet) - { - return Initialize(oAuthTokens, new NetFrameworkAuthenticationBroker(), new NetFrameworkPasswordManager(), new NetFrameworkStorageManager(), requiredPermissions); - } - - /// - /// Initialize underlying provider with relevant token information. - /// - /// Client Id. - /// Client secret. - /// Callback URI. Has to match callback URI defined at www.linkedin.com/developer/apps/ (can be arbitrary). - /// Success or failure. - public bool Initialize(string clientId, string clientSecret, string callbackUri) - { - return Initialize(clientId, clientSecret, callbackUri, new NetFrameworkAuthenticationBroker(), new NetFrameworkPasswordManager(), new NetFrameworkStorageManager()); - } -#endif - - /// - /// Initialize underlying provider with relevant token information. - /// - /// Client Id. - /// Client secret. - /// Callback URI. Has to match callback URI defined at www.linkedin.com/developer/apps/ (can be arbitrary). - /// Authentication result interface. - /// Password Manager interface, store the password. - /// Storage Manager interface. - /// Success or failure. - public bool Initialize(string clientId, string clientSecret, string callbackUri, IAuthenticationBroker authentication, IPasswordManager passwordManager, IStorageManager storageManager) - { - if (string.IsNullOrEmpty(clientId)) - { - throw new ArgumentNullException(nameof(clientId)); - } - - if (string.IsNullOrEmpty(clientSecret)) - { - throw new ArgumentNullException(nameof(clientSecret)); - } - - if (string.IsNullOrEmpty(callbackUri)) - { - throw new ArgumentNullException(nameof(callbackUri)); - } - - var oAuthTokens = new LinkedInOAuthTokens - { - ClientId = clientId, - ClientSecret = clientSecret, - CallbackUri = callbackUri - }; - - return Initialize(oAuthTokens, authentication, passwordManager, storageManager, LinkedInPermissions.ReadBasicProfile); - } - - /// - /// Initialize underlying provider with relevant token information. - /// - /// Token instance. - /// Authentication result interface. - /// Password Manager interface, store the password. - /// Storage Manager interface. - /// Scope / permissions app requires user to sign up for. - /// Success or failure. - public bool Initialize(LinkedInOAuthTokens oAuthTokens, IAuthenticationBroker authentication, IPasswordManager passwordManager, IStorageManager storageManager, LinkedInPermissions requiredPermissions = LinkedInPermissions.NotSet) - { - _oAuthTokens = oAuthTokens ?? throw new ArgumentNullException(nameof(oAuthTokens)); - _authenticationBroker = authentication ?? throw new ArgumentNullException(nameof(authentication)); - _storageManager = storageManager ?? throw new ArgumentNullException(nameof(storageManager)); - _passwordManager = passwordManager ?? throw new ArgumentNullException(nameof(passwordManager)); - - _requiredPermissions = requiredPermissions; - - Provider.RequiredPermissions = requiredPermissions; - Provider.Tokens = oAuthTokens; - - _isInitialized = true; - - return true; - } - - /// - /// Request list data from service provider based upon a given config / query. - /// - /// Strong type of model. - /// LinkedInDataConfig instance. - /// Upper limit of records to return. - /// Index of paged results. - /// A comma separated string of required fields, which will have strongly typed representation in the model passed in. - /// Strongly typed list of data returned from the service. - public async Task> RequestAsync(LinkedInDataConfig config, int maxRecords = 20, int startRecord = 0, string fields = "id") - { - List queryResults = new List(); - - var results = await Provider.GetDataAsync(config, maxRecords, startRecord, fields); - - foreach (var result in results) - { - queryResults.Add(result); - } - - return queryResults; - } - - /// - /// Retrieve logged in users profile details. - /// - /// Require email address - which needs user consensus. - /// Strongly typed profile. - public async Task GetUserProfileAsync(bool requireEmailAddress = false) - { - var fields = LinkedInProfile.Fields; - - if (requireEmailAddress) - { - if (!_requiredPermissions.HasFlag(LinkedInPermissions.ReadEmailAddress)) - { - throw new InvalidOperationException("Please re-initialize with email permission and call LoginAsync again so user may grant access."); - } - - fields += ",email-address"; - } - - if (Provider.LoggedIn) - { - var results = await LinkedInService.Instance.RequestAsync(new LinkedInDataConfig { Query = "/people" }, 1, 0, fields); - - return results[0]; - } - - var isLoggedIn = await LoginAsync(); - if (isLoggedIn) - { - return await GetUserProfileAsync(); - } - - return null; - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInShareRequest.cs b/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInShareRequest.cs deleted file mode 100644 index 07bfd76b1..000000000 --- a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInShareRequest.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.LinkedIn -{ - /// - /// Strong type for sharing data to LinkedIn. - /// - public partial class LinkedInShareRequest - { - /// - /// Gets or sets comment property. - /// - public string Comment { get; set; } - - /// - /// Gets or sets visibility property. - /// - public LinkedInVisibility Visibility { get; set; } - - /// - /// Gets or sets content property. - /// - public LinkedInContent Content { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInShareResponse.cs b/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInShareResponse.cs deleted file mode 100644 index 294511da5..000000000 --- a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInShareResponse.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.LinkedIn -{ - /// - /// Strong type for Share Response. - /// - public class LinkedInShareResponse - { - /// - /// Gets or sets UpdateKey property. - /// - public string UpdateKey { get; set; } - - /// - /// Gets or sets UpdateUrl property. - /// - public string UpdateUrl { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInShareVisibility.cs b/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInShareVisibility.cs deleted file mode 100644 index 0ddf125ce..000000000 --- a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInShareVisibility.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Microsoft.Toolkit.Services.LinkedIn -{ - /// - /// List of user related data permissions - /// - [Flags] - public enum LinkedInShareVisibility - { - /// - /// Connections only - /// - ConnectionsOnly = 1, - - /// - /// Anyone - /// - Anyone = 2 - } -} diff --git a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInVisibility.cs b/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInVisibility.cs deleted file mode 100644 index f59235271..000000000 --- a/Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInVisibility.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Microsoft.Toolkit.Services.LinkedIn -{ - /// - /// Strong type representation of Visibility. - /// - public class LinkedInVisibility - { - private const string ANYONE = "anyone"; - private const string CONNECTIONSONLY = "connections-only"; - - /// - /// Gets or sets code property. - /// - public string Code { get; set; } - - /// - /// Converts enum counterpart to appropriate data string. - /// - /// Enumeration. - /// String representation - public static string ParseVisibilityEnumToString(LinkedInShareVisibility visibility) - { - switch (visibility) - { - case LinkedInShareVisibility.Anyone: - return ANYONE; - case LinkedInShareVisibility.ConnectionsOnly: - return CONNECTIONSONLY; - } - - return string.Empty; - } - - /// - /// Converts string to enum counterpart. - /// - /// String. - /// Enumeration. - public static LinkedInShareVisibility ParseVisibilityStringToEnum(string visibility) - { - switch (visibility.ToLower()) - { - case ANYONE: - return LinkedInShareVisibility.Anyone; - case CONNECTIONSONLY: - return LinkedInShareVisibility.ConnectionsOnly; - } - - throw new ArgumentException("Invalid visibility string supplied."); - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/AzureAuthToken.cs b/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/AzureAuthToken.cs deleted file mode 100644 index a26074232..000000000 --- a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/AzureAuthToken.cs +++ /dev/null @@ -1,114 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Net.Http; -using System.Text.Json; -using System.Threading.Tasks; - -namespace Microsoft.Toolkit.Services.MicrosoftTranslator -{ - /// - /// Client to call Cognitive Services Azure Auth Token service in order to get an access token. - /// - internal class AzureAuthToken - { - /// - /// Name of header used to pass the subscription key to the token service - /// - private const string OcpApimSubscriptionKeyHeader = "Ocp-Apim-Subscription-Key"; - - /// - /// URL of the token service - /// - private static readonly Uri ServiceUrl = new Uri("https://api.cognitive.microsoft.com/sts/v1.0/issueToken"); - - // TODO - // private static readonly Uri ServiceUrl = new Uri(THIS SHOULD BE A PARAMETER NOW); - - /// - /// After obtaining a valid token, this class will cache it for this duration. - /// Use a duration of 8 minutes, which is less than the actual token lifetime of 10 minutes. - /// - private static readonly TimeSpan TokenCacheDuration = new TimeSpan(0, 8, 0); - - private static HttpClient client = new HttpClient(); - - private string _storedTokenValue = string.Empty; - private DateTime _storedTokenTime = DateTime.MinValue; - private string _subscriptionKey; - - /// - /// Gets or sets the Service Subscription Key. - /// - public string SubscriptionKey - { - get - { - return _subscriptionKey; - } - - set - { - if (_subscriptionKey != value) - { - // If the subscription key is changed, the token is no longer valid. - _subscriptionKey = value; - _storedTokenValue = string.Empty; - } - } - } - - /// - /// Initializes a new instance of the class, that is used to obtain access token - /// - /// Subscription key to use to get an authentication token. - public AzureAuthToken(string key) - { - SubscriptionKey = key; - } - - /// - /// Gets a token for the specified subscription. - /// - /// The encoded JWT token prefixed with the string "Bearer ". - /// - /// This method uses a cache to limit the number of request to the token service. - /// A fresh token can be re-used during its lifetime of 10 minutes. After a successful - /// request to the token service, this method caches the access token. Subsequent - /// invocations of the method return the cached token for the next 8 minutes. After - /// 8 minutes, a new token is fetched from the token service and the cache is updated. - /// - public async Task GetAccessTokenAsync() - { - if (string.IsNullOrEmpty(_subscriptionKey)) - { - throw new ArgumentNullException(nameof(SubscriptionKey), "A subscription key is required. Go to Azure Portal and sign up for Microsoft Translator: https://portal.azure.com/#create/Microsoft.CognitiveServices/apitype/TextTranslation"); - } - - // Re-use the cached token if there is one. - if ((DateTime.Now - _storedTokenTime) < TokenCacheDuration && !string.IsNullOrWhiteSpace(_storedTokenValue)) - { - return _storedTokenValue; - } - - using var request = new HttpRequestMessage(HttpMethod.Post, ServiceUrl); - request.Headers.Add(OcpApimSubscriptionKeyHeader, SubscriptionKey); - - var response = await client.SendAsync(request).ConfigureAwait(false); - var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - - if (!response.IsSuccessStatusCode) - { - var error = JsonSerializer.Deserialize(content); - throw new TranslatorServiceException(error?.Error?.Message); - } - - _storedTokenTime = DateTime.Now; - _storedTokenValue = $"Bearer {content}"; - - return _storedTokenValue; - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/DetectedLanguage.cs b/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/DetectedLanguage.cs deleted file mode 100644 index 66cd9cc6b..000000000 --- a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/DetectedLanguage.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; - -namespace Microsoft.Toolkit.Services.MicrosoftTranslator -{ - /// - /// Strong type for Detected Language - /// - /// - /// - public class DetectedLanguage : DetectedLanguageBase - { - /// - /// Gets a value indicating whether the detected language is one of the languages supported for text translation. - /// - public bool IsTranslationSupported { get; } - - /// - /// Gets a value indicating whether the detected language is one of the languages supported for transliteration. - /// - public bool IsTransliterationSupported { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The code of the detected language. - /// A float value indicating the confidence in the result. The score is between zero and one and a low score indicates a low confidence. - /// A value indicating whether the detected language is one of the languages supported for text translation. - /// A value indicating whether the detected language is one of the languages supported for transliteration. - /// - public DetectedLanguage(string language, float score, bool isTranslationSupported, bool isTransliterationSupported) - : base(language, score) - { - IsTranslationSupported = isTranslationSupported; - IsTransliterationSupported = isTransliterationSupported; - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/DetectedLanguageBase.cs b/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/DetectedLanguageBase.cs deleted file mode 100644 index 7cfa46c1b..000000000 --- a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/DetectedLanguageBase.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; - -namespace Microsoft.Toolkit.Services.MicrosoftTranslator -{ - /// - /// Strong type for Base Detected Language - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public class DetectedLanguageBase - { - /// - /// Gets the code of the detected language. - /// - public string Language { get; } - - /// - /// Gets a float value indicating the confidence in the result. The score is between zero and one and a low score indicates a low confidence. - /// - public float Score { get; } - - /// - public override string ToString() => Language; - - /// - /// Initializes a new instance of the class. - /// Returns the language friendly name. - /// - /// the code of the detected language. - /// a float value indicating the confidence in the result. The score is between zero and one and a low score indicates a low confidence. - public DetectedLanguageBase(string language, float score) - { - Language = language; - Score = score; - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/DetectedLanguageResponse.cs b/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/DetectedLanguageResponse.cs deleted file mode 100644 index ee4d88975..000000000 --- a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/DetectedLanguageResponse.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; - -namespace Microsoft.Toolkit.Services.MicrosoftTranslator -{ - /// - /// Strong type for Detect Language Response - /// - /// - /// - public class DetectedLanguageResponse : DetectedLanguage - { - /// - /// Gets an array of other possible languages. - /// - public IEnumerable Alternatives { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The code of the detected language. - /// A float value indicating the confidence in the result. The score is between zero and one and a low score indicates a low confidence. - /// A value indicating whether the detected language is one of the languages supported for text translation. - /// A value indicating whether the detected language is one of the languages supported for transliteration. - /// An array of other possible languages - /// - public DetectedLanguageResponse(string language, float score, bool isTranslationSupported, bool isTransliterationSupported, IEnumerable alternatives) - : base(language, score, isTranslationSupported, isTransliterationSupported) - { - Alternatives = alternatives; - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/ErrorResponse.cs b/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/ErrorResponse.cs deleted file mode 100644 index 870ee897f..000000000 --- a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/ErrorResponse.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.MicrosoftTranslator -{ -#pragma warning disable SA1402 // File may only contain a single type - /// - /// Holds information about an error occurred while accessing Microsoft Translator Service. - /// - internal class ErrorResponse - { - [JsonPropertyName("error")] - public Error Error { get; set; } - } - - internal class Error - { - /// - /// Gets or sets the error message. - /// - [JsonPropertyName("message")] - public string Message { get; set; } - } -#pragma warning restore SA1402 // File may only contain a single type -} diff --git a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/ITranslatorService.cs b/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/ITranslatorService.cs deleted file mode 100644 index 984a74d66..000000000 --- a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/ITranslatorService.cs +++ /dev/null @@ -1,372 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Microsoft.Toolkit.Services.MicrosoftTranslator -{ - /// - /// The ITranslatorServiceClient interface specifies properties and methods to translate text in various supported languages. - /// - public interface ITranslatorService - { - /// - /// Gets or sets the Subscription key that is necessary to use Microsoft Translator Service. - /// - /// The Subscription Key. - /// - /// You must register Microsoft Translator on https://portal.azure.com/#create/Microsoft.CognitiveServices/apitype/TextTranslation to obtain the Subscription key needed to use the service. - /// - string SubscriptionKey { get; set; } - - /// - /// Gets or sets the string representing the supported language code to translate the text in. - /// - /// The string representing the supported language code to translate the text in. The code must be present in the list of codes returned from the method . - /// - string Language { get; set; } - - /// - /// Initializes the class by getting an access token for the service. - /// - /// A that represents the initialize operation. - /// The property hasn't been set. - /// The provided isn't valid or has expired. - /// Calling this method isn't mandatory, because the token is get/refreshed every time is needed. However, it is called at startup, it can speed-up subsequent requests. - Task InitializeAsync(); - - /// - /// Initializes the class by getting an access token for the service. - /// - /// The subscription key for the Microsoft Translator Service on Azure. - /// A string representing the supported language code to speak the text in. The code must be present in the list of codes returned from the method . - /// A that represents the initialize operation. - /// The property hasn't been set. - /// The provided isn't valid or has expired. - /// - /// Calling this method isn't mandatory, because the token is get/refreshed every time is needed. However, it is called at startup, it can speed-up subsequent requests. - /// You must register Microsoft Translator on https://portal.azure.com to obtain the Subscription key needed to use the service. - /// - Task InitializeAsync(string subscriptionKey, string language = null); - - /// - /// Detects the language of a text. - /// - /// A string representing the text whose language must be detected. - /// A string containing a two-character Language code for the given text. - /// - /// - /// The property hasn't been set. - /// The parameter is null (Nothing in Visual Basic) or empty. - /// - /// - /// The provided isn't valid or has expired. - /// This method performs a non-blocking request for language detection. - /// For more information, go to https://docs.microsoft.com/azure/cognitive-services/translator/reference/v3-0-detect. - /// - /// - /// - Task DetectLanguageAsync(string input); - - /// - /// Detects the language of a text. - /// - /// A string representing the text whose language must be detected. - /// A object containing information about the detected language. - /// - /// - /// The property hasn't been set. - /// The parameter is null (Nothing in Visual Basic) or empty. - /// - /// - /// The provided isn't valid or has expired. - /// This method performs a non-blocking request for language detection. - /// For more information, go to https://docs.microsoft.com/azure/cognitive-services/translator/reference/v3-0-detect. - /// - /// - /// - Task DetectLanguageWithResponseAsync(string input); - - /// - /// Detects the language of a text. - /// - /// A string array containing the sentences whose language must be detected. - /// A array with one result for each string in the input array. Each object contains information about the detected language. - /// - /// - /// The parameter doesn't contain any element. - /// The array contains more than 100 elements. - /// - /// - /// - /// - /// The property hasn't been set. - /// The array is null (Nothing in Visual Basic). - /// - /// - /// The provided isn't valid or has expired. - /// This method performs a non-blocking request for language detection. - /// For more information, go to https://docs.microsoft.com/azure/cognitive-services/translator/reference/v3-0-detect. - /// - /// - /// - Task> DetectLanguagesWithResponseAsync(IEnumerable input); - - /// - /// Retrieves the languages available for translation. - /// - /// A string array containing the language codes supported for translation by Microsoft Translator Service. /// The property hasn't been set. - /// The provided isn't valid or has expired. - /// This method performs a non-blocking request for language codes. - /// For more information, go to https://docs.microsoft.com/azure/cognitive-services/translator/reference/v3-0-languages. - /// - /// - /// - Task> GetLanguagesAsync(); - - /// - /// Retrieves friendly names for the languages available for text translation. - /// - /// The language used to localize the language names. If the parameter is set to null, the language specified in the property will be used. - /// An array of containing the language codes and names supported for translation by Microsoft Translator Service. - /// The property hasn't been set. - /// The provided isn't valid or has expired. - /// This method performs a non-blocking request for language names. - /// For more information, go to https://docs.microsoft.com/azure/cognitive-services/translator/reference/v3-0-languages. - /// - /// - /// - Task> GetLanguageNamesAsync(string language = null); - - /// - /// Translates a text string into the specified language. - /// - /// A string representing the translated text. - /// A string representing the text to translate. - /// A string representing the language code to translate the text into. The code must be present in the list of codes returned from the method. If the parameter is set to null, the language specified in the property will be used. - /// - /// - /// The property hasn't been set. - /// The parameter is null (Nothing in Visual Basic) or empty. - /// - /// - /// The parameter is longer than 1000 characters. - /// The provided isn't valid or has expired. - /// This method perform a non-blocking request for text translation. - /// For more information, go to https://docs.microsoft.com/azure/cognitive-services/translator/reference/v3-0-translate. - /// - /// - /// - /// - Task TranslateAsync(string input, string to = null); - - /// - /// Translates a text string into the specified language. - /// - /// A string representing the translated text. - /// A string representing the text to translate. - /// A string representing the language code of the original text. The code must be present in the list of codes returned from the method. If the parameter is set to null, the language specified in the property will be used. - /// A string representing the language code to translate the text into. The code must be present in the list of codes returned from the method. If the parameter is set to null, the language specified in the property will be used. - /// - /// - /// The property hasn't been set. - /// The parameter is null (Nothing in Visual Basic) or empty. - /// - /// - /// The parameter is longer than 1000 characters. - /// The provided isn't valid or has expired. - /// This method perform a non-blocking request for text translation. - /// For more information, go to https://docs.microsoft.com/azure/cognitive-services/translator/reference/v3-0-translate. - /// - /// - /// - /// - Task TranslateAsync(string input, string from, string to); - - /// - /// Translates a text string into the specified language. - /// - /// A object containing translated text and information. - /// A string representing the text to translate. - /// A string representing the language code to translate the text into. The code must be present in the list of codes returned from the method. If the parameter is set to null, the language specified in the property will be used. - /// - /// - /// The property hasn't been set. - /// The parameter is null (Nothing in Visual Basic) or empty. - /// - /// - /// The parameter is longer than 1000 characters. - /// The provided isn't valid or has expired. - /// This method perform a non-blocking request for text translation. - /// For more information, go to https://docs.microsoft.com/azure/cognitive-services/translator/reference/v3-0-translate. - /// - /// - /// - /// - Task TranslateWithResponseAsync(string input, string to = null); - - /// - /// Translates a text string into the specified languages. - /// - /// A object containing translated text and information. - /// A string representing the text to translate. - /// A string representing the language code of the original text. The code must be present in the list of codes returned from the method. If the parameter is set to null, the language specified in the property will be used. - /// A string representing the language code to translate the text into. The code must be present in the list of codes returned from the method. If the parameter is set to null, the language specified in the property will be used. - /// - /// - /// The property hasn't been set. - /// The parameter is null (Nothing in Visual Basic) or empty. - /// - /// - /// The parameter is longer than 1000 characters. - /// The provided isn't valid or has expired. - /// This method perform a non-blocking request for text translation. - /// For more information, go to https://docs.microsoft.com/azure/cognitive-services/translator/reference/v3-0-translate. - /// - /// - /// - /// - Task TranslateWithResponseAsync(string input, string from, string to); - - /// - /// Translates a list of sentences into the specified language. - /// - /// A array with one result for each language code in the array. Each object contains translated text and information. - /// A string array containing the sentences to translate. - /// A string representing the language code of the original text. The code must be present in the list of codes returned from the method. If the parameter is set to null, the language specified in the property will be used. - /// A string representing the language code to translate the text into. The code must be present in the list of codes returned from the method. If the parameter is set to null, the language specified in the property will be used. - /// - /// - /// The property hasn't been set. - /// The parameter is null (Nothing in Visual Basic). - /// - /// - /// - /// - /// The parameter is longer than 1000 characters. - /// The array contains more than 25 elements. - /// - /// - /// The provided isn't valid or has expired. - /// This method perform a non-blocking request for text translation. - /// For more information, go to https://docs.microsoft.com/azure/cognitive-services/translator/reference/v3-0-translate. - /// - /// - /// - /// - Task> TranslateWithResponseAsync(IEnumerable input, string from, string to); - - /// - /// Translates a text into the specified languages. - /// - /// A object containing translated text and information. - /// A string representing the text to translate. - /// A string representing the language code of the original text. The code must be present in the list of codes returned from the method. If the parameter is set to null, the language specified in the property will be used. - /// A string array representing the language codes to translate the text into. The code must be present in the list of codes returned from the method. If the parameter is set to null, the language specified in the property will be used. - /// - /// - /// The property hasn't been set. - /// The parameter is null (Nothing in Visual Basic) or empty. - /// - /// - /// - /// - /// The parameter is longer than 1000 characters. - /// The array contains more than 25 elements. - /// - /// - /// The provided isn't valid or has expired. - /// This method perform a non-blocking request for text translation. - /// For more information, go to https://docs.microsoft.com/azure/cognitive-services/translator/reference/v3-0-translate. - /// - /// - /// - /// - Task TranslateWithResponseAsync(string input, string from, IEnumerable to); - - /// - /// Translates a text string into the specified languages. - /// - /// A object containing translated text and information. - /// A string representing the text to translate. - /// A string array representing the language codes to translate the text into. The code must be present in the list of codes returned from the method. If the parameter is set to null, the language specified in the property will be used. - /// - /// - /// The property hasn't been set. - /// The parameter is null (Nothing in Visual Basic) or empty. - /// - /// - /// - /// - /// The parameter is longer than 1000 characters. - /// The array contains more than 25 elements. - /// - /// - /// The provided isn't valid or has expired. - /// This method perform a non-blocking request for text translation. - /// For more information, go to https://docs.microsoft.com/azure/cognitive-services/translator/reference/v3-0-translate. - /// - /// - /// - /// - Task TranslateWithResponseAsync(string input, IEnumerable to); - - /// - /// Translates a list of sentences into the specified languages. - /// - /// A array with one result for each language code in the array. Each object contains translated text and information. - /// A string array containing the sentences to translate. - /// A string array representing the language codes to translate the text into. The code must be present in the list of codes returned from the method. If the parameter is set to null, the language specified in the property will be used. - /// - /// - /// The property hasn't been set. - /// The parameter is null (Nothing in Visual Basic). - /// - /// - /// - /// - /// The parameter is longer than 1000 characters. - /// The array contains more than 25 elements. - /// - /// - /// The provided isn't valid or has expired. - /// This method perform a non-blocking request for text translation. - /// For more information, go to https://docs.microsoft.com/azure/cognitive-services/translator/reference/v3-0-translate. - /// - /// - /// - /// - Task> TranslateWithResponseAsync(IEnumerable input, IEnumerable to = null); - - /// - /// Translates a list of sentences into the specified languages. - /// - /// A array with one result for each language code in the array. Each object contains translated text and information. - /// A string array containing the sentences to translate. - /// A string representing the language code of the original text. The code must be present in the list of codes returned from the method. If the parameter is set to null, the language specified in the property will be used. - /// A string array representing the language codes to translate the text into. The code must be present in the list of codes returned from the method. If the parameter is set to null, the language specified in the property will be used. - /// - /// - /// The property hasn't been set. - /// The parameter is null (Nothing in Visual Basic). - /// - /// - /// - /// - /// The parameter is longer than 1000 characters. - /// The array contains more than 25 elements. - /// - /// - /// The provided isn't valid or has expired. - /// This method perform a non-blocking request for text translation. - /// For more information, go to https://docs.microsoft.com/azure/cognitive-services/translator/reference/v3-0-translate. - /// - /// - /// - /// - Task> TranslateWithResponseAsync(IEnumerable input, string from, IEnumerable to); - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/ServiceLanguage.cs b/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/ServiceLanguage.cs deleted file mode 100644 index abed597f9..000000000 --- a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/ServiceLanguage.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.MicrosoftTranslator -{ - /// - /// Holds information about languages supported for text translation and speech synthesis. - /// - /// - public class ServiceLanguage - { - /// - /// Gets the language code. - /// - public string Code { get; internal set; } - - /// - /// Gets the language friendly name. - /// - public string Name { get; } - - /// - /// Gets the display name of the language in the locale native for this language. - /// - public string NativeName { get; } - - /// - /// Gets the directionality, which is rtl for right-to-left languages or ltr for left-to-right languages. - /// - [JsonPropertyName("dir")] - public string Directionality { get; } - - /// - /// Returns the language friendly name. - /// - /// The language friendly name. - public override string ToString() => Name; - - /// - /// Initializes a new instance of the class. - /// Returns the language friendly name. - /// - /// The language code. - /// The language friendly name. - /// The display name of the language in the locale native for this language. - /// The directionality, which is rtl for right-to-left languages or ltr for left-to-right languages - public ServiceLanguage(string code, string name, string nativeName = null, string directionality = null) - { - Code = code; - Name = name; - NativeName = nativeName ?? name; - Directionality = directionality ?? "ltr"; - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/Translation.cs b/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/Translation.cs deleted file mode 100644 index b8dc3bf22..000000000 --- a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/Translation.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.MicrosoftTranslator -{ - /// - /// Strong type for Translation - /// - /// - public class Translation - { - /// - /// Gets a string giving the translated text. - /// - public string Text { get; } - - /// - /// Gets a string representing the language code of the target language. - /// - public string To { get; } - - /// - /// Initializes a new instance of the class. - /// - /// A string giving the translated text. - /// a string representing the language code of the target language. - public Translation(string text, string to) - { - Text = text; - To = to; - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/TranslationResponse.cs b/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/TranslationResponse.cs deleted file mode 100644 index 8046108bc..000000000 --- a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/TranslationResponse.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; -using System.Linq; - -namespace Microsoft.Toolkit.Services.MicrosoftTranslator -{ - /// - /// Strong type for Translate Response - /// - /// - public class TranslationResponse - { - /// - /// Gets a object describing the detected language. - /// - /// This property has a value only when the method is invoked without the from parameter, so that automatic language detection is applied to determine the source language. - /// - public DetectedLanguageBase DetectedLanguage { get; } - - /// - /// Gets an array of results. - /// - public IEnumerable Translations { get; } - - /// - /// Gets the first translation result. - /// - public Translation Translation => Translations?.FirstOrDefault(); - - /// - /// Initializes a new instance of the class. - /// - /// A object describing the detected language. - /// an array of results. - /// - /// - public TranslationResponse(DetectedLanguageBase detectedLanguage, IEnumerable translations) - { - DetectedLanguage = detectedLanguage; - Translations = translations; - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/TranslatorService.cs b/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/TranslatorService.cs deleted file mode 100644 index aec1fb584..000000000 --- a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/TranslatorService.cs +++ /dev/null @@ -1,261 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text.Json; -using System.Threading.Tasks; - -namespace Microsoft.Toolkit.Services.MicrosoftTranslator -{ - /// - /// The TranslatorService class provides methods to translate text in various supported languages. - /// - /// - /// To use this library, you must register Microsoft Translator on https://portal.azure.com/#create/Microsoft.CognitiveServices/apitype/TextTranslation to obtain the Subscription key. - /// - /// - public class TranslatorService : ITranslatorService - { - private const string BaseUrl = "https://api.cognitive.microsofttranslator.com/"; - private const string ApiVersion = "api-version=3.0"; - private const string AuthorizationUri = "Authorization"; - private const string JsonMediaType = "application/json"; - - private const int _MaxArrayLengthForTranslation = 25; - private const int _MaxTextLengthForTranslation = 5000; - private const int _MaxArrayLengthForDetection = 100; - private const int _MaxTextLengthForDetection = 10000; - - private static HttpClient client = new HttpClient(); - - /// - /// Private singleton field. - /// - private static TranslatorService instance; - - /// - /// Gets public singleton property. - /// - public static TranslatorService Instance => instance ?? (instance = new TranslatorService()); - - private AzureAuthToken _authToken; - private string _authorizationHeaderValue = string.Empty; - - /// - /// Gets a reference to an instance of the underlying data provider. - /// - public object Provider - { - get { throw new NotImplementedException(); } - } - - private TranslatorService() - { - _authToken = new AzureAuthToken(string.Empty); - Language = CultureInfo.CurrentCulture.Name.ToLower(); - } - - /// - public string SubscriptionKey - { - get { return _authToken.SubscriptionKey; } - set { _authToken.SubscriptionKey = value; } - } - - /// - public string Language { get; set; } - - /// - public async Task DetectLanguageAsync(string input) - { - var response = await DetectLanguageWithResponseAsync(input).ConfigureAwait(false); - return response?.Language; - } - - /// - public async Task DetectLanguageWithResponseAsync(string input) - { - var response = await DetectLanguagesWithResponseAsync(new string[] { input }).ConfigureAwait(false); - return response.FirstOrDefault(); - } - - /// - public async Task> DetectLanguagesWithResponseAsync(IEnumerable input) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - if (!input.Any()) - { - throw new ArgumentException($"{nameof(input)} array must contain at least 1 element"); - } - - if (input.Count() > _MaxArrayLengthForDetection) - { - throw new ArgumentException($"{nameof(input)} array can have at most {_MaxArrayLengthForDetection} elements"); - } - - // Checks if it is necessary to obtain/update access token. - await CheckUpdateTokenAsync().ConfigureAwait(false); - - var uriString = $"{BaseUrl}detect?{ApiVersion}"; - using var request = CreateHttpRequest(uriString, HttpMethod.Post, input.Select(t => new { Text = t.Substring(0, Math.Min(t.Length, _MaxTextLengthForDetection)) })); - - var response = await client.SendAsync(request).ConfigureAwait(false); - var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - - var responseContent = JsonSerializer.Deserialize>(content); - return responseContent; - } - - /// - public async Task> GetLanguagesAsync() - { - var languages = await GetLanguageNamesAsync(); - return languages.OrderBy(l => l.Code).Select(l => l.Code).ToList(); - } - - /// - public async Task> GetLanguageNamesAsync(string language = null) - { - // Check if it is necessary to obtain/update access token. - await CheckUpdateTokenAsync().ConfigureAwait(false); - - var uriString = $"{BaseUrl}languages?scope=translation&{ApiVersion}"; - using var request = CreateHttpRequest(uriString); - - language = language ?? Language; - if (!string.IsNullOrWhiteSpace(language)) - { - // If necessary, adds the Accept-Language header in order to get localized language names. - request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(language)); - } - - var response = await client.SendAsync(request).ConfigureAwait(false); - var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - - var jsonContent = JsonDocument.Parse(content).RootElement.GetProperty("translation"); - var responseContent = JsonSerializer.Deserialize>(jsonContent.ToString()).ToList(); - responseContent.ForEach(r => r.Value.Code = r.Key); - - return responseContent.Select(r => r.Value).OrderBy(r => r.Name).ToList(); - } - - /// - public Task TranslateAsync(string input, string to = null) => TranslateAsync(input, null, to ?? Language); - - /// - public async Task TranslateAsync(string input, string from, string to) - { - var response = await TranslateWithResponseAsync(new string[] { input }, from, new string[] { to }).ConfigureAwait(false); - return response.FirstOrDefault()?.Translation.Text; - } - - /// - public Task TranslateWithResponseAsync(string input, string to = null) => TranslateWithResponseAsync(input, null, to ?? Language); - - /// - public async Task TranslateWithResponseAsync(string input, string from, string to) - { - var response = await TranslateWithResponseAsync(new string[] { input }, from, new string[] { to }).ConfigureAwait(false); - return response.FirstOrDefault(); - } - - /// - public Task> TranslateWithResponseAsync(IEnumerable input, string from, string to) => TranslateWithResponseAsync(input, from, new string[] { to }); - - /// - public Task TranslateWithResponseAsync(string input, IEnumerable to) => TranslateWithResponseAsync(input, null, to); - - /// - public async Task TranslateWithResponseAsync(string input, string from, IEnumerable to) - { - var response = await TranslateWithResponseAsync(new string[] { input }, from, to).ConfigureAwait(false); - return response.FirstOrDefault(); - } - - /// - public Task> TranslateWithResponseAsync(IEnumerable input, IEnumerable to = null) => TranslateWithResponseAsync(input, null, to); - - /// - public async Task> TranslateWithResponseAsync(IEnumerable input, string from, IEnumerable to) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - if (input.Count() > _MaxArrayLengthForTranslation) - { - throw new ArgumentException($"{nameof(input)} array can have at most {_MaxArrayLengthForTranslation} elements"); - } - - if (input.Any(str => string.IsNullOrWhiteSpace(str) || str.Length > _MaxTextLengthForTranslation)) - { - throw new ArgumentException($"Each sentence cannot be null and longer than {_MaxTextLengthForTranslation} characters"); - } - - if (to == null || !to.Any()) - { - to = new string[] { Language }; - } - - // Checks if it is necessary to obtain/update access token. - await CheckUpdateTokenAsync().ConfigureAwait(false); - - var toQueryString = string.Join("&", to.Select(t => $"to={t}")); - var uriString = (string.IsNullOrWhiteSpace(from) ? $"{BaseUrl}translate?{toQueryString}" : $"{BaseUrl}translate?from={from}&{toQueryString}") + $"&{ApiVersion}"; - using var request = CreateHttpRequest(uriString, HttpMethod.Post, input.Select(t => new { Text = t })); - - var response = await client.SendAsync(request).ConfigureAwait(false); - var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - - var responseContent = JsonSerializer.Deserialize>(content); - return responseContent; - } - - /// - public Task InitializeAsync() => CheckUpdateTokenAsync(); - - /// - public Task InitializeAsync(string subscriptionKey, string language = null) - { - _authToken = new AzureAuthToken(subscriptionKey); - Language = language ?? CultureInfo.CurrentCulture.Name.ToLower(); - - return InitializeAsync(); - } - - private async Task CheckUpdateTokenAsync() - { - // If necessary, updates the access token. - _authorizationHeaderValue = await _authToken.GetAccessTokenAsync().ConfigureAwait(false); - } - - private HttpRequestMessage CreateHttpRequest(string uriString) - => CreateHttpRequest(uriString, HttpMethod.Get); - - private HttpRequestMessage CreateHttpRequest(string uriString, HttpMethod method, object content = null) - { - var request = new HttpRequestMessage(method, new Uri(uriString)); - request.Headers.Add(AuthorizationUri, _authorizationHeaderValue); - - if (content != null) - { - var jsonRequest = JsonSerializer.Serialize(content); - var requestContent = new StringContent(jsonRequest, System.Text.Encoding.UTF8, JsonMediaType); - request.Content = requestContent; - } - - return request; - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/TranslatorServiceException.cs b/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/TranslatorServiceException.cs deleted file mode 100644 index f16374287..000000000 --- a/Microsoft.Toolkit.Services/Services/MicrosoftTranslator/TranslatorServiceException.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Microsoft.Toolkit.Services.MicrosoftTranslator -{ - /// - /// The TranslatorServiceException class holds information about Exception related to . - /// - /// - public class TranslatorServiceException : Exception - { - /// - /// Initializes a new instance of the class using the specified error message. - /// - /// Message that describes the error - public TranslatorServiceException(string message) - : base(message) - { - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/ITwitterResult.cs b/Microsoft.Toolkit.Services/Services/Twitter/ITwitterResult.cs deleted file mode 100644 index 65fc5d93d..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/ITwitterResult.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Any kind of twitter object. - /// - public interface ITwitterResult - { - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/Tweet.cs b/Microsoft.Toolkit.Services/Services/Twitter/Tweet.cs deleted file mode 100644 index c0dea2d00..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/Tweet.cs +++ /dev/null @@ -1,213 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Globalization; -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Timeline item. - /// - public class Tweet : Toolkit.Parsers.SchemaBase, ITwitterResult - { - private string _text; - - /// - /// Gets or sets time item was created. - /// - [JsonPropertyName("created_at")] - public string CreatedAt { get; set; } - - /// - /// Gets or sets item Id. - /// - [JsonPropertyName("id_str")] - public string Id { get; set; } - - /// - /// Gets or sets text of the tweet (handles both 140 and 280 characters) - /// - [JsonPropertyName("text")] - public string Text - { - get { return _text ?? FullText; } - set { _text = value; } - } - - /// - /// Gets or sets text of the tweet (280 characters). - /// - [JsonPropertyName("full_text")] - private string FullText { get; set; } - - /// - /// Gets or sets display text range (indexes of tweet text without RT and leading user mentions) - /// - [JsonPropertyName("display_text_range")] - public int[] DisplayTextRange { get; set; } - - /// - /// Gets or sets a value indicating whether tweet is truncated - /// (true when tweet is longer than 140 characters) - /// This entity may be deprecated - it never seems to be set to true. - /// - [JsonPropertyName("truncated")] - public bool IsTruncated { get; set; } - - /// - /// Gets or sets attached content of the tweet - /// - [JsonPropertyName("entities")] - public TwitterEntities Entities { get; set; } - - /// - /// Gets or sets extended attached content of the tweet - /// - [JsonPropertyName("extended_entities")] - public TwitterExtendedEntities ExtendedEntities { get; set; } - - /// - /// Gets or sets tweet source (client or website used) - /// - [JsonPropertyName("source")] - public string Source { get; set; } - - /// - /// Gets or sets in_reply_to_screen_name - /// - [JsonPropertyName("in_reply_to_screen_name")] - public string InReplyToScreenName { get; set; } - - /// - /// Gets or sets in_reply_to_status_id_str - /// - [JsonPropertyName("in_reply_to_status_id_str")] - public string InReplyToStatusId { get; set; } - - /// - /// Gets or sets in_reply_to_user_id_str - /// - [JsonPropertyName("in_reply_to_user_id_str")] - public string InReplyToUserId { get; set; } - - /// - /// Gets or sets user who posted the status. - /// - [JsonPropertyName("user")] - public TwitterUser User { get; set; } - - /// - /// Gets or sets geo coordinates (latitude and longitude) returned by Twitter for some locations - /// - [JsonPropertyName("coordinates")] - [JsonConverter(typeof(TwitterCoordinatesConverter))] - public TwitterCoordinates Coordinates { get; set; } - - /// - /// Gets or sets the Place object returned by Twitter for some locations - /// - [JsonPropertyName("place")] - public TwitterPlace Place { get; set; } - - /// - /// Gets or sets the Retweeted Tweet - /// - [JsonPropertyName("retweeted_status")] - public Tweet RetweetedStatus { get; set; } - - /// - /// Gets the creation date - /// - public DateTime CreationDate - { - get - { - DateTime dt; - if (!DateTime.TryParseExact(CreatedAt, "ddd MMM dd HH:mm:ss zzzz yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt)) - { - dt = DateTime.Today; - } - - return dt; - } - } - - /// - /// Gets or sets quoted_status - /// - [JsonPropertyName("quoted_status")] - public Tweet QuotedStatus { get; set; } - - /// - /// Gets or sets quoted_status_id_str - /// - [JsonPropertyName("quoted_status_id_str")] - public string QuotedStatusId { get; set; } - - /// - /// Gets or sets quoted_status_permalink - /// - [JsonPropertyName("quoted_status_permalink")] - public TwitterUrl QuotedStatusPermalink { get; set; } - - /// - /// Gets or sets approximate count of tweets quoting tweet - /// - [JsonPropertyName("quote_count")] - public int QuoteCount { get; set; } - - /// - /// Gets or sets number of replies to tweet - /// - /// - /// Premium and Enterprise API access only - /// - [JsonPropertyName("reply_count")] - public int ReplyCount { get; set; } - - /// - /// Gets or sets number of times tweet has been retweeted - /// - [JsonPropertyName("retweet_count")] - public int RetweetCount { get; set; } - - /// - /// Gets or sets number of times tweet has been liked - /// - [JsonPropertyName("favorite_count")] - public int FavoriteCount { get; set; } - - /// - /// Gets or sets a value indicating whether or not logged-in user has liked tweet - /// - [JsonPropertyName("favorited")] - public bool Favorited { get; set; } - - /// - /// Gets or sets a value indicating whether or not logged-in user has retweeted tweet - /// - [JsonPropertyName("retweeted")] - public bool Retweeted { get; set; } - - /// - /// Gets or sets a value indicating whether URL in tweet has been flagged for sensitive content - /// - [JsonPropertyName("possibly_sensitive")] - public bool Sensitive { get; set; } - - /// - /// Gets or sets stream filter of tweet - /// - [JsonPropertyName("filter_level")] - public string FilterLevel { get; set; } - - /// - /// Gets or sets BCP 47 language identifier of tweet content - /// - [JsonPropertyName("lang")] - public string Language { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TweetParser.cs b/Microsoft.Toolkit.Services/Services/Twitter/TweetParser.cs deleted file mode 100644 index 26a544cb6..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TweetParser.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; -using System.Text.Json; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Timeline Parser. - /// - public class TweetParser : Parsers.IParser - { - /// - /// Parse string data into strongly typed list. - /// - /// Input string. - /// List of strongly typed objects. - public IEnumerable Parse(string data) - { - if (string.IsNullOrEmpty(data)) - { - return null; - } - - return JsonSerializer.Deserialize>(data); - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterCoordinates.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterCoordinates.cs deleted file mode 100644 index 4369619ae..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterCoordinates.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Longitude and Latitude for a tweet - /// - public class TwitterCoordinates - { - /// - /// Gets the numeric latitude (null if the value could not be converted) - /// - public double Latitude { get; internal set; } - - /// - /// Gets the numeric longitude (null if the value could not be converted) - /// - public double Longitude { get; internal set; } - - /// - public override string ToString() - { - return $"({Latitude}, {Longitude})"; - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterCoordinatesConverter.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterCoordinatesConverter.cs deleted file mode 100644 index 3e459a1cf..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterCoordinatesConverter.cs +++ /dev/null @@ -1,115 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - internal class TwitterCoordinatesConverter : JsonConverter - { - private readonly JsonEncodedText latitudeName = JsonEncodedText.Encode("Latitude"); - private readonly JsonEncodedText longitudeName = JsonEncodedText.Encode("Longitude"); - - public override bool CanConvert(Type objectType) - { - return false; - } - - private readonly JsonConverter doubleConverter; - - public TwitterCoordinatesConverter(JsonSerializerOptions options) - { - doubleConverter = options?.GetConverter(typeof(double)) as JsonConverter ?? throw new InvalidOperationException(); - } - - public override TwitterCoordinates Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - try - { - if (reader.TokenType != JsonTokenType.StartObject) - { - return null; - } - - double latitude = default; - bool latitudeSet = false; - - double longitude = default; - bool longitudeSet = false; - - // Get the first property. - reader.Read(); - if (reader.TokenType != JsonTokenType.PropertyName) - { - throw new JsonException(); - } - - if (reader.ValueTextEquals(latitudeName.EncodedUtf8Bytes)) - { - latitude = ReadProperty(ref reader, options); - latitudeSet = true; - } - else if (reader.ValueTextEquals(longitudeName.EncodedUtf8Bytes)) - { - longitude = ReadProperty(ref reader, options); - longitudeSet = true; - } - else - { - throw new JsonException(); - } - - // Get the second property. - reader.Read(); - if (reader.TokenType != JsonTokenType.PropertyName) - { - throw new JsonException(); - } - - if (latitudeSet && reader.ValueTextEquals(longitudeName.EncodedUtf8Bytes)) - { - longitude = ReadProperty(ref reader, options); - } - else if (longitudeSet && reader.ValueTextEquals(latitudeName.EncodedUtf8Bytes)) - { - latitude = ReadProperty(ref reader, options); - } - else - { - throw new JsonException(); - } - - reader.Read(); - - if (reader.TokenType != JsonTokenType.EndObject) - { - throw new JsonException(); - } - - return new TwitterCoordinates - { - Latitude = latitude, - Longitude = longitude - }; - } - catch - { - return null; - } - } - - private double ReadProperty(ref Utf8JsonReader reader, JsonSerializerOptions options) - { - reader.Read(); - return doubleConverter.Read(ref reader, typeof(double), options); - } - - public override void Write(Utf8JsonWriter writer, TwitterCoordinates value, JsonSerializerOptions options) - { - throw new NotImplementedException(); - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterDataConfig.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterDataConfig.cs deleted file mode 100644 index 96735e3d2..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterDataConfig.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Query string configuration. - /// - public class TwitterDataConfig - { - /// - /// Gets or sets twitter query type. - /// - public TwitterQueryType QueryType { get; set; } - - /// - /// Gets or sets query parameters. - /// - public string Query { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterDataProvider.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterDataProvider.cs deleted file mode 100644 index 3ba3d3627..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterDataProvider.cs +++ /dev/null @@ -1,705 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text.Json; -using System.Threading.Tasks; -using Microsoft.Toolkit.Services.Core; - -#if WINRT -using System.Runtime.InteropServices.WindowsRuntime; -using Microsoft.Toolkit.Services.PlatformSpecific.Uwp; -using Windows.Storage.Streams; -#endif - -#if NET462 -using Microsoft.Toolkit.Services.PlatformSpecific.NetFramework; -#endif - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Data Provider for connecting to Twitter service. - /// - public class TwitterDataProvider : Toolkit.Services.DataProviderBase - { - /// - /// Base Url for service. - /// - private const string BaseUrl = "https://api.twitter.com/1.1"; - private const string OAuthBaseUrl = "https://api.twitter.com/oauth"; - private const string PublishUrl = "https://upload.twitter.com/1.1"; - private const string UserStreamUrl = "https://userstream.twitter.com/1.1"; - - private static HttpClient _client; - - /// - /// Base Url for service. - /// - private readonly TwitterOAuthTokens _tokens; - private readonly IAuthenticationBroker _authenticationBroker; - private readonly IPasswordManager _passwordManager; - private readonly IStorageManager _storageManager; - private readonly ISignatureManager _signatureManager; - private TwitterOAuthRequest _streamRequest; - - /// - /// Gets or sets logged in user information. - /// - public string UserScreenName { get; set; } - - /// - /// Gets a value indicating whether the provider is already logged in - /// - public bool LoggedIn { get; private set; } - - /// - /// Initializes a new instance of the class. - /// Constructor. - /// - /// OAuth tokens for request. - /// Authentication result interface. - /// Platform password manager - /// Platform storage provider - /// Platform signature manager - public TwitterDataProvider(TwitterOAuthTokens tokens, IAuthenticationBroker authenticationBroker, IPasswordManager passwordManager, IStorageManager storageManager, ISignatureManager signatureManager) - { - if (string.IsNullOrEmpty(tokens.ConsumerSecret)) - { - throw new ArgumentException("Missing consumer secret"); - } - - if (string.IsNullOrEmpty(tokens.ConsumerKey)) - { - throw new ArgumentException("Missing consumer key"); - } - - if (string.IsNullOrEmpty(tokens.CallbackUri)) - { - throw new ArgumentException("Missing callback uri"); - } - - _tokens = tokens; - _authenticationBroker = authenticationBroker ?? throw new ArgumentException("Missing AuthenticationBroker"); - _passwordManager = passwordManager ?? throw new ArgumentException("Missing PasswordManager"); - _storageManager = storageManager ?? throw new ArgumentException("Missing StorageManager"); - _signatureManager = signatureManager ?? throw new ArgumentException("Missing SignatureManager"); - - if (_client == null) - { - HttpClientHandler handler = new HttpClientHandler(); - handler.AutomaticDecompression = DecompressionMethods.GZip; - _client = new HttpClient(handler); - } - } - -#if WINRT - /// - /// Initializes a new instance of the class. - /// Constructor. - /// - /// OAuth tokens for request. - public TwitterDataProvider(TwitterOAuthTokens tokens) - : this(tokens, new UwpAuthenticationBroker(), new UwpPasswordManager(), new UwpStorageManager(), new UwpSignatureManager()) - { - } -#endif - -#if NET462 - /// - /// Initializes a new instance of the class. - /// Constructor. - /// - /// OAuth tokens for request. - public TwitterDataProvider(TwitterOAuthTokens tokens) - : this(tokens, new NetFrameworkAuthenticationBroker(), new NetFrameworkPasswordManager(), new NetFrameworkStorageManager(), new NetFrameworkSignatureManager()) - { - } -#endif - - /// - /// Retrieve user data. - /// - /// User screen name or null for current logged user - /// Returns user data. - public async Task GetUserAsync(string screenName = null) - { - string rawResult = null; - try - { - var userScreenName = screenName ?? UserScreenName; - var uri = new Uri($"{BaseUrl}/users/show.json?screen_name={userScreenName}"); - - TwitterOAuthRequest request = new TwitterOAuthRequest(); - rawResult = await request.ExecuteGetAsync(uri, _tokens, _signatureManager); - return JsonSerializer.Deserialize(rawResult); - } - catch (UserNotFoundException) - { - throw new UserNotFoundException(screenName); - } - catch - { - if (!string.IsNullOrEmpty(rawResult)) - { - var errors = JsonSerializer.Deserialize(rawResult); - - throw new TwitterException { Errors = errors }; - } - - throw; - } - } - - /// - /// Retrieve user timeline data with specific parser. - /// - /// Strong type for results. - /// User screen name. - /// Upper record limit. - /// Specific results parser. - /// Returns strongly typed list of results. - public async Task> GetUserTimeLineAsync(string screenName, int maxRecords, Toolkit.Parsers.IParser parser) - where TSchema : Toolkit.Parsers.SchemaBase - { - string rawResult = null; - try - { - var uri = new Uri($"{BaseUrl}/statuses/user_timeline.json?screen_name={screenName}&count={maxRecords}&include_rts=1&tweet_mode=extended"); - - TwitterOAuthRequest request = new TwitterOAuthRequest(); - rawResult = await request.ExecuteGetAsync(uri, _tokens, _signatureManager); - - var result = parser.Parse(rawResult); - return result - .Take(maxRecords) - .ToList(); - } - catch (UserNotFoundException) - { - throw new UserNotFoundException(screenName); - } - catch - { - if (!string.IsNullOrEmpty(rawResult)) - { - var errors = JsonSerializer.Deserialize(rawResult); - - throw new TwitterException { Errors = errors }; - } - - throw; - } - } - - /// - /// Search for specific hash tag with specific parser. - /// - /// Strong type for results. - /// Hash tag. - /// Upper record limit. - /// Specific results parser. - /// Returns strongly typed list of results. - public async Task> SearchAsync(string hashTag, int maxRecords, Toolkit.Parsers.IParser parser) - where TSchema : Toolkit.Parsers.SchemaBase - { - var uri = new Uri($"{BaseUrl}/search/tweets.json?q={Uri.EscapeDataString(hashTag)}&count={maxRecords}&tweet_mode=extended"); - TwitterOAuthRequest request = new TwitterOAuthRequest(); - var rawResult = await request.ExecuteGetAsync(uri, _tokens, _signatureManager); - - var result = parser.Parse(rawResult); - return result - .Take(maxRecords) - .ToList(); - } - - /// - /// Log user in to Twitter. - /// - /// Boolean indicating login success. - public async Task LoginAsync() - { - var credentials = _passwordManager.Get("TwitterAccessToken"); - var user = await _storageManager.GetAsync("TwitterScreenName"); - if (!string.IsNullOrEmpty(user) && credentials != null) - { - _tokens.AccessToken = credentials.UserName; - _tokens.AccessTokenSecret = credentials.Password; - UserScreenName = user; - LoggedIn = true; - return true; - } - - if (await InitializeRequestAccessTokensAsync(_tokens.CallbackUri) == false) - { - LoggedIn = false; - return false; - } - - string requestToken = _tokens.RequestToken; - string twitterUrl = $"{OAuthBaseUrl}/authorize?oauth_token={requestToken}"; - - Uri startUri = new Uri(twitterUrl); - Uri endUri = new Uri(_tokens.CallbackUri); - - var result = await _authenticationBroker.Authenticate(startUri, endUri); - - switch (result.ResponseStatus) - { - case AuthenticationResultStatus.Success: - LoggedIn = true; - return await ExchangeRequestTokenForAccessTokenAsync(result.ResponseData); - - case AuthenticationResultStatus.ErrorHttp: - Debug.WriteLine("WAB failed, message={0}", result.ResponseErrorDetail.ToString()); - LoggedIn = false; - return false; - - case AuthenticationResultStatus.UserCancel: - Debug.WriteLine("WAB user aborted."); - LoggedIn = false; - return false; - } - - LoggedIn = false; - return false; - } - - /// - /// Log user out of Twitter. - /// - /// A representing the asynchronous operation. - public async Task LogoutAsync() - { - var credential = _passwordManager.Get("TwitterAccessToken"); - - if (credential != null) - { - _passwordManager.Remove("TwitterAccessToken"); - await _storageManager.SetAsync("TwitterScreenName", null); - } - - UserScreenName = null; - LoggedIn = false; - } - - /// - /// Tweets a status update. - /// - /// Tweet text. - /// Pictures to attach to the tweet (up to 4). - /// Success or failure. - public async Task TweetStatusAsync(string tweet, params Stream[] pictures) - { - return await TweetStatusAsync(new TwitterStatus { Message = tweet }, pictures); - } - - /// - /// Tweets a status update. - /// - /// Tweet text. - /// Pictures to attach to the tweet (up to 4). - /// Success or failure. - public async Task TweetStatusAsync(TwitterStatus status, params Stream[] pictures) - { - var mediaIds = string.Empty; - - if (pictures != null && pictures.Length > 0) - { - var ids = new List(); - foreach (var picture in pictures) - { - ids.Add(await UploadPictureAsync(picture)); - } - - mediaIds = "&media_ids=" + string.Join(",", ids); - } - - var uri = new Uri($"{BaseUrl}/statuses/update.json?{status.RequestParameters}{mediaIds}"); - - TwitterOAuthRequest request = new TwitterOAuthRequest(); - await request.ExecutePostAsync(uri, _tokens, _signatureManager); - - return true; - } - - /// - /// Publish a picture to Twitter user's medias. - /// - /// Picture stream. - /// Media ID - public async Task UploadPictureAsync(Stream stream) - { - var uri = new Uri($"{PublishUrl}/media/upload.json"); - - byte[] fileBytes; - - using (var ms = new MemoryStream()) - { - await stream.CopyToAsync(ms); - fileBytes = ms.ToArray(); - } - - string boundary = DateTime.Now.Ticks.ToString("x"); - - TwitterOAuthRequest request = new TwitterOAuthRequest(); - return await request.ExecutePostMultipartAsync(uri, _tokens, boundary, fileBytes, _signatureManager); - } - - /// - /// Open a connection to user streams service (Events, DirectMessages...). - /// - /// Specific stream's result parser. - /// Method invoked each time a result occurs. - /// Awaitable task. - public Task StartUserStreamAsync(TwitterUserStreamParser parser, TwitterStreamCallbacks.TwitterStreamCallback callback) - { - var uri = new Uri($"{UserStreamUrl}/user.json?replies=all"); - - _streamRequest = new TwitterOAuthRequest(); - - return _streamRequest.ExecuteGetStreamAsync(uri, _tokens, rawResult => callback(parser.Parse(rawResult)), _signatureManager); - } - - /// - /// Stop user's stream - /// - public void StopStream() - { - _streamRequest?.Abort(); - _streamRequest = null; - } - - /// - /// Returns parser implementation for specified configuration. - /// - /// Query configuration. - /// Strongly typed parser. - protected override Toolkit.Parsers.IParser GetDefaultParser(TwitterDataConfig config) - { - if (config == null) - { - throw new ConfigNullException(); - } - - switch (config.QueryType) - { - case TwitterQueryType.Search: - return new TwitterSearchParser(); - - case TwitterQueryType.Home: - case TwitterQueryType.User: - case TwitterQueryType.Custom: - return new TwitterParser(); - - default: - return new TwitterParser(); - } - } - - /// - /// Wrapper around REST API for making data request. - /// - /// Schema to use - /// Query configuration. - /// Upper limit for records returned. - /// The zero-based index of the page that corresponds to the items to retrieve. - /// IParser implementation for interpreting results. - /// Strongly typed list of results. - protected override async Task> GetDataAsync(TwitterDataConfig config, int maxRecords, int pageIndex, Toolkit.Parsers.IParser parser) - { - IEnumerable items; - switch (config.QueryType) - { - case TwitterQueryType.User: - items = await GetUserTimeLineAsync(config.Query, maxRecords, parser); - break; - - case TwitterQueryType.Search: - items = await SearchAsync(config.Query, maxRecords, parser); - break; - - case TwitterQueryType.Custom: - items = await GetCustomSearch(config.Query, parser); - break; - - case TwitterQueryType.Home: - default: - items = await GetHomeTimeLineAsync(maxRecords, parser); - break; - } - - return items; - } - - /// - /// Check validity of configuration. - /// - /// Query configuration. - protected override void ValidateConfig(TwitterDataConfig config) - { - if (config?.Query == null && config?.QueryType != TwitterQueryType.Home) - { - throw new ConfigParameterNullException(nameof(config.Query)); - } - - if (_tokens == null) - { - throw new ConfigParameterNullException(nameof(_tokens)); - } - - if (string.IsNullOrEmpty(_tokens.ConsumerKey)) - { - throw new OAuthKeysNotPresentException(nameof(_tokens.ConsumerKey)); - } - - if (string.IsNullOrEmpty(_tokens.ConsumerSecret)) - { - throw new OAuthKeysNotPresentException(nameof(_tokens.ConsumerSecret)); - } - } - - /// - /// Extract requested token from the REST API response string. - /// - /// REST API response string. - /// Token type to retrieve. - /// Required token. - private static string ExtractTokenFromResponse(string getResponse, TwitterOAuthTokenType tokenType) - { - string requestOrAccessToken = null; - string requestOrAccessTokenSecret = null; - string oauthVerifier = null; - string oauthCallbackConfirmed = null; - string screenName = null; - string[] keyValPairs = getResponse.Split('&'); - - for (int i = 0; i < keyValPairs.Length; i++) - { - string[] splits = keyValPairs[i].Split('='); - switch (splits[0]) - { - case "screen_name": - screenName = splits[1]; - break; - - case "oauth_token": - requestOrAccessToken = splits[1]; - break; - - case "oauth_token_secret": - requestOrAccessTokenSecret = splits[1]; - break; - - case "oauth_callback_confirmed": - oauthCallbackConfirmed = splits[1]; - break; - - case "oauth_verifier": - oauthVerifier = splits[1]; - break; - } - } - - switch (tokenType) - { - case TwitterOAuthTokenType.OAuthRequestOrAccessToken: - return requestOrAccessToken; - - case TwitterOAuthTokenType.OAuthRequestOrAccessTokenSecret: - return requestOrAccessTokenSecret; - - case TwitterOAuthTokenType.OAuthVerifier: - return oauthVerifier; - - case TwitterOAuthTokenType.ScreenName: - return screenName; - - case TwitterOAuthTokenType.OAuthCallbackConfirmed: - return oauthCallbackConfirmed; - } - - return string.Empty; - } - - /// - /// Get home time line data. - /// - /// Strong typed result. - /// Upper record limit. - /// Specific result parser. - /// Return strong typed list of results. - private async Task> GetHomeTimeLineAsync(int maxRecords, Toolkit.Parsers.IParser parser) - where TSchema : Toolkit.Parsers.SchemaBase - { - var uri = new Uri($"{BaseUrl}/statuses/home_timeline.json?count={maxRecords}&tweet_mode=extended"); - - TwitterOAuthRequest request = new TwitterOAuthRequest(); - var rawResult = await request.ExecuteGetAsync(uri, _tokens, _signatureManager); - - return parser.Parse(rawResult); - } - - private async Task> GetCustomSearch(string query, Toolkit.Parsers.IParser parser) - where TSchema : Toolkit.Parsers.SchemaBase - { - var uri = new Uri($"{BaseUrl}/{query}"); - - TwitterOAuthRequest request = new TwitterOAuthRequest(); - - var rawResult = await request.ExecuteGetAsync(uri, _tokens, _signatureManager); - - return parser.Parse(rawResult); - } - - /// - /// Package up token request. - /// - /// Callback Uri. - /// Success or failure. - private async Task InitializeRequestAccessTokensAsync(string twitterCallbackUrl) - { - var twitterUrl = $"{OAuthBaseUrl}/request_token"; - - string nonce = GetNonce(); - string timeStamp = GetTimeStamp(); - string sigBaseStringParams = GetSignatureBaseStringParams(_tokens.ConsumerKey, nonce, timeStamp, "oauth_callback=" + Uri.EscapeDataString(twitterCallbackUrl)); - string sigBaseString = "GET&" + Uri.EscapeDataString(twitterUrl) + "&" + Uri.EscapeDataString(sigBaseStringParams); - string signature = _signatureManager.GetSignature(sigBaseString, _tokens.ConsumerSecret, true); - - twitterUrl += "?" + sigBaseStringParams + "&oauth_signature=" + Uri.EscapeDataString(signature); - - string getResponse; - - using (var request = new HttpRequestMessage(HttpMethod.Get, new Uri(twitterUrl))) - { - using var response = await _client.SendAsync(request).ConfigureAwait(false); - var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - if (response.IsSuccessStatusCode) - { - getResponse = data; - } - else - { - Debug.WriteLine("HttpHelper call failed trying to retrieve Twitter Request Tokens. Message: {0}", data); - return false; - } - } - - var callbackConfirmed = ExtractTokenFromResponse(getResponse, TwitterOAuthTokenType.OAuthCallbackConfirmed); - if (Convert.ToBoolean(callbackConfirmed) != true) - { - return false; - } - - _tokens.RequestToken = ExtractTokenFromResponse(getResponse, TwitterOAuthTokenType.OAuthRequestOrAccessToken); - _tokens.RequestTokenSecret = ExtractTokenFromResponse(getResponse, TwitterOAuthTokenType.OAuthRequestOrAccessTokenSecret); - - return true; - } - - /// - /// Build signature base string. - /// - /// Consumer Key. - /// Nonce. - /// Timestamp. - /// Any additional parameter name/values that need appending to base string. - /// Signature base string. - private string GetSignatureBaseStringParams(string consumerKey, string nonce, string timeStamp, string additionalParameters = "") - { - string sigBaseStringParams = additionalParameters; - sigBaseStringParams += "&" + "oauth_consumer_key=" + consumerKey; - sigBaseStringParams += "&" + "oauth_nonce=" + nonce; - sigBaseStringParams += "&" + "oauth_signature_method=HMAC-SHA1"; - sigBaseStringParams += "&" + "oauth_timestamp=" + timeStamp; - sigBaseStringParams += "&" + "oauth_version=1.0"; - - return sigBaseStringParams; - } - - /// - /// Extract and initialize access tokens. - /// - /// WAB data containing appropriate tokens. - /// Success or failure. - private async Task ExchangeRequestTokenForAccessTokenAsync(string webAuthResultResponseData) - { - string responseData = webAuthResultResponseData.Substring(webAuthResultResponseData.IndexOf("oauth_token")); - string requestToken = ExtractTokenFromResponse(responseData, TwitterOAuthTokenType.OAuthRequestOrAccessToken); - - // Ensure requestToken matches accessToken per Twitter documentation. - if (requestToken != _tokens.RequestToken) - { - return false; - } - - string oAuthVerifier = ExtractTokenFromResponse(responseData, TwitterOAuthTokenType.OAuthVerifier); - - string twitterUrl = $"{OAuthBaseUrl}/access_token"; - - string timeStamp = GetTimeStamp(); - string nonce = GetNonce(); - - string sigBaseStringParams = GetSignatureBaseStringParams(_tokens.ConsumerKey, nonce, timeStamp, "oauth_token=" + requestToken); - - string sigBaseString = "POST&"; - sigBaseString += Uri.EscapeDataString(twitterUrl) + "&" + Uri.EscapeDataString(sigBaseStringParams); - - string signature = _signatureManager.GetSignature(sigBaseString, _tokens.ConsumerSecret); - string data = null; - - string authorizationHeaderParams = "oauth_consumer_key=\"" + _tokens.ConsumerKey + "\", oauth_nonce=\"" + nonce + "\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"" + Uri.EscapeDataString(signature) + "\", oauth_timestamp=\"" + timeStamp + "\", oauth_token=\"" + Uri.EscapeDataString(requestToken) + "\", oauth_verifier=\"" + Uri.EscapeUriString(oAuthVerifier) + "\" , oauth_version=\"1.0\""; - - using (var request = new HttpRequestMessage(HttpMethod.Post, new Uri(twitterUrl))) - { - request.Headers.Authorization = new AuthenticationHeaderValue("OAuth", authorizationHeaderParams); - - using var response = await _client.SendAsync(request).ConfigureAwait(false); - data = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - } - - var screenName = ExtractTokenFromResponse(data, TwitterOAuthTokenType.ScreenName); - var accessToken = ExtractTokenFromResponse(data, TwitterOAuthTokenType.OAuthRequestOrAccessToken); - var accessTokenSecret = ExtractTokenFromResponse(data, TwitterOAuthTokenType.OAuthRequestOrAccessTokenSecret); - - UserScreenName = screenName; - _tokens.AccessToken = accessToken; - _tokens.AccessTokenSecret = accessTokenSecret; - - _passwordManager.Store("TwitterAccessToken", new PasswordCredential { UserName = accessToken, Password = accessTokenSecret }); - await _storageManager.SetAsync("TwitterScreenName", screenName); - - return true; - } - - /// - /// Generate nonce. - /// - /// Nonce. - private string GetNonce() - { - Random rand = new Random(); - int nonce = rand.Next(1000000000); - return nonce.ToString(); - } - - /// - /// Generate timestamp. - /// - /// Timestamp. - private string GetTimeStamp() - { - TimeSpan sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1); - return Math.Round(sinceEpoch.TotalSeconds).ToString(); - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterDirectMessage.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterDirectMessage.cs deleted file mode 100644 index 803c9b740..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterDirectMessage.cs +++ /dev/null @@ -1,103 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Globalization; -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter User type. - /// - public class TwitterDirectMessage : ITwitterResult - { - /// - /// Gets or sets the direct message id. - /// - /// The direct message id. - [JsonPropertyName("id")] - public decimal Id { get; set; } - - /// - /// Gets or sets the sender id. - /// - /// The sender id. - [JsonPropertyName("sender_id")] - public decimal SenderId { get; set; } - - /// - /// Gets or sets the direct message text. - /// - /// The direct message text. - [JsonPropertyName("text")] - public string Text { get; set; } - - /// - /// Gets or sets the recipient id. - /// - /// The recipient id. - [JsonPropertyName("recipient_id")] - public decimal RecipientId { get; set; } - - /// - /// Gets or sets the created date. - /// - /// The created date. - [JsonPropertyName("created_at")] - public string CreatedAt { get; set; } - - /// - /// Gets or sets the name of the sender screen. - /// - /// The name of the sender screen. - [JsonPropertyName("sender_screen_name")] - public string SenderScreenName { get; set; } - - /// - /// Gets or sets the name of the recipient screen. - /// - /// The name of the recipient screen. - [JsonPropertyName("recipient_screen_name")] - public string RecipientScreenName { get; set; } - - /// - /// Gets or sets the sender. - /// - /// The sender. - [JsonPropertyName("sender")] - public TwitterUser Sender { get; set; } - - /// - /// Gets or sets the recipient. - /// - /// The recipient. - [JsonPropertyName("recipient")] - public TwitterUser Recipient { get; set; } - - /// - /// Gets or sets the entities. - /// - /// The entities. - [JsonPropertyName("entities")] - public TwitterEntities Entities { get; set; } - - /// - /// Gets the creation date - /// - public DateTime CreationDate - { - get - { - DateTime dt; - if (!DateTime.TryParseExact(CreatedAt, "ddd MMM dd HH:mm:ss zzzz yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt)) - { - dt = DateTime.Today; - } - - return dt; - } - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterEntities.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterEntities.cs deleted file mode 100644 index d4e76c90a..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterEntities.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Entities containing Twitter entities object tweet - /// - public class TwitterEntities - { - /// - /// Gets or sets Hashtags array of the tweet. - /// This array will be empty if no Hashtags are present. - /// - [JsonPropertyName("Hashtags")] - public TwitterHashtag[] Hashtags { get; set; } - - /// - /// Gets or sets Symbols array of the tweet. - /// This array will be empty if no Symbols are present. - /// - [JsonPropertyName("Symbols")] - public TwitterSymbol[] Symbols { get; set; } - - /// - /// Gets or sets Media array of the tweet. - /// This array will not exist if no media is present. - /// - [JsonPropertyName("media")] - public TwitterMedia[] Media { get; set; } - - /// - /// Gets or sets Urls array of the tweet. - /// This array will be empty if no Urls are present. - /// - [JsonPropertyName("urls")] - public TwitterUrl[] Urls { get; set; } - - /// - /// Gets or sets array of usernames mentioned in the tweet. - /// This array will be empty if no usernames are mentioned. - /// - [JsonPropertyName("user_mentions")] - public TwitterUserMention[] UserMentions { get; set; } - - /// - /// Gets or sets the poll in a tweet. - /// This array will not exist if no poll is present. - /// This array will always have one poll. - /// - [JsonPropertyName("polls")] - public TwitterPoll Poll { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterError.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterError.cs deleted file mode 100644 index 3df83ff3c..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterError.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter error type - /// - public class TwitterError - { - /// - /// Gets or sets error code - /// - [JsonPropertyName("code")] - public int Code { get; set; } - - /// - /// Gets or sets error message - /// - [JsonPropertyName("message")] - public string Message { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterErrors.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterErrors.cs deleted file mode 100644 index 801c7485b..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterErrors.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter errors type. - /// - public class TwitterErrors - { - /// - /// Gets or sets the list of errors - /// - [JsonPropertyName("errors")] - public TwitterError[] Errors { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterException.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterException.cs deleted file mode 100644 index c4cf269cf..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterException.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter specific exception. - /// - public class TwitterException : Exception - { - /// - /// Gets or sets the errors returned by Twitter - /// - public TwitterErrors Errors { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterExtended.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterExtended.cs deleted file mode 100644 index d9cca155f..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterExtended.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter User type. - /// - public class TwitterExtended - { - /// - /// Gets or sets the text of the tweet (280 characters). - /// - [JsonPropertyName("full_text")] - public string FullText { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterExtendedEntities.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterExtendedEntities.cs deleted file mode 100644 index 6f4ae88d5..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterExtendedEntities.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Extended Entities containing an array of TwitterMedia. - /// - public class TwitterExtendedEntities - { - /// - /// Gets or sets Media of the tweet. - /// - [JsonPropertyName("media")] - public TwitterMedia[] Media { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterGeoData.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterGeoData.cs deleted file mode 100644 index 977090f6f..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterGeoData.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Globalization; -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// A class to contain the latitude and longitude of a tweet. - /// - public class TwitterGeoData - { - private const int LatitudeIndex = 0; - private const int LongitudeIndex = 1; - private const string PointType = "Point"; - - /// - /// Gets or sets the type of data - /// - [JsonPropertyName("type")] - public string DataType { get; set; } - - /// - /// Gets the latitude and longitude in a coordinate format. - /// - public string DisplayCoordinates - { - get - { - string result = null; - - if (Coordinates != null) - { - result = $"({Coordinates[LatitudeIndex]}, {Coordinates[LongitudeIndex]})"; - } - - return result; - } - } - - /// - /// Gets or sets the coordinates of the geographic data - /// - [JsonPropertyName("coordinates")] - public string[] Coordinates { get; set; } - - /// - /// Gets the numeric latitude (null if the value could not be converted) - /// - public double? Latitude - { - get - { - return ParseCoordinate(LatitudeIndex); - } - } - - /// - /// Gets the numeric longitude (null if the value could not be converted) - /// - public double? Longitude - { - get - { - return ParseCoordinate(LongitudeIndex); - } - } - - private double? ParseCoordinate(int index) - { - double? result = null; - double parsed; - - if (DataType == PointType - && Coordinates != null - && !string.IsNullOrEmpty(Coordinates[index]) - && double.TryParse(Coordinates[index], NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out parsed)) - { - result = parsed; - } - - return result; - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterHashtag.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterHashtag.cs deleted file mode 100644 index d5350ede0..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterHashtag.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Hashtag object containing all hashtags in a tweet. - /// - public class TwitterHashtag - { - /// - /// Gets or sets indices of hashtag location in tweet string. - /// - [JsonPropertyName("indices")] - public int[] Indices { get; set; } - - /// - /// Gets or sets hashtag text, excluding #. - /// - [JsonPropertyName("text")] - public string Text { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterMedia.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterMedia.cs deleted file mode 100644 index 2ebe86dac..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterMedia.cs +++ /dev/null @@ -1,86 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Media - /// - public class TwitterMedia - { - /// - /// Gets or sets ID as string. - /// - [JsonPropertyName("id_str")] - public string Id { get; set; } - - /// - /// Gets or sets indices array. - /// - [JsonPropertyName("indices")] - public int[] Indices { get; set; } - - /// - /// Gets or sets MediaUrl (direct link to image). - /// - [JsonPropertyName("media_url")] - public string MediaUrl { get; set; } - - /// - /// Gets or sets HTTPS MediaUrl. - /// - [JsonPropertyName("media_url_https")] - public string MediaUrlHttps { get; set; } - - /// - /// Gets or sets t.co shortened tweet Url. - /// - [JsonPropertyName("url")] - public string Url { get; set; } - - /// - /// Gets or sets DisplayUrl (pics.twitter.com Url). - /// - [JsonPropertyName("display_url")] - public string DisplayUrl { get; set; } - - /// - /// Gets or sets DisplayUrl (pics.twitter.com Url). - /// - [JsonPropertyName("expanded_url")] - public string ExpandedUrl { get; set; } - - /// - /// Gets or sets MediaType - photo, animated_gif, or video - /// - [JsonPropertyName("type")] - public string MediaType { get; set; } - - /// - /// Gets or sets size array - /// - [JsonPropertyName("sizes")] - public TwitterMediaSizes Sizes { get; set; } - - /// - /// Gets or sets the SourceId - tweet ID of media's original tweet - /// - [JsonPropertyName("source_status_id_str")] - public string SourceIdStr { get; set; } - - /// - /// Gets or sets metadata for video attached to tweet - /// - [JsonPropertyName("video_info")] - public TwitterMediaVideoInfo VideoInfo { get; set; } - - /// - /// Gets or sets extended metadata for video attached to tweet. - /// - [JsonPropertyName("additional_media_info")] - public TwitterMediaAdditionalInfo AdditionalMediaInfo { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaAdditionalInfo.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaAdditionalInfo.cs deleted file mode 100644 index 4ded7817d..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaAdditionalInfo.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Media Info - /// - public class TwitterMediaAdditionalInfo - { - /// - /// Gets or sets title of video - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// Gets or sets description of video - /// - [JsonPropertyName("description")] - public string Description { get; set; } - - /// - /// Gets or sets a value indicating whether video is embeddable - /// - [JsonPropertyName("embeddable")] - public bool Embeddable { get; set; } - - /// - /// Gets or sets a value indicating whether "monetizable" - /// - [JsonPropertyName("monetizable")] - public bool Monetizable { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaSizeData.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaSizeData.cs deleted file mode 100644 index 7c787eb4a..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaSizeData.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Entities containing size details for each size of an image. - /// - public class TwitterMediaSizeData - { - /// - /// Gets or sets width integer. - /// - [JsonPropertyName("w")] - public int Width { get; set; } - - /// - /// Gets or sets height integer. - /// - [JsonPropertyName("h")] - public int Height { get; set; } - - /// - /// Gets or sets resize string. - /// - [JsonPropertyName("resize")] - public string Resize { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaSizes.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaSizes.cs deleted file mode 100644 index dbffbf70c..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaSizes.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Media Sizes containing size data for different image sizes. - /// - public class TwitterMediaSizes - { - /// - /// Gets or sets small metadata. - /// - [JsonPropertyName("small")] - public TwitterMediaSizeData Small { get; set; } - - /// - /// Gets or sets thumbnail metadata. - /// - [JsonPropertyName("thumb")] - public TwitterMediaSizeData Thumb { get; set; } - - /// - /// Gets or sets large metadata. - /// - [JsonPropertyName("large")] - public TwitterMediaSizeData Large { get; set; } - - /// - /// Gets or sets medium metadata. - /// - [JsonPropertyName("medium")] - public TwitterMediaSizeData Medium { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaVideoInfo.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaVideoInfo.cs deleted file mode 100644 index 889049023..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaVideoInfo.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Video information - /// - public class TwitterMediaVideoInfo - { - /// - /// Gets or sets video aspect ratio (width, height) - /// - [JsonPropertyName("aspect_ratio")] - public int[] AspectRatio { get; set; } - - /// - /// Gets or sets duration of video in milliseconds - /// - [JsonPropertyName("duration_millis")] - public int Duration { get; set; } - - /// - /// Gets or sets video variants for different codecs, bitrates, etc. - /// - [JsonPropertyName("variants")] - public TwitterMediaVideoVariants[] Variants { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaVideoVariants.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaVideoVariants.cs deleted file mode 100644 index 38301583b..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterMediaVideoVariants.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Video properties - /// - public class TwitterMediaVideoVariants - { - /// - /// Gets or sets video bitrate in bits-per-second - /// - [JsonPropertyName("bitrate")] - public int Bitrate { get; set; } - - /// - /// Gets or sets the MIME type of the video - /// - [JsonPropertyName("content_type")] - public string ContentType { get; set; } - - /// - /// Gets or sets the direct URL for the video variant - /// - [JsonPropertyName("url")] - public string Url { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthRequest.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthRequest.cs deleted file mode 100644 index 303cee3de..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthRequest.cs +++ /dev/null @@ -1,168 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.IO; -using System.IO.Compression; -using System.Net; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text.Json; -using System.Threading.Tasks; -using Microsoft.Toolkit.Services.Core; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// OAuth request. - /// - internal class TwitterOAuthRequest - { - private static HttpClient client; - - private bool _abort; - - /// - /// Initializes a new instance of the class. - /// - public TwitterOAuthRequest() - { - if (client == null) - { - HttpClientHandler handler = new HttpClientHandler(); - handler.AutomaticDecompression = DecompressionMethods.GZip; - client = new HttpClient(handler); - } - } - - /// - /// HTTP Get request to specified Uri. - /// - /// Uri to make OAuth request. - /// Tokens to pass in request. - /// Signature manager to sign the OAuth request - /// String result. - public async Task ExecuteGetAsync(Uri requestUri, TwitterOAuthTokens tokens, ISignatureManager signatureManager) - { - using var request = new HttpRequestMessage(HttpMethod.Get, requestUri); - var requestBuilder = new TwitterOAuthRequestBuilder(requestUri, tokens, signatureManager, "GET"); - - request.Headers.Authorization = AuthenticationHeaderValue.Parse(requestBuilder.AuthorizationHeader); - - using var response = await client.SendAsync(request).ConfigureAwait(false); - response.ThrowIfNotValid(); - return ProcessErrors(await response.Content.ReadAsStringAsync().ConfigureAwait(false)); - } - - /// - /// HTTP Get request for stream service. - /// - /// Uri to make OAuth request. - /// Tokens to pass in request. - /// Function invoked when stream available. - /// Signature manager to sign the OAuth requests - /// awaitable task - public async Task ExecuteGetStreamAsync(Uri requestUri, TwitterOAuthTokens tokens, TwitterStreamCallbacks.RawJsonCallback callback, ISignatureManager signatureManager) - { - using var request = new HttpRequestMessage(HttpMethod.Get, requestUri); - var requestBuilder = new TwitterOAuthRequestBuilder(requestUri, tokens, signatureManager); - - request.Headers.Authorization = AuthenticationHeaderValue.Parse(requestBuilder.AuthorizationHeader); - - using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false); - response.ThrowIfNotValid(); - using var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); - using var reader = new StreamReader(responseStream); - while (!_abort && !reader.EndOfStream) - { - var result = reader.ReadLine(); - - if (!string.IsNullOrEmpty(result)) - { - callback?.Invoke(result); - } - } - } - - /// - /// Stop reading stream - /// - public void Abort() - { - _abort = true; - } - - /// - /// HTTP Post request to specified Uri. - /// - /// Uri to make OAuth request. - /// Tokens to pass in request. - /// Signature manager to sign the OAuth requests - /// String result. - public async Task ExecutePostAsync(Uri requestUri, TwitterOAuthTokens tokens, ISignatureManager signatureManager) - { - using var request = new HttpRequestMessage(HttpMethod.Post, requestUri); - var requestBuilder = new TwitterOAuthRequestBuilder(requestUri, tokens, signatureManager, "POST"); - - request.Headers.Authorization = AuthenticationHeaderValue.Parse(requestBuilder.AuthorizationHeader); - - using var response = await client.SendAsync(request).ConfigureAwait(false); - response.ThrowIfNotValid(); - return ProcessErrors(await response.Content.ReadAsStringAsync().ConfigureAwait(false)); - } - - /// - /// HTTP Post request to specified Uri. - /// - /// Uri to make OAuth request. - /// Tokens to pass in request. - /// Boundary used to separate data. - /// Data to post to server. - /// Signature manager to sign the OAuth requests - /// String result. - public async Task ExecutePostMultipartAsync(Uri requestUri, TwitterOAuthTokens tokens, string boundary, byte[] content, ISignatureManager signatureManager) - { - JsonElement mediaId = default; - - try - { - using var multipartFormDataContent = new MultipartFormDataContent(boundary); - using var byteContent = new ByteArrayContent(content); - multipartFormDataContent.Add(byteContent, "media"); - - using var request = new HttpRequestMessage(HttpMethod.Post, requestUri); - var requestBuilder = new TwitterOAuthRequestBuilder(requestUri, tokens, signatureManager, "POST"); - - request.Headers.Authorization = AuthenticationHeaderValue.Parse(requestBuilder.AuthorizationHeader); - - request.Content = multipartFormDataContent; - - using var response = await client.SendAsync(request).ConfigureAwait(false); - response.ThrowIfNotValid(); - using var jsonResult = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); - var jObj = await JsonDocument.ParseAsync(jsonResult).ConfigureAwait(false); - mediaId = jObj.RootElement.GetProperty("media_id_string"); - } - catch (ObjectDisposedException) - { - // known issue - // http://stackoverflow.com/questions/39109060/httpmultipartformdatacontent-dispose-throws-objectdisposedexception - } - - return mediaId.ToString(); - } - - private string ProcessErrors(string content) - { - if (content.StartsWith("{\"errors\":")) - { - var errors = JsonSerializer.Deserialize(content); - - throw new TwitterException { Errors = errors }; - } - - return content; - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthRequestBuilder.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthRequestBuilder.cs deleted file mode 100644 index 671bbff15..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthRequestBuilder.cs +++ /dev/null @@ -1,251 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; -using Microsoft.Toolkit.Services.Core; -using Microsoft.Toolkit.Services.OAuth; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// OAuth request builder. - /// - internal class TwitterOAuthRequestBuilder - { - private ISignatureManager _signatureManager; - - /// - /// Realm for request. - /// - public const string Realm = "Twitter API"; - - /// - /// Gets or sets HTTP verb for request. - /// - public string Verb { get; set; } - - /// - /// Gets encoded Request Uri. - /// - public Uri EncodedRequestUri { get; private set; } - - /// - /// Gets request Uri without query. - /// - public Uri RequestUriWithoutQuery { get; private set; } - - /// - /// Gets list of query parameters. - /// - public IEnumerable QueryParams { get; private set; } - - /// - /// Gets version. - /// - public OAuthParameter Version { get; private set; } - - /// - /// Gets nonce. - /// - public OAuthParameter Nonce { get; private set; } - - /// - /// Gets timestamp. - /// - public OAuthParameter Timestamp { get; private set; } - - /// - /// Gets signature method. - /// - public OAuthParameter SignatureMethod { get; private set; } - - /// - /// Gets consumer key. - /// - public OAuthParameter ConsumerKey { get; private set; } - - /// - /// Gets consumer secret. - /// - public OAuthParameter ConsumerSecret { get; private set; } - - /// - /// Gets access token. - /// - public OAuthParameter Token { get; private set; } - - /// - /// Gets access token secret. - /// - public OAuthParameter TokenSecret { get; private set; } - - /// - /// Gets signature getter. - /// - public OAuthParameter Signature => new OAuthParameter("oauth_signature", GenerateSignature()); - - /// - /// Gets authorization header getter. - /// - public string AuthorizationHeader => GenerateAuthorizationHeader(); - - /// - /// Initializes a new instance of the class. - /// Authorization request builder. - /// - /// Request Uri. - /// Tokens to form request. - /// Signature manager to sign the OAuth request - /// Method to use with request. - public TwitterOAuthRequestBuilder(Uri requestUri, TwitterOAuthTokens tokens, ISignatureManager signatureManager, string method = "GET") - { - _signatureManager = signatureManager; - Verb = method; - - RequestUriWithoutQuery = new Uri(requestUri.AbsoluteWithoutQuery()); - - if (!string.IsNullOrEmpty(requestUri.Query)) - { - QueryParams = requestUri.GetQueryParams() - .Select(p => new OAuthParameter(p.Key, Uri.UnescapeDataString(p.Value))) - .ToList(); - } - else - { - QueryParams = new List(); - } - - EncodedRequestUri = GetEncodedUri(requestUri, QueryParams); - - Version = new OAuthParameter("oauth_version", "1.0"); - Nonce = new OAuthParameter("oauth_nonce", GenerateNonce()); - Timestamp = new OAuthParameter("oauth_timestamp", GenerateTimeStamp()); - SignatureMethod = new OAuthParameter("oauth_signature_method", "HMAC-SHA1"); - ConsumerKey = new OAuthParameter("oauth_consumer_key", tokens.ConsumerKey); - ConsumerSecret = new OAuthParameter("oauth_consumer_secret", tokens.ConsumerSecret); - Token = new OAuthParameter("oauth_token", tokens.AccessToken); - TokenSecret = new OAuthParameter("oauth_token_secret", tokens.AccessTokenSecret); - } - - /// - /// Get encoded Uri. - /// - /// Request uri. - /// List of parameters. - /// Encoded Uri. - private static Uri GetEncodedUri(Uri requestUri, IEnumerable parameters) - { - StringBuilder requestParametersBuilder = new StringBuilder(requestUri.AbsoluteWithoutQuery()); - var oAuthParameters = parameters as OAuthParameter[] ?? parameters.ToArray(); - if (oAuthParameters.Any()) - { - requestParametersBuilder.Append("?"); - - foreach (var queryParam in oAuthParameters) - { - requestParametersBuilder.AppendFormat("{0}&", queryParam.ToString()); - } - - requestParametersBuilder.Remove(requestParametersBuilder.Length - 1, 1); - } - - return new Uri(requestParametersBuilder.ToString()); - } - - /// - /// Generate nonce. - /// - /// String nonce. - private static string GenerateNonce() - { - return new Random() - .Next(123400, int.MaxValue) - .ToString("X", CultureInfo.InvariantCulture); - } - - /// - /// Generate timestamp string. - /// - /// Timestamp string. - private static string GenerateTimeStamp() - { - TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); - return Convert.ToInt64(ts.TotalSeconds, CultureInfo.CurrentCulture).ToString(CultureInfo.CurrentCulture); - } - - /// - /// Generate signature. - /// - /// Generated signature string. - private string GenerateSignature() - { - string signatureBaseString = string.Format( - CultureInfo.InvariantCulture, - "{2}&{0}&{1}", - OAuthEncoder.UrlEncode(RequestUriWithoutQuery.Normalize()), - OAuthEncoder.UrlEncode(GetSignParameters()), - Verb); - - string key = string.Format( - CultureInfo.InvariantCulture, - "{0}&{1}", - OAuthEncoder.UrlEncode(ConsumerSecret.Value), - OAuthEncoder.UrlEncode(TokenSecret.Value)); - - return _signatureManager.GetSignature(signatureBaseString, key); - } - - /// - /// Generate authorization header. - /// - /// Generated authorization header string. - private string GenerateAuthorizationHeader() - { - StringBuilder authHeaderBuilder = new StringBuilder(); - - authHeaderBuilder.AppendFormat("OAuth realm=\"{0}\",", Realm); - authHeaderBuilder.Append(string.Join(",", GetAuthHeaderParameters().OrderBy(p => p.Key).Select(p => p.ToString(true)).ToArray())); - authHeaderBuilder.AppendFormat(",{0}", Signature.ToString(true)); - - return authHeaderBuilder.ToString(); - } - - /// - /// Get list of sign parameters. - /// - /// List of sign parameters. - private IEnumerable GetSignParameters() - { - foreach (var queryParam in QueryParams) - { - yield return queryParam; - } - - yield return Version; - yield return Nonce; - yield return Timestamp; - yield return SignatureMethod; - yield return ConsumerKey; - yield return Token; - } - - /// - /// Get list of auth header parameters. - /// - /// List of auth header parameters. - private IEnumerable GetAuthHeaderParameters() - { - yield return Version; - yield return Nonce; - yield return Timestamp; - yield return SignatureMethod; - yield return ConsumerKey; - yield return Token; - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthRequestExtensions.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthRequestExtensions.cs deleted file mode 100644 index 7d48701f2..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthRequestExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Net; -using System.Net.Http; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Oauth request extensions to add utilities for internal use. - /// - internal static class TwitterOAuthRequestExtensions - { - public static void ThrowIfNotValid(this HttpResponseMessage response) - { - if (response.StatusCode == HttpStatusCode.NotFound) - { - throw new UserNotFoundException(); - } - - if ((int)response.StatusCode == 429) - { - throw new TooManyRequestsException(); - } - - if (response.StatusCode == HttpStatusCode.Unauthorized) - { - throw new OAuthKeysRevokedException(); - } - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthTokenType.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthTokenType.cs deleted file mode 100644 index ad4f62475..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthTokenType.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// OAuth token types - /// - public enum TwitterOAuthTokenType - { - /// - /// Request or access token - /// - OAuthRequestOrAccessToken, - - /// - /// Request or access token secret - /// - OAuthRequestOrAccessTokenSecret, - - /// - /// Verifier - /// - OAuthVerifier, - - /// - /// Callback confirmed - /// - OAuthCallbackConfirmed, - - /// - /// Screen name - /// - ScreenName - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthTokens.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthTokens.cs deleted file mode 100644 index 9a968cbd0..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterOAuthTokens.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter OAuth tokens. - /// - public class TwitterOAuthTokens - { - /// - /// Gets or sets consumer Key. - /// - public string ConsumerKey { get; set; } - - /// - /// Gets or sets consumer Secret. - /// - public string ConsumerSecret { get; set; } - - /// - /// Gets or sets access token. - /// - public string AccessToken { get; set; } - - /// - /// Gets or sets access token Secret. - /// - public string AccessTokenSecret { get; set; } - - /// - /// Gets or sets access Request Token. - /// - public string RequestToken { get; set; } - - /// - /// Gets or sets access Request Token Secret. - /// - public string RequestTokenSecret { get; set; } - - /// - /// Gets or sets callback Uri. - /// - public string CallbackUri { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterParser.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterParser.cs deleted file mode 100644 index 3404467d8..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterParser.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; -using System.Text.Json; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Parser. - /// - /// Type to parse in to. - public class TwitterParser : Toolkit.Parsers.IParser - where T : Toolkit.Parsers.SchemaBase - { - /// - /// Parse string data into strongly typed list. - /// - /// Input string. - /// List of strongly typed objects. - IEnumerable Toolkit.Parsers.IParser.Parse(string data) - { - if (string.IsNullOrEmpty(data)) - { - return null; - } - - try - { - return JsonSerializer.Deserialize>(data); - } - catch (JsonException) - { - List items = new List(); - items.Add(JsonSerializer.Deserialize(data)); - return items; - } - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterPlace.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterPlace.cs deleted file mode 100644 index 0b5f45113..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterPlace.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Place - /// - public class TwitterPlace - { - /// - /// Gets or sets the ID of the place - /// - [JsonPropertyName("id")] - public string Id { get; set; } - - /// - /// Gets or sets the URL of additional place metadata - /// - [JsonPropertyName("url")] - public string Url { get; set; } - - /// - /// Gets or sets the place type. - /// - [JsonPropertyName("place_type")] - public string PlaceType { get; set; } - - /// - /// Gets or sets the place name. - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// Gets or sets the full, human-readable place name. - /// - [JsonPropertyName("full_name")] - public string FullName { get; set; } - - /// - /// Gets or sets the shortened country code (e.g. US) for the place. - /// - [JsonPropertyName("country_code")] - public string CountryCode { get; set; } - - /// - /// Gets or sets the name of the country for the place. - /// - [JsonPropertyName("country")] - public string Country { get; set; } - - /// - /// Gets or sets the bounding box coordinates of a location. - /// - [JsonPropertyName("bounding_box")] - public TwitterPlaceBoundingBox BoundingBox { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterPlaceBoundingBox.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterPlaceBoundingBox.cs deleted file mode 100644 index fb39af14c..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterPlaceBoundingBox.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Place Bounding Box - /// - public class TwitterPlaceBoundingBox - { - /// - /// Gets or sets the bounding box coordinates of the tweet's geolocation data. - /// - [JsonPropertyName("coordinates")] - public List> Coordinates { get; set; } - - /// - /// Gets or sets the coordinate type. Polygon for a bounding box, Point for an exact coordinate. - /// - [JsonPropertyName("type")] - public string Type { get; set; } - - /// - /// Gets the coordinates array of the tweet's geolocation data - /// - public List CoordinatesArray - { - get - { - List result = null; - - if (Coordinates != null) - { - result = Coordinates[0]; - } - - return result; - } - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterPoll.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterPoll.cs deleted file mode 100644 index 24f65ee1c..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterPoll.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Globalization; -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter poll object containing poll data. - /// - public class TwitterPoll - { - /// - /// Gets or sets poll questions. - /// - [JsonPropertyName("options")] - public TwitterPollOptions[] Options { get; set; } - - /// - /// Gets or sets end timestamp as a string. - /// - [JsonPropertyName("end_datetime")] - public string EndDateTime { get; set; } - - /// - /// Gets or sets duration of the poll in minutes. - /// - [JsonPropertyName("duration_minutes")] - public string DurationMinutes { get; set; } - - /// - /// Gets end timestamp as a DateTime object. - /// - public DateTime PollEnd - { - get { return FormatDate(EndDateTime); } - } - - private DateTime FormatDate(string input) - { - DateTime formattedDateTime; - if (!DateTime.TryParseExact(input, "ddd MMM dd HH:mm:ss zzzz yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out formattedDateTime)) - { - formattedDateTime = DateTime.Today; - } - - return formattedDateTime; - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterPollOptions.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterPollOptions.cs deleted file mode 100644 index af44d2149..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterPollOptions.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter poll options object containing poll questions. - /// - public class TwitterPollOptions - { - /// - /// Gets or sets int value of the poll position. - /// - [JsonPropertyName("position")] - public int Position { get; set; } - - /// - /// Gets or sets text of the poll question. - /// - [JsonPropertyName("text")] - public string Text { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterQueryType.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterQueryType.cs deleted file mode 100644 index c5072f225..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterQueryType.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Type of Twitter Query. - /// - public enum TwitterQueryType - { - /// - /// Home - /// - Home, - - /// - /// User - /// - User, - - /// - /// Search - /// - Search, - - /// - /// Custom - /// - Custom - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterSearchParser.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterSearchParser.cs deleted file mode 100644 index 263cddbdf..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterSearchParser.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; -using System.Linq; -using System.Text.Json; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Search Parser. - /// - public class TwitterSearchParser : Parsers.IParser - { - /// - /// Parse string into strong typed list. - /// - /// Input string. - /// Strong typed list. - public IEnumerable Parse(string data) - { - if (string.IsNullOrEmpty(data)) - { - return null; - } - - var result = JsonSerializer.Deserialize(data); - - return result.Statuses.ToList(); - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterSearchResult.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterSearchResult.cs deleted file mode 100644 index 9f6129ace..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterSearchResult.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Search Results. - /// - internal class TwitterSearchResult - { - /// - /// Gets or sets array of timeline statuses. - /// - public Tweet[] Statuses { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterService.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterService.cs deleted file mode 100644 index c8a9c9e66..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterService.cs +++ /dev/null @@ -1,440 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Toolkit.Services.Core; - -#if WINRT -using Microsoft.Toolkit.Services.PlatformSpecific.Uwp; -using Windows.Storage.Streams; -#endif - -#if NET462 -using Microsoft.Toolkit.Services.PlatformSpecific.NetFramework; -#endif - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Class for connecting to Twitter. - /// - public class TwitterService - { - /// - /// Private field for TwitterDataProvider. - /// - private TwitterDataProvider twitterDataProvider; - - /// - /// Field for tracking oAuthTokens. - /// - private TwitterOAuthTokens tokens; - - private IPasswordManager passwordManager; - private IStorageManager storageManager; - private IAuthenticationBroker authenticationBroker; - private ISignatureManager signatureManager; - - /// - /// Field for tracking initialization status. - /// - private bool isInitialized; - - /// - /// Initializes a new instance of the class. - /// - public TwitterService() - { - } - - /// - /// Private singleton field. - /// - private static TwitterService instance; - - /// - /// Gets public singleton property. - /// - public static TwitterService Instance => instance ?? (instance = new TwitterService()); - - /// - /// Gets the current logged in user screen name. - /// - public string UserScreenName => Provider.UserScreenName; - - /// - /// Initialize underlying provider with relevant token information. - /// - /// Consumer key. - /// Consumer secret. - /// Callback URI. Has to match callback URI defined at apps.twitter.com (can be arbitrary). - /// Authentication result interface. - /// Password Manager interface, store the password. - /// Storage Manager interface - /// Signature manager to sign the OAuth request - /// Success or failure. - public bool Initialize(string consumerKey, string consumerSecret, string callbackUri, IAuthenticationBroker authenticationBroker, IPasswordManager passwordManager, IStorageManager storageManager, ISignatureManager signatureManager) - { - if (string.IsNullOrEmpty(consumerKey)) - { - throw new ArgumentNullException(nameof(consumerKey)); - } - - if (string.IsNullOrEmpty(consumerSecret)) - { - throw new ArgumentNullException(nameof(consumerSecret)); - } - - if (string.IsNullOrEmpty(callbackUri)) - { - throw new ArgumentNullException(nameof(callbackUri)); - } - - if (authenticationBroker == null) - { - throw new ArgumentException(nameof(authenticationBroker)); - } - - if (passwordManager == null) - { - throw new ArgumentException(nameof(passwordManager)); - } - - if (storageManager == null) - { - throw new ArgumentException(nameof(storageManager)); - } - - if (signatureManager == null) - { - throw new ArgumentException(nameof(signatureManager)); - } - - var oAuthTokens = new TwitterOAuthTokens - { - ConsumerKey = consumerKey, - ConsumerSecret = consumerSecret, - CallbackUri = callbackUri - }; - - return Initialize(oAuthTokens, authenticationBroker, passwordManager, storageManager, signatureManager); - } - - /// - /// Initialize underlying provider with relevant token information. - /// - /// Token instance. - /// Authentication result interface. - /// Password Manager interface, store the password. - /// Storage Manager interface - /// Signature manager to sign the OAuth request - /// Success or failure. - public bool Initialize(TwitterOAuthTokens oAuthTokens, IAuthenticationBroker authenticationBroker, IPasswordManager passwordManager, IStorageManager storageManager, ISignatureManager signatureManager) - { - tokens = oAuthTokens ?? throw new ArgumentNullException(nameof(oAuthTokens)); - this.authenticationBroker = authenticationBroker ?? throw new ArgumentNullException(nameof(authenticationBroker)); - this.passwordManager = passwordManager ?? throw new ArgumentNullException(nameof(passwordManager)); - this.storageManager = storageManager ?? throw new ArgumentNullException(nameof(storageManager)); - this.signatureManager = signatureManager ?? throw new ArgumentNullException(nameof(signatureManager)); - - isInitialized = true; - - twitterDataProvider = null; - - return true; - } - -#if WINRT - /// - /// Initialize underlying provider with relevant token information for UWP. - /// - /// Consumer key. - /// Consumer secret. - /// Callback URI. Has to match callback URI defined at apps.twitter.com (can be arbitrary). - /// Success or failure. - public bool Initialize(string consumerKey, string consumerSecret, string callbackUri) - { - return Initialize(consumerKey, consumerSecret, callbackUri, new UwpAuthenticationBroker(), new UwpPasswordManager(), new UwpStorageManager(), new UwpSignatureManager()); - } - - /// - /// Initialize underlying provider with relevant token information. - /// - /// Token instance. - /// Success or failure. - public bool Initialize(TwitterOAuthTokens oAuthTokens) - { - return Initialize(oAuthTokens, new UwpAuthenticationBroker(), new UwpPasswordManager(), new UwpStorageManager(), new UwpSignatureManager()); - } -#endif - -#if NET462 - /// - /// Initialize underlying provider with relevant token information for UWP. - /// - /// Consumer key. - /// Consumer secret. - /// Callback URI. Has to match callback URI defined at apps.twitter.com (can be arbitrary). - /// Success or failure. - public bool Initialize(string consumerKey, string consumerSecret, string callbackUri) - { - return Initialize(consumerKey, consumerSecret, callbackUri, new NetFrameworkAuthenticationBroker(), new NetFrameworkPasswordManager(), new NetFrameworkStorageManager(), new NetFrameworkSignatureManager()); - } - - /// - /// Initialize underlying provider with relevant token information. - /// - /// Token instance. - /// Success or failure. - public bool Initialize(TwitterOAuthTokens oAuthTokens) - { - return Initialize(oAuthTokens, new NetFrameworkAuthenticationBroker(), new NetFrameworkPasswordManager(), new NetFrameworkStorageManager(), new NetFrameworkSignatureManager()); - } -#endif - - /// - /// Gets a reference to an instance of the underlying data provider. - /// - public TwitterDataProvider Provider - { - get - { - if (!isInitialized) - { - throw new InvalidOperationException("Provider not initialized."); - } - - return twitterDataProvider ?? (twitterDataProvider = new TwitterDataProvider(tokens, authenticationBroker, passwordManager, storageManager, signatureManager)); - } - } - - /// - /// Search for specific hash tag. - /// - /// Hash tag. - /// Upper record limit. - /// Returns strongly typed list of results. - public async Task> SearchAsync(string hashTag, int maxRecords = 20) - { - if (Provider.LoggedIn) - { - return await Provider.SearchAsync(hashTag, maxRecords, new TwitterSearchParser()); - } - - var isLoggedIn = await LoginAsync(); - if (isLoggedIn) - { - return await SearchAsync(hashTag, maxRecords); - } - - return null; - } - - /// - /// Retrieve user data. - /// - /// User screen name or null for current logged user. - /// Returns user data. - public async Task GetUserAsync(string screenName = null) - { - if (Provider.LoggedIn) - { - return await Provider.GetUserAsync(screenName); - } - - var isLoggedIn = await LoginAsync(); - if (isLoggedIn) - { - return await GetUserAsync(screenName); - } - - return null; - } - - /// - /// Retrieve user timeline data. - /// - /// User screen name. - /// Upper record limit. - /// Returns strongly typed list of results. - public async Task> GetUserTimeLineAsync(string screenName, int maxRecords = 20) - { - if (Provider.LoggedIn) - { - return await Provider.GetUserTimeLineAsync(screenName, maxRecords, new TweetParser()); - } - - var isLoggedIn = await LoginAsync(); - if (isLoggedIn) - { - return await GetUserTimeLineAsync(screenName, maxRecords); - } - - return null; - } - - /// - /// Post a Tweet with associated pictures. - /// - /// Tweet message. - /// Returns success or failure of post request. - public async Task TweetStatusAsync(string message) - { - return await TweetStatusAsync(new TwitterStatus { Message = message }); - } - - /// - /// Post a Tweet with associated pictures. - /// - /// Tweet message. - /// Pictures to attach to the tweet (up to 4). - /// Returns success or failure of post request. - public async Task TweetStatusAsync(string message, params Stream[] pictures) - { - return await TweetStatusAsync(new TwitterStatus { Message = message }, pictures); - } - - /// - /// Post a Tweet with associated pictures. - /// - /// The tweet information. - /// Returns success or failure of post request. - public async Task TweetStatusAsync(TwitterStatus status) - { - if (Provider.LoggedIn) - { - return await Provider.TweetStatusAsync(status); - } - - var isLoggedIn = await LoginAsync(); - if (isLoggedIn) - { - return await TweetStatusAsync(status); - } - - return false; - } - - /// - /// Post a Tweet with associated pictures. - /// - /// The tweet information. - /// Pictures to attach to the tweet (up to 4). - /// Returns success or failure of post request. - public async Task TweetStatusAsync(TwitterStatus status, params Stream[] pictures) - { - if (pictures.Length > 4) - { - throw new ArgumentOutOfRangeException(nameof(pictures)); - } - - if (Provider.LoggedIn) - { - return await Provider.TweetStatusAsync(status, pictures); - } - - var isLoggedIn = await LoginAsync(); - if (isLoggedIn) - { - return await TweetStatusAsync(status, pictures); - } - - return false; - } - - /// - /// Request list data from service provider based upon a given config / query. - /// - /// TwitterDataConfig instance. - /// Upper limit of records to return. Up to a maximum of 200 per distinct request. - /// Strongly typed list of data returned from the service. - public async Task> RequestAsync(TwitterDataConfig config, int maxRecords = 20) - { - return await RequestAsync(config, maxRecords); - } - - /// - /// Request list data from service provider based upon a given config / query. - /// - /// Model type expected back - e.g. Tweet. - /// TwitterDataConfig instance. - /// Upper limit of records to return. Up to a maximum of 200 per distinct request. - /// Strongly typed list of data returned from the service. - public async Task> RequestAsync(TwitterDataConfig config, int maxRecords = 20) - where T : Toolkit.Parsers.SchemaBase - { - if (Provider.LoggedIn) - { - List queryResults = new List(); - - var results = await Provider.LoadDataAsync(config, maxRecords, 0, new TwitterParser()); - - foreach (var result in results) - { - queryResults.Add(result); - } - - return queryResults; - } - - var isLoggedIn = await LoginAsync(); - if (isLoggedIn) - { - return await RequestAsync(config, maxRecords); - } - - return null; - } - - /// - /// Log user in to Twitter. - /// - /// Returns success or failure of login attempt. - public Task LoginAsync() - { - return Provider.LoginAsync(); - } - - /// - /// Log user out of Twitter. - /// - /// A representing the asynchronous operation. - public Task LogoutAsync() - { - return Provider.LogoutAsync(); - } - - /// - /// Open a connection to user's stream service - /// - /// Method called each time a tweet arrives - /// Task - public async Task StartUserStreamAsync(TwitterStreamCallbacks.TwitterStreamCallback callback) - { - if (Provider.LoggedIn) - { - await Provider.StartUserStreamAsync(new TwitterUserStreamParser(), callback); - return; - } - - var isLoggedIn = await LoginAsync(); - if (isLoggedIn) - { - await StartUserStreamAsync(callback); - } - } - - /// - /// Close the connection to user's stream service - /// - public void StopUserStream() - { - Provider.StopStream(); - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterStatus.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterStatus.cs deleted file mode 100644 index fdcef7488..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterStatus.cs +++ /dev/null @@ -1,112 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Globalization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// A class for Twitter status other than the pictures - /// NOTE: Can be extended to handle the other pieces of the Twitter Status REST API. - /// https://dev.twitter.com/rest/reference/post/statuses/update - /// Validation COULD be added to the Lat/Long, but since Twitter ignores these if they are invalid then no big deal. - /// - public class TwitterStatus - { - /// - /// Gets or sets a value indicating whether the explicit latitude and longitude of the "tweet" message is displayed. - /// NOTE: Whether or not to put a pin on the exact coordinates a Tweet has been sent from. - /// - public bool DisplayCoordinates { get; set; } - - /// - /// Gets or sets the ID of the original tweet. - /// - public string InReplyToStatusId { get; set; } - - /// - /// Gets or sets the latitude of the "tweet" message. - /// NOTE: This parameter will be ignored unless it is inside the range -90.0 to +90.0 (North is positive) inclusive. - /// It will also be ignored if there isn’t a corresponding long parameter. - /// - public double? Latitude { get; set; } - - /// - /// Gets or sets the longitude of the "tweet" message. - /// NOTE: The valid ranges for longitude is -180.0 to +180.0 (East is positive) inclusive. - /// This parameter will be ignored if outside that range, if it is not a number, if geo_enabled is disabled, - /// or if there not a corresponding lat parameter. - /// - public double? Longitude { get; set; } - - /// - /// Gets or sets the text of the Tweet message. - /// - public string Message { get; set; } - - /// - /// Gets or sets the text of the Tweet message. - /// - public string PlaceId { get; set; } - - /// - /// Gets or sets a value indicating whether the Tweet contains sensitive content (such as nudity, etc.). - /// - public bool PossiblySensitive { get; set; } - - /// - /// Gets the request parameters - /// - public string RequestParameters - { - get - { - string result = $"status={Uri.EscapeDataString(Message)}"; - - if (Latitude.HasValue && Longitude.HasValue) - { - result = $"{result}&lat={Latitude.Value.ToString(CultureInfo.InvariantCulture)}&long={Longitude.Value.ToString(CultureInfo.InvariantCulture)}"; - result = AddRequestParameter(result, "display_coordinates", DisplayCoordinates); - } - - result = AddRequestParameter(result, "in_reply_to_status_id", InReplyToStatusId); - result = AddRequestParameter(result, "place_id", PlaceId); - result = AddRequestParameter(result, "possibly_sensitive", PossiblySensitive); - result = AddRequestParameter(result, "trim_user", TrimUser); - - return result; - } - } - - /// - /// Gets or sets a value indicating whether the Tweet returned in a timeline will include a user object including only the status authors numerical ID. - /// - public bool TrimUser { get; set; } - - private string AddRequestParameter(string request, string parameterName, bool value) - { - var result = request; - - if (value) - { - result = $"{result}&{parameterName}=true"; - } - - return result; - } - - private string AddRequestParameter(string request, string parameterName, string value) - { - var result = request; - - if (!string.IsNullOrEmpty(value)) - { - result = $"{result}&{parameterName}={Uri.EscapeDataString(value)}"; - } - - return result; - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterStreamCallbacks.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterStreamCallbacks.cs deleted file mode 100644 index c74ef1100..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterStreamCallbacks.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Callbacks used for Twitter streams. - /// - public class TwitterStreamCallbacks - { - /// - /// Callback converting json to Tweet - /// - /// Raw Json from Twitter API - public delegate void RawJsonCallback(string json); - - /// - /// Callback returning the parsed tweet - /// - /// Strongly typed tweet - public delegate void TwitterStreamCallback(ITwitterResult tweet); - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterStreamDeletedEvent.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterStreamDeletedEvent.cs deleted file mode 100644 index fa52090e8..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterStreamDeletedEvent.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter User type. - /// - public class TwitterStreamDeletedEvent : ITwitterResult - { - /// - /// Gets or sets the user id of the event. This is always the user who initiated the event. - /// - /// The user Id. - [JsonPropertyName("user_id_str")] - public string UserId { get; set; } - - /// - /// Gets or sets the id of the event. This is the tweet that was affected. - /// - /// The tweet Id. - [JsonPropertyName("id_str")] - public string Id { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterStreamEvent.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterStreamEvent.cs deleted file mode 100644 index 8bd3b68b2..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterStreamEvent.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Globalization; -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter User type. - /// - public class TwitterStreamEvent : ITwitterResult - { - /// - /// Gets or sets the type of the event. - /// - /// The type of the event. - [JsonPropertyName("event")] - [JsonConverter(typeof(JsonStringEnumConverter))] - public TwitterStreamEventType EventType { get; set; } - - /// - /// Gets or sets the source of the event. This is always the user who initiated the event. - /// - /// The source. - public TwitterUser Source { get; set; } - - /// - /// Gets or sets the target of the event. This is the user who was affected, or who owns the affected object. - /// - /// The source. - public TwitterUser Target { get; set; } - - /// - /// Gets or sets the target object. - /// - /// The target object. - public Tweet TargetObject { get; set; } - - /// - /// Gets or sets the creation date. - /// - /// The creation date. - [JsonPropertyName("created_at")] - public string CreatedAt { get; set; } - - /// - /// Gets the creation date - /// - public DateTime CreationDate - { - get - { - DateTime dt; - if (!DateTime.TryParseExact(CreatedAt, "ddd MMM dd HH:mm:ss zzzz yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt)) - { - dt = DateTime.Today; - } - - return dt; - } - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterStreamEventType.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterStreamEventType.cs deleted file mode 100644 index 91f582f41..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterStreamEventType.cs +++ /dev/null @@ -1,115 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Runtime.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Describes the type of event that has occurred on twitter - /// - public enum TwitterStreamEventType - { - /// - /// The event is an unknown type - /// - Unknown, - - /// - /// The source user has blocked the target user. - /// - [EnumMember(Value = "block")] - Block, - - /// - /// The source user has unblocked the target user. - /// - [EnumMemberAttribute(Value = "unblock")] - Unblock, - - /// - /// The source user has favorited the target users tweet. - /// - [EnumMemberAttribute(Value = "favorite")] - Favorite, - - /// - /// The source user has unfavorited the target users tweet. - /// - [EnumMemberAttribute(Value = "unfavorite")] - Unfavorite, - - /// - /// The source user has followed the target user. - /// - [EnumMemberAttribute(Value = "follow")] - Follow, - - /// - /// The source user has unfollowed the target user. - /// - [EnumMemberAttribute(Value = "unfollow")] - Unfollow, - - /// - /// The source user has added the target user to the a list. - /// - [EnumMemberAttribute(Value = "list_member_added")] - ListMemberAdded, - - /// - /// The source user has removed the target user from a list. - /// - [EnumMemberAttribute(Value = "list_member_removed")] - ListMemberRemoved, - - /// - /// The source user has subscribed to a list. - /// - [EnumMemberAttribute(Value = "list_user_subscribed")] - ListUserSubscribed, - - /// - /// The source user has unsubscribed from a list. - /// - [EnumMemberAttribute(Value = "list_user_unsubscribed")] - ListUserUnsubscribed, - - /// - /// The source user created a list. - /// - [EnumMemberAttribute(Value = "list_created")] - ListCreated, - - /// - /// The source user update a lists properties. - /// - [EnumMemberAttribute(Value = "list_updated")] - ListUpdated, - - /// - /// The source user deleted a list. - /// - [EnumMemberAttribute(Value = "list_destroyed")] - ListDestroyed, - - /// - /// The source users profile was updated. - /// - [EnumMemberAttribute(Value = "user_update")] - UserUpdated, - - /// - /// The source users profile was updated. - /// - [EnumMemberAttribute(Value = "access_revoked")] - AccessRevoked, - - /// - /// The source users tweet was quoted. - /// - [EnumMemberAttribute(Value = "quoted_tweet")] - QuotedTweet - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterSymbol.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterSymbol.cs deleted file mode 100644 index dcac308e6..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterSymbol.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter symbol object containing all stock symbols in a tweet. - /// - public class TwitterSymbol - { - /// - /// Gets or sets indices of hashtag location in tweet string. - /// - [JsonPropertyName("indices")] - public int[] Indices { get; set; } - - /// - /// Gets or sets hashtag text, excluding #. - /// - [JsonPropertyName("text")] - public string Text { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterUrl.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterUrl.cs deleted file mode 100644 index ebadd1348..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterUrl.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Url - /// - public class TwitterUrl - { - /// - /// Gets or sets DisplayUrl of the Url. - /// - [JsonPropertyName("display_url")] - public string DisplayUrl { get; set; } - - /// - /// Gets or sets ExpandedUrl of the Url. - /// - [JsonPropertyName("expanded_url")] - public string ExpandedUrl { get; set; } - - /// - /// Gets or sets indices position of the tweet. - /// - [JsonPropertyName("indices")] - public int[] Indices { get; set; } - - /// - /// Gets or sets unwound Url metadata position of the tweet. - /// - [JsonPropertyName("unwound")] - public TwitterUrlUnwound Unwound { get; set; } - - /// - /// Gets or sets t.co Url of the tweet. - /// - [JsonPropertyName("url")] - public string Url { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterUrlUnwound.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterUrlUnwound.cs deleted file mode 100644 index c86263412..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterUrlUnwound.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Url Unwound object; provides original Url for shortened t.co links. - /// - public class TwitterUrlUnwound - { - /// - /// Gets or sets fully unwound url. - /// - [JsonPropertyName("url")] - public string Url { get; set; } - - /// - /// Gets or sets status of unwind; if anything but 200 is bad data. - /// - [JsonPropertyName("status")] - public int Status { get; set; } - - /// - /// Gets or sets HTML title for url. - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// Gets or sets description of link. - /// - [JsonPropertyName("description")] - public string Description { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterUser.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterUser.cs deleted file mode 100644 index fd458ebeb..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterUser.cs +++ /dev/null @@ -1,207 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter User type. - /// - public class TwitterUser - { - /// - /// Gets or sets user Id. - /// - [JsonPropertyName("id_str")] - public string Id { get; set; } - - /// - /// Gets or sets user name. - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// Gets or sets user screen name. - /// - [JsonPropertyName("screen_name")] - public string ScreenName { get; set; } - - /// - /// Gets or sets profile location. - /// - [JsonPropertyName("location")] - public string Location { get; set; } - - /// - /// Gets or sets profile url. - /// - [JsonPropertyName("url")] - public string Url { get; set; } - - /// - /// Gets or sets profile description. - /// - [JsonPropertyName("description")] - public string Description { get; set; } - - /// - /// Gets or sets a value indicating whether protected status of user. - /// - [JsonPropertyName("protected")] - public bool Protected { get; set; } - - /// - /// Gets or sets a value indicating whether account is verified (blue check mark). - /// - [JsonPropertyName("verified")] - public bool Verified { get; set; } - - /// - /// Gets or sets followers count. - /// - [JsonPropertyName("followers_count")] - public int FollowersCount { get; set; } - - /// - /// Gets or sets count of accounts user is following. - /// - [JsonPropertyName("friends_count")] - public int FriendsCount { get; set; } - - /// - /// Gets or sets count of public lists user is a member of. - /// - [JsonPropertyName("listed_count")] - public int ListedCount { get; set; } - - /// - /// Gets or sets total count of tweets user has liked. - /// - [JsonPropertyName("favourites_count")] - public int FavoritesCount { get; set; } - - /// - /// Gets or sets total count of tweets (including retweets) posted by user. - /// - [JsonPropertyName("statuses_count")] - public int StatusesCount { get; set; } - - /// - /// Gets or sets a value indicating whether geotagging is enabled. - /// This determines whether or not to geotag the user's posts. - /// - [JsonPropertyName("geo_enabled")] - public bool GeoEnabled { get; set; } - - /// - /// Gets or sets BCP 47 language code according to user's account settings. - /// - [JsonPropertyName("lang")] - public string Lang { get; set; } - - /// - /// Gets or sets a value indicating whether contributor mode is enabled. - /// - [JsonPropertyName("contributors_enabled")] - public bool ContributorsEnabled { get; set; } - - /// - /// Gets or sets profile background color (web hex value). - /// - [JsonPropertyName("profile_background_color")] - public string ProfileBackgroundColor { get; set; } - - /// - /// Gets or sets profile background image url. - /// - [JsonPropertyName("profile_background_image_url")] - public string ProfileBackgroundImageUrl { get; set; } - - /// - /// Gets or sets profile background image url using https. - /// - [JsonPropertyName("profile_background_image_url_https")] - public string ProfileBackgroundImageUrlHttps { get; set; } - - /// - /// Gets or sets a value indicating whether profile background image is tiled. - /// - [JsonPropertyName("profile_background_tile")] - public bool ProfileBackgroundTile { get; set; } - - /// - /// Gets or sets profile banner url. - /// - [JsonPropertyName("profile_banner_url")] - public string ProfileBannerUrl { get; set; } - - /// - /// Gets or sets profile image url. - /// - [JsonPropertyName("profile_image_url")] - public string ProfileImageUrl { get; set; } - - /// - /// Gets or sets profile image url using https. - /// - [JsonPropertyName("profile_image_url_https")] - public string ProfileImageUrlHttps { get; set; } - - /// - /// Gets or sets profile link color (web hex value). - /// - [JsonPropertyName("profile_link_color")] - public string ProfileLinkColor { get; set; } - - /// - /// Gets or sets profile sidebar border color (web hex value). - /// - [JsonPropertyName("profile_sidebar_border_color")] - public string ProfileSidebarBorderColor { get; set; } - - /// - /// Gets or sets profile sidebar fill color (web hex value). - /// - [JsonPropertyName("profile_sidebar_fill_color")] - public string ProfileSidebarFillColor { get; set; } - - /// - /// Gets or sets profile text color (web hex value). - /// - [JsonPropertyName("profile_text_color")] - public string ProfileTextColor { get; set; } - - /// - /// Gets or sets a value indicating whether the user has selected to use their uploaded background image in their profile. - /// - [JsonPropertyName("profile_use_background_image")] - public bool ProfileUseBackgroundImage { get; set; } - - /// - /// Gets or sets a value indicating whether or not user is using the default profile theme and background. - /// - [JsonPropertyName("default_profile")] - public bool DefaultProfile { get; set; } - - /// - /// Gets or sets a value indicating whether or not the user is using the default profile image. - /// - [JsonPropertyName("default_profile_image")] - public bool DefaultProfileImage { get; set; } - - /// - /// Gets or sets "withheld in" countries. - /// - [JsonPropertyName("withheld_in_countries")] - public string[] WithheldInCountries { get; set; } - - /// - /// Gets or sets withheld scope (status or profile). - /// - [JsonPropertyName("withheld_scope")] - public string WithheldScope { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterUserMention.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterUserMention.cs deleted file mode 100644 index aa7b6ac86..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterUserMention.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter user object containing user mention indices. - /// - public class TwitterUserMention : TwitterUser - { - /// - /// Gets or sets the start and end position of the user mention - /// - [JsonPropertyName("indices")] - public int[] Indices { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Twitter/TwitterUserStreamParser.cs b/Microsoft.Toolkit.Services/Services/Twitter/TwitterUserStreamParser.cs deleted file mode 100644 index e8c3af63d..000000000 --- a/Microsoft.Toolkit.Services/Services/Twitter/TwitterUserStreamParser.cs +++ /dev/null @@ -1,72 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json; - -namespace Microsoft.Toolkit.Services.Twitter -{ - /// - /// Twitter Timeline Parser. - /// - public class TwitterUserStreamParser - { - /// - /// Parse string data into strongly typed list. - /// - /// Input string. - /// List of strongly typed objects. - public ITwitterResult Parse(string data) - { - if (string.IsNullOrEmpty(data)) - { - return null; - } - - var obj = JsonDocument.Parse(data); - - if (obj.RootElement.TryGetProperty("friends", out var friends) && friends.GetArrayLength() > 0) - { - return null; - } - - if (obj.RootElement.TryGetProperty("delete", out var delete)) - { - if (delete.TryGetProperty("status", out var deletedStatus) && deletedStatus.GetArrayLength() > 0) - { - return JsonSerializer.Deserialize(deletedStatus.ToString()); - } - - if (delete.TryGetProperty("direct_message", out var deletedDirectMessage) && deletedDirectMessage.GetArrayLength() > 0) - { - return JsonSerializer.Deserialize(deletedDirectMessage.ToString()); - } - } - - if (obj.RootElement.TryGetProperty("event", out var events)) - { - Tweet endTargetObject = null; - if (obj.RootElement.TryGetProperty("target_object", out var targetObject) && targetObject.TryGetProperty("user", out _)) - { - endTargetObject = JsonSerializer.Deserialize(targetObject.ToString()); - } - - var endEvent = JsonSerializer.Deserialize(obj.ToString()); - endEvent.TargetObject = endTargetObject; - return endEvent; - } - - if (obj.RootElement.TryGetProperty("user", out var user) && user.GetArrayLength() > 0) - { - return JsonSerializer.Deserialize(obj.ToString()); - } - - if (obj.RootElement.TryGetProperty("direct_message", out var directMessage) && directMessage.GetArrayLength() > 0) - { - return JsonSerializer.Deserialize(directMessage.ToString()); - } - - return null; - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Weibo/WeiboDataConfig.cs b/Microsoft.Toolkit.Services/Services/Weibo/WeiboDataConfig.cs deleted file mode 100644 index ced23b195..000000000 --- a/Microsoft.Toolkit.Services/Services/Weibo/WeiboDataConfig.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.Weibo -{ - /// - /// Query string configuration. - /// - public class WeiboDataConfig - { - /// - /// Gets or sets Weibo query type. - /// - public WeiboQueryType QueryType { get; set; } - - /// - /// Gets or sets query parameters. - /// - public string Query { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Weibo/WeiboDataProvider.cs b/Microsoft.Toolkit.Services/Services/Weibo/WeiboDataProvider.cs deleted file mode 100644 index ca888d224..000000000 --- a/Microsoft.Toolkit.Services/Services/Weibo/WeiboDataProvider.cs +++ /dev/null @@ -1,452 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Text.Json; -using System.Threading.Tasks; -using Microsoft.Toolkit.Parsers; -using Microsoft.Toolkit.Services.Core; -using Microsoft.Toolkit.Services.OAuth; - -#if WINRT -using System.Runtime.InteropServices.WindowsRuntime; -using Microsoft.Toolkit.Services.PlatformSpecific.Uwp; -using Windows.Storage.Streams; -#endif - -#if NET462 -using Microsoft.Toolkit.Services.PlatformSpecific.NetFramework; -#endif - -namespace Microsoft.Toolkit.Services.Weibo -{ - /// - /// Data Provider for connecting to Weibo service. - /// - public class WeiboDataProvider : Toolkit.Services.DataProviderBase - { - /// - /// Base Url for service. - /// - private const string BaseUrl = "https://api.weibo.com/2"; - private const string OAuthBaseUrl = "https://api.weibo.com/oauth2"; - private const string PasswordKey = "Weibo"; - private const string StorageKey = "WeiboUid"; - - private static HttpClient _client; - - /// - /// Base Url for service. - /// - private readonly WeiboOAuthTokens _tokens; - private readonly IAuthenticationBroker _authenticationBroker; - private readonly IPasswordManager _passwordManager; - private readonly IStorageManager _storageManager; - - /// - /// Gets if logged in user information. - /// - public long? Uid { get; private set; } - - /// - /// Gets a value indicating whether the provider is already logged in - /// - public bool LoggedIn { get; private set; } - - /// - /// Initializes a new instance of the class. - /// Constructor. - /// - /// OAuth tokens for request. - /// Authentication result interface. - /// Platform password manager - /// Platform storage provider - public WeiboDataProvider(WeiboOAuthTokens tokens, IAuthenticationBroker authenticationBroker, IPasswordManager passwordManager, IStorageManager storageManager) - { - if (string.IsNullOrEmpty(tokens.AppSecret)) - { - throw new ArgumentException("Missing app secret"); - } - - if (string.IsNullOrEmpty(tokens.AppKey)) - { - throw new ArgumentException("Missing app key"); - } - - if (string.IsNullOrEmpty(tokens.RedirectUri)) - { - throw new ArgumentException("Missing redirect uri"); - } - - _tokens = tokens; - _authenticationBroker = authenticationBroker ?? throw new ArgumentException("Invalid AuthenticationBroker"); - _passwordManager = passwordManager ?? throw new ArgumentException("Invalid PasswordManager"); - _storageManager = storageManager ?? throw new ArgumentException("Invalid StorageManager"); - if (_client == null) - { - HttpClientHandler handler = new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip }; - _client = new HttpClient(handler); - } - } - -#if WINRT - /// - /// Initializes a new instance of the class. - /// Constructor. - /// - /// OAuth tokens for request. - public WeiboDataProvider(WeiboOAuthTokens tokens) - : this(tokens, new UwpAuthenticationBroker(), new UwpPasswordManager(), new UwpStorageManager()) - { - } -#endif - -#if NET462 - /// - /// Initializes a new instance of the class. - /// Constructor. - /// - /// OAuth tokens for request. - public WeiboDataProvider(WeiboOAuthTokens tokens) - : this(tokens, new NetFrameworkAuthenticationBroker(), new NetFrameworkPasswordManager(), new NetFrameworkStorageManager()) - { - } -#endif - - /// - /// Log user in to Weibo. - /// - /// Boolean indicating login success. - public async Task LoginAsync() - { - var credentials = _passwordManager.Get(PasswordKey); - string uidString = await _storageManager.GetAsync(StorageKey); - if (long.TryParse(uidString, out var uid) && credentials != null) - { - _tokens.AccessToken = credentials.Password; - Uid = uid; - LoggedIn = true; - return true; - } - - string appKey = _tokens.AppKey; - string redirectUri = _tokens.RedirectUri; - string weiboUrl = $"{OAuthBaseUrl}/authorize?client_id={appKey}&redirect_uri={redirectUri}"; - - Uri startUri = new Uri(weiboUrl); - Uri endUri = new Uri(redirectUri); - - var result = await _authenticationBroker.Authenticate(startUri, endUri); - - switch (result.ResponseStatus) - { - case AuthenticationResultStatus.Success: - LoggedIn = true; - return await ExchangeRequestTokenForAccessTokenAsync(result.ResponseData); - case AuthenticationResultStatus.ErrorHttp: - LoggedIn = false; - return false; - - case AuthenticationResultStatus.UserCancel: - LoggedIn = false; - return false; - } - - LoggedIn = false; - return false; - } - - /// - /// Log user out of Weibo. - /// - /// A representing the asynchronous operation. - public async Task LogoutAsync() - { - var credential = _passwordManager.Get(PasswordKey); - - if (credential != null) - { - _passwordManager.Remove(PasswordKey); - await _storageManager.SetAsync(StorageKey, null); - } - - Uid = null; - LoggedIn = false; - } - - /// - /// Extract and initialize access tokens. - /// - /// WAB data containing appropriate tokens. - /// Success or failure. - private async Task ExchangeRequestTokenForAccessTokenAsync(string webAuthResultResponseData) - { - string query = new Uri(webAuthResultResponseData, UriKind.Absolute).Query; - string code = null; - foreach (var keyValue in query.Split(new[] { '?', '&' }, StringSplitOptions.RemoveEmptyEntries)) - { - if (keyValue.StartsWith("code=", StringComparison.OrdinalIgnoreCase)) - { - code = keyValue.Substring("code=".Length); - break; - } - } - - if (code == null) - { - return false; - } - - string weiboUrl = $"{OAuthBaseUrl}/access_token"; - - Dictionary postData = new Dictionary - { - ["client_id"] = _tokens.AppKey, - ["client_secret"] = _tokens.AppSecret, - ["grant_type"] = "authorization_code", - ["code"] = code, - ["redirect_uri"] = _tokens.RedirectUri - }; - - FormUrlEncodedContent postContent = new FormUrlEncodedContent(postData); - - string data = null; - - using (HttpResponseMessage response = await _client.PostAsync(weiboUrl, postContent).ConfigureAwait(false)) - { - data = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - } - - var jObject = JsonDocument.Parse(data); - - string accessToken = jObject.RootElement.GetProperty("access_token").GetString(); - if (string.IsNullOrEmpty(accessToken)) - { - throw new NullReferenceException("The accessToken is null."); - } - - long uid = jObject.RootElement.GetProperty("uid").GetInt64(); - - Uid = uid; - _tokens.AccessToken = accessToken; - - _passwordManager.Store(PasswordKey, new PasswordCredential { UserName = "AccessToken", Password = accessToken }); - await _storageManager.SetAsync(StorageKey, uid.ToString()); - - return true; - } - - /// - /// Retrieve user data. - /// - /// User screen name or null for current logged user - /// Returns user data. - public async Task GetUserAsync(string screenName = null) - { - string rawResult = null; - try - { - Uri uri; - if (screenName == null) - { - uri = new Uri($"{BaseUrl}/users/show.json?uid={Uid}"); - } - else - { - uri = new Uri($"{BaseUrl}/users/show.json?screen_name={OAuthEncoder.UrlEncode(screenName)}"); - } - - WeiboOAuthRequest request = new WeiboOAuthRequest(); - rawResult = await request.ExecuteGetAsync(uri, _tokens); - return JsonSerializer.Deserialize(rawResult); - } - catch (UserNotFoundException) - { - throw new UserNotFoundException(screenName); - } - catch - { - if (!string.IsNullOrEmpty(rawResult)) - { - var error = JsonSerializer.Deserialize(rawResult); - - throw new WeiboException { Error = error }; - } - - throw; - } - } - - /// - /// Retrieve user timeline data with specific parser. - /// - /// Strong type for results. - /// User screen name. - /// Upper record limit. - /// Specific results parser. - /// Returns strongly typed list of results. - public async Task> GetUserTimeLineAsync(string screenName, int maxRecords, Toolkit.Parsers.IParser parser) - where TSchema : Toolkit.Parsers.SchemaBase - { - string rawResult = null; - try - { - var uri = new Uri($"{BaseUrl}/statuses/user_timeline.json?screen_name={OAuthEncoder.UrlEncode(screenName)}&count={maxRecords}"); - - WeiboOAuthRequest request = new WeiboOAuthRequest(); - rawResult = await request.ExecuteGetAsync(uri, _tokens); - - var result = parser.Parse(rawResult); - return result - .Take(maxRecords) - .ToList(); - } - catch (UserNotFoundException) - { - throw new UserNotFoundException(screenName); - } - catch - { - if (!string.IsNullOrEmpty(rawResult)) - { - var errors = JsonSerializer.Deserialize(rawResult); - - throw new WeiboException { Error = errors }; - } - - throw; - } - } - - /// - /// Get home time line data. - /// - /// Strong typed result. - /// Upper record limit. - /// Specific result parser. - /// Return strong typed list of results. - private async Task> GetHomeTimeLineAsync(int maxRecords, Toolkit.Parsers.IParser parser) - where TSchema : Toolkit.Parsers.SchemaBase - { - var uri = new Uri($"{BaseUrl}/statuses/home_timeline.json?count={maxRecords}"); - - WeiboOAuthRequest request = new WeiboOAuthRequest(); - var rawResult = await request.ExecuteGetAsync(uri, _tokens); - - return parser.Parse(rawResult); - } - - /// - /// Wrapper around REST API for making data request. - /// - /// Schema to use - /// Query configuration. - /// Upper limit for records returned. - /// The zero-based index of the page that corresponds to the items to retrieve. - /// IParser implementation for interpreting results. - /// Strongly typed list of results. - protected override async Task> GetDataAsync(WeiboDataConfig config, int maxRecords, int pageIndex, IParser parser) - { - IEnumerable items; - switch (config.QueryType) - { - case WeiboQueryType.User: - items = await GetUserTimeLineAsync(config.Query, maxRecords, parser); - break; - - case WeiboQueryType.Home: - default: - items = await GetHomeTimeLineAsync(maxRecords, parser); - break; - } - - return items; - } - - /// - /// Check validity of configuration. - /// - /// Query configuration. - protected override void ValidateConfig(WeiboDataConfig config) - { - if (config?.Query == null && config?.QueryType != WeiboQueryType.Home) - { - throw new ConfigParameterNullException(nameof(config.Query)); - } - - if (_tokens == null) - { - throw new ConfigParameterNullException(nameof(_tokens)); - } - - if (string.IsNullOrEmpty(_tokens.AppKey)) - { - throw new OAuthKeysNotPresentException(nameof(_tokens.AppKey)); - } - - if (string.IsNullOrEmpty(_tokens.AppSecret)) - { - throw new OAuthKeysNotPresentException(nameof(_tokens.AppSecret)); - } - } - - /// - /// Returns parser implementation for specified configuration. - /// - /// Query configuration. - /// Strongly typed parser. - protected override IParser GetDefaultParser(WeiboDataConfig config) - { - if (config == null) - { - throw new ConfigNullException(); - } - - switch (config.QueryType) - { - case WeiboQueryType.Home: - case WeiboQueryType.User: - return new WeiboParser(); - - default: - return new WeiboParser(); - } - } - - /// - /// Posts a status update. - /// - /// Status text. - /// Picture to attach to the status. - /// Success or failure. - public async Task PostStatusAsync(string status, Stream picture = null) - { - var uri = new Uri($"{BaseUrl}/statuses/share.json"); - - WeiboOAuthRequest request = new WeiboOAuthRequest(); - - if (picture == null) - { - return await request.ExecutePostAsync(uri, _tokens, status); - } - else - { - byte[] fileBytes; - - using (var ms = new MemoryStream()) - { - await picture.CopyToAsync(ms); - fileBytes = ms.ToArray(); - } - - return await request.ExecutePostMultipartAsync(uri, _tokens, status, fileBytes); - } - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Weibo/WeiboError.cs b/Microsoft.Toolkit.Services/Services/Weibo/WeiboError.cs deleted file mode 100644 index 0a426bc9c..000000000 --- a/Microsoft.Toolkit.Services/Services/Weibo/WeiboError.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Weibo -{ - /// - /// Weibo error type - /// - public class WeiboError - { - /// - /// Gets or sets error code - /// - [JsonPropertyName("error_code")] - public int Code { get; set; } - - /// - /// Gets or sets error message - /// - [JsonPropertyName("error")] - public string Message { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Weibo/WeiboException.cs b/Microsoft.Toolkit.Services/Services/Weibo/WeiboException.cs deleted file mode 100644 index b453ca0e7..000000000 --- a/Microsoft.Toolkit.Services/Services/Weibo/WeiboException.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Microsoft.Toolkit.Services.Weibo -{ - /// - /// Weibo specific exception. - /// - public class WeiboException : Exception - { - /// - /// Gets or sets the errors returned by Weibo - /// - public WeiboError Error { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Weibo/WeiboGeoInfo.cs b/Microsoft.Toolkit.Services/Services/Weibo/WeiboGeoInfo.cs deleted file mode 100644 index d7a19d136..000000000 --- a/Microsoft.Toolkit.Services/Services/Weibo/WeiboGeoInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Services.Weibo -{ - /// - /// Geographic information for a Weibo status - /// - public class WeiboGeoInfo - { - /// - /// Gets the type of geographic information - /// - [JsonPropertyName("type")] - public string Type { get; internal set; } - - /// - /// Gets the coordinates - /// - [JsonPropertyName("coordinates")] - public double[] Coordinates { get; internal set; } - - /// - public override string ToString() - { - if (Coordinates.Length > 1) - { - return $"({Coordinates[0]}, {Coordinates[1]})"; - } - - return "(0, 0)"; - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Weibo/WeiboImage.cs b/Microsoft.Toolkit.Services/Services/Weibo/WeiboImage.cs deleted file mode 100644 index dcb56e4b0..000000000 --- a/Microsoft.Toolkit.Services/Services/Weibo/WeiboImage.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Weibo -{ - /// - /// Weibo image - /// - public class WeiboImage - { - /// - /// Gets or sets the url of the attached image in thumbnail size. - /// - [JsonPropertyName("thumbnail_pic")] - public string ThumbnailImageUrl { get; set; } - - /// - /// Gets or sets the url of the attached image in medium size. - /// - [JsonPropertyName("bmiddle_pic")] - public string MediumImageUrl { get; set; } - - /// - /// Gets or sets the url of the attached image in original size. - /// - [JsonPropertyName("original_pic")] - public string OriginalImageUrl { get; set; } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Weibo/WeiboOAuthRequest.cs b/Microsoft.Toolkit.Services/Services/Weibo/WeiboOAuthRequest.cs deleted file mode 100644 index 8db8a7685..000000000 --- a/Microsoft.Toolkit.Services/Services/Weibo/WeiboOAuthRequest.cs +++ /dev/null @@ -1,182 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text.Json; -using System.Threading.Tasks; -using Microsoft.Toolkit.Services.OAuth; - -namespace Microsoft.Toolkit.Services.Weibo -{ - /// - /// OAuth request. - /// - internal class WeiboOAuthRequest - { - private static HttpClient _client; - - /// - /// Initializes a new instance of the class. - /// - public WeiboOAuthRequest() - { - if (_client == null) - { - HttpClientHandler handler = new HttpClientHandler(); - handler.AutomaticDecompression = DecompressionMethods.GZip; - _client = new HttpClient(handler); - } - } - - /// - /// HTTP Get request to specified Uri. - /// - /// Uri to make OAuth request. - /// Tokens to pass in request. - /// String result. - public async Task ExecuteGetAsync(Uri requestUri, WeiboOAuthTokens tokens) - { - using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri); - UriBuilder requestUriBuilder = new UriBuilder(request.RequestUri); - if (requestUriBuilder.Query.StartsWith("?")) - { - requestUriBuilder.Query = requestUriBuilder.Query.Substring(1) + "&access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken); - } - else - { - requestUriBuilder.Query = requestUriBuilder.Query + "?access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken); - } - - request.RequestUri = requestUriBuilder.Uri; - - using HttpResponseMessage response = await _client.SendAsync(request).ConfigureAwait(false); - response.ThrowIfNotValid(); - return ProcessError(await response.Content.ReadAsStringAsync().ConfigureAwait(false)); - } - - /// - /// HTTP Post request to specified Uri. - /// - /// Uri to make OAuth request. - /// Tokens to pass in request. - /// Status text. - /// String result. - public async Task ExecutePostAsync(Uri requestUri, WeiboOAuthTokens tokens, string status) - { - var contentDict = new Dictionary(); - contentDict.Add("status", status); - - using var formUrlEncodedContent = new FormUrlEncodedContent(contentDict); - using var request = new HttpRequestMessage(HttpMethod.Post, requestUri); - UriBuilder requestUriBuilder = new UriBuilder(request.RequestUri); - if (requestUriBuilder.Query.StartsWith("?")) - { - requestUriBuilder.Query = requestUriBuilder.Query.Substring(1) + "&access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken); - } - else - { - requestUriBuilder.Query = requestUriBuilder.Query + "access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken); - } - - request.RequestUri = requestUriBuilder.Uri; - - request.Content = formUrlEncodedContent; - - using var response = await _client.SendAsync(request).ConfigureAwait(false); - if (response.StatusCode == HttpStatusCode.OK) - { - using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); - return await JsonSerializer.DeserializeAsync(stream).ConfigureAwait(false); - } - else - { - response.ThrowIfNotValid(); - ProcessError(await response.Content.ReadAsStringAsync().ConfigureAwait(false)); - return null; - } - } - - /// - /// HTTP Post request to specified Uri. - /// - /// Uri to make OAuth request. - /// Tokens to pass in request. - /// Status text. - /// Data to post to server. - /// String result. - public async Task ExecutePostMultipartAsync(Uri requestUri, WeiboOAuthTokens tokens, string status, byte[] content) - { - try - { - using var multipartFormDataContent = new MultipartFormDataContent(); - using var stringContent = new StringContent(status); - multipartFormDataContent.Add(stringContent, "status"); - using var byteContent = new ByteArrayContent(content); - - // Somehow Weibo's backend requires a Filename field to work - byteContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { FileName = "attachment", Name = "pic" }; - multipartFormDataContent.Add(byteContent, "pic"); - - using var request = new HttpRequestMessage(HttpMethod.Post, requestUri); - UriBuilder requestUriBuilder = new UriBuilder(request.RequestUri); - if (requestUriBuilder.Query.StartsWith("?")) - { - requestUriBuilder.Query = requestUriBuilder.Query.Substring(1) + "&access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken); - } - else - { - requestUriBuilder.Query = requestUriBuilder.Query + "access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken); - } - - request.RequestUri = requestUriBuilder.Uri; - - request.Content = multipartFormDataContent; - - using var response = await _client.SendAsync(request).ConfigureAwait(false); - if (response.StatusCode == HttpStatusCode.OK) - { - using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); - return await JsonSerializer.DeserializeAsync(stream).ConfigureAwait(false); - } - else - { - response.ThrowIfNotValid(); - ProcessError(await response.Content.ReadAsStringAsync().ConfigureAwait(false)); - return null; - } - } - catch (ObjectDisposedException) - { - // known issue - // http://stackoverflow.com/questions/39109060/httpmultipartformdatacontent-dispose-throws-objectdisposedexception - } - - return null; - } - - private string ProcessError(string content) - { - if (content.StartsWith("{\"error\":")) - { - WeiboError error; - try - { - error = JsonSerializer.Deserialize(content); - } - catch (JsonException e) - { - throw new JsonException("Invalid Weibo error response!", e); - } - - throw new WeiboException { Error = error }; - } - - return content; - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Weibo/WeiboOAuthRequestExtensions.cs b/Microsoft.Toolkit.Services/Services/Weibo/WeiboOAuthRequestExtensions.cs deleted file mode 100644 index 0a49a6bd2..000000000 --- a/Microsoft.Toolkit.Services/Services/Weibo/WeiboOAuthRequestExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Net; -using System.Net.Http; - -namespace Microsoft.Toolkit.Services.Weibo -{ - /// - /// Weibo Oauth request extensions to add utilities for internal use. - /// - internal static class WeiboOAuthRequestExtensions - { - public static void ThrowIfNotValid(this HttpResponseMessage response) - { - if (response.StatusCode == HttpStatusCode.NotFound) - { - throw new UserNotFoundException(); - } - - if ((int)response.StatusCode == 429) - { - throw new TooManyRequestsException(); - } - - if (response.StatusCode == HttpStatusCode.Unauthorized) - { - throw new OAuthKeysRevokedException(); - } - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Weibo/WeiboOAuthTokens.cs b/Microsoft.Toolkit.Services/Services/Weibo/WeiboOAuthTokens.cs deleted file mode 100644 index d0ca0c099..000000000 --- a/Microsoft.Toolkit.Services/Services/Weibo/WeiboOAuthTokens.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Services.Weibo -{ - /// - /// Weibo OAuth tokens. - /// - public class WeiboOAuthTokens - { - /// - /// Gets or sets app Key. - /// - public string AppKey { get; set; } - - /// - /// Gets or sets app Secret. - /// - public string AppSecret { get; set; } - - /// - /// Gets or sets access token. - /// - public string AccessToken { get; set; } - - /// - /// Gets or sets redirect Uri. - /// - public string RedirectUri { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Weibo/WeiboParser.cs b/Microsoft.Toolkit.Services/Services/Weibo/WeiboParser.cs deleted file mode 100644 index 7691ea269..000000000 --- a/Microsoft.Toolkit.Services/Services/Weibo/WeiboParser.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; -using System.Text.Json; - -namespace Microsoft.Toolkit.Services.Weibo -{ - /// - /// Twitter Parser. - /// - /// Type to parse in to. - public class WeiboParser : Toolkit.Parsers.IParser - where T : Toolkit.Parsers.SchemaBase - { - /// - /// Parse string data into strongly typed list. - /// - /// Input string. - /// List of strongly typed objects. - IEnumerable Toolkit.Parsers.IParser.Parse(string data) - { - if (string.IsNullOrEmpty(data)) - { - return null; - } - - try - { - return JsonSerializer.Deserialize>(data); - } - catch (JsonException) - { - List items = new List(); - items.Add(JsonSerializer.Deserialize(data)); - return items; - } - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Weibo/WeiboQueryType.cs b/Microsoft.Toolkit.Services/Services/Weibo/WeiboQueryType.cs deleted file mode 100644 index bb05f1c35..000000000 --- a/Microsoft.Toolkit.Services/Services/Weibo/WeiboQueryType.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.Toolkit.Services.Weibo -{ - /// - /// Type of Weibo Query. - /// - public enum WeiboQueryType - { - /// - /// Home - /// - Home, - - /// - /// User - /// - User - } -} diff --git a/Microsoft.Toolkit.Services/Services/Weibo/WeiboService.cs b/Microsoft.Toolkit.Services/Services/Weibo/WeiboService.cs deleted file mode 100644 index d77384773..000000000 --- a/Microsoft.Toolkit.Services/Services/Weibo/WeiboService.cs +++ /dev/null @@ -1,285 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading.Tasks; -using Microsoft.Toolkit.Services.Core; -#if WINRT -using Microsoft.Toolkit.Services.PlatformSpecific.Uwp; -using Windows.Storage.Streams; -#endif - -namespace Microsoft.Toolkit.Services.Weibo -{ - /// - /// Class for connecting to Weibo. - /// - public class WeiboService - { - /// - /// Private field for WeiboDataProvider. - /// - private WeiboDataProvider _weiboDataProvider; - - /// - /// Field for tracking oAuthTokens. - /// - private WeiboOAuthTokens _tokens; - - private IPasswordManager _passwordManager; - private IStorageManager _storageManager; - private IAuthenticationBroker _authenticationBroker; - - /// - /// Field for tracking initialization status. - /// - private bool _isInitialized; - - /// - /// Initializes a new instance of the class. - /// - public WeiboService() - { - } - - /// - /// Private singleton field. - /// - private static WeiboService _instance; - - /// - /// Gets public singleton property. - /// - public static WeiboService Instance => _instance ?? (_instance = new WeiboService()); - - /// - /// Gets the current logged in user id. - /// - public long? Uid => Provider.Uid; - - /// - /// Initialize underlying provider with relevant token information. - /// - /// App key. - /// App secret. - /// Redirect URI. Has to match redirect URI defined at open.weibo.com/apps (can be arbitrary). - /// Authentication result interface. - /// Password Manager interface, store the password. - /// Storage Manager interface - /// Success or failure. - public bool Initialize(string appKey, string appSecret, string redirectUri, IAuthenticationBroker authenticationBroker, IPasswordManager passwordManager, IStorageManager storageManager) - { - if (string.IsNullOrEmpty(appKey)) - { - throw new ArgumentNullException(nameof(appKey)); - } - - if (string.IsNullOrEmpty(appSecret)) - { - throw new ArgumentNullException(nameof(appSecret)); - } - - if (string.IsNullOrEmpty(redirectUri)) - { - throw new ArgumentNullException(nameof(redirectUri)); - } - - if (authenticationBroker == null) - { - throw new ArgumentException(nameof(authenticationBroker)); - } - - if (passwordManager == null) - { - throw new ArgumentException(nameof(passwordManager)); - } - - if (storageManager == null) - { - throw new ArgumentException(nameof(storageManager)); - } - - var oAuthTokens = new WeiboOAuthTokens - { - AppKey = appKey, - AppSecret = appSecret, - RedirectUri = redirectUri - }; - - return Initialize(oAuthTokens, authenticationBroker, passwordManager, storageManager); - } - - /// - /// Initialize underlying provider with relevant token information. - /// - /// Token instance. - /// Authentication result interface. - /// Password Manager interface, store the password. - /// Storage Manager interface - /// Success or failure. - public bool Initialize(WeiboOAuthTokens oAuthTokens, IAuthenticationBroker authenticationBroker, IPasswordManager passwordManager, IStorageManager storageManager) - { - _tokens = oAuthTokens ?? throw new ArgumentNullException(nameof(oAuthTokens)); - this._authenticationBroker = authenticationBroker ?? throw new ArgumentNullException(nameof(authenticationBroker)); - this._passwordManager = passwordManager ?? throw new ArgumentNullException(nameof(passwordManager)); - this._storageManager = storageManager ?? throw new ArgumentNullException(nameof(storageManager)); - - _isInitialized = true; - - _weiboDataProvider = null; - - return true; - } - -#if WINRT - /// - /// Initialize underlying provider with relevant token information for UWP. - /// - /// App key. - /// App secret. - /// Redirect URI. Has to match redirect URI defined at open.weibo.com/apps (can be arbitrary). - /// Success or failure. - public bool Initialize(string appKey, string appSecret, string redirectUri) - { - return Initialize(appKey, appSecret, redirectUri, new UwpAuthenticationBroker(), new UwpPasswordManager(), new UwpStorageManager()); - } - - /// - /// Initialize underlying provider with relevant token information. - /// - /// Token instance. - /// Success or failure. - public bool Initialize(WeiboOAuthTokens oAuthTokens) - { - return Initialize(oAuthTokens, new UwpAuthenticationBroker(), new UwpPasswordManager(), new UwpStorageManager()); - } -#endif - - /// - /// Gets a reference to an instance of the underlying data provider. - /// - public WeiboDataProvider Provider - { - get - { - if (!_isInitialized) - { - throw new InvalidOperationException("Provider not initialized."); - } - - return _weiboDataProvider ?? (_weiboDataProvider = new WeiboDataProvider(_tokens, _authenticationBroker, _passwordManager, _storageManager)); - } - } - - /// - /// Log user in to Weibo. - /// - /// Returns success of failure of login attempt. - public Task LoginAsync() - { - return Provider.LoginAsync(); - } - - /// - /// Log user out of Weibo. - /// - /// A representing the asynchronous operation. - public Task LogoutAsync() - { - return Provider.LogoutAsync(); - } - - /// - /// Retrieve user data. - /// - /// User screen name or null for current logged user. - /// Returns user data. - public async Task GetUserAsync(string screenName = null) - { - if (Provider.LoggedIn) - { - return await Provider.GetUserAsync(screenName); - } - - var isLoggedIn = await LoginAsync(); - if (isLoggedIn) - { - return await GetUserAsync(screenName); - } - - return null; - } - - /// - /// Retrieve user timeline data. - /// - /// User screen name. - /// Upper record limit. - /// Returns strongly typed list of results. - public async Task> GetUserTimeLineAsync(string screenName, int maxRecords = 20) - { - if (Provider.LoggedIn) - { - return await Provider.GetUserTimeLineAsync(screenName, maxRecords, new WeiboStatusParser()); - } - - var isLoggedIn = await LoginAsync(); - if (isLoggedIn) - { - return await GetUserTimeLineAsync(screenName, maxRecords); - } - - return null; - } - - /// - /// Post a status. - /// Due to the restriction by Weibo API, your status must include a url which starts with "http"/"https". - /// You can add a url to the list of secure domains in the basic information section on your Weibo application page. - /// - /// The status information. - /// Returns the published weibo status. - public async Task PostStatusAsync(string status) - { - if (Provider.LoggedIn) - { - return await Provider.PostStatusAsync(status); - } - - var isLoggedIn = await LoginAsync(); - if (isLoggedIn) - { - return await PostStatusAsync(status); - } - - return null; - } - - /// - /// Post a status with a picture. - /// Due to the restriction by Weibo API, your status must include a url which starts with "http"/"https". - /// You can add a url to the list of secure domains in the basic information section on your Weibo application page. - /// - /// The status information. - /// Picture to attach to the status. - /// Returns the published weibo status. - public async Task PostStatusAsync(string status, Stream picture) - { - if (Provider.LoggedIn) - { - return await Provider.PostStatusAsync(status, picture); - } - - var isLoggedIn = await LoginAsync(); - if (isLoggedIn) - { - return await PostStatusAsync(status, picture); - } - - return null; - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Services/Services/Weibo/WeiboStatus.cs b/Microsoft.Toolkit.Services/Services/Weibo/WeiboStatus.cs deleted file mode 100644 index 7e8c06a8f..000000000 --- a/Microsoft.Toolkit.Services/Services/Weibo/WeiboStatus.cs +++ /dev/null @@ -1,143 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Globalization; -using System.Text.Json.Serialization; -using Microsoft.Toolkit.Services.Services.Weibo; - -namespace Microsoft.Toolkit.Services.Weibo -{ - /// - /// Weibo Timeline item. - /// - public class WeiboStatus : Toolkit.Parsers.SchemaBase - { - /// - /// Gets or sets time item was created. - /// - [JsonPropertyName("created_at")] - public string CreatedAt { get; set; } - - /// - /// Gets the creation date - /// - public DateTime CreationDate - { - get - { - DateTime dt; - if (!DateTime.TryParseExact(CreatedAt, "ddd MMM dd HH:mm:ss zzzz yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt)) - { - dt = DateTime.Today; - } - - return dt; - } - } - - /// - /// Gets or sets item Id. - /// - [JsonPropertyName("id")] - public string Id { get; set; } - - /// - /// Gets or sets text of the status (handles both 140 and 280 characters) - /// - [JsonPropertyName("text")] - public string Text { get; set; } - - /// - /// Gets or sets a value indicating whether status is truncated - /// (true when Weibo status is longer than 140 characters) - /// This entity may be deprecated - it never seems to be set to true. - /// - [JsonPropertyName("truncated")] - public bool IsTruncated { get; set; } - - /// - /// Gets or sets status source (client or website used) - /// - [JsonPropertyName("source")] - public string Source { get; set; } - - /// - /// Gets or sets in_reply_to_screen_name - /// - [JsonPropertyName("in_reply_to_screen_name")] - public string InReplyToScreenName { get; set; } - - /// - /// Gets or sets in_reply_to_status_id - /// - [JsonPropertyName("in_reply_to_status_id")] - public string InReplyToStatusId { get; set; } - - /// - /// Gets or sets in_reply_to_user_id - /// - [JsonPropertyName("in_reply_to_user_id")] - public string InReplyToUserId { get; set; } - - /// - /// Gets or sets user who posted the status. - /// - [JsonPropertyName("user")] - public WeiboUser User { get; set; } - - /// - /// Gets or sets the Reposted Weibo status - /// - [JsonPropertyName("retweeted_status")] - public WeiboStatus RepostedStatus { get; set; } - - /// - /// Gets or sets the repost count - /// - [JsonPropertyName("reposts_count")] - public int RepostCount { get; set; } - - /// - /// Gets or sets the comment count - /// - [JsonPropertyName("comments_count")] - public int CommentCount { get; set; } - - /// - /// Gets or sets the url of the attached image in thumbnail size. - /// - [JsonPropertyName("thumbnail_pic")] - public string ThumbnailImageUrl { get; set; } - - /// - /// Gets or sets the url of the attached image in medium size. - /// - [JsonPropertyName("bmiddle_pic")] - public string MediumImageUrl { get; set; } - - /// - /// Gets or sets the url of the attached image in original size. - /// - [JsonPropertyName("original_pic")] - public string OriginalImageUrl { get; set; } - - /// - /// Gets or sets attached images array of the weibo. - /// - [JsonPropertyName("pic_urls")] - public WeiboImage[] AttachedImages { get; set; } - - /// - /// Gets or sets the geographic information. - /// - [JsonPropertyName("geo")] - public WeiboGeoInfo GeographicInfo { get; set; } - - /// - /// Gets a value indicating whether the weibo status includes attached images. - /// - public bool HasAttachedImage => AttachedImages != null && AttachedImages.Length > 0; - } -} diff --git a/Microsoft.Toolkit.Services/Services/Weibo/WeiboStatusParser.cs b/Microsoft.Toolkit.Services/Services/Weibo/WeiboStatusParser.cs deleted file mode 100644 index cdeac8285..000000000 --- a/Microsoft.Toolkit.Services/Services/Weibo/WeiboStatusParser.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; -using System.Text.Json; - -namespace Microsoft.Toolkit.Services.Weibo -{ - /// - /// Weibo Timeline Parser. - /// - public class WeiboStatusParser : Parsers.IParser - { - /// - /// Parse string data into strongly typed list. - /// - /// Input string. - /// List of strongly typed objects. - public IEnumerable Parse(string data) - { - if (string.IsNullOrEmpty(data)) - { - return null; - } - - var rawObject = JsonDocument.Parse(data); - - var rawStatuses = rawObject.RootElement.GetProperty("statuses"); - - IList statuses = new List(); - foreach (var rawStatus in rawStatuses.EnumerateArray()) - { - WeiboStatus searchResult = JsonSerializer.Deserialize(rawStatus.ToString()); - statuses.Add(searchResult); - } - - return statuses; - } - } -} diff --git a/Microsoft.Toolkit.Services/Services/Weibo/WeiboUser.cs b/Microsoft.Toolkit.Services/Services/Weibo/WeiboUser.cs deleted file mode 100644 index c815af4d7..000000000 --- a/Microsoft.Toolkit.Services/Services/Weibo/WeiboUser.cs +++ /dev/null @@ -1,92 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text.Json.Serialization; - -namespace Microsoft.Toolkit.Services.Weibo -{ - /// - /// Weibo User type. - /// - public class WeiboUser - { - /// - /// Gets or sets user Id. - /// - [JsonPropertyName("id")] - public string Id { get; set; } - - /// - /// Gets or sets user name. - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// Gets or sets user screen name. - /// - [JsonPropertyName("screen_name")] - public string ScreenName { get; set; } - - /// - /// Gets or sets profile location. - /// - [JsonPropertyName("location")] - public string Location { get; set; } - - /// - /// Gets or sets profile url. - /// - [JsonPropertyName("url")] - public string Url { get; set; } - - /// - /// Gets or sets profile description. - /// - [JsonPropertyName("description")] - public string Description { get; set; } - - /// - /// Gets or sets profile image url. - /// - [JsonPropertyName("profile_image_url")] - public string ProfileImageUrl { get; set; } - - /// - /// Gets or sets high resolution profile image url. - /// - [JsonPropertyName("avatar_large")] - public string HighResolutionProfileImageUrl { get; set; } - - /// - /// Gets or sets followers count. - /// - [JsonPropertyName("followers_count")] - public int FollowersCount { get; set; } - - /// - /// Gets or sets count of accounts user is following. - /// - [JsonPropertyName("friends_count")] - public int FriendsCount { get; set; } - - /// - /// Gets or sets total count of statuses user has liked. - /// - [JsonPropertyName("favourites_count")] - public int FavoritesCount { get; set; } - - /// - /// Gets or sets total count of Weibo statuses (including reposted statuses) posted by user. - /// - [JsonPropertyName("statuses_count")] - public int StatusesCount { get; set; } - - /// - /// Gets or sets a value indicating whether account is verified (blue check mark). - /// - [JsonPropertyName("verified")] - public bool Verified { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index d55194bd8..528dee72b 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -330,7 +330,6 @@ - @@ -338,10 +337,8 @@ - - @@ -363,13 +360,9 @@ - - - - @@ -399,7 +392,6 @@ - @@ -421,7 +413,6 @@ - @@ -493,7 +484,6 @@ - AutoFocusBehaviorPage.xaml @@ -837,9 +827,6 @@ MarkdownTextBlockPage.xaml - - MicrosoftTranslatorPage.xaml - TileControlPage.xaml @@ -860,9 +847,6 @@ - - LinkedInPage.xaml - LoadingPage.xaml @@ -902,13 +886,9 @@ ToastPage.xaml - - TwitterPage.xaml - ImageExPage.xaml - ViewportBehaviorPage.xaml @@ -924,9 +904,6 @@ RangeSelectorPage.xaml - - WeiboPage.xaml - WrapPanelPage.xaml @@ -1278,10 +1255,6 @@ MSBuild:Compile Designer - - MSBuild:Compile - Designer - MSBuild:Compile Designer @@ -1310,10 +1283,6 @@ MSBuild:Compile Designer - - Designer - MSBuild:Compile - MSBuild:Compile Designer @@ -1366,10 +1335,6 @@ MSBuild:Compile Designer - - MSBuild:Compile - Designer - MSBuild:Compile Designer @@ -1394,10 +1359,6 @@ MSBuild:Compile Designer - - Designer - MSBuild:Compile - Designer MSBuild:Compile @@ -1444,10 +1405,6 @@ {42CA4935-54BE-42EA-AC19-992378C08DE6} Microsoft.Toolkit.Parsers - - {34398053-fc70-4243-84f9-f355defff66d} - Microsoft.Toolkit.Services - {b1e850ff-dde6-44d5-a830-34250e97a687} Microsoft.Toolkit.Uwp.Connectivity diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/LinkedIn Service/LinkedInCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/LinkedIn Service/LinkedInCode.bind deleted file mode 100644 index d15b97d47..000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/LinkedIn Service/LinkedInCode.bind +++ /dev/null @@ -1,16 +0,0 @@ -// Initialize service -LinkedInService.Instance.Initialize(ClientId.Text, ClientSecret.Text, CallbackUri.Text); - -// Login to LinkedIn -if (!await LinkedInService.Instance.LoginAsync()) -{ - return; -} - -// Get current user's profile details -await LinkedInService.Instance.GetUserProfileAsync(); - -// Share message to LinkedIn (text should include a Url so LinkedIn can scrape preview information) -await LinkedInService.Instance.ShareActivityAsync(ShareText.Text); - - diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/LinkedIn Service/LinkedInLogo.png b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/LinkedIn Service/LinkedInLogo.png deleted file mode 100644 index ed6da08c7953059cf2e860fbd52b316b0e53aa6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1661 zcmeAS@N?(olHy`uVBq!ia0y~yU{nCI4{)#n$t4^1Z39v)#ZI0f96(URk7VKo<=nzy; zaBFCgU}Q=f;+z?MUl_KWyHQa8_sPYFRR#6_x$iU9|JN<%?*4lG`m)-k{+;XvwE4%AE`PKDm`OEt2CHsGoAV=JscdjaB!*;gn-ItOtIxt;PF#c@*>bd@(wa4b~uQS*YDYRF!*8#(-nc|`seSO+HJQf`&DyR zS10d+i-JS%$3yqmuglsy{eDgPT=m9&4gvY%w|{596wDA{%<7nT?yBwm3tO)$9z0gK z#q`LF#=EPd-d~tE_q7dYjZ1@6Qp){xRavd&6X#o7?s{dcn!(DLH9=keXU*S7FPOdc ztjmkG@bQ1m{orCUx4xWr)81t7+WIfWrC%=G`}JA+f93A z@7bGt-&v+7IP@4RT)TVbPw%d8|Mst5mG%DITf2ZBe$Ieq8|&KCn@?-4w_Q82FSh(n z-OE>7XYKoRZ`192b)Mz5AJgXUw+Y|B+hFsP+xExWe!qUfT%G;pz&q7?xwDE6yq{j^ z$48a@40h+!lWcjZ{eJC^x9pGauUxfi|Guy5t3JJ)KK<{jIh`wS@=u@t>)G^I?(zSf zlrg?&<659{spuWM~?# ze$MaOSJ(H>*;0&2XF)Dl{(RZB5_w?K`FeZ*o{Nh*Z|JaenC|{-ICrZ>-Lc4k%NzpV zr*Ip8ekpjvL9S)lQ;?Qu=f77k-wXuB`kgPY&QFM&IrICKnr03G-LLKPHEZSM-u%6h zYya<yp2sC>h@$s1+@ zE!(cJQK-Mw%B z|N2%?Z@Z)Z=kG<9EGry=>EmzwZQgHXR}=EXz0*GQir+b>Dj|SmLBQ-C`znlW54B}p z+PBRbn0v(2o?TYXnW6SJd$;fcv%*(1!?V-=xmER)nj6 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -