Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(uppercase): allow lowercase bpn #400

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ public IAsyncEnumerable<ConnectorEndPointData> GetCompanyConnectorEndPointAsync(
}

return _portalRepositories.GetInstance<IConnectorsRepository>()
.GetConnectorEndPointDataAsync(bpns)
.GetConnectorEndPointDataAsync(bpns.Select(x => x.ToUpper()))
.PreSortedGroupBy(data => data.BusinessPartnerNumber)
.Select(group =>
new ConnectorEndPointData(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLog

public sealed class RegistrationBusinessLogic : IRegistrationBusinessLogic
{
private static readonly Regex BpnRegex = new(@"(\w|\d){16}", RegexOptions.Compiled, TimeSpan.FromSeconds(1));
private static readonly Regex BpnRegex = new(ValidationExpressions.Bpn, RegexOptions.Compiled, TimeSpan.FromSeconds(1));

private readonly IPortalRepositories _portalRepositories;
private readonly RegistrationSettings _settings;
Expand Down Expand Up @@ -215,7 +215,7 @@ public Task UpdateCompanyBpn(Guid applicationId, string bpn)
private async Task UpdateCompanyBpnInternal(Guid applicationId, string bpn)
{
var result = await _portalRepositories.GetInstance<IUserRepository>()
.GetBpnForIamUserUntrackedAsync(applicationId, bpn).ToListAsync().ConfigureAwait(false);
.GetBpnForIamUserUntrackedAsync(applicationId, bpn.ToUpper()).ToListAsync().ConfigureAwait(false);
if (!result.Exists(item => item.IsApplicationCompany))
{
throw new NotFoundException($"application {applicationId} not found");
Expand Down Expand Up @@ -262,7 +262,7 @@ private async Task UpdateCompanyBpnInternal(Guid applicationId, string bpn)
.ConfigureAwait(false);

_portalRepositories.GetInstance<ICompanyRepository>().AttachAndModifyCompany(applicationCompanyData.CompanyId, null,
c => { c.BusinessPartnerNumber = bpn; });
c => { c.BusinessPartnerNumber = bpn.ToUpper(); });

var registrationValidationFailed = context.Checklist[ApplicationChecklistEntryTypeId.REGISTRATION_VERIFICATION] == new ValueTuple<ApplicationChecklistEntryStatusId, string?>(ApplicationChecklistEntryStatusId.FAILED, null);

Expand Down Expand Up @@ -290,7 +290,7 @@ private async Task UpdateCompanyBpnInternal(Guid applicationId, string bpn)
public async Task ProcessClearinghouseResponseAsync(ClearinghouseResponseData data, CancellationToken cancellationToken)
{
_logger.LogInformation("Process SelfDescription called with the following data {Data}", data);
var result = await _portalRepositories.GetInstance<IApplicationRepository>().GetSubmittedApplicationIdsByBpn(data.BusinessPartnerNumber).ToListAsync(cancellationToken).ConfigureAwait(false);
var result = await _portalRepositories.GetInstance<IApplicationRepository>().GetSubmittedApplicationIdsByBpn(data.BusinessPartnerNumber.ToUpper()).ToListAsync(cancellationToken).ConfigureAwait(false);
if (!result.Any())
{
throw new NotFoundException($"No companyApplication for BPN {data.BusinessPartnerNumber} is not in status SUBMITTED");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Models;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Service;
using System.Text.RegularExpressions;

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

Expand All @@ -40,6 +41,7 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLog
/// </summary>
public class UserBusinessLogic : IUserBusinessLogic
{
private static readonly Regex BpnRegex = new(ValidationExpressions.Bpn, RegexOptions.Compiled, TimeSpan.FromSeconds(1));
private readonly IProvisioningManager _provisioningManager;
private readonly IUserProvisioningService _userProvisioningService;
private readonly IProvisioningDBAccess _provisioningDbAccess;
Expand Down Expand Up @@ -315,9 +317,9 @@ await Task.WhenAll(details.IdpUserIds.Select(async x =>

public async Task<int> AddOwnCompanyUsersBusinessPartnerNumbersAsync(Guid userId, IEnumerable<string> businessPartnerNumbers)
{
if (businessPartnerNumbers.Any(businessPartnerNumber => businessPartnerNumber.Length > 20))
if (businessPartnerNumbers.Any(bpn => !BpnRegex.IsMatch(bpn)))
{
throw new ControllerArgumentException("businessPartnerNumbers must not exceed 20 characters", nameof(businessPartnerNumbers));
throw new ControllerArgumentException("BPN must contain exactly 16 characters and must be prefixed with BPNL", nameof(businessPartnerNumbers));
}

var companyId = _identityData.CompanyId;
Expand All @@ -332,7 +334,7 @@ public async Task<int> AddOwnCompanyUsersBusinessPartnerNumbersAsync(Guid userId
await _provisioningManager.AddBpnAttributetoUserAsync(iamUserId, businessPartnerNumbers).ConfigureAwait(false);
foreach (var businessPartnerToAdd in businessPartnerNumbers.Except(assignedBusinessPartnerNumbers))
{
businessPartnerRepository.CreateCompanyUserAssignedBusinessPartner(userId, businessPartnerToAdd);
businessPartnerRepository.CreateCompanyUserAssignedBusinessPartner(userId, businessPartnerToAdd.ToUpper());
}

return await _portalRepositories.SaveAsync();
Expand Down Expand Up @@ -579,7 +581,7 @@ public async Task<int> DeleteOwnUserBusinessPartnerNumbersAsync(Guid userId, str
{
var userBusinessPartnerRepository = _portalRepositories.GetInstance<IUserBusinessPartnerRepository>();

var (isValidUser, isAssignedBusinessPartner, isSameCompany) = await userBusinessPartnerRepository.GetOwnCompanyUserWithAssignedBusinessPartnerNumbersAsync(userId, _identityData.CompanyId, businessPartnerNumber).ConfigureAwait(false);
var (isValidUser, isAssignedBusinessPartner, isSameCompany) = await userBusinessPartnerRepository.GetOwnCompanyUserWithAssignedBusinessPartnerNumbersAsync(userId, _identityData.CompanyId, businessPartnerNumber.ToUpper()).ConfigureAwait(false);

if (!isValidUser)
{
Expand All @@ -598,9 +600,9 @@ public async Task<int> DeleteOwnUserBusinessPartnerNumbersAsync(Guid userId, str

var iamUserId = await _provisioningManager.GetUserByUserName(userId.ToString()).ConfigureAwait(false) ?? throw new ConflictException($"user {userId} is not associated with a user in keycloak");

userBusinessPartnerRepository.DeleteCompanyUserAssignedBusinessPartner(userId, businessPartnerNumber);
userBusinessPartnerRepository.DeleteCompanyUserAssignedBusinessPartner(userId, businessPartnerNumber.ToUpper());

await _provisioningManager.DeleteCentralUserBusinessPartnerNumberAsync(iamUserId, businessPartnerNumber).ConfigureAwait(false);
await _provisioningManager.DeleteCentralUserBusinessPartnerNumberAsync(iamUserId, businessPartnerNumber.ToUpper()).ConfigureAwait(false);

return await _portalRepositories.SaveAsync().ConfigureAwait(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ public Task<IEnumerable<UserRoleWithId>> ModifyAppUserRolesAsync([FromRoute] Gui
/// <param name="companyUserId" example="ac1cf001-7fbc-1f2f-817f-bce0575a0011">Id of the user to add the business partner numbers to.</param>
/// <param name="businessPartnerNumbers">the business partner numbers that should be added.</param>
/// <returns></returns>
/// <remarks>Example: POST: api/administration/user/owncompany/users/ac1cf001-7fbc-1f2f-817f-bce0575a0011/businessPartnerNumbers</remarks>
/// <remarks>Example: POST: api/administration/user/owncompany/users/{companyUserId}/businessPartnerNumbers</remarks>
/// <response code="200">The business partner numbers have been added successfully.</response>
/// <response code="400">Business Partner Numbers must not exceed 20 characters.</response>
/// <response code="404">User not found.</response>
Expand All @@ -269,7 +269,7 @@ public Task<int> AddOwnCompanyUserBusinessPartnerNumbers(Guid companyUserId, IEn
/// <param name="companyUserId" example="ac1cf001-7fbc-1f2f-817f-bce0575a0011">Id of the user to add the business partner numbers to.</param>
/// <param name="businessPartnerNumber" example="CAXSDUMMYCATENAZZ">the business partner number that should be added.</param>
/// <returns></returns>
/// <remarks>Example: PUT: api/administration/user/owncompany/users/ac1cf001-7fbc-1f2f-817f-bce0575a0011/businessPartnerNumbers/CAXSDUMMYCATENAZZ</remarks>
/// <remarks>Example: PUT: api/administration/user/owncompany/users/{companyUserId}/businessPartnerNumbers/{businessPartnerNumber}</remarks>
/// <response code="200">The business partner number have been added successfully.</response>
/// <response code="400">Business Partner Numbers must not exceed 20 characters.</response>
/// <response code="404">User is not existing.</response>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public void CreateUpdateDeleteIdentifiers(Guid companyId, IEnumerable<(UniqueIde
_context.Companies
.AsNoTracking()
.Where(company => company.CompanyStatusId == CompanyStatusId.ACTIVE &&
(bpnIds == null || bpnIds.Contains(company.BusinessPartnerNumber) &&
(bpnIds == null || bpnIds.Select(x => x.ToUpper()).Contains(company.BusinessPartnerNumber) &&
company.BusinessPartnerNumber != null))
.Select(company => company.BusinessPartnerNumber)
.AsAsyncEnumerable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public Task<CompanyBpdmDetailData> GetCompanyBpdmDetailDataByBusinessPartnerNumb
{
throw new ControllerArgumentException("BPN must contain exactly 16 digits or letters.", nameof(businessPartnerNumber));
}
return GetCompanyBpdmDetailDataByBusinessPartnerNumberInternal(businessPartnerNumber, token, cancellationToken);
return GetCompanyBpdmDetailDataByBusinessPartnerNumberInternal(businessPartnerNumber.ToUpper(), token, cancellationToken);
}

private async Task<CompanyBpdmDetailData> GetCompanyBpdmDetailDataByBusinessPartnerNumberInternal(string businessPartnerNumber, string token, CancellationToken cancellationToken)
Expand Down Expand Up @@ -376,15 +376,15 @@ private static void ModifyCompany(Guid addressId, CompanyApplicationDetailData i
modifyData.CompanyId,
c =>
{
c.BusinessPartnerNumber = initialData.BusinessPartnerNumber;
c.BusinessPartnerNumber = initialData.BusinessPartnerNumber?.ToUpper();
c.Name = initialData.Name;
c.Shortname = initialData.ShortName;
c.CompanyStatusId = initialData.CompanyStatusId;
c.AddressId = initialData.AddressId;
},
c =>
{
c.BusinessPartnerNumber = modifyData.BusinessPartnerNumber;
c.BusinessPartnerNumber = modifyData.BusinessPartnerNumber?.ToUpper();
c.Name = modifyData.Name;
c.Shortname = modifyData.ShortName;
c.CompanyStatusId = CompanyStatusId.PENDING;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -998,31 +998,31 @@ public async Task GetCompanyConnectorEndPoint_WithValidData_ReturnsExpectedResul
//Arrange
var bpns = new[]
{
"BPNL00000002CRHL",
"bpnL00000002CRHL",
"BPNL00000003CRHL",
"BPNL00000004CRHL",
"BPNL00000003CRHK"
};
A.CallTo(() => _connectorsRepository.GetConnectorEndPointDataAsync(bpns))
A.CallTo(() => _connectorsRepository.GetConnectorEndPointDataAsync(A<IEnumerable<string>>._))
.Returns(new[] {
(BusinessPartnerNumber: "BPNL00000002CRHL", ConnectorEndPoint: "www.googlr5.com"),
(BusinessPartnerNumber: "BPNL00000003CRHL", ConnectorEndPoint: "www.googlr0.com"),
(BusinessPartnerNumber: "BPNL00000003CRHL", ConnectorEndPoint: "www.googlr1.com"),
(BusinessPartnerNumber: "BPNL00000004CRHL", ConnectorEndPoint: "www.googlr2.com"),
(BusinessPartnerNumber: "BPNL00000004CRHL", ConnectorEndPoint: "www.googlr3.com"),
(BusinessPartnerNumber: "BPNL00000004CRHL", ConnectorEndPoint: "www.googlr4.com"),
(BusinessPartnerNumber: "BPNL00000002CRHL", ConnectorEndPoint: "www.googlr5.com")
(BusinessPartnerNumber: "BPNL00000004CRHL", ConnectorEndPoint: "www.googlr4.com")
}.ToAsyncEnumerable());

//Act
var result = await _logic.GetCompanyConnectorEndPointAsync(bpns).ToListAsync().ConfigureAwait(false);

//Assert
A.CallTo(() => _connectorsRepository.GetConnectorEndPointDataAsync(bpns)).MustHaveHappenedOnceExactly();
A.CallTo(() => _connectorsRepository.GetConnectorEndPointDataAsync(A<IEnumerable<string>>.That.IsSameSequenceAs(bpns.Select(x => x.ToUpper())))).MustHaveHappenedOnceExactly();
result.Should().HaveCount(3).And.Satisfy(
x => x.Bpn == "BPNL00000002CRHL" && x.ConnectorEndpoint.Count() == 1 && x.ConnectorEndpoint.Contains("www.googlr5.com"),
x => x.Bpn == "BPNL00000003CRHL" && x.ConnectorEndpoint.Count() == 2 && x.ConnectorEndpoint.Contains("www.googlr0.com") && x.ConnectorEndpoint.Contains("www.googlr1.com"),
x => x.Bpn == "BPNL00000004CRHL" && x.ConnectorEndpoint.Count() == 3 && x.ConnectorEndpoint.Contains("www.googlr2.com") && x.ConnectorEndpoint.Contains("www.googlr3.com") && x.ConnectorEndpoint.Contains("www.googlr4.com")
);
x => x.Bpn == "BPNL00000002CRHL" && x.ConnectorEndpoint.Count() == 1 && x.ConnectorEndpoint.Contains("www.googlr5.com"),
x => x.Bpn == "BPNL00000003CRHL" && x.ConnectorEndpoint.Count() == 2 && x.ConnectorEndpoint.Contains("www.googlr0.com") && x.ConnectorEndpoint.Contains("www.googlr1.com"),
x => x.Bpn == "BPNL00000004CRHL" && x.ConnectorEndpoint.Count() == 3 && x.ConnectorEndpoint.Contains("www.googlr2.com") && x.ConnectorEndpoint.Contains("www.googlr3.com") && x.ConnectorEndpoint.Contains("www.googlr4.com")
);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,21 +267,6 @@ public async Task UpdateCompanyBpnAsync_WithInvalidBpn_ThrowsControllerArgumentE
ex.Message.Should().Be("BPN must contain exactly 16 characters long. (Parameter 'bpn')");
}

[Fact]
public async Task UpdateCompanyBpnAsync_WithInvalidBpnPrefix_ThrowsControllerArgumentException()
{
// Arrange
var bpn = "BPXX123698762345";

// Act
async Task Act() => await _logic.UpdateCompanyBpn(IdWithBpn, bpn).ConfigureAwait(false);

// Assert
var ex = await Assert.ThrowsAsync<ControllerArgumentException>(Act);
ex.ParamName.Should().Be("bpn");
ex.Message.Should().Be("businessPartnerNumbers must prefixed with BPNL (Parameter 'bpn')");
}

[Fact]
public async Task UpdateCompanyBpnAsync_WithNotExistingApplication_ThrowsNotFoundException()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1400,7 +1400,7 @@ public async Task GetOwnCompanyAppUsersAsync_WithUnassignedBusinessPartner_Throw
var businessPartnerNumber = _fixture.Create<string>();
A.CallTo(() => _identity.IdentityId).Returns(_adminUserId);
A.CallTo(() => _identity.CompanyId).Returns(_adminCompanyId);
A.CallTo(() => _userBusinessPartnerRepository.GetOwnCompanyUserWithAssignedBusinessPartnerNumbersAsync(companyUserId, _adminCompanyId, businessPartnerNumber))
A.CallTo(() => _userBusinessPartnerRepository.GetOwnCompanyUserWithAssignedBusinessPartnerNumbersAsync(companyUserId, _adminCompanyId, businessPartnerNumber.ToUpper()))
.Returns((true, false, false));
A.CallTo(() => _portalRepositories.GetInstance<IUserBusinessPartnerRepository>()).Returns(_userBusinessPartnerRepository);
var sut = new UserBusinessLogic(null!, null!, null!, _portalRepositories, _identityService, null!, null!, A.Fake<IOptions<UserSettings>>());
Expand All @@ -1423,7 +1423,7 @@ public async Task GetOwnCompanyAppUsersAsync_WithoutUserForBpn_ThrowsArgumentExc
A.CallTo(() => _identity.CompanyId).Returns(_adminCompanyId);
A.CallTo(() => _provisioningManager.GetUserByUserName(companyUserId.ToString()))
.Returns((string?)null);
A.CallTo(() => _userBusinessPartnerRepository.GetOwnCompanyUserWithAssignedBusinessPartnerNumbersAsync(companyUserId, _adminCompanyId, businessPartnerNumber))
A.CallTo(() => _userBusinessPartnerRepository.GetOwnCompanyUserWithAssignedBusinessPartnerNumbersAsync(companyUserId, _adminCompanyId, businessPartnerNumber.ToUpper()))
.Returns((true, true, true));
A.CallTo(() => _portalRepositories.GetInstance<IUserBusinessPartnerRepository>()).Returns(_userBusinessPartnerRepository);
var sut = new UserBusinessLogic(_provisioningManager, null!, null!, _portalRepositories, _identityService, null!, null!, A.Fake<IOptions<UserSettings>>());
Expand All @@ -1444,7 +1444,7 @@ public async Task GetOwnCompanyAppUsersAsync_WithInvalidUser_ThrowsForbiddenExce
var businessPartnerNumber = _fixture.Create<string>();
A.CallTo(() => _identity.IdentityId).Returns(_adminUserId);
A.CallTo(() => _identity.CompanyId).Returns(_adminCompanyId);
A.CallTo(() => _userBusinessPartnerRepository.GetOwnCompanyUserWithAssignedBusinessPartnerNumbersAsync(companyUserId, _adminCompanyId, businessPartnerNumber))
A.CallTo(() => _userBusinessPartnerRepository.GetOwnCompanyUserWithAssignedBusinessPartnerNumbersAsync(companyUserId, _adminCompanyId, businessPartnerNumber.ToUpper()))
.Returns((true, true, false));
A.CallTo(() => _portalRepositories.GetInstance<IUserBusinessPartnerRepository>()).Returns(_userBusinessPartnerRepository);
var sut = new UserBusinessLogic(null!, null!, null!, _portalRepositories, _identityService, null!, null!, A.Fake<IOptions<UserSettings>>());
Expand All @@ -1466,17 +1466,17 @@ public async Task GetOwnCompanyAppUsersAsync_WithValidData_ThrowsForbiddenExcept
var businessPartnerNumber = _fixture.Create<string>();
A.CallTo(() => _identity.IdentityId).Returns(_adminUserId);
A.CallTo(() => _identity.CompanyId).Returns(_adminCompanyId);
A.CallTo(() => _userBusinessPartnerRepository.GetOwnCompanyUserWithAssignedBusinessPartnerNumbersAsync(companyUserId, _adminCompanyId, businessPartnerNumber))
A.CallTo(() => _userBusinessPartnerRepository.GetOwnCompanyUserWithAssignedBusinessPartnerNumbersAsync(companyUserId, _adminCompanyId, businessPartnerNumber.ToUpper()))
.Returns((true, true, true));
A.CallTo(() => _portalRepositories.GetInstance<IUserBusinessPartnerRepository>()).Returns(_userBusinessPartnerRepository);
A.CallTo(() => _provisioningManager.GetUserByUserName(companyUserId.ToString())).Returns(iamUserId);
var sut = new UserBusinessLogic(_provisioningManager, null!, null!, _portalRepositories, _identityService, null!, null!, A.Fake<IOptions<UserSettings>>());

// Act
await sut.DeleteOwnUserBusinessPartnerNumbersAsync(companyUserId, businessPartnerNumber).ConfigureAwait(false);
await sut.DeleteOwnUserBusinessPartnerNumbersAsync(companyUserId, businessPartnerNumber.ToUpper()).ConfigureAwait(false);

// Assert
A.CallTo(() => _provisioningManager.DeleteCentralUserBusinessPartnerNumberAsync(iamUserId, businessPartnerNumber)).MustHaveHappenedOnceExactly();
A.CallTo(() => _provisioningManager.DeleteCentralUserBusinessPartnerNumberAsync(iamUserId, businessPartnerNumber.ToUpper())).MustHaveHappenedOnceExactly();
A.CallTo(() => _portalRepositories.SaveAsync()).MustHaveHappenedOnceExactly();
}

Expand Down
Loading