Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion AspNet.Security.OAuth.Providers.sln
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{C2CA4B38-A
docs\digitalocean.md = docs\digitalocean.md
docs\discord.md = docs\discord.md
docs\docusign.md = docs\docusign.md
douyin.md = douyin.md
docs\dropbox.md = docs\dropbox.md
docs\ebay.md = docs\ebay.md
docs\eveonline.md = docs\eveonline.md
Expand Down
3 changes: 1 addition & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ covered by the section above.
| Bitbucket | _Optional_ | [Documentation](bitbucket.md "Bitbucket provider documentation") |
| DigitalOcean | _Optional_ | [Documentation](digitalocean.md "DigitalOcean provider documentation") |
| Discord | _Optional_ | [Documentation](discord.md "Discord provider documentation") |
| Docusign | **Required** | [Documentation](docusign.md "Docusign provider documentation") |
| Douyin | _Optional_ | [Documentation](douyin.md "Douyin provider documentation") |
| Docusign | **Required** | [Documentation](docusign.md "Docusign provider documentation") |
| eBay | **Required** | [Documentation](ebay.md "eBay provider documentation") |
| EVEOnline | _Optional_ | [Documentation](eveonline.md "EVEOnline provider documentation") |
| Foursquare | _Optional_ | [Documentation](foursquare.md "Foursquare provider documentation") |
Expand Down
20 changes: 0 additions & 20 deletions docs/douyin.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<PackageValidationBaselineVersion>9.1.0</PackageValidationBaselineVersion>
<TargetFrameworks>$(DefaultNetCoreTargetFramework)</TargetFrameworks>
</PropertyGroup>

<!-- TODO Remove once published to NuGet.org -->
<PropertyGroup>
<DisablePackageBaselineValidation>true</DisablePackageBaselineValidation>
</PropertyGroup>

<PropertyGroup>
<Description>ASP.NET Core security middleware enabling Douyin authentication.</Description>
<Authors>Loongle Tse</Authors>
Expand Down
54 changes: 5 additions & 49 deletions src/AspNet.Security.OAuth.Douyin/DouyinAuthenticationHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,6 @@ public DouyinAuthenticationHandler(
{
}

private const string AuthCode = "auth_code";

protected override Task<HandleRequestResult> HandleRemoteAuthenticateAsync()
{
if (TryStandardizeRemoteAuthenticateQuery(Request.Query, out var queryString))
{
Request.QueryString = queryString;
}

return base.HandleRemoteAuthenticateAsync();
}

protected override async Task<OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
{
// See https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/openapi/account-permission/get-access-token for details.
Expand Down Expand Up @@ -126,19 +114,19 @@ protected override async Task<AuthenticationTicket> CreateTicketAsync(
/// <summary>
/// Check the code sent back by server for potential server errors.
/// </summary>
/// <param name="element">Main part of json document from response</param>
/// <param name="element">Main part of JSON document from response</param>
/// <param name="errorCode">Returned error_code from server</param>
/// <remarks>See https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/openapi/status-code for details.</remarks>
/// <returns>True if succeed, otherwise false.</returns>
private static bool ValidateReturnCode(JsonElement element, out int errorCode)
{
if (!element.TryGetProperty("error_code", out JsonElement errorCodeElement))
errorCode = 0;

if (element.TryGetProperty("error_code", out JsonElement errorCodeElement))
{
errorCode = 0;
return true;
errorCode = errorCodeElement.GetInt32()!;
}

errorCode = errorCodeElement.GetInt32()!;
return errorCode == 0;
}

Expand Down Expand Up @@ -166,38 +154,6 @@ protected override string BuildChallengeUrl([NotNull] AuthenticationProperties p
return QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, parameters);
}

private static bool TryStandardizeRemoteAuthenticateQuery(IQueryCollection query, out QueryString queryString)
{
if (!query.TryGetValue(AuthCode, out var authCode))
{
queryString = default;
return false;
}

// Before: mydomain/signin-douyin?auth_code=xxx&state=xxx&...
// After: mydomain/signin-douyin?code=xxx&state=xxx&...
var queryParams = new List<KeyValuePair<string, StringValues>>(query.Count)
{
new("code", authCode)
};
foreach (var item in query)
{
switch (item.Key)
{
case "code":
case AuthCode: // No need in fact, skip it
break;

default:
queryParams.Add(item);
break;
}
}

queryString = QueryString.Create(queryParams);
return true;
}

private static partial class Log
{
internal static async Task UserProfileErrorAsync(ILogger logger, HttpResponseMessage response, CancellationToken cancellationToken)
Expand Down
31 changes: 31 additions & 0 deletions test/AspNet.Security.OAuth.Providers.Tests/Douyin/DouyinTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* for more information concerning the license and the contributors participating to this project.
*/

using AspNet.Security.OAuth.Xero;
using Microsoft.AspNetCore.WebUtilities;

namespace AspNet.Security.OAuth.Douyin;
Expand All @@ -27,4 +28,34 @@ protected internal override void RegisterAuthentication(AuthenticationBuilder bu
[InlineData("urn:douyin:nickname", "TestAccount")]
public async Task Can_Sign_In_Using_Douyin(string claimType, string claimValue)
=> await AuthenticateUserAndAssertClaimValue(claimType, claimValue);

[Fact]
public async Task BuildChallengeUrl_Generates_Correct_Url()
{
// Arrange
var options = new DouyinAuthenticationOptions();

var redirectUrl = "https://my-site.local/signin-douyin";

// Act
Uri actual = await BuildChallengeUriAsync(
options,
redirectUrl,
(options, loggerFactory, encoder) => new DouyinAuthenticationHandler(options, loggerFactory, encoder));

// Assert
actual.ShouldNotBeNull();
actual.ToString().ShouldStartWith("https://open.douyin.com/platform/oauth/connect/");

var query = QueryHelpers.ParseQuery(actual.Query);

query.ShouldContainKey("state");
query.ShouldContainKeyAndValue("client_key", options.ClientId);
query.ShouldContainKeyAndValue("redirect_uri", redirectUrl);
query.ShouldContainKeyAndValue("response_type", "code");
query.ShouldContainKeyAndValue("scope", "user_info");

query.ShouldNotContainKey(OAuthConstants.CodeChallengeKey);
query.ShouldNotContainKey(OAuthConstants.CodeChallengeMethodKey);
}
}