From 230f3ab0bdedc4b59ab5014bba1ce1eb5004243f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Sun, 27 Nov 2022 05:40:15 +0100 Subject: [PATCH] Add Mixcloud to the list of supported providers --- ...ctClientWebIntegrationHandlers.Userinfo.cs | 60 ++++++++++++++++++- .../OpenIddictClientWebIntegrationHandlers.cs | 21 ++++++- ...penIddictClientWebIntegrationProviders.xml | 8 +++ 3 files changed, 86 insertions(+), 3 deletions(-) diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs index 5b13013e..29f09ea5 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs +++ b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs @@ -6,7 +6,9 @@ using System.Collections.Immutable; using System.Diagnostics; +using System.Net.Http.Headers; using System.Text.Json; +using static OpenIddict.Client.SystemNetHttp.OpenIddictClientSystemNetHttpConstants; using static OpenIddict.Client.SystemNetHttp.OpenIddictClientSystemNetHttpHandlerFilters; using static OpenIddict.Client.SystemNetHttp.OpenIddictClientSystemNetHttpHandlers; using static OpenIddict.Client.SystemNetHttp.OpenIddictClientSystemNetHttpHandlers.Userinfo; @@ -28,6 +30,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers /* * Userinfo response extraction: */ + NormalizeContentType.Descriptor, UnwrapUserinfoResponse.Descriptor); /// @@ -110,7 +113,9 @@ public static partial class OpenIddictClientWebIntegrationHandlers (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), _ => (context.Request.AccessToken, request.Headers.Authorization) @@ -120,6 +125,59 @@ public static partial class OpenIddictClientWebIntegrationHandlers } } + /// + /// Contains the logic responsible for normalizing the returned content + /// type of userinfo responses for the providers that require it. + /// + public sealed class NormalizeContentType : IOpenIddictClientHandler + { + /// + /// Gets the default descriptor definition assigned to this handler. + /// + public static OpenIddictClientHandlerDescriptor Descriptor { get; } + = OpenIddictClientHandlerDescriptor.CreateBuilder() + .UseSingletonHandler() + .SetOrder(ExtractUserinfoTokenHttpResponse.Descriptor.Order - 250) + .SetType(OpenIddictClientHandlerType.BuiltIn) + .Build(); + + /// + 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; + } + } + /// /// Contains the logic responsible for extracting the userinfo response /// from nested JSON nodes (e.g "data") for the providers that require it. diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs index 6419a409..96879f94 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs +++ b/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; } } @@ -142,6 +156,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers if (context.Registration.ProviderName is Providers.Apple) { var options = context.Registration.GetAppleOptions(); + context.ClientAssertionTokenPrincipal.SetClaim(Claims.Private.Issuer, options.TeamId); context.ClientAssertionTokenPrincipal.SetAudiences("https://appleid.apple.com"); } @@ -240,7 +255,8 @@ public static partial class OpenIddictClientWebIntegrationHandlers 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), name: Parameters.State, value: context.StateToken).AbsoluteUri, @@ -481,7 +497,8 @@ public static partial class OpenIddictClientWebIntegrationHandlers (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), name: Parameters.State, value: context.Request.State).AbsoluteUri, null), diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml index cb24f5b9..a68e613d 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml +++ b/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)" /> + + + + + +