diff --git a/src/administration/Administration.Service/BusinessLogic/InvitationBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/InvitationBusinessLogic.cs
index 80f7c8ad70..d53bb1004d 100644
--- a/src/administration/Administration.Service/BusinessLogic/InvitationBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/InvitationBusinessLogic.cs
@@ -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;
///
@@ -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");
}
diff --git a/src/administration/Administration.Service/BusinessLogic/NetworkBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/NetworkBusinessLogic.cs
index 16061c9d8d..ee1f0488c9 100644
--- a/src/administration/Administration.Service/BusinessLogic/NetworkBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/NetworkBusinessLogic.cs
@@ -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;
@@ -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");
}
diff --git a/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs
index a52b76e1cf..ff5c3cc14c 100644
--- a/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs
@@ -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;
@@ -105,7 +102,7 @@ private async Task 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");
}
@@ -144,7 +141,7 @@ private async Task GetCompanyWithAddressAsyncInternal(Gu
public Task> 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));
}
@@ -183,7 +180,7 @@ private async Task GetCompanyWithAddressAsyncInternal(Gu
public Task> 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));
}
diff --git a/src/framework/Framework.Models/ValidationExpressions.cs b/src/framework/Framework.Models/ValidationExpressions.cs
index be30311273..8612fb411a 100644
--- a/src/framework/Framework.Models/ValidationExpressions.cs
+++ b/src/framework/Framework.Models/ValidationExpressions.cs
@@ -17,6 +17,8 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
+using System.Text.RegularExpressions;
+
namespace Org.Eclipse.TractusX.Portal.Backend.Framework.Models;
public static class ValidationExpressions
@@ -24,4 +26,5 @@ 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));
}
diff --git a/src/framework/Framework.Models/ValidationExpressionsValidator.cs b/src/framework/Framework.Models/ValidationExpressionsValidator.cs
new file mode 100644
index 0000000000..c0f79ed0bd
--- /dev/null
+++ b/src/framework/Framework.Models/ValidationExpressionsValidator.cs
@@ -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);
+ }
+}
diff --git a/src/marketplace/Apps.Service/BusinessLogic/AppReleaseBusinessLogic.cs b/src/marketplace/Apps.Service/BusinessLogic/AppReleaseBusinessLogic.cs
index cb00807b4e..6bdb2d02b7 100644
--- a/src/marketplace/Apps.Service/BusinessLogic/AppReleaseBusinessLogic.cs
+++ b/src/marketplace/Apps.Service/BusinessLogic/AppReleaseBusinessLogic.cs
@@ -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;
@@ -40,7 +39,6 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Apps.Service.BusinessLogic;
///
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;
@@ -189,7 +187,7 @@ public Task 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));
}
@@ -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));
}
diff --git a/src/marketplace/Apps.Service/BusinessLogic/AppsBusinessLogic.cs b/src/marketplace/Apps.Service/BusinessLogic/AppsBusinessLogic.cs
index 4c36b0a64e..36e8d4b341 100644
--- a/src/marketplace/Apps.Service/BusinessLogic/AppsBusinessLogic.cs
+++ b/src/marketplace/Apps.Service/BusinessLogic/AppsBusinessLogic.cs
@@ -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;
@@ -39,7 +38,6 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Apps.Service.BusinessLogic;
///
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;
@@ -162,7 +160,7 @@ public async Task AddFavouriteAppForUserAsync(Guid appId)
///
public async Task> 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}");
}
diff --git a/src/marketplace/Services.Service/BusinessLogic/ServiceBusinessLogic.cs b/src/marketplace/Services.Service/BusinessLogic/ServiceBusinessLogic.cs
index 07e9e52343..0eba542632 100644
--- a/src/marketplace/Services.Service/BusinessLogic/ServiceBusinessLogic.cs
+++ b/src/marketplace/Services.Service/BusinessLogic/ServiceBusinessLogic.cs
@@ -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;
@@ -38,7 +37,6 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Services.Service.BusinessLogic;
///
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;
@@ -139,7 +137,7 @@ public Task AutoSetupServiceAsync(OfferAutoSetupData
///
public async Task> 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}");
}
diff --git a/tests/administration/Administration.Service.Tests/BusinessLogic/InvitationBusinessLogicTests.cs b/tests/administration/Administration.Service.Tests/BusinessLogic/InvitationBusinessLogicTests.cs
index d36048f7d1..27d0214e5e 100644
--- a/tests/administration/Administration.Service.Tests/BusinessLogic/InvitationBusinessLogicTests.cs
+++ b/tests/administration/Administration.Service.Tests/BusinessLogic/InvitationBusinessLogicTests.cs
@@ -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;
@@ -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")]
+ [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")]
+ public async Task ExecuteInvitation_WithValidOrganisationName_DoesNotThrowException(string validName)
+ {
+ var invitationData = _fixture.Build()
+ .With(x => x.OrganisationName, validName)
+ .Create();
+
+ Func Act = async () => await _sut.ExecuteInvitation(invitationData);
+
+ await Act.Should().NotThrowAsync();
+ }
+
+ [Theory]
+ [InlineData("Organisation Name ")] // Ends with whitespace
+ [InlineData("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWX")] // Exceeds 160 characters
+ public async Task ExecuteInvitation_WithInvalidOrganisationName_ThrowsControllerArgumentException(string invalidName)
+ {
+ var invitationData = _fixture.Build()
+ .With(x => x.OrganisationName, invalidName)
+ .Create();
+
+ async Task Act() => await _sut.ExecuteInvitation(invitationData);
+
+ var ex = await Assert.ThrowsAsync(Act);
+ ex.Message.Should().Be($"OrganisationName: {ValidationExpressionErrorMessages.CompanyError} (Parameter 'organisationName')");
+ ex.ParamName.Should().Be("organisationName");
+ }
+
#endregion
#region RetriggerCreateCentralIdp
diff --git a/tests/framework/Framework.Models.Tests/ValidationExpressionsTests.cs b/tests/framework/Framework.Models.Tests/ValidationExpressionsTests.cs
new file mode 100644
index 0000000000..8c77d4986d
--- /dev/null
+++ b/tests/framework/Framework.Models.Tests/ValidationExpressionsTests.cs
@@ -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);
+
+ [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", 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);
+ }
+}
\ No newline at end of file