From 324765648fe02e5334bafaa671e43237ef10f77b Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Mon, 11 Nov 2024 16:57:51 +0100 Subject: [PATCH] feat: add support for bitstring statuslist Refs: #80 --- charts/dim/templates/cronjob-processes.yaml | 2 ++ charts/dim/values.yaml | 3 ++ src/clients/Dim.Clients/Api/Dim/DimClient.cs | 11 ++++--- src/clients/Dim.Clients/Api/Dim/IDimClient.cs | 5 +-- .../Api/Div/IProvisioningClient.cs | 1 - .../ServiceKeyOperationCreationRequest.cs | 2 -- .../Dim.Clients/Api/Div/ProvisioningClient.cs | 4 --- src/clients/Dim.Clients/Dim.Clients.csproj | 4 +++ .../Token/IBasicAuthTokenService.cs | 4 --- .../Dim.DbAccess/Models/StatusListType.cs | 27 +++++++++++++++ .../DependencyInjection/DimHandlerSettings.cs | 4 +++ .../DimProcess.Library/DimProcessHandler.cs | 2 +- .../TechnicalUserProcessHandler.cs | 1 - .../Processes.Worker/appsettings.json | 23 ++++++------- .../Dim.Web/BusinessLogic/DimBusinessLogic.cs | 8 ++--- .../BusinessLogic/IDimBusinessLogic.cs | 4 +-- src/web/Dim.Web/Controllers/DimController.cs | 22 ++++++++----- .../Models/CreateStatusListParameters.cs | 33 +++++++++++++++++++ .../Dim.Web/Models/GetStatusListParameters.cs | 33 +++++++++++++++++++ .../Dim.Clients.Tests/DimClientTests.cs | 17 +++++----- .../ProvisioningClientTests.cs | 1 - .../DimRepositoriesTests.cs | 2 -- .../Dim.DbAccess.Tests/Setup/TestDbFixture.cs | 1 - .../TechnicalUserRepositoryTests.cs | 2 -- .../TenantRepositoryTests.cs | 2 -- .../DimProcessHandlerTests.cs | 2 +- .../TechnicalUserProcessHandlerTests.cs | 1 - .../Dim.Web.Tests/DimBusinessLogicTests.cs | 20 +++++------ .../appsettings.IntegrationTests.json | 3 +- 29 files changed, 169 insertions(+), 75 deletions(-) create mode 100644 src/database/Dim.DbAccess/Models/StatusListType.cs create mode 100644 src/web/Dim.Web/Models/CreateStatusListParameters.cs create mode 100644 src/web/Dim.Web/Models/GetStatusListParameters.cs diff --git a/charts/dim/templates/cronjob-processes.yaml b/charts/dim/templates/cronjob-processes.yaml index 79e2c32..9cab75a 100644 --- a/charts/dim/templates/cronjob-processes.yaml +++ b/charts/dim/templates/cronjob-processes.yaml @@ -82,6 +82,8 @@ spec: value: "{{ .Values.processesworker.provisioning.encryptionConfigs.index0.cipherMode }}" - name: "DIM__ENCRYPTIONCONFIGS__0__PADDINGMODE" value: "{{ .Values.processesworker.provisioning.encryptionConfigs.index0.paddingMode }}" + - name: "DIM__STATUSLISTTYPE" + value: "{{ .Values.processesworker.dim.statusListType }}" - name: "PROVISIONING__CLIENTID" value: "{{ .Values.processesworker.provisioning.clientId }}" - name: "PROVISIONING__CLIENTSECRET" diff --git a/charts/dim/values.yaml b/charts/dim/values.yaml index 107a0d5..da29e5f 100644 --- a/charts/dim/values.yaml +++ b/charts/dim/values.yaml @@ -85,6 +85,9 @@ processesworker: memory: 300M dim: applicationName: "" + # -- Sets the type of the status list which will be created for the issuer wallet + # -- valid types are: StatusList2021, BitstringStatusList + statusListType: "BitstringStatusList" provisioning: clientId: "" clientSecret: "" diff --git a/src/clients/Dim.Clients/Api/Dim/DimClient.cs b/src/clients/Dim.Clients/Api/Dim/DimClient.cs index 52352ee..3d7fa17 100644 --- a/src/clients/Dim.Clients/Api/Dim/DimClient.cs +++ b/src/clients/Dim.Clients/Api/Dim/DimClient.cs @@ -21,6 +21,7 @@ using Dim.Clients.Api.Dim.Models; using Dim.Clients.Extensions; using Dim.Clients.Token; +using Dim.DbAccess.Models; using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; using Org.Eclipse.TractusX.Portal.Backend.Framework.HttpClientExtensions; using System.Net.Http.Json; @@ -61,7 +62,7 @@ public async Task GetCompanyData(BasicAuthSettings dimAuth, string } } - public async Task GetStatusList(BasicAuthSettings dimAuth, string dimBaseUrl, Guid companyId, CancellationToken cancellationToken) + public async Task GetStatusList(BasicAuthSettings dimAuth, string dimBaseUrl, Guid companyId, StatusListType statusListType, CancellationToken cancellationToken) { var client = await basicAuthTokenService.GetBasicAuthorizedClient(dimAuth, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); var result = await client.GetAsync($"{dimBaseUrl}/api/v2.0.0/companyIdentities/{companyId}/revocationLists", cancellationToken) @@ -76,12 +77,12 @@ public async Task GetStatusList(BasicAuthSettings dimAuth, string dimBas var response = await result.Content .ReadFromJsonAsync(JsonSerializerExtensions.Options, cancellationToken) .ConfigureAwait(ConfigureAwaitOptions.None); - if (response?.Data == null || !response.Data.Any(x => x.RemainingSpace > 0)) + if (response?.Data == null || !response.Data.Where(x => x.Type == statusListType.ToString()).Any(x => x.RemainingSpace > 0)) { throw new ConflictException("There is no status list with remaining space, please create a new one."); } - return response.Data.First(x => x.RemainingSpace > 0).StatusListCredential; + return response.Data.First(x => x.RemainingSpace > 0 && x.Type == statusListType.ToString()).StatusListCredential; } catch (JsonException je) { @@ -89,10 +90,10 @@ public async Task GetStatusList(BasicAuthSettings dimAuth, string dimBas } } - public async Task CreateStatusList(BasicAuthSettings dimAuth, string dimBaseUrl, Guid companyId, CancellationToken cancellationToken) + public async Task CreateStatusList(BasicAuthSettings dimAuth, string dimBaseUrl, Guid companyId, StatusListType statusListType, CancellationToken cancellationToken) { var client = await basicAuthTokenService.GetBasicAuthorizedClient(dimAuth, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); - var data = new CreateStatusListRequest(new CreateStatusListPaypload(new CreateStatusList("StatusList2021", DateTimeOffset.UtcNow.ToString("yyyyMMdd"), "New revocation list", 2097152))); + var data = new CreateStatusListRequest(new CreateStatusListPaypload(new CreateStatusList(statusListType.ToString(), DateTimeOffset.UtcNow.ToString("yyyyMMdd"), "New revocation list", 2097152))); var result = await client.PostAsJsonAsync($"{dimBaseUrl}/api/v2.0.0/companyIdentities/{companyId}/revocationLists", data, JsonSerializerExtensions.Options, cancellationToken) .CatchingIntoServiceExceptionFor("assign-application", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, async m => diff --git a/src/clients/Dim.Clients/Api/Dim/IDimClient.cs b/src/clients/Dim.Clients/Api/Dim/IDimClient.cs index 985a840..32445f0 100644 --- a/src/clients/Dim.Clients/Api/Dim/IDimClient.cs +++ b/src/clients/Dim.Clients/Api/Dim/IDimClient.cs @@ -20,12 +20,13 @@ using Dim.Clients.Api.Dim.Models; using Dim.Clients.Token; +using Dim.DbAccess.Models; namespace Dim.Clients.Api.Dim; public interface IDimClient { Task GetCompanyData(BasicAuthSettings dimAuth, string dimBaseUrl, string tenantName, string application, CancellationToken cancellationToken); - Task GetStatusList(BasicAuthSettings dimAuth, string dimBaseUrl, Guid companyId, CancellationToken cancellationToken); - Task CreateStatusList(BasicAuthSettings dimAuth, string dimBaseUrl, Guid companyId, CancellationToken cancellationToken); + Task GetStatusList(BasicAuthSettings dimAuth, string dimBaseUrl, Guid companyId, StatusListType statusListType, CancellationToken cancellationToken); + Task CreateStatusList(BasicAuthSettings dimAuth, string dimBaseUrl, Guid companyId, StatusListType statusListType, CancellationToken cancellationToken); } diff --git a/src/clients/Dim.Clients/Api/Div/IProvisioningClient.cs b/src/clients/Dim.Clients/Api/Div/IProvisioningClient.cs index ccf0233..0b3f5a6 100644 --- a/src/clients/Dim.Clients/Api/Div/IProvisioningClient.cs +++ b/src/clients/Dim.Clients/Api/Div/IProvisioningClient.cs @@ -19,7 +19,6 @@ ********************************************************************************/ using Dim.Clients.Api.Div.Models; -using Dim.Clients.Token; namespace Dim.Clients.Api.Div; diff --git a/src/clients/Dim.Clients/Api/Div/Models/ServiceKeyOperationCreationRequest.cs b/src/clients/Dim.Clients/Api/Div/Models/ServiceKeyOperationCreationRequest.cs index bf9fb61..7df430c 100644 --- a/src/clients/Dim.Clients/Api/Div/Models/ServiceKeyOperationCreationRequest.cs +++ b/src/clients/Dim.Clients/Api/Div/Models/ServiceKeyOperationCreationRequest.cs @@ -18,8 +18,6 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -using System; -using System.Collections.Generic; using System.Text.Json.Serialization; namespace Dim.Clients.Api.Div.Models; diff --git a/src/clients/Dim.Clients/Api/Div/ProvisioningClient.cs b/src/clients/Dim.Clients/Api/Div/ProvisioningClient.cs index c21ffd3..b9c62af 100644 --- a/src/clients/Dim.Clients/Api/Div/ProvisioningClient.cs +++ b/src/clients/Dim.Clients/Api/Div/ProvisioningClient.cs @@ -25,12 +25,8 @@ 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; diff --git a/src/clients/Dim.Clients/Dim.Clients.csproj b/src/clients/Dim.Clients/Dim.Clients.csproj index 7897523..edc83a8 100644 --- a/src/clients/Dim.Clients/Dim.Clients.csproj +++ b/src/clients/Dim.Clients/Dim.Clients.csproj @@ -41,4 +41,8 @@ + + + + diff --git a/src/clients/Dim.Clients/Token/IBasicAuthTokenService.cs b/src/clients/Dim.Clients/Token/IBasicAuthTokenService.cs index 58d736a..299030b 100644 --- a/src/clients/Dim.Clients/Token/IBasicAuthTokenService.cs +++ b/src/clients/Dim.Clients/Token/IBasicAuthTokenService.cs @@ -18,10 +18,6 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - namespace Dim.Clients.Token; public interface IBasicAuthTokenService diff --git a/src/database/Dim.DbAccess/Models/StatusListType.cs b/src/database/Dim.DbAccess/Models/StatusListType.cs new file mode 100644 index 0000000..795e4d4 --- /dev/null +++ b/src/database/Dim.DbAccess/Models/StatusListType.cs @@ -0,0 +1,27 @@ +/******************************************************************************** + * Copyright (c) 2024 BMW Group AG + * Copyright 2024 SAP SE or an SAP affiliate company and ssi-dim-middle-layer contributors. + * + * 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 + ********************************************************************************/ + +namespace Dim.DbAccess.Models; + +public enum StatusListType +{ + StatusList2021 = 1, + BitstringStatusList = 2, +} diff --git a/src/processes/DimProcess.Library/DependencyInjection/DimHandlerSettings.cs b/src/processes/DimProcess.Library/DependencyInjection/DimHandlerSettings.cs index bae117c..3c67da7 100644 --- a/src/processes/DimProcess.Library/DependencyInjection/DimHandlerSettings.cs +++ b/src/processes/DimProcess.Library/DependencyInjection/DimHandlerSettings.cs @@ -18,6 +18,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ +using Dim.DbAccess.Models; using Org.Eclipse.TractusX.Portal.Backend.Framework.Models.Configuration; using Org.Eclipse.TractusX.Portal.Backend.Framework.Models.Validation; using System.ComponentModel.DataAnnotations; @@ -35,4 +36,7 @@ public class DimHandlerSettings [Required] [DistinctValues("x => x.Index")] public IEnumerable EncryptionConfigs { get; set; } = null!; + + [Required] + public StatusListType StatusListType { get; set; } } diff --git a/src/processes/DimProcess.Library/DimProcessHandler.cs b/src/processes/DimProcess.Library/DimProcessHandler.cs index d484c58..938c183 100644 --- a/src/processes/DimProcess.Library/DimProcessHandler.cs +++ b/src/processes/DimProcess.Library/DimProcessHandler.cs @@ -214,7 +214,7 @@ public class DimProcessHandler( ClientId = clientId, ClientSecret = secret }; - await dimClient.CreateStatusList(dimAuth, baseUrl, companyId.Value, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); + await dimClient.CreateStatusList(dimAuth, baseUrl, companyId.Value, _settings.StatusListType, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); return new ValueTuple?, ProcessStepStatusId, bool, string?>( Enumerable.Repeat(ProcessStepTypeId.SEND_CALLBACK, 1), diff --git a/src/processes/DimProcess.Library/TechnicalUserProcessHandler.cs b/src/processes/DimProcess.Library/TechnicalUserProcessHandler.cs index 0f5ec0d..398cda0 100644 --- a/src/processes/DimProcess.Library/TechnicalUserProcessHandler.cs +++ b/src/processes/DimProcess.Library/TechnicalUserProcessHandler.cs @@ -20,7 +20,6 @@ using Dim.Clients.Api.Div; using Dim.Clients.Api.Div.Models; -using Dim.Clients.Token; using Dim.DbAccess; using Dim.DbAccess.Extensions; using Dim.DbAccess.Repositories; diff --git a/src/processes/Processes.Worker/appsettings.json b/src/processes/Processes.Worker/appsettings.json index 1bf1544..8598525 100644 --- a/src/processes/Processes.Worker/appsettings.json +++ b/src/processes/Processes.Worker/appsettings.json @@ -24,7 +24,17 @@ "DimDb": "Server=placeholder;Database=placeholder;Port=5432;User Id=placeholder;Password=placeholder;Ssl Mode=Disable;" }, "Dim": { - "ApplicationName": "" + "ApplicationName": "", + "EncryptionConfigIndex": 0, + "EncryptionConfigs": [ + { + "Index": 0, + "EncryptionKey": "", + "CipherMode": "", + "PaddingMode": "" + } + ], + "StatusListType": "" }, "Processes": { "LockExpirySeconds": 300 @@ -34,16 +44,7 @@ "ClientSecret": "", "TokenAddress": "", "BaseUrl": "", - "GrantType": "", - "EncryptionConfigIndex": 0, - "EncryptionConfigs": [ - { - "Index": 0, - "EncryptionKey": "", - "CipherMode": "", - "PaddingMode": "" - } - ] + "GrantType": "" }, "Callback": { "Username": "", diff --git a/src/web/Dim.Web/BusinessLogic/DimBusinessLogic.cs b/src/web/Dim.Web/BusinessLogic/DimBusinessLogic.cs index 4746e1f..c4729ab 100644 --- a/src/web/Dim.Web/BusinessLogic/DimBusinessLogic.cs +++ b/src/web/Dim.Web/BusinessLogic/DimBusinessLogic.cs @@ -62,7 +62,7 @@ public async Task StartSetupDim(string companyName, string bpn, string didDocume await dimRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None); } - public async Task GetStatusList(string bpn, CancellationToken cancellationToken) + public async Task GetStatusList(string bpn, StatusListType statusListType, CancellationToken cancellationToken) { var (exists, companyId, baseUrl, walletData) = await dimRepositories.GetInstance().GetCompanyAndWalletDataForBpn(bpn).ConfigureAwait(ConfigureAwaitOptions.None); var (tokenAddress, clientId, clientSecret, initializationVector, encryptionMode) = walletData.ValidateData(); @@ -90,10 +90,10 @@ public async Task GetStatusList(string bpn, CancellationToken cancellati ClientId = clientId, ClientSecret = secret }; - return await dimClient.GetStatusList(dimAuth, baseUrl, companyId.Value, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); + return await dimClient.GetStatusList(dimAuth, baseUrl, companyId.Value, statusListType, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); } - public async Task CreateStatusList(string bpn, CancellationToken cancellationToken) + public async Task CreateStatusList(string bpn, StatusListType statusListType, CancellationToken cancellationToken) { var (exists, companyId, baseUrl, walletData) = await dimRepositories.GetInstance().GetCompanyAndWalletDataForBpn(bpn).ConfigureAwait(ConfigureAwaitOptions.None); var (tokenAddress, clientId, clientSecret, initializationVector, encryptionMode) = walletData.ValidateData(); @@ -121,7 +121,7 @@ public async Task CreateStatusList(string bpn, CancellationToken cancell ClientId = clientId, ClientSecret = secret }; - return await dimClient.CreateStatusList(dimAuth, baseUrl, companyId.Value, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); + return await dimClient.CreateStatusList(dimAuth, baseUrl, companyId.Value, statusListType, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); } public async Task CreateTechnicalUser(string bpn, TechnicalUserData technicalUserData) diff --git a/src/web/Dim.Web/BusinessLogic/IDimBusinessLogic.cs b/src/web/Dim.Web/BusinessLogic/IDimBusinessLogic.cs index ee75f04..43db449 100644 --- a/src/web/Dim.Web/BusinessLogic/IDimBusinessLogic.cs +++ b/src/web/Dim.Web/BusinessLogic/IDimBusinessLogic.cs @@ -28,8 +28,8 @@ namespace Dim.Web.BusinessLogic; public interface IDimBusinessLogic : ITransient { Task StartSetupDim(string companyName, string bpn, string didDocumentLocation, bool isIssuer); - Task GetStatusList(string bpn, CancellationToken cancellationToken); - Task CreateStatusList(string bpn, CancellationToken cancellationToken); + Task GetStatusList(string bpn, StatusListType statusListType, CancellationToken cancellationToken); + Task CreateStatusList(string bpn, StatusListType statusListType, CancellationToken cancellationToken); Task CreateTechnicalUser(string bpn, TechnicalUserData technicalUserData); Task DeleteTechnicalUser(string bpn, TechnicalUserData technicalUserData); Task GetSetupProcess(string bpn, string companyName); diff --git a/src/web/Dim.Web/Controllers/DimController.cs b/src/web/Dim.Web/Controllers/DimController.cs index 642a32a..8b680a6 100644 --- a/src/web/Dim.Web/Controllers/DimController.cs +++ b/src/web/Dim.Web/Controllers/DimController.cs @@ -34,6 +34,7 @@ public static class DimController public static RouteGroupBuilder MapDimApi(this RouteGroupBuilder group) { var dim = group.MapGroup("/dim"); + const string BpnDescription = "bpn of the company"; dim.MapPost("setup-dim", ([FromQuery] string companyName, [FromQuery] string bpn, [FromQuery] string didDocumentLocation, IDimBusinessLogic dimBusinessLogic) => dimBusinessLogic.StartSetupDim(companyName, bpn, didDocumentLocation, false)) .WithSwaggerDescription("Creates a holder wallet", @@ -53,31 +54,34 @@ public static RouteGroupBuilder MapDimApi(this RouteGroupBuilder group) .RequireAuthorization(r => r.RequireRole("setup_wallet")) .Produces(StatusCodes.Status201Created); - dim.MapGet("status-list", ([FromQuery] string bpn, CancellationToken cancellationToken, [FromServices] IDimBusinessLogic dimBusinessLogic) => dimBusinessLogic.GetStatusList(bpn, cancellationToken)) + dim.MapGet("status-list", ([AsParameters] GetStatusListParameters parameters, CancellationToken cancellationToken, [FromServices] IDimBusinessLogic dimBusinessLogic) => dimBusinessLogic.GetStatusList(parameters.Bpn, parameters.StatusListType, cancellationToken)) .WithSwaggerDescription("Gets the status list for the given company", - "Example: GET: api/dim/status-list/{bpn}", - "id of the dim company") + "Example: GET: api/dim/status-list/{bpn}/{statusListType}", + "id of the dim company", + "The type of the statuslist to receive") .RequireAuthorization(r => r.RequireRole("view_status_list")) .Produces(StatusCodes.Status200OK, responseType: typeof(string), contentType: Constants.JsonContentType); - dim.MapPost("status-list", ([FromQuery] string bpn, CancellationToken cancellationToken, [FromServices] IDimBusinessLogic dimBusinessLogic) => dimBusinessLogic.CreateStatusList(bpn, cancellationToken)) + dim.MapPost("status-list", ([AsParameters] CreateStatusListParameters parameters, CancellationToken cancellationToken, [FromServices] IDimBusinessLogic dimBusinessLogic) => dimBusinessLogic.CreateStatusList(parameters.Bpn, parameters.StatusListType, cancellationToken)) .WithSwaggerDescription("Creates a status list for the given company", "Example: Post: api/dim/status-list/{bpn}", - "bpn of the company") + BpnDescription, + "The type of the statuslist that should be created") .RequireAuthorization(r => r.RequireRole("create_status_list")) + .AllowAnonymous() .Produces(StatusCodes.Status200OK, responseType: typeof(string), contentType: Constants.JsonContentType); dim.MapPost("technical-user/{bpn}", ([FromRoute] string bpn, [FromBody] TechnicalUserData technicalUserData, [FromServices] IDimBusinessLogic dimBusinessLogic) => dimBusinessLogic.CreateTechnicalUser(bpn, technicalUserData)) .WithSwaggerDescription("Creates a technical user for the dim of the given bpn", "Example: Post: api/dim/technical-user/{bpn}", - "bpn of the company") + BpnDescription) .RequireAuthorization(r => r.RequireRole("create_technical_user")) .Produces(StatusCodes.Status200OK, contentType: Constants.JsonContentType); dim.MapPost("technical-user/{bpn}/delete", ([FromRoute] string bpn, [FromBody] TechnicalUserData technicalUserData, [FromServices] IDimBusinessLogic dimBusinessLogic) => dimBusinessLogic.DeleteTechnicalUser(bpn, technicalUserData)) .WithSwaggerDescription("Deletes a technical user with the given name of the given bpn", "Example: Post: api/dim/technical-user/{bpn}/delete", - "bpn of the company") + BpnDescription) .RequireAuthorization(r => r.RequireRole("delete_technical_user")) .Produces(StatusCodes.Status200OK, contentType: Constants.JsonContentType); @@ -89,7 +93,7 @@ public static RouteGroupBuilder MapDimApi(this RouteGroupBuilder group) ) .WithSwaggerDescription("Gets the wallet creation process id for the given bpn and companyName", "Example: Post: api/dim/process/setup?bpn={bpn}&companyName={companyName}", - "bpn of the company", + BpnDescription, "name of the company") .RequireAuthorization(r => r.RequireRole("get_process")) .Produces(StatusCodes.Status200OK, contentType: Constants.JsonContentType); @@ -103,7 +107,7 @@ public static RouteGroupBuilder MapDimApi(this RouteGroupBuilder group) ) .WithSwaggerDescription("Gets the technical user creation process id for the given technicalUserName", "Example: Post: api/dim/process/technical-user?bpn={bpn}&companyName={companyName}&technicalUserName={technicalUserName}", - "bpn of the company", + BpnDescription, "name of the company", "name of the techincal user to get the process for") .RequireAuthorization(r => r.RequireRole("get_process")) diff --git a/src/web/Dim.Web/Models/CreateStatusListParameters.cs b/src/web/Dim.Web/Models/CreateStatusListParameters.cs new file mode 100644 index 0000000..7893ad4 --- /dev/null +++ b/src/web/Dim.Web/Models/CreateStatusListParameters.cs @@ -0,0 +1,33 @@ +/******************************************************************************** + * Copyright (c) 2024 BMW Group AG + * Copyright 2024 SAP SE or an SAP affiliate company and ssi-dim-middle-layer contributors. + * + * 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 Dim.DbAccess.Models; +using Microsoft.AspNetCore.Mvc; + +namespace Dim.Web.Models; + +public struct CreateStatusListParameters +{ + [FromQuery] + public string Bpn { get; set; } + + [FromQuery] + public StatusListType StatusListType { get; set; } +} diff --git a/src/web/Dim.Web/Models/GetStatusListParameters.cs b/src/web/Dim.Web/Models/GetStatusListParameters.cs new file mode 100644 index 0000000..e0c4123 --- /dev/null +++ b/src/web/Dim.Web/Models/GetStatusListParameters.cs @@ -0,0 +1,33 @@ +/******************************************************************************** + * Copyright (c) 2024 BMW Group AG + * Copyright 2024 SAP SE or an SAP affiliate company and ssi-dim-middle-layer contributors. + * + * 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 Dim.DbAccess.Models; +using Microsoft.AspNetCore.Mvc; + +namespace Dim.Web.Models; + +public struct GetStatusListParameters +{ + [FromQuery] + public string Bpn { get; set; } + + [FromQuery] + public StatusListType StatusListType { get; set; } +} diff --git a/tests/clients/Dim.Clients.Tests/DimClientTests.cs b/tests/clients/Dim.Clients.Tests/DimClientTests.cs index 3b8be3f..ab4db62 100644 --- a/tests/clients/Dim.Clients.Tests/DimClientTests.cs +++ b/tests/clients/Dim.Clients.Tests/DimClientTests.cs @@ -5,6 +5,7 @@ using Dim.Clients.Extensions; using Dim.Clients.Tests.Extensions; using Dim.Clients.Token; +using Dim.DbAccess.Models; using FluentAssertions; using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; using System.Net; @@ -89,7 +90,7 @@ public async Task GetStatusList_WithNoContent_ThrowsServiceException() // Arrange _fixture.ConfigureTokenServiceFixture(new HttpResponseMessage(HttpStatusCode.OK)); var sut = _fixture.Create(); - Task Act() => sut.GetStatusList(_fixture.Create(), "https://example.org", Guid.NewGuid(), CancellationToken.None); + Task Act() => sut.GetStatusList(_fixture.Create(), "https://example.org", Guid.NewGuid(), StatusListType.BitstringStatusList, CancellationToken.None); // Act var ex = await Assert.ThrowsAsync(Act); @@ -102,10 +103,10 @@ public async Task GetStatusList_WithNoContent_ThrowsServiceException() public async Task GetStatusList_WithNoSpaceLeft_ThrowsConflictException() { // Arrange - var data = new StatusListListResponse(1, new[] { new StatusListResponse(Guid.NewGuid().ToString(), "test", "test", "test", 1024, 0) }); + var data = new StatusListListResponse(1, new[] { new StatusListResponse(Guid.NewGuid().ToString(), "test", "BitstringStatusList", "test", 1024, 0) }); _fixture.ConfigureTokenServiceFixture(new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(JsonSerializer.Serialize(data, JsonSerializerExtensions.Options)) }); var sut = _fixture.Create(); - Task Act() => sut.GetStatusList(_fixture.Create(), "https://example.org", Guid.NewGuid(), CancellationToken.None); + Task Act() => sut.GetStatusList(_fixture.Create(), "https://example.org", Guid.NewGuid(), StatusListType.BitstringStatusList, CancellationToken.None); // Act var ex = await Assert.ThrowsAsync(Act); @@ -118,12 +119,12 @@ public async Task GetStatusList_WithNoSpaceLeft_ThrowsConflictException() public async Task GetStatusList_WithValidData_ReturnsCompanyData() { // Arrange - var data = new StatusListListResponse(1, new[] { new StatusListResponse(Guid.NewGuid().ToString(), "test", "testCred", "test", 1024, 100) }); + var data = new StatusListListResponse(1, new[] { new StatusListResponse(Guid.NewGuid().ToString(), "test", "testCred", "BitstringStatusList", 1024, 100) }); _fixture.ConfigureTokenServiceFixture(new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(JsonSerializer.Serialize(data, JsonSerializerExtensions.Options)) }); var sut = _fixture.Create(); // Act - var result = await sut.GetStatusList(_fixture.Create(), "https://example.org", Guid.NewGuid(), CancellationToken.None); + var result = await sut.GetStatusList(_fixture.Create(), "https://example.org", Guid.NewGuid(), StatusListType.BitstringStatusList, CancellationToken.None); // Assert result.Should().Be("testCred"); @@ -142,7 +143,7 @@ public async Task CreateStatusList_WithNoContent_ThrowsServiceException() new HttpResponseMessage(HttpStatusCode.OK), requestMessage => request = requestMessage); var sut = _fixture.Create(); - Task Act() => sut.CreateStatusList(_fixture.Create(), "https://example.org", Guid.NewGuid(), CancellationToken.None); + Task Act() => sut.CreateStatusList(_fixture.Create(), "https://example.org", Guid.NewGuid(), StatusListType.StatusList2021, CancellationToken.None); // Act var ex = await Assert.ThrowsAsync(Act); @@ -157,7 +158,7 @@ public async Task CreateStatusList_WithNoSpaceLeft_ThrowsConflictException() // Arrange _fixture.ConfigureTokenServiceFixture(new HttpResponseMessage(HttpStatusCode.BadRequest)); var sut = _fixture.Create(); - Task Act() => sut.CreateStatusList(_fixture.Create(), "https://example.org", Guid.NewGuid(), CancellationToken.None); + Task Act() => sut.CreateStatusList(_fixture.Create(), "https://example.org", Guid.NewGuid(), StatusListType.StatusList2021, CancellationToken.None); // Act var ex = await Assert.ThrowsAsync(Act); @@ -181,7 +182,7 @@ public async Task CreateStatusList_WithValidData_ReturnsCompanyData() var sut = _fixture.Create(); // Act - var result = await sut.CreateStatusList(_fixture.Create(), "https://example.org", Guid.NewGuid(), CancellationToken.None); + var result = await sut.CreateStatusList(_fixture.Create(), "https://example.org", Guid.NewGuid(), StatusListType.StatusList2021, CancellationToken.None); // Assert result.Should().Be(recovationVc); diff --git a/tests/clients/Dim.Clients.Tests/ProvisioningClientTests.cs b/tests/clients/Dim.Clients.Tests/ProvisioningClientTests.cs index bade2dc..821b737 100644 --- a/tests/clients/Dim.Clients.Tests/ProvisioningClientTests.cs +++ b/tests/clients/Dim.Clients.Tests/ProvisioningClientTests.cs @@ -4,7 +4,6 @@ using Dim.Clients.Api.Div.Models; using Dim.Clients.Extensions; using Dim.Clients.Tests.Extensions; -using Dim.Clients.Token; using FluentAssertions; using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; using System.Net; diff --git a/tests/database/Dim.DbAccess.Tests/DimRepositoriesTests.cs b/tests/database/Dim.DbAccess.Tests/DimRepositoriesTests.cs index 49dacf1..6d1050d 100644 --- a/tests/database/Dim.DbAccess.Tests/DimRepositoriesTests.cs +++ b/tests/database/Dim.DbAccess.Tests/DimRepositoriesTests.cs @@ -18,8 +18,6 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -using AutoFixture; -using AutoFixture.AutoFakeItEasy; using Dim.DbAccess.Repositories; using Dim.DbAccess.Tests.Setup; using Dim.Entities; diff --git a/tests/database/Dim.DbAccess.Tests/Setup/TestDbFixture.cs b/tests/database/Dim.DbAccess.Tests/Setup/TestDbFixture.cs index 782b210..fb8f1e5 100644 --- a/tests/database/Dim.DbAccess.Tests/Setup/TestDbFixture.cs +++ b/tests/database/Dim.DbAccess.Tests/Setup/TestDbFixture.cs @@ -19,7 +19,6 @@ ********************************************************************************/ using Dim.Entities; -using Dim.Migrations.Migrations; using Dim.Migrations.Seeder; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; diff --git a/tests/database/Dim.DbAccess.Tests/TechnicalUserRepositoryTests.cs b/tests/database/Dim.DbAccess.Tests/TechnicalUserRepositoryTests.cs index 9aa8cff..85d9eda 100644 --- a/tests/database/Dim.DbAccess.Tests/TechnicalUserRepositoryTests.cs +++ b/tests/database/Dim.DbAccess.Tests/TechnicalUserRepositoryTests.cs @@ -1,5 +1,3 @@ -using AutoFixture; -using AutoFixture.AutoFakeItEasy; using Dim.DbAccess.Repositories; using Dim.DbAccess.Tests.Setup; using Dim.Entities; diff --git a/tests/database/Dim.DbAccess.Tests/TenantRepositoryTests.cs b/tests/database/Dim.DbAccess.Tests/TenantRepositoryTests.cs index ee060b4..d9cbbfb 100644 --- a/tests/database/Dim.DbAccess.Tests/TenantRepositoryTests.cs +++ b/tests/database/Dim.DbAccess.Tests/TenantRepositoryTests.cs @@ -1,5 +1,3 @@ -using AutoFixture; -using AutoFixture.AutoFakeItEasy; using Dim.DbAccess.Repositories; using Dim.DbAccess.Tests.Setup; using Dim.Entities; diff --git a/tests/processes/DimProcess.Library.Tests/DimProcessHandlerTests.cs b/tests/processes/DimProcess.Library.Tests/DimProcessHandlerTests.cs index 7f8e240..142c648 100644 --- a/tests/processes/DimProcess.Library.Tests/DimProcessHandlerTests.cs +++ b/tests/processes/DimProcess.Library.Tests/DimProcessHandlerTests.cs @@ -383,7 +383,7 @@ public async Task CreateStatusList_WithValidData_ReturnsExpected() var result = await _sut.CreateStatusList(_tenantId, CancellationToken.None); // Assert - A.CallTo(() => _dimClient.CreateStatusList(A._, BaseUrl, companyId, A._)) + A.CallTo(() => _dimClient.CreateStatusList(A._, BaseUrl, companyId, A._, A._)) .MustHaveHappenedOnceExactly(); result.modified.Should().BeFalse(); diff --git a/tests/processes/DimProcess.Library.Tests/TechnicalUserProcessHandlerTests.cs b/tests/processes/DimProcess.Library.Tests/TechnicalUserProcessHandlerTests.cs index 26d2660..f09fe62 100644 --- a/tests/processes/DimProcess.Library.Tests/TechnicalUserProcessHandlerTests.cs +++ b/tests/processes/DimProcess.Library.Tests/TechnicalUserProcessHandlerTests.cs @@ -20,7 +20,6 @@ using Dim.Clients.Api.Div; using Dim.Clients.Api.Div.Models; -using Dim.Clients.Token; using Dim.DbAccess; using Dim.DbAccess.Models; using Dim.DbAccess.Repositories; diff --git a/tests/web/Dim.Web.Tests/DimBusinessLogicTests.cs b/tests/web/Dim.Web.Tests/DimBusinessLogicTests.cs index 74b97f4..d1e0fdb 100644 --- a/tests/web/Dim.Web.Tests/DimBusinessLogicTests.cs +++ b/tests/web/Dim.Web.Tests/DimBusinessLogicTests.cs @@ -158,7 +158,7 @@ public async Task GetStatusList_WithNotExisting_ThrowsNotFoundException() var bpn = "BPNL00000001TEST"; A.CallTo(() => _tenantRepository.GetCompanyAndWalletDataForBpn(bpn)) .Returns((false, null, null, GetWalletData())); - Task Act() => _sut.GetStatusList(bpn, CancellationToken.None); + Task Act() => _sut.GetStatusList(bpn, StatusListType.BitstringStatusList, CancellationToken.None); // Act var result = await Assert.ThrowsAsync(Act); @@ -174,7 +174,7 @@ public async Task GetStatusList_WithoutCompanyId_ThrowsConflictException() const string Bpn = "BPNL00000001TEST"; A.CallTo(() => _tenantRepository.GetCompanyAndWalletDataForBpn(Bpn)) .Returns((true, null, null, GetWalletData())); - Task Act() => _sut.GetStatusList(Bpn, CancellationToken.None); + Task Act() => _sut.GetStatusList(Bpn, StatusListType.BitstringStatusList, CancellationToken.None); // Act var result = await Assert.ThrowsAsync(Act); @@ -191,7 +191,7 @@ public async Task GetStatusList_WithBaseUrlNotSet_ThrowsConflictException() var companyId = Guid.NewGuid(); A.CallTo(() => _tenantRepository.GetCompanyAndWalletDataForBpn(Bpn)) .Returns((true, companyId, null, GetWalletData())); - Task Act() => _sut.GetStatusList(Bpn, CancellationToken.None); + Task Act() => _sut.GetStatusList(Bpn, StatusListType.BitstringStatusList, CancellationToken.None); // Act var result = await Assert.ThrowsAsync(Act); @@ -209,11 +209,11 @@ public async Task GetStatusList_WithValid_ReturnsExpected() var companyId = Guid.NewGuid(); A.CallTo(() => _tenantRepository.GetCompanyAndWalletDataForBpn(Bpn)) .Returns((true, companyId, BaseUrl, GetWalletData())); - A.CallTo(() => _dimClient.GetStatusList(A._, BaseUrl, companyId, A._)) + A.CallTo(() => _dimClient.GetStatusList(A._, BaseUrl, companyId, StatusListType.BitstringStatusList, A._)) .Returns("https://example.org/statuslist"); // Act - var result = await _sut.GetStatusList(Bpn, CancellationToken.None); + var result = await _sut.GetStatusList(Bpn, StatusListType.BitstringStatusList, CancellationToken.None); // Assert result.Should().Be("https://example.org/statuslist"); @@ -230,7 +230,7 @@ public async Task CreateStatusList_WithNotExisting_ThrowsNotFoundException() var bpn = "BPNL00000001TEST"; A.CallTo(() => _tenantRepository.GetCompanyAndWalletDataForBpn(bpn)) .Returns((false, null, null, GetWalletData())); - Task Act() => _sut.CreateStatusList(bpn, CancellationToken.None); + Task Act() => _sut.CreateStatusList(bpn, StatusListType.BitstringStatusList, CancellationToken.None); // Act var result = await Assert.ThrowsAsync(Act); @@ -246,7 +246,7 @@ public async Task CreateStatusList_WithoutCompanyId_ThrowsConflictException() const string Bpn = "BPNL00000001TEST"; A.CallTo(() => _tenantRepository.GetCompanyAndWalletDataForBpn(Bpn)) .Returns((true, null, null, GetWalletData())); - Task Act() => _sut.CreateStatusList(Bpn, CancellationToken.None); + Task Act() => _sut.CreateStatusList(Bpn, StatusListType.BitstringStatusList, CancellationToken.None); // Act var result = await Assert.ThrowsAsync(Act); @@ -263,7 +263,7 @@ public async Task CreateStatusList_WithBaseUrlNotSet_ThrowsConflictException() var companyId = Guid.NewGuid(); A.CallTo(() => _tenantRepository.GetCompanyAndWalletDataForBpn(Bpn)) .Returns((true, companyId, null, GetWalletData())); - Task Act() => _sut.CreateStatusList(Bpn, CancellationToken.None); + Task Act() => _sut.CreateStatusList(Bpn, StatusListType.BitstringStatusList, CancellationToken.None); // Act var result = await Assert.ThrowsAsync(Act); @@ -281,11 +281,11 @@ public async Task CreateStatusList_WithValid_ReturnsExpected() var companyId = Guid.NewGuid(); A.CallTo(() => _tenantRepository.GetCompanyAndWalletDataForBpn(Bpn)) .Returns((true, companyId, BaseUrl, GetWalletData())); - A.CallTo(() => _dimClient.CreateStatusList(A._, BaseUrl, companyId, A._)) + A.CallTo(() => _dimClient.CreateStatusList(A._, BaseUrl, companyId, A._, A._)) .Returns("https://example.org/statuslist"); // Act - var result = await _sut.CreateStatusList(Bpn, CancellationToken.None); + var result = await _sut.CreateStatusList(Bpn, StatusListType.BitstringStatusList, CancellationToken.None); // Assert result.Should().Be("https://example.org/statuslist"); diff --git a/tests/web/Dim.Web.Tests/appsettings.IntegrationTests.json b/tests/web/Dim.Web.Tests/appsettings.IntegrationTests.json index 3abb5a2..01a691e 100644 --- a/tests/web/Dim.Web.Tests/appsettings.IntegrationTests.json +++ b/tests/web/Dim.Web.Tests/appsettings.IntegrationTests.json @@ -18,7 +18,8 @@ "CipherMode": "", "PaddingMode": "" } - ] + ], + "StatusListType": "BitstringStatusList" }, "SwaggerEnabled": true, "JwtBearerOptions": {