in src/JetBrains.Space.Common/RefreshTokenConnection.cs [53:95]
protected override async Task EnsureAuthenticatedAsync(string? functionName, HttpRequestMessage request, CancellationToken cancellationToken)
{
// Authenticate when token expired or when no access token is provided (but refresh token is known)
if (AuthenticationTokens != null &&
!string.IsNullOrEmpty(AuthenticationTokens.RefreshToken) && (AuthenticationTokens.HasExpired() || string.IsNullOrEmpty(AuthenticationTokens.AccessToken)))
{
// Get new token
var spaceTokenRequest = new HttpRequestMessage(HttpMethod.Post, ServerUrl + "oauth/token")
{
Headers =
{
Authorization = AuthenticationHeaderValue.Parse(
"Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes($"{_clientId}:{_clientSecret}")))
},
Content = new FormUrlEncodedContent(new []
{
new KeyValuePair<string?, string?>("grant_type", "refresh_token"),
new KeyValuePair<string?, string?>("refresh_token", AuthenticationTokens.RefreshToken),
new KeyValuePair<string?, string?>("scope", Scope.ToString())
})
}
.WithClientAndSdkHeaders(SdkInfo.Version);
var spaceTokenResponse = await HttpClient.SendAsync(spaceTokenRequest, cancellationToken);
if (!spaceTokenResponse.IsSuccessStatusCode)
{
var exception = await BuildException(functionName, spaceTokenRequest, spaceTokenResponse);
throw exception;
}
// Parse new access/refresh token
using var spaceTokenDocument = await JsonDocument.ParseAsync(await spaceTokenResponse.Content.ReadAsStreamAsync(), cancellationToken: cancellationToken);
var spaceToken = spaceTokenDocument.RootElement;
AuthenticationTokens = new AuthenticationTokens(
accessToken: spaceToken.GetStringValue("access_token"),
refreshToken: spaceToken.GetStringValue("refresh_token") ?? AuthenticationTokens.RefreshToken,
expires: DateTimeOffset.UtcNow.AddSeconds(spaceToken.GetInt32Value("expires_in"))
);
}
await base.EnsureAuthenticatedAsync(functionName, request, cancellationToken);
}