Skip to content

Commit

Permalink
optimized the company regex
Browse files Browse the repository at this point in the history
  • Loading branch information
dhiren-singh-007 committed Jul 24, 2024
1 parent 735b100 commit e63ec91
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,11 @@
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;
using Org.Eclipse.TractusX.Portal.Backend.Processes.Library;
using System.Text.RegularExpressions;

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

public class InvitationBusinessLogic : IInvitationBusinessLogic
{
private static readonly Regex Company = new(ValidationExpressions.Company, RegexOptions.Compiled, TimeSpan.FromSeconds(1));
private readonly IPortalRepositories _portalRepositories;

/// <summary>
Expand All @@ -55,7 +53,7 @@ public Task ExecuteInvitation(CompanyInvitationData invitationData)
throw new ControllerArgumentException("organisationName must not be empty", "organisationName");
}

if (!string.IsNullOrEmpty(invitationData.OrganisationName) && !Company.IsMatch(invitationData.OrganisationName))
if (!string.IsNullOrEmpty(invitationData.OrganisationName) && !ValidationExpressionsValidator.IsValidCompanyName(invitationData.OrganisationName))
{
throw new ControllerArgumentException($"OrganisationName: {ValidationExpressionErrorMessages.CompanyError}", "organisationName");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ public class NetworkBusinessLogic : 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 Company = new(ValidationExpressions.Company, RegexOptions.Compiled, TimeSpan.FromSeconds(1));

private readonly IPortalRepositories _portalRepositories;
private readonly IIdentityData _identityData;
private readonly IUserProvisioningService _userProvisioningService;
Expand All @@ -60,7 +58,7 @@ public NetworkBusinessLogic(IPortalRepositories portalRepositories, IIdentitySer

public async Task HandlePartnerRegistration(PartnerRegistrationData data)
{
if (!string.IsNullOrEmpty(data.Name) && !Company.IsMatch(data.Name))
if (!ValidationExpressionsValidator.IsValidCompanyName(data.Name))
{
throw new ControllerArgumentException($"OrganisationName: {ValidationExpressionErrorMessages.CompanyError}", "organisationName");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLog
public sealed class RegistrationBusinessLogic : IRegistrationBusinessLogic
{
private static readonly Regex BpnRegex = new(ValidationExpressions.Bpn, RegexOptions.Compiled, TimeSpan.FromSeconds(1));

private static readonly Regex Company = new(ValidationExpressions.Company, RegexOptions.Compiled, TimeSpan.FromSeconds(1));

private readonly IPortalRepositories _portalRepositories;
private readonly RegistrationSettings _settings;
private readonly IApplicationChecklistService _checklistService;
Expand Down Expand Up @@ -105,7 +102,7 @@ private async Task<CompanyWithAddressData> GetCompanyWithAddressAsyncInternal(Gu
{
throw NotFoundException.Create(AdministrationRegistrationErrors.APPLICATION_NOT_FOUND, [new("applicationId", applicationId.ToString())]);
}
if (!string.IsNullOrEmpty(companyWithAddress.Name) && !Company.IsMatch(companyWithAddress.Name))
if (!ValidationExpressionsValidator.IsValidCompanyName(companyWithAddress.Name))
{
throw new ControllerArgumentException($"OrganisationName: {ValidationExpressionErrorMessages.CompanyError}", "organisationName");
}
Expand Down Expand Up @@ -144,7 +141,7 @@ private async Task<CompanyWithAddressData> GetCompanyWithAddressAsyncInternal(Gu

public Task<Pagination.Response<CompanyApplicationDetails>> GetCompanyApplicationDetailsAsync(int page, int size, CompanyApplicationStatusFilter? companyApplicationStatusFilter = null, string? companyName = null)
{
if (!string.IsNullOrEmpty(companyName) && !Company.IsMatch(companyName))
if (!string.IsNullOrEmpty(companyName) && !ValidationExpressionsValidator.IsValidCompanyName(companyName))
{
throw new ControllerArgumentException($"CompanyName: {ValidationExpressionErrorMessages.CompanyError}", nameof(companyName));
}
Expand Down Expand Up @@ -183,7 +180,7 @@ private async Task<CompanyWithAddressData> GetCompanyWithAddressAsyncInternal(Gu

public Task<Pagination.Response<CompanyApplicationWithCompanyUserDetails>> GetAllCompanyApplicationsDetailsAsync(int page, int size, string? companyName = null)
{
if (!string.IsNullOrEmpty(companyName) && !Company.IsMatch(companyName))
if (!ValidationExpressionsValidator.IsValidCompanyName(companyName))
{
throw new ControllerArgumentException($"CompanyName: {ValidationExpressionErrorMessages.CompanyError}", nameof(companyName));
}
Expand Down
3 changes: 3 additions & 0 deletions src/framework/Framework.Models/ValidationExpressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using System.Text.RegularExpressions;

namespace Org.Eclipse.TractusX.Portal.Backend.Framework.Models;

public static class ValidationExpressions
{
public const string Name = @"^.+$";
public const string Bpn = @"^(BPNL|bpnl)[\w|\d]{12}$";
public const string Company = @"^(?!.*\s$)([\wÀ-ÿ£$€¥¢@%*+\-/\\,.:;=<>!?&^#'\x22()[\]]\s?){1,160}$";
public static readonly Regex CompanyRegex = new(ValidationExpressions.Company, RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture, TimeSpan.FromSeconds(1));
}
30 changes: 30 additions & 0 deletions src/framework/Framework.Models/ValidationExpressionsValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/********************************************************************************
* Copyright (c) 2022 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using System.Text.RegularExpressions;

namespace Org.Eclipse.TractusX.Portal.Backend.Framework.Models;

public static class ValidationExpressionsValidator
{
public static bool IsValidCompanyName(string companyName)
{
return ValidationExpressions.CompanyRegex.IsMatch(companyName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Identities;
using System.Text.RegularExpressions;

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

Expand All @@ -40,7 +39,6 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Apps.Service.BusinessLogic;
/// </summary>
public class AppReleaseBusinessLogic : IAppReleaseBusinessLogic
{
private static readonly Regex Company = new(ValidationExpressions.Company, RegexOptions.Compiled, TimeSpan.FromSeconds(1));
private readonly IPortalRepositories _portalRepositories;
private readonly AppsSettings _settings;
private readonly IOfferService _offerService;
Expand Down Expand Up @@ -189,7 +187,7 @@ public Task<Guid> AddAppAsync(AppRequestModel appRequestModel)
throw new ControllerArgumentException("Use Case Ids must not be null or empty", nameof(appRequestModel.UseCaseIds));
}

if (!string.IsNullOrEmpty(appRequestModel.Provider) && !Company.IsMatch(appRequestModel.Provider))
if (!string.IsNullOrEmpty(appRequestModel.Provider) && !ValidationExpressionsValidator.IsValidCompanyName(appRequestModel.Provider))
{
throw new ControllerArgumentException($"Provider: {ValidationExpressionErrorMessages.CompanyError}", nameof(appRequestModel.Provider));
}
Expand Down Expand Up @@ -269,7 +267,7 @@ public async Task UpdateAppReleaseAsync(Guid appId, AppRequestModel appRequestMo
throw new ForbiddenException($"Company {companyId} is not the app provider.");
}

if (!string.IsNullOrEmpty(appRequestModel.Provider) && !Company.IsMatch(appRequestModel.Provider))
if (!string.IsNullOrEmpty(appRequestModel.Provider) && !ValidationExpressionsValidator.IsValidCompanyName(appRequestModel.Provider))
{
throw new ControllerArgumentException($"Provider: {ValidationExpressionErrorMessages.CompanyError}", nameof(appRequestModel.Provider));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Identities;
using System.Text.RegularExpressions;

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

Expand All @@ -39,7 +38,6 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Apps.Service.BusinessLogic;
/// </summary>
public class AppsBusinessLogic : IAppsBusinessLogic
{
private static readonly Regex Company = new(ValidationExpressions.Company, RegexOptions.Compiled, TimeSpan.FromSeconds(1));
private readonly IPortalRepositories _portalRepositories;
private readonly IOfferSubscriptionService _offerSubscriptionService;
private readonly AppsSettings _settings;
Expand Down Expand Up @@ -162,7 +160,7 @@ public async Task AddFavouriteAppForUserAsync(Guid appId)
/// <inheritdoc/>
public async Task<Pagination.Response<OfferCompanySubscriptionStatusResponse>> GetCompanyProvidedAppSubscriptionStatusesForUserAsync(int page, int size, SubscriptionStatusSorting? sorting, OfferSubscriptionStatusId? statusId, Guid? offerId, string? companyName = null)
{
if (!string.IsNullOrWhiteSpace(companyName) && !Company.IsMatch(companyName))
if (!string.IsNullOrEmpty(companyName) && !ValidationExpressionsValidator.IsValidCompanyName(companyName))
{
throw new ControllerArgumentException($"CompanyName: {ValidationExpressionErrorMessages.CompanyError}");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Identities;
using Org.Eclipse.TractusX.Portal.Backend.Services.Service.ViewModels;
using System.Text.RegularExpressions;

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

Expand All @@ -38,7 +37,6 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Services.Service.BusinessLogic;
/// </summary>
public class ServiceBusinessLogic : IServiceBusinessLogic
{
private static readonly Regex Company = new(ValidationExpressions.Company, RegexOptions.Compiled, TimeSpan.FromSeconds(1));
private readonly IPortalRepositories _portalRepositories;
private readonly IOfferService _offerService;
private readonly IOfferSubscriptionService _offerSubscriptionService;
Expand Down Expand Up @@ -139,7 +137,7 @@ public Task<OfferAutoSetupResponseData> AutoSetupServiceAsync(OfferAutoSetupData
/// <inheritdoc/>
public async Task<Pagination.Response<OfferCompanySubscriptionStatusResponse>> GetCompanyProvidedServiceSubscriptionStatusesForUserAsync(int page, int size, SubscriptionStatusSorting? sorting, OfferSubscriptionStatusId? statusId, Guid? offerId, string? companyName = null)
{
if (!string.IsNullOrEmpty(companyName) && !Company.IsMatch(companyName))
if (!string.IsNullOrEmpty(companyName) && !ValidationExpressionsValidator.IsValidCompanyName(companyName))
{
throw new ControllerArgumentException($"CompanyName: {ValidationExpressionErrorMessages.CompanyError}");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLogic;
using Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Models;
using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling;
using Org.Eclipse.TractusX.Portal.Backend.Framework.Models;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Models;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;
Expand Down Expand Up @@ -112,6 +113,49 @@ public async Task ExecuteInvitation_WithValidData_CreatesExpected()
invitations.Should().ContainSingle().And.Satisfy(x => x.ProcessId == processes.Single().Id && x.UserName == "testUserName");
}

[Theory]
[InlineData("ValidOrganisationName123")]
[InlineData("Organisation Name")]
[InlineData("Organisation$Name")]
[InlineData("Organisation\\Name")]
[InlineData("Organisation/Name")]
[InlineData("Organisation<Name>")]
[InlineData("Organisation Name!")]
[InlineData("7-ELEVEN INTERNATIONAL LLC")]
[InlineData("C")]
[InlineData("+SEN Inc.")]
[InlineData("Double \"Quote\" Company S.A.")]
[InlineData("Special Characters ^&%#@*/_-\\")]
[InlineData("German: ÄÖÜß")]
[InlineData("Icelandic: ÆÐÞ")]
[InlineData("C")]

Check warning on line 131 in tests/administration/Administration.Service.Tests/BusinessLogic/InvitationBusinessLogicTests.cs

View workflow job for this annotation

GitHub Actions / Build, check and test services (8.0)

Theory method 'ExecuteInvitation_WithValidOrganisationName_DoesNotThrowException' on test class 'InvitationBusinessLogicTests' has InlineData duplicate(s). Remove redundant attribute(s) from the theory method.
public async Task ExecuteInvitation_WithValidOrganisationName_DoesNotThrowException(string validName)
{
var invitationData = _fixture.Build<CompanyInvitationData>()
.With(x => x.OrganisationName, validName)
.Create();

Func<Task> Act = async () => await _sut.ExecuteInvitation(invitationData);

await Act.Should().NotThrowAsync<ControllerArgumentException>();
}

[Theory]
[InlineData("Organisation Name ")] // Ends with whitespace
[InlineData("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWX")] // Exceeds 160 characters
public async Task ExecuteInvitation_WithInvalidOrganisationName_ThrowsControllerArgumentException(string invalidName)
{
var invitationData = _fixture.Build<CompanyInvitationData>()
.With(x => x.OrganisationName, invalidName)
.Create();

async Task Act() => await _sut.ExecuteInvitation(invitationData);

var ex = await Assert.ThrowsAsync<ControllerArgumentException>(Act);
ex.Message.Should().Be($"OrganisationName: {ValidationExpressionErrorMessages.CompanyError} (Parameter 'organisationName')");
ex.ParamName.Should().Be("organisationName");
}

#endregion

#region RetriggerCreateCentralIdp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@

/********************************************************************************
* Copyright (c) 2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using System.Text.RegularExpressions;

namespace Org.Eclipse.TractusX.Portal.Backend.Framework.Models.Tests;

public class ValidationExpressionsTests
{
private static readonly Regex regex = new Regex(ValidationExpressions.Company);

Check warning on line 27 in tests/framework/Framework.Models.Tests/ValidationExpressionsTests.cs

View workflow job for this annotation

GitHub Actions / Build, check and test services (8.0)

Private member 'ValidationExpressionsTests.regex' can be removed as the value assigned to it is never read

[Theory]
[InlineData("ValidCompanyName123", true)] // Valid company name
[InlineData("Company Name", true)] // Valid with space
[InlineData("Company$Name", true)] // Valid with special character
[InlineData("Company\\Name", true)] // Valid with backslash
[InlineData("Company/Name", true)] // Valid with forward slash
[InlineData("Company<Name>", true)] // Valid with angle brackets
[InlineData("Company Name!", true)] // Valid with exclamation mark
[InlineData("Company@Name", true)] // Valid with @ symbol
[InlineData("C", true)] // Minimum valid length
[InlineData("7-ELEVEN INTERNATIONAL LLC", true)]
[InlineData("Recht 24/7 Schröder Rechtsanwaltsgesellschaft mbH", true)]
[InlineData("Currency £$€¥¢", true)]
[InlineData("Brackets []()", true)]
[InlineData("Punctuation !?,.;:", true)]
[InlineData("Double \"Quote\" Company S.A.", true)]
[InlineData("Single 'Quote' Company LLC", true)]
[InlineData("Special Characters ^&%#@*/_-\\", true)]
[InlineData("German: ÄÖÜß", true)]
[InlineData("+SEN Inc.", true)] // leading special character
[InlineData("Danish: ÆØÅ", true)]
[InlineData("Bayerische Motoren Werke Aktiengesellschaft ", false)] // Ends with whitespace
[InlineData(" Bayerische Motoren Werke Aktiengesellschaft", false)] // starts with whitespace
[InlineData("Bayerische Motoren Werke Aktiengesellschaft", false)] // double whitespace
[InlineData(@"123456789012345678901234567890
123456789012345678901234567890
123456789012345678901234567890
123456789012345678901234567890
123456789012345678901234567890
12345678901234567890", false)] // Exceeds 160 characters
[InlineData("", false)] // Empty string
[InlineData(" ", false)] // Single space
[InlineData(" ", false)] // Multiple spaces
public void TestCompanyNameRegex(string companyName, bool expectedResult)
{
var result = ValidationExpressionsValidator.IsValidCompanyName(companyName);
Assert.Equal(expectedResult, result);
}
}

0 comments on commit e63ec91

Please sign in to comment.