Skip to content

Commit

Permalink
fix(osp): add companyUsers to invitation for osp process (#896)
Browse files Browse the repository at this point in the history
Refs: #892
Reviewed-By: Evelyn Gurschler <evelyn.gurschler@bmw.de>
  • Loading branch information
Phil91 authored Aug 2, 2024
1 parent 7825b1b commit 41525c3
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,44 +37,39 @@

namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLogic;

public class NetworkBusinessLogic : INetworkBusinessLogic
public class NetworkBusinessLogic(
IPortalRepositories portalRepositories,
IIdentityService identityService,
IUserProvisioningService userProvisioningService,
INetworkRegistrationProcessHelper processHelper,
IOptions<PartnerRegistrationSettings> options)
: INetworkBusinessLogic
{
private static readonly Regex Name = new(ValidationExpressions.Name, RegexOptions.Compiled, TimeSpan.FromSeconds(1));
private static readonly Regex ExternalID = new("^[A-Za-z0-9\\-+_/,.]{6,36}$", RegexOptions.Compiled, TimeSpan.FromSeconds(1));
private static readonly Regex ExternalId = new("^[A-Za-z0-9\\-+_/,.]{6,36}$", RegexOptions.Compiled, TimeSpan.FromSeconds(1));
private static readonly Regex Company = new(ValidationExpressions.Company, RegexOptions.Compiled, TimeSpan.FromSeconds(1));

private readonly IPortalRepositories _portalRepositories;
private readonly IIdentityData _identityData;
private readonly IUserProvisioningService _userProvisioningService;
private readonly INetworkRegistrationProcessHelper _processHelper;
private readonly PartnerRegistrationSettings _settings;

public NetworkBusinessLogic(IPortalRepositories portalRepositories, IIdentityService identityService, IUserProvisioningService userProvisioningService, INetworkRegistrationProcessHelper processHelper, IOptions<PartnerRegistrationSettings> options)
{
_portalRepositories = portalRepositories;
_identityData = identityService.IdentityData;
_userProvisioningService = userProvisioningService;
_processHelper = processHelper;
_settings = options.Value;
}
private readonly IIdentityData _identityData = identityService.IdentityData;
private readonly PartnerRegistrationSettings _settings = options.Value;

public async Task HandlePartnerRegistration(PartnerRegistrationData data)
{
if (!string.IsNullOrEmpty(data.Name) && !Company.IsMatch(data.Name))
{
throw new ControllerArgumentException("OrganisationName length must be 3-40 characters and *+=#%\\s not used as one of the first three characters in the Organisation name", "organisationName");
}

var ownerCompanyId = _identityData.CompanyId;
var networkRepository = _portalRepositories.GetInstance<INetworkRepository>();
var companyRepository = _portalRepositories.GetInstance<ICompanyRepository>();
var processStepRepository = _portalRepositories.GetInstance<IProcessStepRepository>();
var identityProviderRepository = _portalRepositories.GetInstance<IIdentityProviderRepository>();
var networkRepository = portalRepositories.GetInstance<INetworkRepository>();
var companyRepository = portalRepositories.GetInstance<ICompanyRepository>();
var processStepRepository = portalRepositories.GetInstance<IProcessStepRepository>();
var identityProviderRepository = portalRepositories.GetInstance<IIdentityProviderRepository>();

var (roleData, identityProviderIdAliase, singleIdentityProviderIdAlias, allIdentityProviderIds) = await ValidatePartnerRegistrationData(data, networkRepository, identityProviderRepository, ownerCompanyId).ConfigureAwait(ConfigureAwaitOptions.None);

var companyId = CreatePartnerCompany(companyRepository, data);

var applicationId = _portalRepositories.GetInstance<IApplicationRepository>().CreateCompanyApplication(companyId, CompanyApplicationStatusId.CREATED, CompanyApplicationTypeId.EXTERNAL,
var applicationId = portalRepositories.GetInstance<IApplicationRepository>().CreateCompanyApplication(companyId, CompanyApplicationStatusId.CREATED, CompanyApplicationTypeId.EXTERNAL,
ca =>
{
ca.OnboardingServiceProviderId = ownerCompanyId;
Expand All @@ -101,7 +96,7 @@ string GetIdpAlias(Guid? identityProviderId) =>

async IAsyncEnumerable<(Guid CompanyUserId, Exception? Error)> CreateUsers()
{
var userRepository = _portalRepositories.GetInstance<IUserRepository>();
var userRepository = portalRepositories.GetInstance<IUserRepository>();
await foreach (var (aliasData, creationInfos) in GetUserCreationData(companyId, GetIdpId, GetIdpAlias, data, roleData).ToAsyncEnumerable())
{
foreach (var creationInfo in creationInfos)
Expand All @@ -110,9 +105,10 @@ string GetIdpAlias(Guid? identityProviderId) =>
Exception? error = null;
try
{
var (_, companyUserId) = await _userProvisioningService.GetOrCreateCompanyUser(userRepository, aliasData.IdpAlias,
var (_, companyUserId) = await userProvisioningService.GetOrCreateCompanyUser(userRepository, aliasData.IdpAlias,
creationInfo, companyId, aliasData.IdpId, data.BusinessPartnerNumber?.ToUpper()).ConfigureAwait(ConfigureAwaitOptions.None);
identityId = companyUserId;
portalRepositories.GetInstance<IApplicationRepository>().CreateInvitation(applicationId, companyUserId);
}
catch (Exception ex)
{
Expand All @@ -127,7 +123,7 @@ string GetIdpAlias(Guid? identityProviderId) =>
var userCreationErrors = await CreateUsers().Where(x => x.Error != null).Select(x => x.Error!).ToListAsync();
userCreationErrors.IfAny(errors => throw new ServiceException($"Errors occured while saving the users: ${string.Join("", errors.Select(x => x.Message))}", errors.First()));

await _portalRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None);
await portalRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None);
}

private Guid CreatePartnerCompany(ICompanyRepository companyRepository, PartnerRegistrationData data)
Expand All @@ -148,7 +144,7 @@ private Guid CreatePartnerCompany(ICompanyRepository companyRepository, PartnerR
});

companyRepository.CreateUpdateDeleteIdentifiers(company.Id, Enumerable.Empty<(UniqueIdentifierId, string)>(), data.UniqueIds.Select(x => (x.UniqueIdentifierId, x.Value)));
_portalRepositories.GetInstance<ICompanyRolesRepository>().CreateCompanyAssignedRoles(company.Id, data.CompanyRoles);
portalRepositories.GetInstance<ICompanyRolesRepository>().CreateCompanyAssignedRoles(company.Id, data.CompanyRoles);

return company.Id;
}
Expand Down Expand Up @@ -184,14 +180,14 @@ private Guid CreatePartnerCompany(ICompanyRepository companyRepository, PartnerR
});

public Task RetriggerProcessStep(string externalId, ProcessStepTypeId processStepTypeId) =>
_processHelper.TriggerProcessStep(externalId, processStepTypeId);
processHelper.TriggerProcessStep(externalId, processStepTypeId);

private async Task<(IEnumerable<UserRoleData> RoleData, IDictionary<Guid, string>? IdentityProviderIdAliase, (Guid IdentityProviderId, string Alias)? SingleIdentityProviderIdAlias, IEnumerable<Guid> AllIdentityProviderIds)> ValidatePartnerRegistrationData(PartnerRegistrationData data, INetworkRepository networkRepository, IIdentityProviderRepository identityProviderRepository, Guid ownerCompanyId)
{
var countryRepository = _portalRepositories.GetInstance<ICountryRepository>();
var countryRepository = portalRepositories.GetInstance<ICountryRepository>();
data.ValidateData();
await data.ValidateDatabaseData(
bpn => _portalRepositories.GetInstance<ICompanyRepository>().CheckBpnExists(bpn),
bpn => portalRepositories.GetInstance<ICompanyRepository>().CheckBpnExists(bpn),
alpha2Code => countryRepository.CheckCountryExistsByAlpha2CodeAsync(alpha2Code),
(countryAlpha2Code, uniqueIdentifierIds) => countryRepository.GetCountryAssignedIdentifiers(countryAlpha2Code, uniqueIdentifierIds),
true).ConfigureAwait(ConfigureAwaitOptions.None);
Expand All @@ -206,7 +202,7 @@ await data.ValidateDatabaseData(
ValidateUsers(user);
}

if (!ExternalID.IsMatch(data.ExternalId))
if (!ExternalId.IsMatch(data.ExternalId))
{
throw new ControllerArgumentException("ExternalId must be between 6 and 36 characters");
}
Expand All @@ -222,7 +218,7 @@ await data.ValidateDatabaseData(
IEnumerable<UserRoleData> roleData;
try
{
roleData = await _userProvisioningService.GetRoleDatas(_settings.InitialRoles).ToListAsync().ConfigureAwait(false);
roleData = await userProvisioningService.GetRoleDatas(_settings.InitialRoles).ToListAsync().ConfigureAwait(false);
}
catch (Exception e)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ public async Task HandlePartnerRegistration_WithIdpNotSetAndOnlyOneIdp_CallsExpe
[Theory]
[InlineData(Bpn)]
[InlineData(null)]
public async Task HandlePartnerRegistration_WithValidData_CallsExpected(string? BusinessPartnerNumberl)
public async Task HandlePartnerRegistration_WithValidData_CallsExpected(string? businessPartnerNumber)
{
// Arrange
var newCompanyId = Guid.NewGuid();
Expand All @@ -563,11 +563,12 @@ public async Task HandlePartnerRegistration_WithValidData_CallsExpected(string?
var processSteps = new List<ProcessStep>();
var companyApplications = new List<CompanyApplication>();
var networkRegistrations = new List<NetworkRegistration>();
var invitations = new List<Invitation>();

var data = new PartnerRegistrationData(
Guid.NewGuid().ToString(),
"Test N2N",
BusinessPartnerNumberl,
businessPartnerNumber,
"Munich",
"Street",
"DE",
Expand Down Expand Up @@ -634,6 +635,11 @@ public async Task HandlePartnerRegistration_WithValidData_CallsExpected(string?
companyApplications.Add(companyApplication);
return companyApplication;
});
A.CallTo(() => _applicationRepository.CreateInvitation(A<Guid>._, A<Guid>._))
.Invokes((Guid applicationId, Guid companyUserId) =>
{
invitations.Add(new Invitation(Guid.NewGuid(), applicationId, companyUserId, InvitationStatusId.CREATED, DateTimeOffset.UtcNow));
});
A.CallTo(() => _networkRepository.CreateNetworkRegistration(A<string>._, A<Guid>._, A<Guid>._, A<Guid>._, A<Guid>._))
.Invokes((string externalId, Guid companyId, Guid pId, Guid ospId, Guid companyApplicationId) =>
{
Expand Down Expand Up @@ -670,8 +676,10 @@ public async Task HandlePartnerRegistration_WithValidData_CallsExpected(string?
x.ExternalId == data.ExternalId &&
x.ProcessId == newProcessId &&
x.ApplicationId == newApplicationId);
invitations.Should().ContainSingle()
.Which.Should().Match<Invitation>(x => x.CompanyApplicationId == newApplicationId);

A.CallTo(() => _userProvisioningService.GetOrCreateCompanyUser(A<IUserRepository>._, "test-alias", A<UserCreationRoleDataIdpInfo>._, newCompanyId, IdpId, BusinessPartnerNumberl))
A.CallTo(() => _userProvisioningService.GetOrCreateCompanyUser(A<IUserRepository>._, "test-alias", A<UserCreationRoleDataIdpInfo>._, newCompanyId, IdpId, businessPartnerNumber))
.MustHaveHappenedOnceExactly();
var idpCreationData = new[] { (newCompanyId, IdpId) };
A.CallTo(() => _identityProviderRepository.CreateCompanyIdentityProviders(A<IEnumerable<(Guid, Guid)>>.That.IsSameSequenceAs(idpCreationData)))
Expand Down

0 comments on commit 41525c3

Please sign in to comment.