Browse Source

Merge 3a647d2243 into 5c1cda0ac5

pull/2398/merge
DevTKSS 3 days ago
committed by GitHub
parent
commit
a8536badd0
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 6
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs
  2. 19
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs
  3. 38
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml

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

@ -118,6 +118,12 @@ public static partial class OpenIddictClientWebIntegrationHandlers
request.Headers.Add("X-API-Key", settings.ApplicationKey); request.Headers.Add("X-API-Key", settings.ApplicationKey);
} }
// Etsy requires sending the client identifier 'client_id' gotten from Authorization Code exchange aka x-api-key in the Headers (AttachAccessTokenParameter sets Authorization Bearer header already by default).
else if (context.Registration.ProviderType is ProviderTypes.Etsy)
{
request.Headers.Add("x-api-key", context.Registration.ClientId);
}
// Notion requires sending an explicit API version (which is statically set // Notion requires sending an explicit API version (which is statically set
// to the last version known to be supported by the OpenIddict integration). // to the last version known to be supported by the OpenIddict integration).
else if (context.Registration.ProviderType is ProviderTypes.Notion) else if (context.Registration.ProviderType is ProviderTypes.Notion)

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

@ -1044,6 +1044,13 @@ public static partial class OpenIddictClientWebIntegrationHandlers
left : new Uri("https://api.dailymotion.com/user", UriKind.Absolute), left : new Uri("https://api.dailymotion.com/user", UriKind.Absolute),
right: new Uri(identifier, UriKind.Relative)), right: new Uri(identifier, UriKind.Relative)),
// Etsy's userinfo endpoint requires sending the user identifier in the URI path, which can be gotten from one of the tokens returned by the Token endpoint.
ProviderTypes.Etsy when (string?) context.TokenResponse?["access_token"] is string accessToken
&& accessToken.Split(['.'],3).First() is string userId // TODO: Check if string type is correct because Etsy Reference states <int64> for this as Path Parameter https://developers.etsy.com/documentation/reference#operation/getUser
=> OpenIddictHelpers.CreateAbsoluteUri(
left : new Uri("https://openapi.etsy.com/v3/application/users/", UriKind.Absolute),
right: new Uri(userId, UriKind.Relative)),
// HubSpot doesn't have a static userinfo endpoint but allows retrieving basic information // HubSpot doesn't have a static userinfo endpoint but allows retrieving basic information
// by using an access token info endpoint that requires sending the token in the URI path. // by using an access token info endpoint that requires sending the token in the URI path.
ProviderTypes.HubSpot when ProviderTypes.HubSpot when
@ -1401,6 +1408,9 @@ public static partial class OpenIddictClientWebIntegrationHandlers
?.Select(parameter => (string?) parameter["email"]) ?.Select(parameter => (string?) parameter["email"])
?.FirstOrDefault(), ?.FirstOrDefault(),
// Etsy returns the email address as a custom "primary_email" node:
ProviderTypes.Etsy => (string?) context.UserInfoResponse?["primary_email"],
// HubSpot returns the email address as a custom "user" node: // HubSpot returns the email address as a custom "user" node:
ProviderTypes.HubSpot => (string?) context.UserInfoResponse?["user"], ProviderTypes.HubSpot => (string?) context.UserInfoResponse?["user"],
@ -1436,7 +1446,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers
=> (string?) context.UserInfoResponse?["username"], => (string?) context.UserInfoResponse?["username"],
// These providers don't return a username so one is created using the "first_name" and "last_name" nodes: // These providers don't return a username so one is created using the "first_name" and "last_name" nodes:
ProviderTypes.Basecamp or ProviderTypes.Harvest or ProviderTypes.VkId ProviderTypes.Basecamp or ProviderTypes.Etsy or ProviderTypes.Harvest or ProviderTypes.VkId
when context.UserInfoResponse?.HasParameter("first_name") is true && when context.UserInfoResponse?.HasParameter("first_name") is true &&
context.UserInfoResponse?.HasParameter("last_name") is true context.UserInfoResponse?.HasParameter("last_name") is true
=> $"{(string?) context.UserInfoResponse?["first_name"]} {(string?) context.UserInfoResponse?["last_name"]}", => $"{(string?) context.UserInfoResponse?["first_name"]} {(string?) context.UserInfoResponse?["last_name"]}",
@ -1514,9 +1524,10 @@ public static partial class OpenIddictClientWebIntegrationHandlers
context.MergedPrincipal.SetClaim(ClaimTypes.NameIdentifier, issuer: issuer, value: context.Registration.ProviderType switch context.MergedPrincipal.SetClaim(ClaimTypes.NameIdentifier, issuer: issuer, value: context.Registration.ProviderType switch
{ {
// These providers return the user identifier as a custom "user_id" node: // These providers return the user identifier as a custom "user_id" node:
ProviderTypes.Amazon or ProviderTypes.HubSpot or ProviderTypes.Amazon or ProviderTypes.Etsy or
ProviderTypes.StackExchange or ProviderTypes.Typeform or ProviderTypes.HubSpot or ProviderTypes.StackExchange or
ProviderTypes.VkId ProviderTypes.Typeform or ProviderTypes.VkId
=> (string?) context.UserInfoResponse?["user_id"], => (string?) context.UserInfoResponse?["user_id"],
// ArcGIS and Trakt don't return a user identifier and require using the username as the identifier: // ArcGIS and Trakt don't return a user identifier and require using the username as the identifier:

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

@ -766,6 +766,44 @@
</Provider> </Provider>
<!-- <!--
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
██ ▄▄▄█▄ ▄█ ▄▄█ ██
██ ▄▄▄██ ██▄▄▀█ ▀▀
██ ▀▀▀██▄██▄▄▄█▀▀▀▄
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
-->
<Provider Name="Etsy" Id="d9f3c1a2-4b7e-4c9d-8a2f-3b7e5c1d9a6f"
Documentation="https://developers.etsy.com/documentation/essentials/authentication">
<Environment Issuer="https://www.etsy.com/">
<Configuration AuthorizationEndpoint="https://www.etsy.com/oauth/connect"
TokenEndpoint="https://openapi.etsy.com/v3/public/oauth/token">
<!--
The getMe Endpoint https://developers.etsy.com/documentation/reference#operation/getMe does only provide the 'user_id' and 'shop_id' parameters,
but the UserInfo Endpoint Response is expected to contain user information like 'nameidentifier', 'email', 'given_name, 'family_name', etc.
To get those additional user information, the getUser Endpoint must be called and got's overridden in 'OpenIdDictClient.WebIntegration.AuthenticationHandlers.OverrideUserInfoEndpoint'
-->
<CodeChallengeMethod Value="S256" />
<!--Etsy API requires Authorization Code flow + Refresh Token to work!-->
<GrantType Value="authorization_code" />
<GrantType Value="refresh_token" />
</Configuration>
<!--
Required for getMe Endpoint, but as this doesn't provide any user information, which we are not already able to extract from 'access_token' ('user_id'),
except from the 'shop_id', we are using getUser Endpoint instead for UserInformation
-->
<Scope Name="shops_r" Default="true" Required="false" />
<!--Email scope is required for UserInfoEndpoint equivalent getUser Endpoint and not only the getMe endpoint as mentioned above-->
<Scope Name="email_r" Default="true" Required="true" />
</Environment>
</Provider>
<!--
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
██ ▄▄▄█ ██ █ ▄▄▄████ ▄▄▄ ██ ▀██ ██ ████▄ ▄██ ▀██ ██ ▄▄▄██ ██ ▄▄▄█ ██ █ ▄▄▄████ ▄▄▄ ██ ▀██ ██ ████▄ ▄██ ▀██ ██ ▄▄▄██
██ ▄▄▄█ ██ █ ▄▄▄████ ███ ██ █ █ ██ █████ ███ █ █ ██ ▄▄▄██ ██ ▄▄▄█ ██ █ ▄▄▄████ ███ ██ █ █ ██ █████ ███ █ █ ██ ▄▄▄██

Loading…
Cancel
Save