Skip to content

Commit

Permalink
fix: adjust name check for tenant and technical user (#113)
Browse files Browse the repository at this point in the history
* replace all characters that are not alphabetical or numeric for technical users and tenants
----------------------
Refs: #112
Reviewed-By: Evelyn Gurschler <[email protected]>
  • Loading branch information
Phil91 authored Oct 16, 2024
1 parent 8cfb9a0 commit cf91f31
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace Dim.Clients.Api.Div.Models;
Expand All @@ -30,7 +32,12 @@ public record ServiceKeyOperationCreationRequest(

public record ServiceKeyCreationPayloadData(
[property: JsonPropertyName("customerWalletId")] Guid CustomerWalletId,
[property: JsonPropertyName("divWalletServiceName")] string ServiceKeyName
[property: JsonPropertyName("divWalletServiceName")] string ServiceKeyName,
[property: JsonPropertyName("divWalletServiceParameters")] ServiceKeyParameter Parameter
);

public record ServiceKeyParameter(
[property: JsonPropertyName("authorities")] IEnumerable<string> Authorities
);

public record ServiceKeyOperationDeletionRequest(
Expand Down
7 changes: 6 additions & 1 deletion src/clients/Dim.Clients/Api/Div/ProvisioningClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@
using Microsoft.Extensions.Options;
using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling;
using Org.Eclipse.TractusX.Portal.Backend.Framework.HttpClientExtensions;
using System;
using System.Linq;
using System.Net.Http.Json;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

namespace Dim.Clients.Api.Div;

Expand Down Expand Up @@ -138,7 +142,8 @@ public async Task<Guid> CreateServiceKey(string technicalUserName, Guid walletId
"create",
new ServiceKeyCreationPayloadData(
walletId,
technicalUserName
technicalUserName,
new ServiceKeyParameter(new[] { "IatpOperations", "ReadCompanyIdentity", "ResolveDID" })
)
);
var client = await basicAuthTokenService
Expand Down
4 changes: 4 additions & 0 deletions src/clients/Dim.Clients/Token/IBasicAuthTokenService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace Dim.Clients.Token;

public interface IBasicAuthTokenService
Expand Down
21 changes: 16 additions & 5 deletions src/web/Dim.Web/BusinessLogic/DimBusinessLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,12 @@ public class DimBusinessLogic(
IOptions<DimSettings> options)
: IDimBusinessLogic
{
private static readonly Regex TenantName = new(@"(?<=[^\w-])|(?<=[^-])[\W_]+|(?<=[^-])$", RegexOptions.Compiled, new TimeSpan(0, 0, 0, 1));
private static readonly Regex TechnicalUserName = new("[^a-zA-Z0-9]+", RegexOptions.Compiled, new TimeSpan(0, 0, 0, 1));
private static readonly Regex NameRegex = new("[^a-zA-Z0-9]+", 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();
var tenant = GetName(companyName, bpn);
if (await dimRepositories.GetInstance<ITenantRepository>().IsTenantExisting(companyName, bpn).ConfigureAwait(ConfigureAwaitOptions.None))
{
throw ConflictException.Create(DimErrors.TENANT_ALREADY_EXISTS, new ErrorParameter[] { new("companyName", companyName), new("bpn", bpn) });
Expand Down Expand Up @@ -138,15 +137,15 @@ public async Task CreateTechnicalUser(string bpn, TechnicalUserData technicalUse
var processId = processStepRepository.CreateProcess(ProcessTypeId.TECHNICAL_USER).Id;
processStepRepository.CreateProcessStep(ProcessStepTypeId.CREATE_TECHNICAL_USER, ProcessStepStatusId.TODO, processId);

var technicalUserName = TechnicalUserName.Replace(technicalUserData.Name, string.Empty).ToLower();
var technicalUserName = GetName(technicalUserData.Name);
dimRepositories.GetInstance<ITechnicalUserRepository>().CreateTenantTechnicalUser(tenantId, technicalUserName, technicalUserData.ExternalId, processId);

await dimRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None);
}

public async Task DeleteTechnicalUser(string bpn, TechnicalUserData technicalUserData)
{
var technicalUserName = TechnicalUserName.Replace(technicalUserData.Name, string.Empty).ToLower();
var technicalUserName = GetName(technicalUserData.Name);
var (exists, technicalUserId, processId) = await dimRepositories.GetInstance<ITechnicalUserRepository>().GetTechnicalUserForBpn(bpn, technicalUserName).ConfigureAwait(ConfigureAwaitOptions.None);
if (!exists)
{
Expand All @@ -171,6 +170,18 @@ public async Task DeleteTechnicalUser(string bpn, TechnicalUserData technicalUse
await dimRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None);
}

private static string GetName(string name, string? additionalName = null)
{
name = NameRegex.Replace(name, string.Empty).TrimStart('-').TrimEnd('-').ToLower();
if (additionalName is null)
{
return name[..(name.Length <= 32 ? name.Length : 32)];
}

var maxLength = name.Length + additionalName.Length <= 32 ? name.Length : 32 - additionalName.Length;
return name[..maxLength];
}

public async Task<ProcessData> GetSetupProcess(string bpn, string companyName)
{
var processData = await dimRepositories.GetInstance<ITenantRepository>().GetWalletProcessForTenant(bpn, companyName)
Expand Down
24 changes: 17 additions & 7 deletions tests/web/Dim.Web.Tests/DimBusinessLogicTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ public async Task StartSetupDim_WithExisting_ThrowsConflictException()
[InlineData("abc-123", "abc123")]
[InlineData("abc#123", "abc123")]
[InlineData("abc'123", "abc123")]
[InlineData("abc\"123", "abc123")]
[InlineData("ä+slidfböü123üü", "slidfb123")]
[InlineData("averylongnamethatexeedsthemaxlengthbysomecharacters", "averylongnametha")]
[InlineData("a test company", "atestcompany")]
public async Task StartSetupDim_WithNewData_CreatesExpected(string companyName, string expectedCompanyName)
{
// Arrange
Expand Down Expand Up @@ -309,8 +311,16 @@ public async Task CreateTechnicalUser_WithExisting_ThrowsNotFoundException()
result.Message.Should().Be(DimErrors.NO_COMPANY_FOR_BPN.ToString());
}

[Fact]
public async Task CreateTechnicalUser_WithNewData_CreatesExpected()
[Theory]
[InlineData("testCompany", "testcompany")]
[InlineData("-abc123", "abc123")]
[InlineData("abc-123", "abc123")]
[InlineData("abc#123", "abc123")]
[InlineData("abc'123", "abc123")]
[InlineData("ä+slidfböü123üü", "slidfb123")]
[InlineData("averylongnamethatexeedsthemaxlengthbysomecharacters", "averylongnamethatexeedsthemaxlen")]
[InlineData("a test company", "atestcompany")]
public async Task CreateTechnicalUser_WithNewData_CreatesExpected(string name, string expectedName)
{
// Arrange
const string Bpn = "BPNL00001Test";
Expand All @@ -333,20 +343,20 @@ public async Task CreateTechnicalUser_WithNewData_CreatesExpected()
});
A.CallTo(() =>
_technicalUserRepository.CreateTenantTechnicalUser(A<Guid>._, A<string>._, A<Guid>._, A<Guid>._))
.Invokes((Guid tenantId, string name, Guid externalId, Guid pId) =>
.Invokes((Guid tenantId, string technicalUserName, Guid externalId, Guid pId) =>
{
technicalUsers.Add(new TechnicalUser(Guid.NewGuid(), tenantId, externalId, name, pId));
technicalUsers.Add(new TechnicalUser(Guid.NewGuid(), tenantId, externalId, technicalUserName, pId));
});

// Act
await _sut.CreateTechnicalUser(Bpn, _fixture.Create<TechnicalUserData>());
await _sut.CreateTechnicalUser(Bpn, _fixture.Build<TechnicalUserData>().With(x => x.Name, name).Create());

// Assert
processes.Should().ContainSingle()
.Which.ProcessTypeId.Should().Be(ProcessTypeId.TECHNICAL_USER);
processSteps.Should().ContainSingle()
.And.Satisfy(x => x.ProcessId == processId && x.ProcessStepTypeId == ProcessStepTypeId.CREATE_TECHNICAL_USER);
technicalUsers.Should().ContainSingle();
technicalUsers.Should().ContainSingle().And.Satisfy(x => x.TechnicalUserName == expectedName);
}

#endregion
Expand Down

0 comments on commit cf91f31

Please sign in to comment.