-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Code moved from api to server project
- Loading branch information
Kurt Monge
committed
Nov 29, 2024
1 parent
d56510b
commit e68d33c
Showing
24 changed files
with
1,067 additions
and
65 deletions.
There are no files selected for viewing
33 changes: 0 additions & 33 deletions
33
src/oed-testdata.Server/Controllers/WeatherForecastController.cs
This file was deleted.
Oops, something went wrong.
76 changes: 76 additions & 0 deletions
76
src/oed-testdata.Server/Infrastructure/Altinn/AltinnAuthHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using System.Net.Http.Headers; | ||
using Microsoft.AspNetCore.WebUtilities; | ||
using Microsoft.Extensions.Caching.Memory; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace oed_testdata.Server.Infrastructure.Altinn | ||
{ | ||
public class AltinnAuthHandler( | ||
IHttpClientFactory factory, | ||
IOptionsMonitor<AltinnSettings> options, | ||
IMemoryCache cache) | ||
: DelegatingHandler | ||
{ | ||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) | ||
{ | ||
if (request.Headers.Authorization is not null && request.Headers.Authorization.Scheme == "Bearer") | ||
{ | ||
return await base.SendAsync(request, cancellationToken); | ||
} | ||
|
||
// Do auth, add auth header and try again | ||
var token = await GetCachedEnterpriseToken(); | ||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); | ||
return await base.SendAsync(request, cancellationToken); | ||
} | ||
|
||
private async Task<string> GetCachedEnterpriseToken() | ||
{ | ||
// TODO: Build key from params | ||
var cacheKey = "key"; | ||
|
||
var token = await cache.GetOrCreateAsync(cacheKey, async (entry) => | ||
{ | ||
return await GetEnterpriseToken(); | ||
}, | ||
new MemoryCacheEntryOptions | ||
{ | ||
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(86300) | ||
}); | ||
|
||
return token; | ||
} | ||
|
||
private async Task<string> GetEnterpriseToken() | ||
{ | ||
var scopes = "altinn:serviceowner/instances.read altinn:serviceowner/instances.write altinn:lookup"; | ||
|
||
var queryParams = new Dictionary<string, string?> | ||
{ | ||
{ "env", "tt02" }, | ||
{ "orgNo", "991825827" }, | ||
{ "org", "digdir" }, | ||
{ "ttl", "86400" }, | ||
//{ "partyId", "50552094" }, | ||
{ "scopes", scopes } | ||
}; | ||
|
||
var baseUri = new Uri(options.CurrentValue.TokenGeneratorUrl, UriKind.Absolute); | ||
var pathWithQuery = QueryHelpers.AddQueryString("/api/GetEnterpriseToken", queryParams); | ||
var requestUri = new Uri(baseUri, pathWithQuery); | ||
|
||
var auth = $"{options.CurrentValue.Username}:{options.CurrentValue.Password}"; | ||
var encodedAuth = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(auth)); | ||
|
||
var request = new HttpRequestMessage(HttpMethod.Get, requestUri); | ||
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", encodedAuth); | ||
|
||
var httpClient = factory.CreateClient(nameof(AltinnAuthHandler)); | ||
var response = await httpClient.SendAsync(request); | ||
|
||
var token = await response.Content.ReadAsStringAsync(); | ||
|
||
return token; | ||
} | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
src/oed-testdata.Server/Infrastructure/Altinn/AltinnClient.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
using Altinn.Platform.Storage.Interface.Models; | ||
using Microsoft.Extensions.Options; | ||
using oed_testdata.Server.Infrastructure.Altinn.Models; | ||
|
||
namespace oed_testdata.Server.Infrastructure.Altinn; | ||
|
||
public interface IAltinnClient | ||
{ | ||
public Task<List<Instance>> GetOedInstances(); | ||
public Task<List<Instance>> GetOedInstancesByDeceasedNin(string deceasedNin); | ||
|
||
public Task<T> GetOedInstanceData<T>(string instanceId, string instanceDataId); | ||
} | ||
|
||
public class AltinnClient( | ||
HttpClient httpClient, | ||
IOptionsMonitor<AltinnSettings> options) | ||
: IAltinnClient | ||
{ | ||
public async Task<List<Instance>> GetOedInstances() | ||
{ | ||
var baseUri = new Uri(options.CurrentValue.PlatformUrl, UriKind.Absolute); | ||
var requestUri = new Uri(baseUri, "/storage/api/v1/instances?org=digdir&appId=digdir/oed&status.isHardDeleted=false&status.isSoftDeleted=false&size=50"); | ||
|
||
var request = new HttpRequestMessage(HttpMethod.Get, requestUri); | ||
var response = await httpClient.SendAsync(request); | ||
|
||
var s = response.Content.ReadAsStringAsync(); | ||
|
||
await using var contentStream = await response.Content.ReadAsStreamAsync(); | ||
var altinnResponse = await AltinnJsonSerializer.Deserialize<AltinnInstancesResponse>(contentStream); | ||
|
||
return altinnResponse.Instances; | ||
} | ||
|
||
public async Task<List<Instance>> GetOedInstancesByDeceasedNin(string deceasedNin) | ||
{ | ||
var baseUri = new Uri(options.CurrentValue.PlatformUrl, UriKind.Absolute); | ||
var requestUri = new Uri(baseUri, "/storage/api/v1/instances?org=digdir&appId=digdir/oed&status.isHardDeleted=false&status.isSoftDeleted=false"); | ||
|
||
var request = new HttpRequestMessage(HttpMethod.Get, requestUri); | ||
request.Headers.TryAddWithoutValidation("X-Ai-InstanceOwnerIdentifier", $"person:{deceasedNin}"); | ||
var response = await httpClient.SendAsync(request); | ||
|
||
await using var contentStream = await response.Content.ReadAsStreamAsync(); | ||
var altinnResponse = await AltinnJsonSerializer.Deserialize<AltinnInstancesResponse>(contentStream); | ||
|
||
return altinnResponse.Instances; | ||
} | ||
|
||
public async Task<T> GetOedInstanceData<T>(string instanceId, string instanceDataId) | ||
{ | ||
var baseUri = new Uri(options.CurrentValue.PlatformUrl, UriKind.Absolute); | ||
var requestUri = new Uri(baseUri, $"https://platform.tt02.altinn.no/storage/api/v1/instances/{instanceId}/data/{instanceDataId}"); | ||
|
||
var request = new HttpRequestMessage(HttpMethod.Get, requestUri); | ||
var response = await httpClient.SendAsync(request); | ||
|
||
await using var contentStream = await response.Content.ReadAsStreamAsync(); | ||
var data = AltinnXmlSerializer.Deserialize<T>(contentStream); | ||
|
||
return data; | ||
} | ||
|
||
} |
29 changes: 29 additions & 0 deletions
29
src/oed-testdata.Server/Infrastructure/Altinn/AltinnJsonSerializer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
using System.Xml.Serialization; | ||
using Newtonsoft.Json; | ||
|
||
namespace oed_testdata.Server.Infrastructure.Altinn | ||
{ | ||
public static class AltinnJsonSerializer | ||
{ | ||
public static async Task<T> Deserialize<T>(Stream contentStream) | ||
{ | ||
var serializer = new JsonSerializer(); | ||
|
||
using var sr = new StreamReader(contentStream); | ||
await using var jsonTextReader = new JsonTextReader(sr); | ||
return serializer.Deserialize<T>(jsonTextReader)!; | ||
} | ||
} | ||
|
||
public static class AltinnXmlSerializer | ||
{ | ||
public static T Deserialize<T>(Stream contentStream) | ||
{ | ||
var serializer = new XmlSerializer(typeof(T)); | ||
var dataObject = serializer.Deserialize(contentStream); | ||
|
||
var data = (T)dataObject!; | ||
return data; | ||
} | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
src/oed-testdata.Server/Infrastructure/Altinn/AltinnSettings.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
namespace oed_testdata.Server.Infrastructure.Altinn; | ||
|
||
public class AltinnSettings | ||
{ | ||
public required string TokenGeneratorUrl { get; set; } | ||
public required string PlatformUrl { get; set; } | ||
public string? Username { get; set; } | ||
public string? Password { get; set; } | ||
} |
76 changes: 76 additions & 0 deletions
76
src/oed-testdata.Server/Infrastructure/Altinn/MaskinportenAuthHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using System.Net.Http.Headers; | ||
using Microsoft.AspNetCore.WebUtilities; | ||
using Microsoft.Extensions.Caching.Memory; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace oed_testdata.Server.Infrastructure.Altinn | ||
{ | ||
public class MaskinportenAuthHandler( | ||
IHttpClientFactory factory, | ||
IOptionsMonitor<AltinnSettings> options, | ||
IMemoryCache cache) | ||
: DelegatingHandler | ||
{ | ||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) | ||
{ | ||
if (request.Headers.Authorization is not null && request.Headers.Authorization.Scheme == "Bearer") | ||
{ | ||
return await base.SendAsync(request, cancellationToken); | ||
} | ||
|
||
// Do auth, add auth header and try again | ||
var token = await GetCachedEnterpriseToken(); | ||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); | ||
return await base.SendAsync(request, cancellationToken); | ||
} | ||
|
||
private async Task<string> GetCachedEnterpriseToken() | ||
{ | ||
// TODO: Build key from params | ||
var cacheKey = "key"; | ||
|
||
var token = await cache.GetOrCreateAsync(cacheKey, async (entry) => | ||
{ | ||
return await GetEnterpriseToken(); | ||
}, | ||
new MemoryCacheEntryOptions | ||
{ | ||
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(86300) | ||
}); | ||
|
||
return token; | ||
} | ||
|
||
private async Task<string> GetEnterpriseToken() | ||
{ | ||
var scopes = "altinn:serviceowner/instances.read altinn:serviceowner/instances.write altinn:lookup"; | ||
|
||
var queryParams = new Dictionary<string, string?> | ||
{ | ||
{ "env", "tt02" }, | ||
{ "orgNo", "991825827" }, | ||
{ "org", "digdir" }, | ||
{ "ttl", "86400" }, | ||
//{ "partyId", "50552094" }, | ||
{ "scopes", scopes } | ||
}; | ||
|
||
var baseUri = new Uri(options.CurrentValue.TokenGeneratorUrl, UriKind.Absolute); | ||
var pathWithQuery = QueryHelpers.AddQueryString("/api/GetEnterpriseToken", queryParams); | ||
var requestUri = new Uri(baseUri, pathWithQuery); | ||
|
||
var auth = $"{options.CurrentValue.Username}:{options.CurrentValue.Password}"; | ||
var encodedAuth = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(auth)); | ||
|
||
var request = new HttpRequestMessage(HttpMethod.Get, requestUri); | ||
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", encodedAuth); | ||
|
||
var httpClient = factory.CreateClient(nameof(MaskinportenAuthHandler)); | ||
var response = await httpClient.SendAsync(request); | ||
|
||
var token = await response.Content.ReadAsStringAsync(); | ||
|
||
return token; | ||
} | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/oed-testdata.Server/Infrastructure/Altinn/Models/AltinnInstancesResponse.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using System.Text.Json.Serialization; | ||
using Altinn.Platform.Storage.Interface.Models; | ||
using Newtonsoft.Json; | ||
|
||
namespace oed_testdata.Server.Infrastructure.Altinn.Models | ||
{ | ||
public class AltinnInstancesResponse | ||
{ | ||
[JsonProperty("count")] | ||
public int Count { get; set; } | ||
|
||
[JsonPropertyName("self")] | ||
public string Self { get; set; } | ||
|
||
[JsonPropertyName("next")] | ||
public string Next { get; set; } | ||
|
||
[JsonPropertyName("instances")] | ||
public List<Instance> Instances { get; set; } | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/oed-testdata.Server/Infrastructure/Altinn/ServiceCollectionExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
namespace oed_testdata.Server.Infrastructure.Altinn; | ||
|
||
public static class ServiceCollectionExtensions | ||
{ | ||
public static IServiceCollection AddAltinnClient( | ||
this IServiceCollection services, | ||
IConfiguration configuration) | ||
{ | ||
services.Configure<AltinnSettings>(configuration.GetSection("AltinnSettings")); | ||
|
||
services | ||
.AddMemoryCache() | ||
.AddTransient<AltinnAuthHandler>() | ||
.AddHttpClient<IAltinnClient, AltinnClient>() | ||
.AddHttpMessageHandler<AltinnAuthHandler>(); | ||
|
||
return services; | ||
} | ||
} |
Oops, something went wrong.