diff --git a/src/administration/Administration.Service/BusinessLogic/ServiceAccountBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/ServiceAccountBusinessLogic.cs index 1b5c5d02d2..9b9352039a 100644 --- a/src/administration/Administration.Service/BusinessLogic/ServiceAccountBusinessLogic.cs +++ b/src/administration/Administration.Service/BusinessLogic/ServiceAccountBusinessLogic.cs @@ -162,9 +162,11 @@ public async Task GetOwnCompanyServiceAccountD IamClientAuthMethod? iamClientAuthMethod; string? secret; + var authServiceUrl = _settings.AuthServiceUrl; if (result.DimServiceAccountData != null) { + authServiceUrl = result.DimServiceAccountData.AuthenticationServiceUrl; iamClientAuthMethod = IamClientAuthMethod.SECRET; var cryptoHelper = _settings.EncryptionConfigs.GetCryptoHelper(_settings.EncryptionConfigIndex); secret = cryptoHelper.Decrypt( @@ -192,6 +194,8 @@ public async Task GetOwnCompanyServiceAccountD iamClientAuthMethod, result.UserRoleDatas, result.CompanyServiceAccountTypeId, + result.CompanyServiceAccountKindId, + authServiceUrl, result.Status, secret, result.ConnectorData, diff --git a/src/administration/Administration.Service/BusinessLogic/ServiceAccountSettings.cs b/src/administration/Administration.Service/BusinessLogic/ServiceAccountSettings.cs index 1066b7e3b4..bef6188d4e 100644 --- a/src/administration/Administration.Service/BusinessLogic/ServiceAccountSettings.cs +++ b/src/administration/Administration.Service/BusinessLogic/ServiceAccountSettings.cs @@ -40,6 +40,9 @@ public class ServiceAccountSettings [Required] [DistinctValues("x => x.Index")] public IEnumerable EncryptionConfigs { get; set; } = null!; + + [Required] + public string AuthServiceUrl { get; set; } = null!; } public static class ServiceAccountSettingsExtensions diff --git a/src/administration/Administration.Service/Models/ServiceAccountConnectorOfferData.cs b/src/administration/Administration.Service/Models/ServiceAccountConnectorOfferData.cs index ca0ae893b8..c955fceb07 100644 --- a/src/administration/Administration.Service/Models/ServiceAccountConnectorOfferData.cs +++ b/src/administration/Administration.Service/Models/ServiceAccountConnectorOfferData.cs @@ -33,6 +33,8 @@ public record ServiceAccountConnectorOfferData( [property: JsonPropertyName("authenticationType")] IamClientAuthMethod? IamClientAuthMethod, [property: JsonPropertyName("roles")] IEnumerable UserRoleDatas, [property: JsonPropertyName("companyServiceAccountTypeId")] CompanyServiceAccountTypeId CompanyServiceAccountTypeId, + [property: JsonPropertyName("usertype")] CompanyServiceAccountKindId CompanyServiceAccountKindId, + [property: JsonPropertyName("authenticationServiceUrl")] string AuthenticationServiceUrl, [property: JsonPropertyName("status")] UserStatusId UserStatusId, [property: JsonPropertyName("secret")] string? Secret, [property: JsonPropertyName("connector")] ConnectorResponseData? Connector, diff --git a/src/administration/Administration.Service/appsettings.json b/src/administration/Administration.Service/appsettings.json index 377d312c63..9240fc9dbf 100644 --- a/src/administration/Administration.Service/appsettings.json +++ b/src/administration/Administration.Service/appsettings.json @@ -248,7 +248,8 @@ "ServiceAccount": { "ClientId": "", "EncryptionConfigIndex": 0, - "EncryptionConfigs": [] + "EncryptionConfigs": [], + "AuthServiceUrl": "" }, "Connectors": { "MaxPageSize": 20, diff --git a/src/portalbackend/PortalBackend.DBAccess/Models/CompanyServiceAccountDetailedData.cs b/src/portalbackend/PortalBackend.DBAccess/Models/CompanyServiceAccountDetailedData.cs index fee038ac16..136824ec0a 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Models/CompanyServiceAccountDetailedData.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Models/CompanyServiceAccountDetailedData.cs @@ -30,6 +30,7 @@ public record CompanyServiceAccountDetailedData( UserStatusId Status, IEnumerable UserRoleDatas, CompanyServiceAccountTypeId CompanyServiceAccountTypeId, + CompanyServiceAccountKindId CompanyServiceAccountKindId, ConnectorResponseData? ConnectorData, OfferResponseData? OfferSubscriptionData, CompanyLastEditorData? CompanyLastEditorData, @@ -42,6 +43,7 @@ public record OfferResponseData(Guid Id, OfferTypeId Type, string? Name, Guid? S public record CompanyLastEditorData(string? Name, string CompanyName); public record DimServiceAccountData( + string AuthenticationServiceUrl, byte[] ClientSecret, byte[]? InitializationVector, int EncryptionMode diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/ServiceAccountRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/ServiceAccountRepository.cs index 93ed6cdd9f..c4efb0c00a 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/ServiceAccountRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/ServiceAccountRepository.cs @@ -146,6 +146,7 @@ public void AttachAndModifyCompanyServiceAccount( userRole.Offer!.AppInstances.First().IamClient!.ClientClientId, userRole.UserRoleText)), x.ServiceAccount.CompanyServiceAccountTypeId, + x.ServiceAccount.CompanyServiceAccountKindId, x.Connector == null ? null : new ConnectorResponseData( @@ -168,6 +169,7 @@ public void AttachAndModifyCompanyServiceAccount( x.ServiceAccount.DimCompanyServiceAccount == null ? null : new DimServiceAccountData( + x.DimCompanyServiceAccount!.AuthenticationServiceUrl, x.DimCompanyServiceAccount!.ClientSecret, x.DimCompanyServiceAccount.InitializationVector, x.DimCompanyServiceAccount.EncryptionMode))) diff --git a/tests/administration/Administration.Service.Tests/BusinessLogic/ServiceAccountBusinessLogicTests.cs b/tests/administration/Administration.Service.Tests/BusinessLogic/ServiceAccountBusinessLogicTests.cs index 46a761a1ef..1aac18e2aa 100644 --- a/tests/administration/Administration.Service.Tests/BusinessLogic/ServiceAccountBusinessLogicTests.cs +++ b/tests/administration/Administration.Service.Tests/BusinessLogic/ServiceAccountBusinessLogicTests.cs @@ -100,6 +100,7 @@ public ServiceAccountBusinessLogicTests() _options = Options.Create(new ServiceAccountSettings { + AuthServiceUrl = "https://auth.test/auth", ClientId = ClientId, EncryptionConfigIndex = 1, EncryptionConfigs = new[] { new EncryptionModeConfig() { Index = 1, EncryptionKey = Convert.ToHexString(encryptionKey), CipherMode = System.Security.Cryptography.CipherMode.CBC, PaddingMode = System.Security.Cryptography.PaddingMode.PKCS7 } }, @@ -238,6 +239,54 @@ public async Task GetOwnCompanyServiceAccountDetailsAsync_WithValidInputAndDimCo A.CallTo(() => _provisioningManager.GetCentralClientAuthDataAsync(A._)).MustNotHaveHappened(); } + [Fact] + public async Task GetOwnCompanyServiceAccountDetailsAsync_WithValidUserTypeInternal_AuthenticationUrl() + { + // Arrange + SetupGetOwnComapnyServiceAccountInternalType(); + var sut = new ServiceAccountBusinessLogic(_provisioningManager, _portalRepositories, _options, null!, _identityService, _serviceAccountManagement); + + // Act + var result = await sut.GetOwnCompanyServiceAccountDetailsAsync(ValidServiceAccountId); + + // Assert + result.Should().NotBeNull(); + result.CompanyServiceAccountKindId.Should().Be(CompanyServiceAccountKindId.INTERNAL); + result.AuthenticationServiceUrl.Should().Be("https://auth.test/auth"); + } + + [Fact] + public async Task GetOwnCompanyServiceAccountDetailsAsync_WithValidUserTypeExternal_AuthenticationUrl() + { + // Arrange + SetupGetOwnComapnyServiceAccountExternalType(); + var sut = new ServiceAccountBusinessLogic(_provisioningManager, _portalRepositories, _options, null!, _identityService, _serviceAccountManagement); + + // Act + var result = await sut.GetOwnCompanyServiceAccountDetailsAsync(ValidServiceAccountId); + + // Assert + result.Should().NotBeNull(); + result.CompanyServiceAccountKindId.Should().Be(CompanyServiceAccountKindId.EXTERNAL); + result.AuthenticationServiceUrl.Should().Be("https://test.org/auth"); + } + + [Fact] + public async Task GetOwnCompanyServiceAccountDetailsAsync_WithInValidUserTypeInternal_AuthenticationUrl() + { + // Arrange + SetupGetOwnCompanyServiceAccountDetails(); + var sut = new ServiceAccountBusinessLogic(_provisioningManager, _portalRepositories, _options, null!, _identityService, _serviceAccountManagement); + + // Act + var result = await sut.GetOwnCompanyServiceAccountDetailsAsync(ValidServiceAccountId); + + // Assert + result.Should().NotBeNull(); + result.CompanyServiceAccountKindId.Should().NotBe(CompanyServiceAccountKindId.INTERNAL); + result.AuthenticationServiceUrl.Should().NotBe("https://auth.test/auth"); + } + [Fact] public async Task GetOwnCompanyServiceAccountDetailsAsync_WithInvalidCompany_NotFoundException() { @@ -790,21 +839,16 @@ private void SetupUpdateOwnCompanyServiceAccountDetails() private void SetupGetOwnCompanyServiceAccount() { - var data = _fixture.Build() - .With(x => x.Status, UserStatusId.ACTIVE) - .With(x => x.DimServiceAccountData, default(DimServiceAccountData?)) - .Create(); - - var cryptoConfig = _options.Value.EncryptionConfigs.Single(x => x.Index == _options.Value.EncryptionConfigIndex); - var (secret, initializationVector) = CryptoHelper.Encrypt("test", Convert.FromHexString(cryptoConfig.EncryptionKey), cryptoConfig.CipherMode, cryptoConfig.PaddingMode); + var cryptoHelper = _options.Value.EncryptionConfigs.GetCryptoHelper(_options.Value.EncryptionConfigIndex); + var (secret, initializationVector) = cryptoHelper.Encrypt("test"); - var dimServiceAccountData = new DimServiceAccountData(secret, initializationVector, _options.Value.EncryptionConfigIndex); + var dimServiceAccountData = new DimServiceAccountData("https://example.org/auth", secret, initializationVector, _options.Value.EncryptionConfigIndex); var dataWithDim = _fixture.Build() .With(x => x.DimServiceAccountData, dimServiceAccountData) .Create(); A.CallTo(() => _serviceAccountRepository.GetOwnCompanyServiceAccountDetailedDataUntrackedAsync(ValidServiceAccountId, ValidCompanyId)) - .Returns(data); + .Returns(dataWithDim); A.CallTo(() => _serviceAccountRepository.GetOwnCompanyServiceAccountDetailedDataUntrackedAsync(ValidServiceAccountWithDimDataId, ValidCompanyId)) .Returns(dataWithDim); A.CallTo(() => _serviceAccountRepository.GetOwnCompanyServiceAccountDetailedDataUntrackedAsync( @@ -814,6 +858,35 @@ private void SetupGetOwnCompanyServiceAccount() .Returns(null); } + private void SetupGetOwnComapnyServiceAccountInternalType() + { + var data = _fixture.Build() + .With(x => x.Status, UserStatusId.ACTIVE) + .With(x => x.CompanyServiceAccountKindId, CompanyServiceAccountKindId.INTERNAL) + .With(x => x.DimServiceAccountData, default(DimServiceAccountData?)) + .Create(); + + A.CallTo(() => _serviceAccountRepository.GetOwnCompanyServiceAccountDetailedDataUntrackedAsync(ValidServiceAccountId, ValidCompanyId)) + .Returns(data); + } + + private void SetupGetOwnComapnyServiceAccountExternalType() + { + var cryptoHelper = _options.Value.EncryptionConfigs.GetCryptoHelper(_options.Value.EncryptionConfigIndex); + var (secret, initializationVector) = cryptoHelper.Encrypt("test"); + + var dimServiceAccountData = new DimServiceAccountData("https://test.org/auth", secret, initializationVector, _options.Value.EncryptionConfigIndex); + + var externalData = _fixture.Build() + .With(x => x.Status, UserStatusId.ACTIVE) + .With(x => x.CompanyServiceAccountKindId, CompanyServiceAccountKindId.EXTERNAL) + .With(x => x.DimServiceAccountData, dimServiceAccountData) + .Create(); + + A.CallTo(() => _serviceAccountRepository.GetOwnCompanyServiceAccountDetailedDataUntrackedAsync(ValidServiceAccountId, ValidCompanyId)) + .Returns(externalData); + } + private void SetupDeleteOwnCompanyServiceAccount(Connector? connector = null, Identity? identity = null, Guid? processId = null) { var serviceAccount = new CompanyServiceAccount(Guid.NewGuid(), Guid.NewGuid(), "test-sa", "test", CompanyServiceAccountTypeId.OWN, CompanyServiceAccountKindId.INTERNAL); diff --git a/tests/administration/Administration.Service.Tests/appsettings.IntegrationTests.json b/tests/administration/Administration.Service.Tests/appsettings.IntegrationTests.json index b6600bcbfa..3b35ac7fde 100644 --- a/tests/administration/Administration.Service.Tests/appsettings.IntegrationTests.json +++ b/tests/administration/Administration.Service.Tests/appsettings.IntegrationTests.json @@ -245,7 +245,8 @@ "CipherMode": "CBC", "PaddingMode": "PKCS7" } - ] + ], + "AuthServiceUrl": "https://auth.test/auth" }, "Connectors": { "MaxPageSize": 20,