Browse Source

Add Trakt to the list of supported providers

pull/1591/head
Kévin Chalet 3 years ago
parent
commit
4d27b50cb5
  1. 56
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs
  2. 26
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs
  3. 8
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml

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

@ -8,6 +8,7 @@ using System.Collections.Immutable;
using System.Diagnostics;
using System.Text.Json;
using static OpenIddict.Client.SystemNetHttp.OpenIddictClientSystemNetHttpHandlerFilters;
using static OpenIddict.Client.SystemNetHttp.OpenIddictClientSystemNetHttpHandlers;
using static OpenIddict.Client.SystemNetHttp.OpenIddictClientSystemNetHttpHandlers.Userinfo;
using static OpenIddict.Client.WebIntegration.OpenIddictClientWebIntegrationConstants;
@ -21,6 +22,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers
/*
* Userinfo request preparation:
*/
AttachRequestHeaders.Descriptor,
AttachAccessTokenParameter.Descriptor,
/*
@ -28,6 +30,50 @@ public static partial class OpenIddictClientWebIntegrationHandlers
*/
UnwrapUserinfoResponse.Descriptor);
/// <summary>
/// Contains the logic responsible for attaching additional
/// headers to the request for the providers that require it.
/// </summary>
public sealed class AttachRequestHeaders : IOpenIddictClientHandler<PrepareUserinfoRequestContext>
{
/// <summary>
/// Gets the default descriptor definition assigned to this handler.
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<PrepareUserinfoRequestContext>()
.AddFilter<RequireHttpMetadataAddress>()
.UseSingletonHandler<AttachRequestHeaders>()
.SetOrder(AttachUserAgentHeader<PrepareUserinfoRequestContext>.Descriptor.Order + 250)
.SetType(OpenIddictClientHandlerType.BuiltIn)
.Build();
/// <inheritdoc/>
public ValueTask HandleAsync(PrepareUserinfoRequestContext context)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}
// This handler only applies to System.Net.Http requests. If the HTTP request cannot be resolved,
// this may indicate that the request was incorrectly processed by another client stack.
var request = context.Transaction.GetHttpRequestMessage() ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID0173));
// Trakt requires sending both an API key (which is always the client identifier) and an API version
// (which is statically set to the last version known to be supported by the OpenIddict integration).
if (context.Registration.ProviderName is Providers.Trakt)
{
var options = context.Registration.GetTraktOptions();
request.Headers.Add("trakt-api-key", options.ClientId);
request.Headers.Add("trakt-api-version", "2");
}
return default;
}
}
/// <summary>
/// Contains the logic responsible for attaching the access token
/// parameter to the request for the providers that require it.
@ -62,11 +108,13 @@ public static partial class OpenIddictClientWebIntegrationHandlers
// using the Bearer authentication scheme. Some providers don't support this method
// and require sending the access token as part of the userinfo request payload.
if (context.Registration.ProviderName is Providers.Deezer or Providers.StackExchange)
(context.Request.AccessToken, request.Headers.Authorization) = context.Registration.ProviderName switch
{
context.Request.AccessToken = request.Headers.Authorization?.Parameter;
request.Headers.Authorization = null;
}
Providers.Deezer or Providers.StackExchange
=> (request.Headers.Authorization?.Parameter, null),
_ => (context.Request.AccessToken, request.Headers.Authorization)
};
return default;
}

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

@ -238,13 +238,15 @@ public static partial class OpenIddictClientWebIntegrationHandlers
// of the authorization requests, the value persisted in the state token principal
// MUST be replaced to include the state token received by the redirection endpoint.
if (context.Registration.ProviderName is Providers.Deezer)
context.TokenRequest.RedirectUri = context.Registration.ProviderName switch
{
context.TokenRequest.RedirectUri = OpenIddictHelpers.AddQueryStringParameter(
Providers.Deezer => OpenIddictHelpers.AddQueryStringParameter(
address: new Uri(context.TokenRequest.RedirectUri, UriKind.Absolute),
name: Parameters.State,
value: context.StateToken).AbsoluteUri;
}
value: context.StateToken).AbsoluteUri,
_ => context.TokenRequest.RedirectUri
};
return default;
}
@ -338,6 +340,12 @@ public static partial class OpenIddictClientWebIntegrationHandlers
context.UserinfoRequest["site"] = options.Site;
}
// Trakt allows retrieving additional user details via the "extended" parameter.
else if (context.Registration.ProviderName is Providers.Trakt)
{
context.UserinfoRequest["extended"] = "full";
}
// Twitter limits the number of fields returned by the userinfo endpoint
// but allows returning additional information using special parameters that
// determine what fields will be returned as part of the userinfo response.
@ -471,15 +479,15 @@ public static partial class OpenIddictClientWebIntegrationHandlers
// Note: this workaround only works for providers that allow dynamic
// redirection URIs and implement a relaxed validation policy logic.
if (context.Registration.ProviderName is Providers.Deezer)
(context.Request.RedirectUri, context.Request.State) = context.Registration.ProviderName switch
{
context.Request.RedirectUri = OpenIddictHelpers.AddQueryStringParameter(
Providers.Deezer => (OpenIddictHelpers.AddQueryStringParameter(
address: new Uri(context.RedirectUri, UriKind.Absolute),
name: Parameters.State,
value: context.Request.State).AbsoluteUri;
value: context.Request.State).AbsoluteUri, null),
context.Request.State = null;
}
_ => (context.Request.RedirectUri, context.Request.State)
};
return default;
}

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

@ -138,6 +138,14 @@
Description="The site specified in userinfo requests (by default, 'stackoverflow')" />
</Provider>
<Provider Name="Trakt" Documentation="https://trakt.docs.apiary.io/#reference/authentication-oauth">
<Environment Issuer="https://trakt.tv/">
<Configuration AuthorizationEndpoint="https://trakt.tv/oauth/authorize"
TokenEndpoint="https://api.trakt.tv/oauth/token"
UserinfoEndpoint="https://api.trakt.tv/users/me" />
</Environment>
</Provider>
<Provider Name="Twitter" Documentation="https://developer.twitter.com/en/docs/authentication/oauth-2-0/authorization-code">
<Environment Issuer="https://twitter.com/">
<Configuration AuthorizationEndpoint="https://twitter.com/i/oauth2/authorize"

Loading…
Cancel
Save