Skip to content

Commit 0c4a7ab

Browse files
committed
fix: deployment auth sometimes has problems if configured with polly
1 parent d536df5 commit 0c4a7ab

File tree

3 files changed

+49
-44
lines changed

3 files changed

+49
-44
lines changed
Lines changed: 4 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,10 @@
1-
using System.Net.Http.Json;
2-
using System.Text.Json;
3-
using System.Text.Json.Serialization;
4-
using Microsoft.Extensions.Options;
1+
namespace Catglobe.CgScript.Deployment;
52

6-
namespace Catglobe.CgScript.Deployment;
7-
8-
internal partial class DeploymentAuthHandler(IOptions<DeploymentOptions> options) : DelegatingHandler
3+
internal class DeploymentAuthHandler(DeploymentAuthenticator authenticator) : DelegatingHandler
94
{
10-
private string? _accessToken;
11-
125
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
136
{
14-
if (_accessToken is null) await AcquireToken(cancellationToken);
15-
request.Headers.Authorization = new("Bearer", _accessToken);
7+
request.Headers.Authorization = new("Bearer", await authenticator.GetToken(cancellationToken));
168
return await base.SendAsync(request, cancellationToken);
179
}
18-
19-
private async Task AcquireToken(CancellationToken cancellationToken)
20-
{
21-
var o = options.Value;
22-
var httpClient = new HttpClient();
23-
httpClient.BaseAddress = options.Value.Authority;
24-
var requestData = new Dictionary<string, string> {
25-
{"grant_type", "client_credentials"},
26-
{"client_id", o.ClientId},
27-
{"client_secret", o.ClientSecret},
28-
// ReSharper disable once StringLiteralTypo
29-
{"scope", "scriptdeployment:w"},
30-
};
31-
32-
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/connect/token") { Content = new FormUrlEncodedContent(requestData), Headers = { Accept = { new("application/json") } } };
33-
34-
var response = await httpClient.SendAsync(requestMessage, cancellationToken);
35-
response.EnsureSuccessStatusCode();
36-
37-
var tokenResponse = await response.Content.ReadFromJsonAsync(Serializer.Default.TokenResponse, cancellationToken) ?? throw new IOException("Failed to obtain authorization");
38-
39-
_accessToken = tokenResponse.AccessToken;
40-
}
41-
42-
private class TokenResponse
43-
{
44-
[JsonPropertyName("access_token")] public string AccessToken { get; set; } = null!;
45-
}
46-
47-
[JsonSerializable(typeof(TokenResponse))]
48-
[JsonSourceGenerationOptions(JsonSerializerDefaults.Web)]
49-
private partial class Serializer : JsonSerializerContext;
50-
}
10+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System.Net.Http.Json;
2+
using System.Text.Json;
3+
using System.Text.Json.Serialization;
4+
using Microsoft.Extensions.Options;
5+
6+
namespace Catglobe.CgScript.Deployment;
7+
8+
internal partial class DeploymentAuthenticator(HttpClient httpClient, IOptions<DeploymentOptions> options)
9+
{
10+
private string? _accessToken;
11+
12+
public async Task<string> GetToken(CancellationToken cancellationToken) => _accessToken ??= await AcquireToken(cancellationToken).ConfigureAwait(false);
13+
14+
private async Task<string> AcquireToken(CancellationToken cancellationToken)
15+
{
16+
var o = options.Value;
17+
httpClient.BaseAddress = options.Value.Authority;
18+
var requestData = new Dictionary<string, string> {
19+
{"grant_type", "client_credentials"},
20+
{"client_id", o.ClientId},
21+
{"client_secret", o.ClientSecret},
22+
// ReSharper disable once StringLiteralTypo
23+
{"scope", "scriptdeployment:w"},
24+
};
25+
26+
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/connect/token") { Content = new FormUrlEncodedContent(requestData), Headers = { Accept = { new("application/json") } } };
27+
28+
var response = await httpClient.SendAsync(requestMessage, cancellationToken).ConfigureAwait(false);
29+
response.EnsureSuccessStatusCode();
30+
31+
var tokenResponse = await response.Content.ReadFromJsonAsync(Serializer.Default.TokenResponse, cancellationToken).ConfigureAwait(false) ?? throw new IOException("Failed to obtain authorization");
32+
33+
return tokenResponse.AccessToken;
34+
}
35+
36+
private class TokenResponse
37+
{
38+
[JsonPropertyName("access_token")] public string AccessToken { get; set; } = null!;
39+
}
40+
41+
[JsonSerializable(typeof(TokenResponse))]
42+
[JsonSourceGenerationOptions(JsonSerializerDefaults.Web)]
43+
private partial class Serializer : JsonSerializerContext;
44+
}

Catglobe.CgScript.Deployment/HostExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public static IServiceCollection AddCgScriptDeployment(this IServiceCollection s
3838
private static IServiceCollection AddCommonCgScript(IServiceCollection services)
3939
{
4040
services.TryAddSingleton<IScriptProvider, FilesFromDirectoryScriptProvider>();
41+
services.AddScoped<DeploymentAuthenticator>();
4142
services.AddScoped<DeploymentAuthHandler>();
4243
services.AddHttpClient<IDeployer, Deployer>((sp, httpClient) => {
4344
var site = sp.GetRequiredService<IOptions<DeploymentOptions>>().Value.Authority;

0 commit comments

Comments
 (0)