Browse Source

Add Mixcloud to the list of supported providers

pull/1596/head
Kévin Chalet 3 years ago
parent
commit
230f3ab0bd
  1. 60
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs
  2. 21
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs
  3. 8
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml

60
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs

@ -6,7 +6,9 @@
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
using System.Net.Http.Headers;
using System.Text.Json; using System.Text.Json;
using static OpenIddict.Client.SystemNetHttp.OpenIddictClientSystemNetHttpConstants;
using static OpenIddict.Client.SystemNetHttp.OpenIddictClientSystemNetHttpHandlerFilters; using static OpenIddict.Client.SystemNetHttp.OpenIddictClientSystemNetHttpHandlerFilters;
using static OpenIddict.Client.SystemNetHttp.OpenIddictClientSystemNetHttpHandlers; using static OpenIddict.Client.SystemNetHttp.OpenIddictClientSystemNetHttpHandlers;
using static OpenIddict.Client.SystemNetHttp.OpenIddictClientSystemNetHttpHandlers.Userinfo; using static OpenIddict.Client.SystemNetHttp.OpenIddictClientSystemNetHttpHandlers.Userinfo;
@ -28,6 +30,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers
/* /*
* Userinfo response extraction: * Userinfo response extraction:
*/ */
NormalizeContentType.Descriptor,
UnwrapUserinfoResponse.Descriptor); UnwrapUserinfoResponse.Descriptor);
/// <summary> /// <summary>
@ -110,7 +113,9 @@ public static partial class OpenIddictClientWebIntegrationHandlers
(context.Request.AccessToken, request.Headers.Authorization) = context.Registration.ProviderName switch (context.Request.AccessToken, request.Headers.Authorization) = context.Registration.ProviderName switch
{ {
Providers.Deezer or Providers.StackExchange Providers.Deezer or
Providers.Mixcloud or
Providers.StackExchange
=> (request.Headers.Authorization?.Parameter, null), => (request.Headers.Authorization?.Parameter, null),
_ => (context.Request.AccessToken, request.Headers.Authorization) _ => (context.Request.AccessToken, request.Headers.Authorization)
@ -120,6 +125,59 @@ public static partial class OpenIddictClientWebIntegrationHandlers
} }
} }
/// <summary>
/// Contains the logic responsible for normalizing the returned content
/// type of userinfo responses for the providers that require it.
/// </summary>
public sealed class NormalizeContentType : IOpenIddictClientHandler<ExtractUserinfoResponseContext>
{
/// <summary>
/// Gets the default descriptor definition assigned to this handler.
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<ExtractUserinfoResponseContext>()
.UseSingletonHandler<NormalizeContentType>()
.SetOrder(ExtractUserinfoTokenHttpResponse.Descriptor.Order - 250)
.SetType(OpenIddictClientHandlerType.BuiltIn)
.Build();
/// <inheritdoc/>
public ValueTask HandleAsync(ExtractUserinfoResponseContext context)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}
// This handler only applies to System.Net.Http requests. If the HTTP response cannot be resolved,
// this may indicate that the request was incorrectly processed by another client stack.
var response = context.Transaction.GetHttpResponseMessage() ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID0173));
if (response.Content is null)
{
return default;
}
// Some providers are known to return invalid or incorrect media types, which prevents
// OpenIddict from extracting userinfo responses. To work around that, the declared
// content type is replaced by the correct value for the providers that require it.
response.Content.Headers.ContentType = context.Registration.ProviderName switch
{
// Mixcloud returns JSON-formatted contents declared as "text/javascript".
Providers.Mixcloud => new MediaTypeHeaderValue(MediaTypes.Json)
{
CharSet = Charsets.Utf8
},
_ => response.Content.Headers.ContentType
};
return default;
}
}
/// <summary> /// <summary>
/// Contains the logic responsible for extracting the userinfo response /// Contains the logic responsible for extracting the userinfo response
/// from nested JSON nodes (e.g "data") for the providers that require it. /// from nested JSON nodes (e.g "data") for the providers that require it.

21
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs

@ -102,6 +102,20 @@ public static partial class OpenIddictClientWebIntegrationHandlers
} }
} }
else if (context.Registration.ProviderName is Providers.Mixcloud)
{
var error = (string?) context.Request[Parameters.Error];
if (string.Equals(error, "user_denied", StringComparison.Ordinal))
{
context.Reject(
error: Errors.AccessDenied,
description: SR.GetResourceString(SR.ID2149),
uri: SR.FormatID8000(SR.ID2149));
return default;
}
}
return default; return default;
} }
} }
@ -142,6 +156,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers
if (context.Registration.ProviderName is Providers.Apple) if (context.Registration.ProviderName is Providers.Apple)
{ {
var options = context.Registration.GetAppleOptions(); var options = context.Registration.GetAppleOptions();
context.ClientAssertionTokenPrincipal.SetClaim(Claims.Private.Issuer, options.TeamId); context.ClientAssertionTokenPrincipal.SetClaim(Claims.Private.Issuer, options.TeamId);
context.ClientAssertionTokenPrincipal.SetAudiences("https://appleid.apple.com"); context.ClientAssertionTokenPrincipal.SetAudiences("https://appleid.apple.com");
} }
@ -240,7 +255,8 @@ public static partial class OpenIddictClientWebIntegrationHandlers
context.TokenRequest.RedirectUri = context.Registration.ProviderName switch context.TokenRequest.RedirectUri = context.Registration.ProviderName switch
{ {
Providers.Deezer => OpenIddictHelpers.AddQueryStringParameter( Providers.Deezer or
Providers.Mixcloud => OpenIddictHelpers.AddQueryStringParameter(
address: new Uri(context.TokenRequest.RedirectUri, UriKind.Absolute), address: new Uri(context.TokenRequest.RedirectUri, UriKind.Absolute),
name: Parameters.State, name: Parameters.State,
value: context.StateToken).AbsoluteUri, value: context.StateToken).AbsoluteUri,
@ -481,7 +497,8 @@ public static partial class OpenIddictClientWebIntegrationHandlers
(context.Request.RedirectUri, context.Request.State) = context.Registration.ProviderName switch (context.Request.RedirectUri, context.Request.State) = context.Registration.ProviderName switch
{ {
Providers.Deezer => (OpenIddictHelpers.AddQueryStringParameter( Providers.Deezer or
Providers.Mixcloud => (OpenIddictHelpers.AddQueryStringParameter(
address: new Uri(context.RedirectUri, UriKind.Absolute), address: new Uri(context.RedirectUri, UriKind.Absolute),
name: Parameters.State, name: Parameters.State,
value: context.Request.State).AbsoluteUri, null), value: context.Request.State).AbsoluteUri, null),

8
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml

@ -92,6 +92,14 @@
Description="The tenant used to identify the Azure AD instance (by default, the common tenant is used)" /> Description="The tenant used to identify the Azure AD instance (by default, the common tenant is used)" />
</Provider> </Provider>
<Provider Name="Mixcloud" Documentation="https://www.mixcloud.com/developers/#authorization">
<Environment Issuer="https://www.mixcloud.com/">
<Configuration AuthorizationEndpoint="https://www.mixcloud.com/oauth/authorize"
TokenEndpoint="https://www.mixcloud.com/oauth/access_token"
UserinfoEndpoint="https://api.mixcloud.com/me" />
</Environment>
</Provider>
<Provider Name="PayPal" Documentation="https://developer.paypal.com/docs/log-in-with-paypal/"> <Provider Name="PayPal" Documentation="https://developer.paypal.com/docs/log-in-with-paypal/">
<!-- <!--
Note: PayPal offers a production and a sandbox environment, but the sandbox server metadata Note: PayPal offers a production and a sandbox environment, but the sandbox server metadata

Loading…
Cancel
Save