From 3b90ad926cde16b59a995cfb2d1ad3b687ef6e59 Mon Sep 17 00:00:00 2001 From: Simen Rekkedal <61084786+simen-rekkedal@users.noreply.github.com> Date: Tue, 23 Apr 2024 12:47:12 +0200 Subject: [PATCH 01/12] unauth systemregister --- .../Controllers/SystemRegisterController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Controllers/SystemRegisterController.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Controllers/SystemRegisterController.cs index 59b636b7..b627dd22 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Controllers/SystemRegisterController.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Controllers/SystemRegisterController.cs @@ -17,7 +17,7 @@ public SystemRegisterController(ISystemRegisterService systemRegisterService) _systemRegisterService = systemRegisterService; } - [Authorize] + //[Authorize] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [HttpGet] public async Task GetListOfRegisteredSystems(CancellationToken cancellationToken = default) From 5cc0c79247c26dce0a1c1b661796731232e14ccf Mon Sep 17 00:00:00 2001 From: Simen Rekkedal <61084786+simen-rekkedal@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:34:34 +0200 Subject: [PATCH 02/12] reauth systemregister --- .../Controllers/SystemRegisterController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Controllers/SystemRegisterController.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Controllers/SystemRegisterController.cs index b627dd22..59b636b7 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Controllers/SystemRegisterController.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Controllers/SystemRegisterController.cs @@ -17,7 +17,7 @@ public SystemRegisterController(ISystemRegisterService systemRegisterService) _systemRegisterService = systemRegisterService; } - //[Authorize] + [Authorize] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [HttpGet] public async Task GetListOfRegisteredSystems(CancellationToken cancellationToken = default) From 7aca52075cf89d9ce307068847cb3194757f8552 Mon Sep 17 00:00:00 2001 From: Simen Rekkedal <61084786+simen-rekkedal@users.noreply.github.com> Date: Tue, 23 Apr 2024 15:03:36 +0200 Subject: [PATCH 03/12] add profileclient and it's dependencies --- .../Altinn.Authentication.UI.Core.csproj | 6 ++ .../Common/Extensions/HttpClientExtensions.cs | 2 +- .../UserProfiles/AccessTokenProvider.cs | 77 +++++++++++++++ .../UserProfiles/IAccessTokenProvider.cs | 7 +- .../UserProfiles/IUserProfileClient.cs | 8 ++ ...ltinn.Authentication.UI.Integration.csproj | 8 +- .../KeyVault/IKeyVaultService.cs | 18 ++++ .../KeyVault/KeyVaultService.cs | 37 ++++++++ .../KeyVault/LocalKeyVaultService.cs | 25 +++++ .../UserProfiles/UserProfileClient.cs | 95 +++++++++++++++---- 10 files changed, 260 insertions(+), 23 deletions(-) create mode 100644 bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/AccessTokenProvider.cs create mode 100644 bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/IKeyVaultService.cs create mode 100644 bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/KeyVaultService.cs create mode 100644 bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/LocalKeyVaultService.cs diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Altinn.Authentication.UI.Core.csproj b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Altinn.Authentication.UI.Core.csproj index cd703e65..0fd05baa 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Altinn.Authentication.UI.Core.csproj +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Altinn.Authentication.UI.Core.csproj @@ -6,6 +6,12 @@ enable + + + + + + diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Common/Extensions/HttpClientExtensions.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Common/Extensions/HttpClientExtensions.cs index 7961aade..26e9df9a 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Common/Extensions/HttpClientExtensions.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Common/Extensions/HttpClientExtensions.cs @@ -1,4 +1,4 @@ -namespace Altinn.Authentication.UI.Core.Common; +namespace Altinn.Authentication.UI.Core.Extensions; public static class HttpClientExtensions { diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/AccessTokenProvider.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/AccessTokenProvider.cs new file mode 100644 index 00000000..f1b9ddaf --- /dev/null +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/AccessTokenProvider.cs @@ -0,0 +1,77 @@ +using Altinn.Authentication.UI.Core.AppConfiguration; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using System.Security.Cryptography.X509Certificates; + +namespace Altinn.Authentication.UI.Core.UserProfiles +{ + /// + public class AccessTokenProvider : IAccessTokenProvider + { + private readonly IKeyVaultService _keyVaultService; + private readonly IAccessTokenGenerator _accessTokenGenerator; + private readonly AccessTokenSettings _accessTokenSettings; + private readonly ClientSettings _clientSettings; + private readonly KeyVaultSettings _keyVaultSettings; + private static readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1, 1); + private static DateTime _cacheTokenUntil = DateTime.MinValue; + private string _accessToken; + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + /// The key vault service. + /// The access token generator. + /// Then access token settings + /// The key vault settings. + /// The client settings for access token generation + /// the logger handler + public AccessTokenProvider( + IKeyVaultService keyVaultService, + IAccessTokenGenerator accessTokenGenerator, + IOptions accessTokenSettings, + IOptions keyVaultSettings, + IOptions clientSettings, + ILogger logger) + { + _keyVaultService = keyVaultService; + _accessTokenGenerator = accessTokenGenerator; + _accessTokenSettings = accessTokenSettings.Value; + _keyVaultSettings = keyVaultSettings.Value; + _clientSettings = clientSettings.Value; + _logger = logger; + } + + /// + public async Task GetAccessToken() + { + await Semaphore.WaitAsync(); + + try + { + if (_accessToken == null || _cacheTokenUntil < DateTime.UtcNow) + { + string certBase64 = await _keyVaultService.GetCertificateAsync(_keyVaultSettings.SecretUri, _clientSettings.CertificateName); + _accessToken = _accessTokenGenerator.GenerateAccessToken( + _clientSettings.Issuer, + _clientSettings.App, + new X509Certificate2(Convert.FromBase64String(certBase64), (string)null, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable)); + + _cacheTokenUntil = DateTime.UtcNow.AddSeconds(_accessTokenSettings.TokenLifetimeInSeconds - 2); // Add some slack to avoid tokens expiring in transit + } + + return _accessToken; + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to generate access token."); + return null; + } + finally + { + Semaphore.Release(); + } + } + } +} diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/IAccessTokenProvider.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/IAccessTokenProvider.cs index 992bfa3f..2b220db7 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/IAccessTokenProvider.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/IAccessTokenProvider.cs @@ -1,5 +1,10 @@ namespace Altinn.Authentication.UI.Core.UserProfiles; -public class IAccessTokenProvider +public interface IAccessTokenProvider { + /// + /// Gets the access token. + /// + /// An access token as a printable string + public Task GetAccessToken(); } diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/IUserProfileClient.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/IUserProfileClient.cs index 873bcf23..1ed843aa 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/IUserProfileClient.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/IUserProfileClient.cs @@ -3,8 +3,16 @@ namespace Altinn.Authentication.UI.Core.UserProfiles; +/// +/// +/// public interface IUserProfileClient { + /// + /// Retrieves the userprofile by id from the Platforms Profile API + /// + /// + /// public Task GetUserProfile(int userid); } diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/Altinn.Authentication.UI.Integration.csproj b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/Altinn.Authentication.UI.Integration.csproj index 8cee2bbf..37fa5d44 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/Altinn.Authentication.UI.Integration.csproj +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/Altinn.Authentication.UI.Integration.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -6,6 +6,12 @@ enable + + + + + + diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/IKeyVaultService.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/IKeyVaultService.cs new file mode 100644 index 00000000..34b84236 --- /dev/null +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/IKeyVaultService.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; + +namespace Altinn.AccessManagement.UI.Core.Services.Interfaces +{ + /// + /// Interface for interacting with key vault + /// + public interface IKeyVaultService + { + /// + /// Gets the value of a secret from the given key vault. + /// + /// The URI of the key vault to ask for secret. + /// The id of the secret. + /// The secret value. + Task GetCertificateAsync(string vaultUri, string secretId); + } +} diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/KeyVaultService.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/KeyVaultService.cs new file mode 100644 index 00000000..ab120b2a --- /dev/null +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/KeyVaultService.cs @@ -0,0 +1,37 @@ +using System.Diagnostics.CodeAnalysis; +using Altinn.AccessManagement.UI.Core.Services.Interfaces; +using Azure; +using Azure.Identity; +using Azure.Security.KeyVault.Certificates; +using Azure.Security.KeyVault.Secrets; + +namespace Altinn.AccessManagement.UI.Core.Services +{ + /// + /// Wrapper implementation for a KeyVaultClient. The wrapped client is created with a principal obtained through configuration. + /// + /// This class is excluded from code coverage because it has no logic to be tested. + [ExcludeFromCodeCoverage] + public class KeyVaultService : IKeyVaultService + { + /// + public async Task GetCertificateAsync(string vaultUri, string secretId) + { + CertificateClient certificateClient = new CertificateClient(new Uri(vaultUri), new DefaultAzureCredential()); + AsyncPageable certificatePropertiesPage = certificateClient.GetPropertiesOfCertificateVersionsAsync(secretId); + await foreach (CertificateProperties certificateProperties in certificatePropertiesPage) + { + if (certificateProperties.Enabled == true && + (certificateProperties.ExpiresOn == null || certificateProperties.ExpiresOn >= DateTime.UtcNow)) + { + SecretClient secretClient = new SecretClient(new Uri(vaultUri), new DefaultAzureCredential()); + + KeyVaultSecret secret = await secretClient.GetSecretAsync(certificateProperties.Name, certificateProperties.Version); + return secret.Value; + } + } + + return null; + } + } +} diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/LocalKeyVaultService.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/LocalKeyVaultService.cs new file mode 100644 index 00000000..79a52099 --- /dev/null +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/LocalKeyVaultService.cs @@ -0,0 +1,25 @@ +using System.Diagnostics.CodeAnalysis; +using System.Text; +using Altinn.AccessManagement.UI.Core.Services.Interfaces; +using Azure; +using Azure.Identity; +using Azure.Security.KeyVault.Certificates; +using Azure.Security.KeyVault.Secrets; + +namespace Altinn.AccessManagement.UI.Core.Services +{ + /// + /// Wrapper implementation for a KeyVaultClient. The wrapped client is created with a principal obtained through configuration. + /// + /// This class is excluded from code coverage because it has no logic to be tested. + [ExcludeFromCodeCoverage] + public class LocalKeyVaultService : IKeyVaultService + { + /// + public Task GetCertificateAsync(string vaultUri, string secretId) + { + string certBase64 = Convert.ToBase64String(Encoding.ASCII.GetBytes("-----BEGIN CERTIFICATE-----\r\nMIIDAzCCAeugAwIBAgIJANTdO8o3I8x5MA0GCSqGSIb3DQEBCwUAMA4xDDAKBgNV\r\nBAMTA3R0ZDAeFw0yMDA1MjUxMjIxMzdaFw0zMDA1MjQxMjIxMzdaMA4xDDAKBgNV\r\nBAMTA3R0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMcfTsXwwLyC\r\nUkIz06eadWJvG3yrzT+ZB2Oy/WPaZosDnPcnZvCDueN+oy0zTx5TyH5gCi1FvzX2\r\n7G2eZEKwQaRPv0yuM+McHy1rXxMSOlH/ebP9KJj3FDMUgZl1DCAjJxSAANdTwdrq\r\nydVg1Crp37AQx8IIEjnBhXsfQh1uPGt1XwgeNyjl00IejxvQOPzd1CofYWwODVtQ\r\nl3PKn1SEgOGcB6wuHNRlnZPCIelQmqxWkcEZiu/NU+kst3NspVUQG2Jf2AF8UWgC\r\nrnrhMQR0Ra1Vi7bWpu6QIKYkN9q0NRHeRSsELOvTh1FgDySYJtNd2xDRSf6IvOiu\r\ntSipl1NZlV0CAwEAAaNkMGIwIAYDVR0OAQH/BBYEFIwq/KbSMzLETdo9NNxj0rz4\r\nqMqVMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgWgMCAGA1UdJQEB/wQWMBQG\r\nCCsGAQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAE56UmH5gEYbe\r\n1kVw7nrfH0R9FyVZGeQQWBn4/6Ifn+eMS9mxqe0Lq74Ue1zEzvRhRRqWYi9JlKNf\r\n7QQNrc+DzCceIa1U6cMXgXKuXquVHLmRfqvKHbWHJfIkaY8Mlfy++77UmbkvIzly\r\nT1HVhKKp6Xx0r5koa6frBh4Xo/vKBlEyQxWLWF0RPGpGErnYIosJ41M3Po3nw3lY\r\nf7lmH47cdXatcntj2Ho/b2wGi9+W29teVCDfHn2/0oqc7K0EOY9c2ODLjUvQyPZR\r\nOD2yykpyh9x/YeYHFDYdLDJ76/kIdxN43kLU4/hTrh9tMb1PZF+/4DshpAlRoQuL\r\no8I8avQm/A==\r\n-----END CERTIFICATE-----")); + return Task.FromResult(certBase64); + } + } +} diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/UserProfiles/UserProfileClient.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/UserProfiles/UserProfileClient.cs index c24623a0..ef8ab305 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/UserProfiles/UserProfileClient.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/UserProfiles/UserProfileClient.cs @@ -1,34 +1,89 @@ -using Altinn.Authentication.UI.Core.UserProfiles; +using Altinn.Authentication.UI.Core.Authentication; +using Altinn.Authentication.UI.Core.UserProfiles; +using Altinn.Authentication.UI.Integration.Configuration; using Altinn.Platform.Profile.Models; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using System.Text.Json; +using System.Text.Json.Serialization; +using Altinn.Authentication.UI.Core.Extensions; namespace Altinn.Authentication.UI.Integration.UserProfiles; +/// +/// Integration client towards the Profile API in Platform +/// public class UserProfileClient : IUserProfileClient { + private readonly ILogger _logger; + private readonly HttpClient _httpClient; + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly PlatformSettings _platformSettings; + private readonly IAccessTokenProvider _accessTokenProvider; + + /// + /// Constructor + /// + /// + /// + /// + /// + /// + public UserProfileClient( + ILogger logger, + HttpClient httpClient, + IHttpContextAccessor httpContextAccessor, + PlatformSettings platformSettings, + IAccessTokenProvider accessTokenProvider) + { + _logger = logger; + _httpClient = httpClient; + _httpContextAccessor = httpContextAccessor; + _platformSettings = platformSettings; + _accessTokenProvider = accessTokenProvider; + } + + /// public async Task GetUserProfile(int userid) { - await Task.Delay(50); + UserProfile user; + try + { + string endpoint = $"users/{userid}"; + user = await GetUserProfileFromEndpoint(endpoint); + } + catch (Exception ex) + { + _logger.LogError(ex, "Authentication.UI // ProfileClient // GetUserProfile // Exception"); + throw; + } + + return user!; + } + + private async Task GetUserProfileFromEndpoint(string endpoint) + { + string token = JwtTokenUtil.GetTokenFromContext(_httpContextAccessor.HttpContext!, _platformSettings.JwtCookieName!)!; + var accessToken = await _accessTokenProvider.GetAccessToken(); + + HttpResponseMessage response = await _httpClient.GetAsync(token, endpoint, accessToken ); - UserProfile user = new() + if(response.StatusCode == System.Net.HttpStatusCode.OK) { - UserId = 20004938, - Email = "1337@altinnstudiotestusers.com", - PhoneNumber = "90001337", - UserName = "Testur Testursson Jr", - PartyId = 50019992, - ExternalIdentity = "", - Party = new Platform.Register.Models.Party + string responseContent = await response.Content.ReadAsStringAsync(); + var options = new JsonSerializerOptions { - Name = "Test Organisasjon" - }, - ProfileSettingPreference = new() - { - Language = "nb" - }, - UserType = Platform.Profile.Enums.UserType.SSNIdentified - - }; + PropertyNameCaseInsensitive = true, + }; + options.Converters.Add(new JsonStringEnumConverter()); + UserProfile userProfile = JsonSerializer.Deserialize(responseContent, options)!; + return userProfile; + } + else + { + _logger.LogError($"Getting user profile information from platform failed with statuscode {response.StatusCode}"); + return null!; + } - return user; } } From f91ce10775eeeb864237cb8673b640870675d3ed Mon Sep 17 00:00:00 2001 From: Simen Rekkedal <61084786+simen-rekkedal@users.noreply.github.com> Date: Tue, 23 Apr 2024 15:24:26 +0200 Subject: [PATCH 04/12] access token etc towards profile api --- .../Altinn.Authentication.UI.Core.csproj | 6 - .../Authentication/HttpClientExtensions.cs | 109 ------------ .../Common/Extensions/HttpClientExtensions.cs | 168 ++++++++---------- .../AccessToken}/AccessTokenProvider.cs | 7 +- .../AccessToken}/IAccessTokenProvider.cs | 2 +- ...ltinn.Authentication.UI.Integration.csproj | 1 + .../KeyVault/IKeyVaultService.cs | 2 +- .../KeyVault/KeyVaultService.cs | 3 +- .../KeyVault/LocalKeyVaultService.cs | 3 +- .../UserProfiles/UserProfileClient.cs | 1 + .../Altinn.Authentication.UI.csproj | 2 +- 11 files changed, 87 insertions(+), 217 deletions(-) delete mode 100644 bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Authentication/HttpClientExtensions.cs rename bff/src/Altinn.Authentication.UI/{Altinn.Authentication.UI.Core/UserProfiles => Altinn.Authentication.UI.Integration/AccessToken}/AccessTokenProvider.cs (94%) rename bff/src/Altinn.Authentication.UI/{Altinn.Authentication.UI.Core/UserProfiles => Altinn.Authentication.UI.Integration/AccessToken}/IAccessTokenProvider.cs (77%) diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Altinn.Authentication.UI.Core.csproj b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Altinn.Authentication.UI.Core.csproj index 0fd05baa..cd703e65 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Altinn.Authentication.UI.Core.csproj +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Altinn.Authentication.UI.Core.csproj @@ -6,12 +6,6 @@ enable - - - - - - diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Authentication/HttpClientExtensions.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Authentication/HttpClientExtensions.cs deleted file mode 100644 index da1361df..00000000 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Authentication/HttpClientExtensions.cs +++ /dev/null @@ -1,109 +0,0 @@ -namespace Altinn.Authentication.UI.Core.Authentication; - -public static class HttpClientExtensions -{ - - /// - /// Extensionmethod to add Authorization token and access token to the header - /// - /// - /// - /// - /// - /// - /// - public static Task PostAsync( - this HttpClient httpClient, - string authorizationToken, string requestURI, - HttpContent content, string? platformAccessToken = null) - { - HttpRequestMessage request = new(HttpMethod.Post, requestURI); - request.Headers.Add("Authorization", "Bearer " + authorizationToken); - request.Content = content; - if (platformAccessToken is not null && platformAccessToken.Length > 0) - { - request.Headers.Add("PlatformAccessToken", platformAccessToken); - } - - return httpClient.SendAsync(request, CancellationToken.None); - } - - /// - /// Extensionmethod to add Authorization token and access token to the header - /// - /// - /// - /// - /// - /// - /// - public static Task PutAsync( - this HttpClient httpClient, - string authorizationToken, string requestURI, - HttpContent content, string? platformAccessToken = null) - { - HttpRequestMessage request = new(HttpMethod.Put, requestURI); - request.Headers.Add("Authorization", "Bearer " + authorizationToken); - request.Content = content; - - if (platformAccessToken is not null && platformAccessToken.Length > 0) - { - request.Headers.Add("PlatformAccessToken", platformAccessToken); - } - - return httpClient.SendAsync(request, CancellationToken.None); - } - - - /// - /// Extensionmethod to add Authorization token and access token to the header - /// - /// - /// - /// - /// - /// - /// - public static Task GetAsync( - this HttpClient httpClient, - string authorizationToken, string requestURI, - HttpContent content, string? platformAccessToken = null) - { - HttpRequestMessage request = new(HttpMethod.Get, requestURI); - request.Headers.Add("Authorization", "Bearer " + authorizationToken); - request.Content = content; - - if (platformAccessToken is not null && platformAccessToken.Length > 0) - { - request.Headers.Add("PlatformAccessToken", platformAccessToken); - } - - return httpClient.SendAsync(request, CancellationToken.None); - } - - /// - /// Extensionmethod to add Authorization token and access token to the header - /// - /// - /// - /// - /// - /// - /// - public static Task DeleteAsync( - this HttpClient httpClient, - string authorizationToken, string requestURI, - HttpContent content, string? platformAccessToken = null) - { - HttpRequestMessage request = new(HttpMethod.Delete, requestURI); - request.Headers.Add("Authorization", "Bearer " + authorizationToken); - request.Content = content; - - if (platformAccessToken is not null && platformAccessToken.Length > 0) - { - request.Headers.Add("PlatformAccessToken", platformAccessToken); - } - - return httpClient.SendAsync(request, CancellationToken.None); - } -} diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Common/Extensions/HttpClientExtensions.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Common/Extensions/HttpClientExtensions.cs index 26e9df9a..9681c65b 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Common/Extensions/HttpClientExtensions.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/Common/Extensions/HttpClientExtensions.cs @@ -1,109 +1,91 @@ namespace Altinn.Authentication.UI.Core.Extensions; -public static class HttpClientExtensions +/// +/// This extension is created to make it easy to add a bearer token to a HttpRequests. +/// +public static class HttpClientExtension { - - /// - /// Extensionmethod to add Authorization token and access token to the header - /// - /// - /// - /// - /// - /// - /// - public static Task PostAsync( - this HttpClient httpClient, - string authorizationToken, string requestURI, - HttpContent content, string? platformAccessToken = null) +/// +/// Extension that add authorization header to request. +/// +/// The HttpClient. +/// the authorization token (jwt). +/// The request Uri. +/// The http content. +/// The platformAccess tokens. +/// A HttpResponseMessage. +public static Task PostAsync(this HttpClient httpClient, string authorizationToken, string requestUri, HttpContent content, string platformAccessToken = null) +{ + HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUri); + request.Headers.Add("Authorization", "Bearer " + authorizationToken); + request.Content = content; + if (!string.IsNullOrEmpty(platformAccessToken)) { - HttpRequestMessage request = new(HttpMethod.Post, requestURI); - request.Headers.Add("Authorization", "Bearer " + authorizationToken); - request.Content = content; - if(platformAccessToken is not null && platformAccessToken.Length > 0) - { - request.Headers.Add("PlatformAccessToken", platformAccessToken); - } - - return httpClient.SendAsync(request, CancellationToken.None); + request.Headers.Add("PlatformAccessToken", platformAccessToken); } - /// - /// Extensionmethod to add Authorization token and access token to the header - /// - /// - /// - /// - /// - /// - /// - public static Task PutAsync( - this HttpClient httpClient, - string authorizationToken, string requestURI, - HttpContent content, string? platformAccessToken = null) - { - HttpRequestMessage request = new(HttpMethod.Put, requestURI); - request.Headers.Add("Authorization", "Bearer " + authorizationToken); - request.Content = content; - - if(platformAccessToken is not null && platformAccessToken.Length > 0) - { - request.Headers.Add("PlatformAccessToken", platformAccessToken); - } + return httpClient.SendAsync(request, CancellationToken.None); +} - return httpClient.SendAsync(request, CancellationToken.None); +/// +/// Extension that add authorization header to request. +/// +/// The HttpClient. +/// the authorization token (jwt). +/// The request Uri. +/// The http content. +/// The platformAccess tokens. +/// A HttpResponseMessage. +public static Task PutAsync(this HttpClient httpClient, string authorizationToken, string requestUri, HttpContent content, string platformAccessToken = null) +{ + HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Put, requestUri); + request.Headers.Add("Authorization", "Bearer " + authorizationToken); + request.Content = content; + if (!string.IsNullOrEmpty(platformAccessToken)) + { + request.Headers.Add("PlatformAccessToken", platformAccessToken); } + return httpClient.SendAsync(request, CancellationToken.None); +} - /// - /// Extensionmethod to add Authorization token and access token to the header - /// - /// - /// - /// - /// - /// - /// - public static Task GetAsync( - this HttpClient httpClient, - string authorizationToken, string requestURI, - HttpContent content, string? platformAccessToken = null) +/// +/// Extension that add authorization header to request. +/// +/// The HttpClient. +/// the authorization token (jwt). +/// The request Uri. +/// The platformAccess tokens. +/// A HttpResponseMessage. +public static Task GetAsync(this HttpClient httpClient, string authorizationToken, string requestUri, string platformAccessToken = null) +{ + HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri); + request.Headers.Add("Authorization", "Bearer " + authorizationToken); + if (!string.IsNullOrEmpty(platformAccessToken)) { - HttpRequestMessage request = new(HttpMethod.Get, requestURI); - request.Headers.Add("Authorization", "Bearer " + authorizationToken); - request.Content = content; - - if(platformAccessToken is not null && platformAccessToken.Length > 0) - { - request.Headers.Add("PlatformAccessToken", platformAccessToken); - } - - return httpClient.SendAsync(request, CancellationToken.None); + request.Headers.Add("PlatformAccessToken", platformAccessToken); } - /// - /// Extensionmethod to add Authorization token and access token to the header - /// - /// - /// - /// - /// - /// - /// - public static Task DeleteAsync( - this HttpClient httpClient, - string authorizationToken, string requestURI, - HttpContent content, string? platformAccessToken = null) - { - HttpRequestMessage request = new(HttpMethod.Delete, requestURI); - request.Headers.Add("Authorization", "Bearer " + authorizationToken); - request.Content = content; - - if(platformAccessToken is not null && platformAccessToken.Length > 0) - { - request.Headers.Add("PlatformAccessToken", platformAccessToken); - } + return httpClient.SendAsync(request, HttpCompletionOption.ResponseContentRead, CancellationToken.None); +} - return httpClient.SendAsync(request, CancellationToken.None); +/// +/// Extension that add authorization header to request. +/// +/// The HttpClient. +/// the authorization token (jwt). +/// The request Uri. +/// The platformAccess tokens. +/// A HttpResponseMessage. +public static Task DeleteAsync(this HttpClient httpClient, string authorizationToken, string requestUri, string platformAccessToken = null) +{ + HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Delete, requestUri); + request.Headers.Add("Authorization", "Bearer " + authorizationToken); + if (!string.IsNullOrEmpty(platformAccessToken)) + { + request.Headers.Add("PlatformAccessToken", platformAccessToken); } + + return httpClient.SendAsync(request, CancellationToken.None); +} } diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/AccessTokenProvider.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/AccessToken/AccessTokenProvider.cs similarity index 94% rename from bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/AccessTokenProvider.cs rename to bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/AccessToken/AccessTokenProvider.cs index f1b9ddaf..f1f72438 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/AccessTokenProvider.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/AccessToken/AccessTokenProvider.cs @@ -2,9 +2,12 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System.Security.Cryptography.X509Certificates; +using Altinn.Authentication.UI.Integration.KeyVault; +using Altinn.Common.AccessTokenClient.Services; +using Altinn.Common.AccessTokenClient.Configuration; -namespace Altinn.Authentication.UI.Core.UserProfiles -{ +namespace Altinn.Authentication.UI.Integration.AccessToken +{ /// public class AccessTokenProvider : IAccessTokenProvider { diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/IAccessTokenProvider.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/AccessToken/IAccessTokenProvider.cs similarity index 77% rename from bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/IAccessTokenProvider.cs rename to bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/AccessToken/IAccessTokenProvider.cs index 2b220db7..6cf9c131 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/IAccessTokenProvider.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/AccessToken/IAccessTokenProvider.cs @@ -1,4 +1,4 @@ -namespace Altinn.Authentication.UI.Core.UserProfiles; +namespace Altinn.Authentication.UI.Integration.AccessToken; public interface IAccessTokenProvider { diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/Altinn.Authentication.UI.Integration.csproj b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/Altinn.Authentication.UI.Integration.csproj index 37fa5d44..4a84849c 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/Altinn.Authentication.UI.Integration.csproj +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/Altinn.Authentication.UI.Integration.csproj @@ -7,6 +7,7 @@ + diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/IKeyVaultService.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/IKeyVaultService.cs index 34b84236..53d0473a 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/IKeyVaultService.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/IKeyVaultService.cs @@ -1,6 +1,6 @@ using System.Threading.Tasks; -namespace Altinn.AccessManagement.UI.Core.Services.Interfaces +namespace Altinn.Authentication.UI.Integration.KeyVault { /// /// Interface for interacting with key vault diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/KeyVaultService.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/KeyVaultService.cs index ab120b2a..e1c77fed 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/KeyVaultService.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/KeyVaultService.cs @@ -1,11 +1,10 @@ using System.Diagnostics.CodeAnalysis; -using Altinn.AccessManagement.UI.Core.Services.Interfaces; using Azure; using Azure.Identity; using Azure.Security.KeyVault.Certificates; using Azure.Security.KeyVault.Secrets; -namespace Altinn.AccessManagement.UI.Core.Services +namespace Altinn.Authentication.UI.Integration.KeyVault { /// /// Wrapper implementation for a KeyVaultClient. The wrapped client is created with a principal obtained through configuration. diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/LocalKeyVaultService.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/LocalKeyVaultService.cs index 79a52099..f9372cbf 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/LocalKeyVaultService.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/KeyVault/LocalKeyVaultService.cs @@ -1,12 +1,11 @@ using System.Diagnostics.CodeAnalysis; using System.Text; -using Altinn.AccessManagement.UI.Core.Services.Interfaces; using Azure; using Azure.Identity; using Azure.Security.KeyVault.Certificates; using Azure.Security.KeyVault.Secrets; -namespace Altinn.AccessManagement.UI.Core.Services +namespace Altinn.Authentication.UI.Integration.KeyVault { /// /// Wrapper implementation for a KeyVaultClient. The wrapped client is created with a principal obtained through configuration. diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/UserProfiles/UserProfileClient.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/UserProfiles/UserProfileClient.cs index ef8ab305..159ba554 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/UserProfiles/UserProfileClient.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/UserProfiles/UserProfileClient.cs @@ -7,6 +7,7 @@ using System.Text.Json; using System.Text.Json.Serialization; using Altinn.Authentication.UI.Core.Extensions; +using Altinn.Authentication.UI.Integration.AccessToken; namespace Altinn.Authentication.UI.Integration.UserProfiles; diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Altinn.Authentication.UI.csproj b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Altinn.Authentication.UI.csproj index 3414291c..83d59e61 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Altinn.Authentication.UI.csproj +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Altinn.Authentication.UI.csproj @@ -15,7 +15,7 @@ - + From 31c62eed76c185a0ac0794b17bb29b80b340bf90 Mon Sep 17 00:00:00 2001 From: Simen Rekkedal <61084786+simen-rekkedal@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:48:05 +0200 Subject: [PATCH 05/12] fix comment --- .../UserProfiles/IUserProfileService.cs | 5 +++++ .../UserProfiles/UserProfileService.cs | 1 + 2 files changed, 6 insertions(+) diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/IUserProfileService.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/IUserProfileService.cs index 5d690267..b077ea93 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/IUserProfileService.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/IUserProfileService.cs @@ -4,5 +4,10 @@ namespace Altinn.Authentication.UI.Core.UserProfiles; public interface IUserProfileService { + /// + /// Get the userprofile from the Platform Profile API + /// + /// + /// Task GetUserProfile(int userid); } diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/UserProfileService.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/UserProfileService.cs index cb2ae31b..fe9c9ec8 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/UserProfileService.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/UserProfileService.cs @@ -16,6 +16,7 @@ public UserProfileService( _profileClient = profileClient; } + /// public async Task GetUserProfile(int userid) { UserProfile userProfile = await _profileClient.GetUserProfile(userid); From cb7c9966ab7aa8fe6b98f3ac09bf8cfe743eada3 Mon Sep 17 00:00:00 2001 From: Simen Rekkedal <61084786+simen-rekkedal@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:54:49 +0200 Subject: [PATCH 06/12] init --- .../Controllers/SystemUserController.cs | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Controllers/SystemUserController.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Controllers/SystemUserController.cs index 03e5656d..bf580efd 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Controllers/SystemUserController.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Controllers/SystemUserController.cs @@ -65,27 +65,6 @@ public async Task GetSystemUserDetailsById(Guid guid, Cancellation return Ok(details); } - - /// - /// Used by IdPorten, to find if a given systemOrg owns a SystemUser Integration for a Vendor's Product, by ClientId. - /// ConsumerId is the first entry in the path. - /// SystemOrg is the second entry in the path. - /// ClientId is the third entry in the path. - /// - /// The unique id maintained by IdPorten tying their clients to the Registered Systems we maintain - /// Cancellationtoken - /// The legal number (Orgno) of the Vendor creating the Registered System (Accounting system) - /// The legal number (Orgno) of the party owning the System User Integration - /// The SystemUserIntegration model API DTO - [Authorize] - [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] - [HttpGet("get-consumers-integration-by-clientId/{consumerId}/{systemOrg}/{clientId}")] - public async Task CheckIfPartyHasIntegration(string clientId, string consumerId, string systemOrg,CancellationToken cancellationToken = default) - { - SystemUserDTO? res = await _systemUserService.CheckIfPartyHasIntegration(clientId, consumerId, systemOrg, cancellationToken); - if (res is null) return NoContent(); - return Ok(res); - } /// /// Used to upload a certificate for the System User From 826ed39b64e6fa9bcb286702214f3422e054f6cc Mon Sep 17 00:00:00 2001 From: Simen Rekkedal <61084786+simen-rekkedal@users.noreply.github.com> Date: Wed, 24 Apr 2024 11:26:35 +0200 Subject: [PATCH 07/12] forgot to switch to the real client from the mock --- .../Extensions/ProgramConfigurationAndDependencyInjection.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Extensions/ProgramConfigurationAndDependencyInjection.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Extensions/ProgramConfigurationAndDependencyInjection.cs index 5731eccf..af99cee9 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Extensions/ProgramConfigurationAndDependencyInjection.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Extensions/ProgramConfigurationAndDependencyInjection.cs @@ -7,6 +7,7 @@ using Altinn.Authentication.UI.Filters; using Altinn.Authentication.UI.Integration.Authentication; using Altinn.Authentication.UI.Integration.Configuration; +using Altinn.Authentication.UI.Integration.UserProfiles; using Altinn.Authentication.UI.Mocks.SystemRegister; using Altinn.Authentication.UI.Mocks.SystemUsers; using Altinn.Authentication.UI.Mocks.UserProfiles; @@ -126,7 +127,7 @@ public static IServiceCollection AddIntegrationLayer(this IServiceCollection ser //Clients in the Integration layer for the login user and auth logic //services.AddHttpClient(); services.AddHttpClient(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); //Clients for the actual Features' Services From 2f54a7f24611c39366fa82ca662f815415d59783 Mon Sep 17 00:00:00 2001 From: Simen Rekkedal <61084786+simen-rekkedal@users.noreply.github.com> Date: Wed, 24 Apr 2024 12:22:32 +0200 Subject: [PATCH 08/12] userprofile and partyclient fixes --- .../UserProfiles/UserProfileService.cs | 6 +- .../Configuration/PlatformSettings.cs | 5 ++ .../UserProfiles/PartyClient.cs | 68 +++++++++++++++++-- .../UserProfiles/UserProfileClient.cs | 2 +- ...gramConfigurationAndDependencyInjection.cs | 10 +-- .../appsettings.AT21.json | 1 + 6 files changed, 77 insertions(+), 15 deletions(-) diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/UserProfileService.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/UserProfileService.cs index fe9c9ec8..e0b442f9 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/UserProfileService.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/UserProfileService.cs @@ -5,14 +5,14 @@ namespace Altinn.Authentication.UI.Core.UserProfiles; public class UserProfileService : IUserProfileService { - //private readonly ILogger _logger; + private readonly ILogger _logger; private readonly IUserProfileClient _profileClient; public UserProfileService( - //ILogger logger, + ILogger logger, IUserProfileClient profileClient) { - //_logger = logger; + _logger = logger; _profileClient = profileClient; } diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/Configuration/PlatformSettings.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/Configuration/PlatformSettings.cs index f353a346..098c5298 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/Configuration/PlatformSettings.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/Configuration/PlatformSettings.cs @@ -5,6 +5,11 @@ /// public class PlatformSettings { + /// + /// Gets or sets the access management api endpoint + /// + public string ApiAccessManagementEndpoint { get; set; } + /// /// Gets or sets the authentication api endpoint /// diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/UserProfiles/PartyClient.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/UserProfiles/PartyClient.cs index c5d587d2..3b3924f5 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/UserProfiles/PartyClient.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/UserProfiles/PartyClient.cs @@ -1,19 +1,73 @@ -using Altinn.Authentication.UI.Core.UserProfiles; +using Altinn.Authentication.UI.Core.Authentication; +using Altinn.Authentication.UI.Core.UserProfiles; +using Altinn.Authentication.UI.Integration.Configuration; +using Altinn.Authentication.UI.Core.Extensions; using Altinn.Platform.Register.Models; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; namespace Altinn.Authentication.UI.Integration.UserProfiles; +/// +/// Proxy implementation for parties +/// +[ExcludeFromCodeCoverage] public class PartyClient : IPartyClient { + private readonly ILogger _logger; + private readonly HttpClient _client; + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly PlatformSettings _platformSettings; + private readonly JsonSerializerOptions _serializerOptions = + new() { PropertyNameCaseInsensitive = true }; + + /// + /// Initializes a new instance of the class + /// + /// HttpClient from default httpclientfactory + /// the logger + /// handler for http context + /// the platform setttings + public PartyClient( + HttpClient httpClient, + ILogger logger, + IHttpContextAccessor httpContextAccessor, + IOptions platformSettings) + { + _logger = logger; + _httpContextAccessor = httpContextAccessor; + _platformSettings = platformSettings.Value; + httpClient.BaseAddress = new Uri(_platformSettings.ApiAccessManagementEndpoint); + _client = httpClient; + _serializerOptions.Converters.Add(new JsonStringEnumConverter()); + } + + /// public async Task GetPartyFromReporteeListIfExists(int partyId) { - Party mock = new() + try { - PartyId = 5001, - OrgNumber = "123456789MVA", - Name = "Framifrå Bedrift AS" - }; + string endpointUrl = $"authorizedparty/{partyId}?includeAltinn2=true"; + string token = JwtTokenUtil.GetTokenFromContext(_httpContextAccessor.HttpContext!, _platformSettings.JwtCookieName!)!; - return mock; + HttpResponseMessage response = await _client.GetAsync(token, endpointUrl); + + if ( response.StatusCode == System.Net.HttpStatusCode.OK ) + { + string responseContent = await response.Content.ReadAsStringAsync(); + return JsonSerializer.Deserialize(responseContent, _serializerOptions)!; + } + + return null!; + } + catch (Exception ex) + { + _logger.LogError(ex, "Authentication.UI // PartyClient // GetPartyFromReporteeListIfExists // Exception"); + throw; + } } } diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/UserProfiles/UserProfileClient.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/UserProfiles/UserProfileClient.cs index 159ba554..91f2f836 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/UserProfiles/UserProfileClient.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Integration/UserProfiles/UserProfileClient.cs @@ -31,7 +31,7 @@ public class UserProfileClient : IUserProfileClient /// /// public UserProfileClient( - ILogger logger, + ILogger logger, HttpClient httpClient, IHttpContextAccessor httpContextAccessor, PlatformSettings platformSettings, diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Extensions/ProgramConfigurationAndDependencyInjection.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Extensions/ProgramConfigurationAndDependencyInjection.cs index af99cee9..d537002f 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Extensions/ProgramConfigurationAndDependencyInjection.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/Extensions/ProgramConfigurationAndDependencyInjection.cs @@ -7,6 +7,8 @@ using Altinn.Authentication.UI.Filters; using Altinn.Authentication.UI.Integration.Authentication; using Altinn.Authentication.UI.Integration.Configuration; +using Altinn.Authentication.UI.Integration.SystemRegister; +using Altinn.Authentication.UI.Integration.SystemUsers; using Altinn.Authentication.UI.Integration.UserProfiles; using Altinn.Authentication.UI.Mocks.SystemRegister; using Altinn.Authentication.UI.Mocks.SystemUsers; @@ -127,12 +129,12 @@ public static IServiceCollection AddIntegrationLayer(this IServiceCollection ser //Clients in the Integration layer for the login user and auth logic //services.AddHttpClient(); services.AddHttpClient(); - services.AddSingleton(); - services.AddSingleton(); + services.AddHttpClient(); //Clients for the actual Features' Services - services.AddSingleton(); - services.AddSingleton(); + services.AddHttpClient(); + services.AddHttpClient(); + services.AddHttpClient(); return services; } diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/appsettings.AT21.json b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/appsettings.AT21.json index 178fe035..ff8a98a3 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/appsettings.AT21.json +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI/appsettings.AT21.json @@ -1,5 +1,6 @@ { "PlatformSettings": { + "ApiAccessManagementEndpoint": "https://platform.at21.altinn.cloud/accessmanagement/api/v1/", "ApiAuthenticationEndpoint": "https://platform.at21.altinn.cloud/authentication/api/v1/", "ApiProfileEndpoint": "https://platform.at21.altinn.cloud/profile/api/v1/", "OpenIdWellKnownEndpoint": "https://platform.at21.altinn.cloud/authentication/api/v1/openid/" From 10c0676a4876f5462744175e444cc54923b79e67 Mon Sep 17 00:00:00 2001 From: Simen Rekkedal <61084786+simen-rekkedal@users.noreply.github.com> Date: Wed, 24 Apr 2024 12:33:18 +0200 Subject: [PATCH 09/12] removed unused method --- .../SystemUsers/SystemUserService.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/SystemUsers/SystemUserService.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/SystemUsers/SystemUserService.cs index 854c2b74..9bd6829b 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/SystemUsers/SystemUserService.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/SystemUsers/SystemUserService.cs @@ -68,9 +68,4 @@ public async Task ChangeSystemUserProduct(string selectedSystemType, Guid { return await _systemUserClient.ChangeSystemUserRealProduct(selectedSystemType, id, cancellationToken); } - - public Task CheckIfPartyHasIntegration(string clientId, string partyId, string systemOrg, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } } From 51e85169861273655c430ea067805ef3fa47b11e Mon Sep 17 00:00:00 2001 From: Simen Rekkedal <61084786+simen-rekkedal@users.noreply.github.com> Date: Wed, 24 Apr 2024 12:35:31 +0200 Subject: [PATCH 10/12] fix --- .../SystemUsers/ISystemUserService.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/SystemUsers/ISystemUserService.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/SystemUsers/ISystemUserService.cs index 4553ea80..950dc809 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/SystemUsers/ISystemUserService.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/SystemUsers/ISystemUserService.cs @@ -13,5 +13,4 @@ public interface ISystemUserService Task ChangeSystemUserTitle(string newTitle, Guid id, CancellationToken cancellationToken = default); Task ChangeSystemUserDescription(string newDescr, Guid id, CancellationToken cancellationToken = default); Task ChangeSystemUserProduct(string selectedSystemType, Guid id, CancellationToken cancellationToken = default); - Task CheckIfPartyHasIntegration(string clientId, string partyId, string systemOrg, CancellationToken cancellationToken = default); } From e5f8546c1c13ba775a39723e8ebd71b9f4fee4c4 Mon Sep 17 00:00:00 2001 From: Simen Rekkedal <61084786+simen-rekkedal@users.noreply.github.com> Date: Wed, 24 Apr 2024 12:44:13 +0200 Subject: [PATCH 11/12] quickfix --- .../Controllers/ProfileControllerTest.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Tests/Controllers/ProfileControllerTest.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Tests/Controllers/ProfileControllerTest.cs index 6cc2ace9..4cae3990 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Tests/Controllers/ProfileControllerTest.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Tests/Controllers/ProfileControllerTest.cs @@ -20,6 +20,7 @@ using System.Text; using System.Text.Json; using Xunit; +using Microsoft.Extensions.Logging; //using Moq; namespace Altinn.Authentication.UI.Tests.Controllers; @@ -32,11 +33,12 @@ public class ProfileControllerTest : IClassFixture factory) + CustomWebApplicationFactory factory + ) { _factory = factory; //_userProfileClient = new UserProfileClientMock(); //Mock.Of(); - _userProfileService = new UserProfileService( new UserProfileClientMock() ); + _userProfileService = new UserProfileService(null, new UserProfileClientMock() ); _client = SetupUtils.GetTestClient(_factory, false); } From 32c39dc9fe01dd71b820092d65013f48b7b0d65e Mon Sep 17 00:00:00 2001 From: Simen Rekkedal <61084786+simen-rekkedal@users.noreply.github.com> Date: Wed, 24 Apr 2024 12:51:00 +0200 Subject: [PATCH 12/12] nudge --- .../UserProfiles/UserProfileService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/UserProfileService.cs b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/UserProfileService.cs index e0b442f9..d4d32811 100644 --- a/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/UserProfileService.cs +++ b/bff/src/Altinn.Authentication.UI/Altinn.Authentication.UI.Core/UserProfiles/UserProfileService.cs @@ -20,6 +20,6 @@ public UserProfileService( public async Task GetUserProfile(int userid) { UserProfile userProfile = await _profileClient.GetUserProfile(userid); - return userProfile; + return userProfile; } }