diff --git a/src/clients/Dim.Clients/Api/SubAccounts/ISubAccountClient.cs b/src/clients/Dim.Clients/Api/SubAccounts/ISubAccountClient.cs index e95ce33..7c73a57 100644 --- a/src/clients/Dim.Clients/Api/SubAccounts/ISubAccountClient.cs +++ b/src/clients/Dim.Clients/Api/SubAccounts/ISubAccountClient.cs @@ -24,7 +24,7 @@ namespace Dim.Clients.Api.SubAccounts; public interface ISubAccountClient { - Task CreateSubaccount(BasicAuthSettings basicAuthSettings, string adminMail, string tenantName, Guid directoryId, CancellationToken cancellationToken); + Task CreateSubaccount(BasicAuthSettings basicAuthSettings, string adminMail, string tenantName, Guid directoryId, string bpn, CancellationToken cancellationToken); Task CreateServiceManagerBindings(BasicAuthSettings basicAuthSettings, Guid subAccountId, CancellationToken cancellationToken); Task GetServiceManagerBindings(BasicAuthSettings basicAuthSettings, Guid subAccountId, CancellationToken cancellationToken); } diff --git a/src/clients/Dim.Clients/Api/SubAccounts/SubAccountClient.cs b/src/clients/Dim.Clients/Api/SubAccounts/SubAccountClient.cs index 3150304..f968336 100644 --- a/src/clients/Dim.Clients/Api/SubAccounts/SubAccountClient.cs +++ b/src/clients/Dim.Clients/Api/SubAccounts/SubAccountClient.cs @@ -28,20 +28,11 @@ namespace Dim.Clients.Api.SubAccounts; -public class SubAccountClient : ISubAccountClient +public class SubAccountClient(IBasicAuthTokenService basicAuthTokenService) : ISubAccountClient { - private static readonly Regex TenantName = new(@"(?<=[^\w-])|(?<=[^-])[\W_]+|(?<=[^-])$", RegexOptions.Compiled, new TimeSpan(0, 0, 0, 1)); - private readonly IBasicAuthTokenService _basicAuthTokenService; - - public SubAccountClient(IBasicAuthTokenService basicAuthTokenService) - { - _basicAuthTokenService = basicAuthTokenService; - } - - public async Task CreateSubaccount(BasicAuthSettings basicAuthSettings, string adminMail, string tenantName, Guid directoryId, CancellationToken cancellationToken) + public async Task CreateSubaccount(BasicAuthSettings basicAuthSettings, string adminMail, string tenantName, Guid directoryId, string bpn, CancellationToken cancellationToken) { - var subdomain = TenantName.Replace(tenantName, "-").ToLower().TrimStart('-').TrimEnd('-'); - var client = await _basicAuthTokenService.GetBasicAuthorizedClient(basicAuthSettings, cancellationToken).ConfigureAwait(false); + var client = await basicAuthTokenService.GetBasicAuthorizedClient(basicAuthSettings, cancellationToken).ConfigureAwait(false); var directory = new CreateSubAccountRequest( false, $"CX customer sub-account {tenantName}", @@ -55,7 +46,7 @@ public async Task CreateSubaccount(BasicAuthSettings basicAuthSettings, st directoryId, "eu10", Enumerable.Repeat(adminMail, 1), - subdomain, + bpn, UsedForProduction.USED_FOR_PRODUCTION ); @@ -86,7 +77,7 @@ public async Task CreateSubaccount(BasicAuthSettings basicAuthSettings, st public async Task CreateServiceManagerBindings(BasicAuthSettings basicAuthSettings, Guid subAccountId, CancellationToken cancellationToken) { - var client = await _basicAuthTokenService.GetBasicAuthorizedClient(basicAuthSettings, cancellationToken).ConfigureAwait(false); + var client = await basicAuthTokenService.GetBasicAuthorizedClient(basicAuthSettings, cancellationToken).ConfigureAwait(false); var data = new { name = "accessServiceManager" @@ -98,7 +89,7 @@ await client.PostAsJsonAsync($"/accounts/v2/subaccounts/{subAccountId}/serviceMa public async Task GetServiceManagerBindings(BasicAuthSettings basicAuthSettings, Guid subAccountId, CancellationToken cancellationToken) { - var client = await _basicAuthTokenService.GetBasicAuthorizedClient(basicAuthSettings, cancellationToken).ConfigureAwait(false); + var client = await basicAuthTokenService.GetBasicAuthorizedClient(basicAuthSettings, cancellationToken).ConfigureAwait(false); var result = await client.GetAsync($"/accounts/v2/subaccounts/{subAccountId}/serviceManagerBindings", cancellationToken) .CatchingIntoServiceExceptionFor("create-subaccount", HttpAsyncResponseMessageExtension.RecoverOptions.ALLWAYS).ConfigureAwait(false); diff --git a/src/database/Dim.DbAccess/Repositories/ITenantRepository.cs b/src/database/Dim.DbAccess/Repositories/ITenantRepository.cs index 101d14e..1b9240e 100644 --- a/src/database/Dim.DbAccess/Repositories/ITenantRepository.cs +++ b/src/database/Dim.DbAccess/Repositories/ITenantRepository.cs @@ -19,6 +19,8 @@ ********************************************************************************/ using Dim.Entities.Entities; +using System; +using System.Threading.Tasks; namespace Dim.DbAccess.Repositories; @@ -47,4 +49,5 @@ public interface ITenantRepository Task GetExternalIdForTechnicalUser(Guid technicalUserId); void RemoveTechnicalUser(Guid technicalUserId); Task IsTenantExisting(string companyName, string bpn); + Task GetTenantBpn(Guid tenantId); } diff --git a/src/database/Dim.DbAccess/Repositories/TenantRepository.cs b/src/database/Dim.DbAccess/Repositories/TenantRepository.cs index 465ecc3..1ff7088 100644 --- a/src/database/Dim.DbAccess/Repositories/TenantRepository.cs +++ b/src/database/Dim.DbAccess/Repositories/TenantRepository.cs @@ -21,6 +21,8 @@ using Dim.Entities; using Dim.Entities.Entities; using Microsoft.EntityFrameworkCore; +using System; +using System.Threading.Tasks; namespace Dim.DbAccess.Repositories; @@ -165,4 +167,10 @@ public void RemoveTechnicalUser(Guid technicalUserId) => public Task IsTenantExisting(string companyName, string bpn) => context.Tenants .AnyAsync(x => x.CompanyName == companyName && x.Bpn == bpn); + + public Task GetTenantBpn(Guid tenantId) => + context.Tenants + .Where(x => x.Id == tenantId) + .Select(x => x.Bpn) + .SingleAsync(); } diff --git a/src/processes/DimProcess.Library/DimProcessHandler.cs b/src/processes/DimProcess.Library/DimProcessHandler.cs index 22aeb68..d7c8946 100644 --- a/src/processes/DimProcess.Library/DimProcessHandler.cs +++ b/src/processes/DimProcess.Library/DimProcessHandler.cs @@ -62,7 +62,8 @@ public class DimProcessHandler( ClientSecret = _settings.ClientsecretCisCentral }; - var subAccountId = await subAccountClient.CreateSubaccount(subAccountAuth, adminMail, tenantName, parentDirectoryId, cancellationToken).ConfigureAwait(false); + var bpn = await dimRepositories.GetInstance().GetTenantBpn(tenantId); + var subAccountId = await subAccountClient.CreateSubaccount(subAccountAuth, adminMail, tenantName, parentDirectoryId, bpn, cancellationToken).ConfigureAwait(false); dimRepositories.GetInstance().AttachAndModifyTenant(tenantId, tenant => { tenant.SubAccountId = null; diff --git a/src/web/Dim.Web/BusinessLogic/DimBusinessLogic.cs b/src/web/Dim.Web/BusinessLogic/DimBusinessLogic.cs index 9ee7657..a57dd66 100644 --- a/src/web/Dim.Web/BusinessLogic/DimBusinessLogic.cs +++ b/src/web/Dim.Web/BusinessLogic/DimBusinessLogic.cs @@ -28,6 +28,7 @@ using Dim.Web.Models; using Microsoft.Extensions.Options; using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; +using System.Text.RegularExpressions; namespace Dim.Web.BusinessLogic; @@ -38,10 +39,12 @@ public class DimBusinessLogic( IOptions options) : IDimBusinessLogic { + private static readonly Regex TenantName = new(@"(?<=[^\w-])|(?<=[^-])[\W_]+|(?<=[^-])$", RegexOptions.Compiled, new TimeSpan(0, 0, 0, 1)); private readonly DimSettings _settings = options.Value; public async Task StartSetupDim(string companyName, string bpn, string didDocumentLocation, bool isIssuer) { + var tenant = TenantName.Replace(companyName, string.Empty).TrimStart('-').TrimEnd('-').ToLower(); if (await dimRepositories.GetInstance().IsTenantExisting(companyName, bpn).ConfigureAwait(ConfigureAwaitOptions.None)) { throw new ConflictException($"Tenant {companyName} with Bpn {bpn} already exists"); @@ -51,7 +54,7 @@ public async Task StartSetupDim(string companyName, string bpn, string didDocume var processId = processStepRepository.CreateProcess(ProcessTypeId.SETUP_DIM).Id; processStepRepository.CreateProcessStep(ProcessStepTypeId.CREATE_SUBACCOUNT, ProcessStepStatusId.TODO, processId); - dimRepositories.GetInstance().CreateTenant(companyName, bpn, didDocumentLocation, isIssuer, processId, _settings.OperatorId); + dimRepositories.GetInstance().CreateTenant(tenant, bpn, didDocumentLocation, isIssuer, processId, _settings.OperatorId); await dimRepositories.SaveAsync().ConfigureAwait(false); } diff --git a/tests/processes/DimProcess.Library.Tests/DimProcessHandlerTests.cs b/tests/processes/DimProcess.Library.Tests/DimProcessHandlerTests.cs index f594324..e3df309 100644 --- a/tests/processes/DimProcess.Library.Tests/DimProcessHandlerTests.cs +++ b/tests/processes/DimProcess.Library.Tests/DimProcessHandlerTests.cs @@ -109,7 +109,7 @@ public async Task CreateSubaccount_WithValidData_ReturnsExpected() initialize?.Invoke(tenant); modify(tenant); }); - A.CallTo(() => _subAccountClient.CreateSubaccount(A._, A._, _tenantName, A._, A._)) + A.CallTo(() => _subAccountClient.CreateSubaccount(A._, A._, _tenantName, A._, A._, A._)) .Returns(subAccountId); // Act diff --git a/tests/web/Dim.Web.Tests/DimBusinessLogicTests.cs b/tests/web/Dim.Web.Tests/DimBusinessLogicTests.cs index 8c37dff..9d32d81 100644 --- a/tests/web/Dim.Web.Tests/DimBusinessLogicTests.cs +++ b/tests/web/Dim.Web.Tests/DimBusinessLogicTests.cs @@ -77,8 +77,14 @@ public async Task StartSetupDim_WithExisting_ThrowsConflictException() result.Message.Should().Be($"Tenant testCompany with Bpn BPNL00000001TEST already exists"); } - [Fact] - public async Task StartSetupDim_WithNewData_CreatesExpected() + [Theory] + [InlineData("testCompany", "testcompany")] + [InlineData("-abc123", "abc123")] + [InlineData("abc-123", "abc123")] + [InlineData("abc#123", "abc123")] + [InlineData("abc'123", "abc123")] + [InlineData("abc\"123", "abc123")] + public async Task StartSetupDim_WithNewData_CreatesExpected(string companyName, string expectedCompanyName) { // Arrange var processId = Guid.NewGuid(); @@ -106,7 +112,7 @@ public async Task StartSetupDim_WithNewData_CreatesExpected() }); // Act - await _sut.StartSetupDim("testCompany", "BPNL00000001TEST", "https://example.org/test", false); + await _sut.StartSetupDim(companyName, "BPNL00000001TEST", "https://example.org/test", false); // Assert processes.Should().ContainSingle() @@ -114,6 +120,6 @@ public async Task StartSetupDim_WithNewData_CreatesExpected() processSteps.Should().ContainSingle() .And.Satisfy(x => x.ProcessId == processId && x.ProcessStepTypeId == ProcessStepTypeId.CREATE_SUBACCOUNT); tenants.Should().ContainSingle() - .And.Satisfy(x => x.CompanyName == "testCompany" && x.Bpn == "BPNL00000001TEST"); + .And.Satisfy(x => x.CompanyName == expectedCompanyName && x.Bpn == "BPNL00000001TEST"); } }