Skip to content

Commit

Permalink
Merge branch 'master' into muxtestinfra
Browse files Browse the repository at this point in the history
  • Loading branch information
azchohfi committed Sep 18, 2020
2 parents 99f18d6 + e3c08ac commit 666d354
Show file tree
Hide file tree
Showing 103 changed files with 1,697 additions and 768 deletions.
6 changes: 3 additions & 3 deletions Microsoft.Toolkit.Services/Microsoft.Toolkit.Services.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
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.
</Description>
<PackageTags>UWP Community Toolkit Windows Microsoft Graph OneDrive Twitter Translator LinkedIn service login OAuth</PackageTags>

<LangVersion>8.0</LangVersion>
<NoWarn>CS8002;CS0618</NoWarn>
<DeterministicSourcePaths Condition="'$(EnableSourceLink)' == ''">false</DeterministicSourcePaths>
</PropertyGroup>
Expand All @@ -27,7 +27,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="System.Text.Json" Version="4.7.2" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>

Expand All @@ -50,4 +50,4 @@
<ItemGroup Condition="!('$(TargetFramework)'=='uap10.0.16299')">
<Compile Remove="PlatformSpecific\Uwp\**\*" />
</ItemGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Library Name="Microsoft.Toolkit.Services">
<Namespace Name="System.Text.Json.Serialization.Converters" Dynamic="Required All"/>
</Library>
</Directives>
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
using System.Diagnostics;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Toolkit.Services.Core;
using Newtonsoft.Json.Linq;

#if WINRT
using Microsoft.Toolkit.Services.PlatformSpecific.Uwp;
Expand Down Expand Up @@ -81,7 +81,8 @@ public LinkedInDataProvider(LinkedInOAuthTokens tokens, LinkedInPermissions requ
throw new ArgumentException("Missing callback uri");
}

if (!Enum.IsDefined(typeof(LinkedInPermissions), requiredPermissions))
// Check if its a valid combination of LinkedInPermissions
if ((~(int)LinkedInPermissionsHelpers.AllPermissions & (int)requiredPermissions) != 0)
{
throw new ArgumentException("Error retrieving required permissions");
}
Expand Down Expand Up @@ -186,22 +187,18 @@ public async Task<IEnumerable<TSchema>> GetDataAsync<TSchema>(LinkedInDataConfig

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);
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(url));
request.Headers.Connection.TryParseAdd("Keep-Alive");

if (response.IsSuccessStatusCode && !string.IsNullOrEmpty(data))
{
return parser.Parse(data);
}
using var response = await client.SendAsync(request).ConfigureAwait(false);
var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

throw new RequestFailedException((System.Net.HttpStatusCode)response.StatusCode, data);
}
if (response.IsSuccessStatusCode && !string.IsNullOrEmpty(data))
{
return parser.Parse(data);
}

throw new RequestFailedException((System.Net.HttpStatusCode)response.StatusCode, data);
}

/// <summary>
Expand All @@ -222,22 +219,18 @@ public async Task<IEnumerable<TSchema>> GetDataAsync<TSchema>(LinkedInDataConfig

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 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);
using var response = await client.SendAsync(request).ConfigureAwait(false);
var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

var responseParser = new LinkedInParser<U>();
var responseParser = new LinkedInParser<U>();

var listResults = responseParser.Parse(data) as List<U>;
return listResults[0];
}
}
var listResults = responseParser.Parse(data) as List<U>;
return listResults[0];
}

return default(U);
Expand All @@ -263,15 +256,13 @@ private async Task<string> GetAccessTokenAsync(LinkedInOAuthTokens tokens, strin
+ "&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))
{
var jsonString = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var json = JObject.Parse(jsonString);
return json.GetValue("access_token").Value<string>();
}
}
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<string> GetAuthorizeCodeAsync(LinkedInOAuthTokens tokens, LinkedInPermissions permissions)
Expand Down
10 changes: 5 additions & 5 deletions Microsoft.Toolkit.Services/Services/LinkedIn/LinkedInParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.

using System.Collections.Generic;
using Newtonsoft.Json;
using System.Text.Json;

namespace Microsoft.Toolkit.Services.LinkedIn
{
Expand All @@ -24,11 +24,11 @@ public IEnumerable<T> Parse(string data)

try
{
results = JsonConvert.DeserializeObject<List<T>>(data);
results = JsonSerializer.Deserialize<List<T>>(data);
}
catch (JsonSerializationException)
catch (JsonException)
{
T linkedInResult = JsonConvert.DeserializeObject<T>(data);
T linkedInResult = JsonSerializer.Deserialize<T>(data);
results = new List<T> { linkedInResult };
}

Expand All @@ -42,7 +42,7 @@ public IEnumerable<T> Parse(string data)
/// <returns>Returns string data.</returns>
public string Parse(T dataToShare)
{
return JsonConvert.SerializeObject(dataToShare, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
return JsonSerializer.Serialize(dataToShare, typeof(T), new JsonSerializerOptions { IgnoreNullValues = true });
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,18 @@ public enum LinkedInPermissions
/// </summary>
WriteShare = 8
}

#pragma warning disable SA1649 // File name should match first type name
internal static class LinkedInPermissionsHelpers
{
/// <summary>
/// Internal AllPermissions for LinkedInPermissions, so we don't expose it. Keep it in sync with <see cref="LinkedInPermissions"/>
/// </summary>
internal const LinkedInPermissions AllPermissions =
LinkedInPermissions.ReadBasicProfile |
LinkedInPermissions.ReadEmailAddress |
LinkedInPermissions.ReadWriteCompanyAdmin |
LinkedInPermissions.WriteShare;
}
#pragma warning restore SA1649 // File name should match first type name
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Microsoft.Toolkit.Services.MicrosoftTranslator
{
Expand All @@ -24,6 +24,9 @@ internal class AzureAuthToken
/// </summary>
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);

/// <summary>
/// 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.
Expand Down Expand Up @@ -90,24 +93,22 @@ public async Task<string> GetAccessTokenAsync()
return _storedTokenValue;
}

using (var request = new HttpRequestMessage(HttpMethod.Post, ServiceUrl))
{
request.Headers.Add(OcpApimSubscriptionKeyHeader, SubscriptionKey);
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);
var response = await client.SendAsync(request).ConfigureAwait(false);
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

if (!response.IsSuccessStatusCode)
{
var error = JsonConvert.DeserializeObject<ErrorResponse>(content);
throw new TranslatorServiceException(error.Message);
}
if (!response.IsSuccessStatusCode)
{
var error = JsonSerializer.Deserialize<ErrorResponse>(content);
throw new TranslatorServiceException(error?.Error?.Message);
}

_storedTokenTime = DateTime.Now;
_storedTokenValue = $"Bearer {content}";
_storedTokenTime = DateTime.Now;
_storedTokenValue = $"Bearer {content}";

return _storedTokenValue;
}
return _storedTokenValue;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,27 @@
// 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
/// <summary>
/// Holds information about an error occurred while accessing Microsoft Translator Service.
/// </summary>
internal class ErrorResponse
{
[JsonPropertyName("error")]
public Error Error { get; set; }
}

internal class Error
{
/// <summary>
/// Gets or sets the error message.
/// </summary>
[JsonPropertyName("message")]
public string Message { get; set; }

/// <summary>
/// Gets or sets the HTTP status code.
/// </summary>
public int StatusCode { get; set; }
}
#pragma warning restore SA1402 // File may only contain a single type
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Newtonsoft.Json;
using System.Text.Json.Serialization;

namespace Microsoft.Toolkit.Services.MicrosoftTranslator
{
Expand Down Expand Up @@ -30,7 +30,7 @@ public class ServiceLanguage
/// <summary>
/// Gets the directionality, which is rtl for right-to-left languages or ltr for left-to-right languages.
/// </summary>
[JsonProperty("dir")]
[JsonPropertyName("dir")]
public string Directionality { get; }

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Microsoft.Toolkit.Services.MicrosoftTranslator
{
Expand Down Expand Up @@ -108,14 +107,13 @@ public async Task<IEnumerable<DetectedLanguageResponse>> DetectLanguagesWithResp
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);
using var request = CreateHttpRequest(uriString, HttpMethod.Post, input.Select(t => new { Text = t.Substring(0, Math.Min(t.Length, _MaxTextLengthForDetection)) }));

var responseContent = JsonConvert.DeserializeObject<IEnumerable<DetectedLanguageResponse>>(content);
return responseContent;
}
var response = await client.SendAsync(request).ConfigureAwait(false);
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

var responseContent = JsonSerializer.Deserialize<IEnumerable<DetectedLanguageResponse>>(content);
return responseContent;
}

/// <inheritdoc/>
Expand All @@ -132,24 +130,23 @@ public async Task<IEnumerable<ServiceLanguage>> GetLanguageNamesAsync(string lan
await CheckUpdateTokenAsync().ConfigureAwait(false);

var uriString = $"{BaseUrl}languages?scope=translation&{ApiVersion}";
using (var request = CreateHttpRequest(uriString))
using var request = CreateHttpRequest(uriString);

language = language ?? Language;
if (!string.IsNullOrWhiteSpace(language))
{
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));
}
// 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 response = await client.SendAsync(request).ConfigureAwait(false);
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

var jsonContent = JToken.Parse(content)["translation"];
var responseContent = JsonConvert.DeserializeObject<Dictionary<string, ServiceLanguage>>(jsonContent.ToString()).ToList();
responseContent.ForEach(r => r.Value.Code = r.Key);
var jsonContent = JsonDocument.Parse(content).RootElement.GetProperty("translation");
var responseContent = JsonSerializer.Deserialize<Dictionary<string, ServiceLanguage>>(jsonContent.ToString()).ToList();
responseContent.ForEach(r => r.Value.Code = r.Key);

return responseContent.Select(r => r.Value).OrderBy(r => r.Name).ToList();
}
return responseContent.Select(r => r.Value).OrderBy(r => r.Name).ToList();
}

/// <inheritdoc/>
Expand Down Expand Up @@ -216,14 +213,13 @@ public async Task<IEnumerable<TranslationResponse>> TranslateWithResponseAsync(I

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);
using var request = CreateHttpRequest(uriString, HttpMethod.Post, input.Select(t => new { Text = t }));

var responseContent = JsonConvert.DeserializeObject<IEnumerable<TranslationResponse>>(content);
return responseContent;
}
var response = await client.SendAsync(request).ConfigureAwait(false);
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

var responseContent = JsonSerializer.Deserialize<IEnumerable<TranslationResponse>>(content);
return responseContent;
}

/// <inheritdoc/>
Expand Down Expand Up @@ -254,7 +250,7 @@ private HttpRequestMessage CreateHttpRequest(string uriString, HttpMethod method

if (content != null)
{
var jsonRequest = JsonConvert.SerializeObject(content);
var jsonRequest = JsonSerializer.Serialize(content);
var requestContent = new StringContent(jsonRequest, System.Text.Encoding.UTF8, JsonMediaType);
request.Content = requestContent;
}
Expand Down
Loading

0 comments on commit 666d354

Please sign in to comment.