protected override async Task EnsureAuthenticatedAsync()

in src/JetBrains.Space.Common/ClientCredentialsConnection.cs [42:80]


    protected override async Task EnsureAuthenticatedAsync(string? functionName, HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // Authenticate?
        if (AuthenticationTokens == null || AuthenticationTokens.HasExpired())
        {
            // 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", "client_credentials"),
                    new KeyValuePair<string?, string?>("scope", Scope.ToString())
                })
            }.WithClientAndSdkHeaders(SdkInfo.Version);

            var spaceTokenResponse = await HttpClient.SendAsync(spaceTokenRequest, cancellationToken);
            if (!spaceTokenResponse.IsSuccessStatusCode)
            {
                throw new ResourceException($"Unable to connect to Space organization. Attempted endpoint was: {ServerUrl + "oauth/token"}",
                    spaceTokenRequest.RequestUri, functionName, spaceTokenResponse.StatusCode, spaceTokenResponse.ReasonPhrase);
            }
                
            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);
    }