Sitelet https://github.com/Altinn/app-lib-dotnet/commit/085f32b0f227335d7a731828fe3ad18a1939a102
Skip to content

Commit 085f32b

Browse files
Also interpret 'altinn3local.no' as running in localtest (#1465)
1 parent bc91f82 commit 085f32b

8 files changed

Lines changed: 75 additions & 40 deletions

File tree

‎src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ IWebHostEnvironment env
194194
services.Configure<FrontEndSettings>(configuration.GetSection(nameof(FrontEndSettings)));
195195
services.Configure<PdfGeneratorSettings>(configuration.GetSection(nameof(PdfGeneratorSettings)));
196196

197+
services.AddRuntimeEnvironment();
197198
if (env.IsDevelopment())
198199
services.AddLocaltestValidation();
199200

‎src/Altinn.App.Core/Features/Auth/AuthenticationContext.cs‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.IdentityModel.Tokens.Jwt;
22
using Altinn.App.Core.Configuration;
33
using Altinn.App.Core.Features.Cache;
4+
using Altinn.App.Core.Internal;
45
using Altinn.App.Core.Internal.Auth;
56
using Altinn.App.Core.Internal.Profile;
67
using Altinn.App.Core.Internal.Registers;
@@ -21,6 +22,7 @@ internal sealed class AuthenticationContext : IAuthenticationContext
2122
private readonly IAltinnPartyClient _altinnPartyClient;
2223
private readonly IAuthorizationClient _authorizationClient;
2324
private readonly IAppConfigurationCache _appConfigurationCache;
25+
private readonly RuntimeEnvironment _runtimeEnvironment;
2426

2527
public AuthenticationContext(
2628
IHttpContextAccessor httpContextAccessor,
@@ -29,7 +31,8 @@ public AuthenticationContext(
2931
IProfileClient profileClient,
3032
IAltinnPartyClient altinnPartyClient,
3133
IAuthorizationClient authorizationClient,
32-
IAppConfigurationCache appConfigurationCache
34+
IAppConfigurationCache appConfigurationCache,
35+
RuntimeEnvironment runtimeEnvironment
3336
)
3437
{
3538
_httpContextAccessor = httpContextAccessor;
@@ -39,6 +42,7 @@ IAppConfigurationCache appConfigurationCache
3942
_altinnPartyClient = altinnPartyClient;
4043
_authorizationClient = authorizationClient;
4144
_appConfigurationCache = appConfigurationCache;
45+
_runtimeEnvironment = runtimeEnvironment;
4246
}
4347

4448
// Currently we're coupling this to the HTTP context directly.
@@ -75,9 +79,7 @@ public Authenticated Current
7579
parsedToken.Payload.TryGetValue("actual_iss", out var actualIss) && actualIss is "localtest";
7680
}
7781

78-
var isLocaltest =
79-
generalSettings.HostName.StartsWith("local.altinn.cloud", StringComparison.OrdinalIgnoreCase)
80-
&& !generalSettings.IsTest;
82+
var isLocaltest = _runtimeEnvironment.IsLocaltestPlatform() && !generalSettings.IsTest;
8183
if (isLocaltest && !isNewLocaltestToken)
8284
{
8385
authInfo = Authenticated.FromOldLocalTest(

‎src/Altinn.App.Core/Internal/Auth/AuthenticationTokenResolver.cs‎

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
using Altinn.App.Core.Configuration;
21
using Altinn.App.Core.Features;
32
using Altinn.App.Core.Features.Auth;
43
using Altinn.App.Core.Features.Maskinporten;
54
using Altinn.App.Core.Helpers;
65
using Altinn.App.Core.Internal.App;
76
using Altinn.App.Core.Models;
8-
using Microsoft.Extensions.Options;
97

108
namespace Altinn.App.Core.Internal.Auth;
119

@@ -25,16 +23,15 @@ public AuthenticationTokenResolver(
2523
IMaskinportenClient maskinportenClient,
2624
IAppMetadata appMetadata,
2725
IAuthenticationContext authenticationContext,
28-
IOptions<PlatformSettings> platformSettings,
29-
IOptions<GeneralSettings> generalSettings
26+
RuntimeEnvironment runtimeEnvironment
3027
)
3128
{
3229
_maskinportenClient = maskinportenClient;
3330
_appMetadata = appMetadata;
3431
_httpClientFactory = httpClientFactory;
3532
_authenticationContext = authenticationContext;
36-
_isDev = LocaltestValidation.IsLocaltest(generalSettings.Value);
37-
_localtestBaseUrl = LocaltestValidation.GetLocaltestBaseUrl(platformSettings.Value);
33+
_isDev = runtimeEnvironment.IsLocaltestPlatform();
34+
_localtestBaseUrl = runtimeEnvironment.GetPlatformBaseUrl();
3835
}
3936

4037
/// <inheritdoc />

‎src/Altinn.App.Core/Internal/LocaltestValidation.cs‎

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,48 +20,37 @@ public static IServiceCollection AddLocaltestValidation(this IServiceCollection
2020

2121
internal sealed class LocaltestValidation : BackgroundService
2222
{
23-
private const string ExpectedHostname = "local.altinn.cloud";
24-
2523
private readonly ILogger<LocaltestValidation> _logger;
2624
private readonly IHttpClientFactory _httpClientFactory;
2725
private readonly IOptionsMonitor<GeneralSettings> _generalSettings;
28-
private readonly IOptionsMonitor<PlatformSettings> _platformSettings;
26+
private readonly RuntimeEnvironment _runtimeEnvironment;
2927
private readonly IHostApplicationLifetime _lifetime;
3028
private readonly TimeProvider _timeProvider;
3129
private readonly Channel<VersionResult> _resultChannel;
3230

3331
internal IAsyncEnumerable<VersionResult> Results => _resultChannel.Reader.ReadAllAsync();
3432

35-
internal static string GetLocaltestBaseUrl(PlatformSettings platformSettings) =>
36-
new Uri(platformSettings.ApiStorageEndpoint).GetLeftPart(UriPartial.Authority);
37-
38-
internal static bool IsLocaltest(GeneralSettings generalSettings) =>
39-
generalSettings.HostName.Equals(ExpectedHostname, StringComparison.OrdinalIgnoreCase);
40-
4133
public LocaltestValidation(
4234
ILogger<LocaltestValidation> logger,
4335
IHttpClientFactory httpClientFactory,
4436
IOptionsMonitor<GeneralSettings> generalSettings,
45-
IOptionsMonitor<PlatformSettings> platformSettings,
37+
RuntimeEnvironment runtimeEnvironment,
4638
IHostApplicationLifetime lifetime,
4739
TimeProvider? timeProvider = null
4840
)
4941
{
5042
_logger = logger;
5143
_httpClientFactory = httpClientFactory;
5244
_generalSettings = generalSettings;
53-
_platformSettings = platformSettings;
45+
_runtimeEnvironment = runtimeEnvironment;
5446
_lifetime = lifetime;
5547
_timeProvider = timeProvider ?? TimeProvider.System;
5648
_resultChannel = Channel.CreateBounded<VersionResult>(
5749
new BoundedChannelOptions(10) { FullMode = BoundedChannelFullMode.DropWrite }
5850
);
5951
}
6052

61-
private void Exit()
62-
{
63-
_lifetime.StopApplication();
64-
}
53+
private void Exit() => _lifetime.StopApplication();
6554

6655
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
6756
{
@@ -71,9 +60,10 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
7160
if (settings.DisableLocaltestValidation)
7261
return;
7362

74-
if (!IsLocaltest(settings))
63+
if (!_runtimeEnvironment.IsLocaltestPlatform())
7564
return;
7665

66+
var baseUrl = _runtimeEnvironment.GetPlatformBaseUrl();
7767
while (!stoppingToken.IsCancellationRequested)
7868
{
7969
var result = await Version();
@@ -99,7 +89,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
9989
_logger.LogError(
10090
"Localtest version may be outdated, as we failed to probe {HostName} API for version information."
10191
+ " Is localtest running? Do you have a recent copy of localtest? Shutting down..",
102-
ExpectedHostname
92+
baseUrl
10393
);
10494
Exit();
10595
return;
@@ -176,7 +166,7 @@ private async Task<VersionResult> Version()
176166
{
177167
using var client = _httpClientFactory.CreateClient();
178168

179-
var baseUrl = GetLocaltestBaseUrl(_platformSettings.CurrentValue);
169+
var baseUrl = _runtimeEnvironment.GetPlatformBaseUrl();
180170
var url = $"{baseUrl}/Home/Localtest/Version";
181171

182172
using var response = await client.GetAsync(url, cancellationToken);
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System.Collections.Frozen;
2+
using Altinn.App.Core.Configuration;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.Extensions.Options;
5+
6+
namespace Altinn.App.Core.Internal;
7+
8+
internal static class RuntimeEnvironmentDI
9+
{
10+
public static IServiceCollection AddRuntimeEnvironment(this IServiceCollection services)
11+
{
12+
services.AddSingleton<RuntimeEnvironment>();
13+
return services;
14+
}
15+
}
16+
17+
internal sealed class RuntimeEnvironment(
18+
IOptionsMonitor<GeneralSettings> _generalSettings,
19+
IOptionsMonitor<PlatformSettings> _platformSettings
20+
)
21+
{
22+
private static readonly FrozenSet<string> _expectedHostnames = new[]
23+
{
24+
"local.altinn.cloud", // Current hostname for localtest
25+
"altinn3local.no", // Old hostname for localtest
26+
}.ToFrozenSet(StringComparer.OrdinalIgnoreCase);
27+
28+
public bool IsLocaltestPlatform()
29+
{
30+
var hostName = _generalSettings.CurrentValue.HostName;
31+
var colonIdx = hostName.IndexOf(':');
32+
if (colonIdx >= 0)
33+
hostName = hostName[..colonIdx];
34+
35+
return _expectedHostnames.Contains(hostName);
36+
}
37+
38+
public string GetPlatformBaseUrl() =>
39+
new Uri(_platformSettings.CurrentValue.ApiStorageEndpoint).GetLeftPart(UriPartial.Authority);
40+
}

‎test/Altinn.App.Core.Tests/Features/Correspondence/CorrespondenceClientTests.cs‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -351,11 +351,12 @@ public static Fixture Create()
351351
services.AddSingleton(mockHttpClientFactory.Object);
352352
services.AddSingleton(mockMaskinportenClient.Object);
353353
services.AddSingleton(authenticationContextMock.Object);
354-
services.AddSingleton(Microsoft.Extensions.Options.Options.Create(new PlatformSettings()));
355-
services.AddSingleton(
354+
services.Configure<PlatformSettings>(_ => { });
355+
services.Configure<GeneralSettings>(options =>
356+
{
356357
// NOTE: This must be set to tt02/prod to avoid localhost token generation in AuthenticationTokenResolver
357-
Microsoft.Extensions.Options.Options.Create(new GeneralSettings { HostName = "tt02.altinn.no" })
358-
);
358+
options.HostName = "tt02.altinn.no";
359+
});
359360
services.Configure<MaskinportenSettings>(options =>
360361
{
361362
options.Authority = "https://maskinporten.dev/";

‎test/Altinn.App.Core.Tests/Infrastructure/Clients/Storage/DataClientTests.cs‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Altinn.App.Core.Helpers;
1111
using Altinn.App.Core.Helpers.Serialization;
1212
using Altinn.App.Core.Infrastructure.Clients.Storage;
13+
using Altinn.App.Core.Internal;
1314
using Altinn.App.Core.Internal.App;
1415
using Altinn.App.Core.Internal.AppModel;
1516
using Altinn.App.Core.Internal.Auth;
@@ -22,7 +23,6 @@
2223
using Microsoft.Extensions.DependencyInjection;
2324
using Microsoft.Extensions.Logging;
2425
using Microsoft.Extensions.Logging.Abstractions;
25-
using Microsoft.Extensions.Options;
2626
using Moq;
2727
using Xunit.Abstractions;
2828

@@ -35,8 +35,6 @@ public DataClientTests() { }
3535

3636
private const string ApiStorageEndpoint = "https://local.platform.altinn.no/api/storage/";
3737
private static readonly ApplicationMetadata _appMetadata = new("test-org/test-app");
38-
private static readonly GeneralSettings _generalSettings = new() { HostName = "tt02.altinn.no" };
39-
private static readonly PlatformSettings _platformSettings = new() { ApiStorageEndpoint = ApiStorageEndpoint };
4038
private static readonly Authenticated _defaultAuth = TestAuthentication.GetUserAuthentication();
4139

4240
private static readonly TestTokens _testTokens = new(
@@ -1049,8 +1047,9 @@ public static Fixture Create(
10491047
.ReturnsAsync(_testTokens.ServiceOwnerToken);
10501048

10511049
var services = new ServiceCollection();
1052-
services.AddSingleton(Options.Create(_platformSettings));
1053-
services.AddSingleton(Options.Create(_generalSettings));
1050+
services.Configure<PlatformSettings>(options => options.ApiStorageEndpoint = ApiStorageEndpoint);
1051+
services.Configure<GeneralSettings>(options => options.HostName = "tt02.altinn.no");
1052+
services.AddRuntimeEnvironment();
10541053
services.AddSingleton<IAuthenticationTokenResolver, AuthenticationTokenResolver>();
10551054
services.AddSingleton<ModelSerializationService>();
10561055
services.AddSingleton(mocks.AppModelMock.Object);

‎test/Altinn.App.Core.Tests/Internal/Auth/AuthenticationTokenResolverTest.cs‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Altinn.App.Core.Features.Auth;
55
using Altinn.App.Core.Features.Maskinporten;
66
using Altinn.App.Core.Helpers.Serialization;
7+
using Altinn.App.Core.Internal;
78
using Altinn.App.Core.Internal.App;
89
using Altinn.App.Core.Internal.AppModel;
910
using Altinn.App.Core.Internal.Auth;
@@ -12,7 +13,6 @@
1213
using Microsoft.Extensions.DependencyInjection;
1314
using Microsoft.Extensions.Logging;
1415
using Microsoft.Extensions.Logging.Abstractions;
15-
using Microsoft.Extensions.Options;
1616
using Moq;
1717
using Xunit.Abstractions;
1818

@@ -183,8 +183,13 @@ public static Fixture Create(
183183
});
184184

185185
var services = new ServiceCollection();
186-
services.AddSingleton(Options.Create(_platformSettings));
187-
services.AddSingleton(Options.Create(generalSettings ?? _generalSettingsLocal));
186+
services.AddRuntimeEnvironment();
187+
services.Configure<PlatformSettings>(options =>
188+
options.ApiStorageEndpoint = _platformSettings.ApiStorageEndpoint
189+
);
190+
services.Configure<GeneralSettings>(options =>
191+
options.HostName = generalSettings?.HostName ?? _generalSettingsLocal.HostName
192+
);
188193
services.AddSingleton<IAuthenticationTokenResolver, AuthenticationTokenResolver>();
189194
services.AddSingleton<ModelSerializationService>();
190195
services.AddSingleton(mocks.AppModelMock.Object);

0 commit comments

Comments
 (0)