From dc9c70da4c0bcba979c71b5c636526c13041c774 Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Fri, 26 Apr 2024 13:18:30 +0200 Subject: [PATCH 01/13] feat(revocation): add endpoints to revoke credentials (#43) * feat(revocation): add endpoints to revoke credentials * add endpoint for issuer to revoke a credential * add endpoint for holder to revoke a credential * add logic to revoke credentials when they are expired * feat(download): add credential download endpoint * chore: adjust statusList Url Refs: #14 #15 #16 #24 --------- Co-authored-by: Norbert Truchsess Reviewed-by: Norbert Truchsess --- DEPENDENCIES | 1 - .../templates/deployment-issuer-service.yaml | 32 + .../ExpiryCheckService.cs | 52 +- .../Models/SsiApprovalData.cs | 2 + .../CompanySsiDetailsRepository.cs | 7 +- .../Repositories/CredentialRepository.cs | 36 + .../Repositories/DocumentRepository.cs | 15 +- .../ICompanySsiDetailsRepository.cs | 2 +- .../Repositories/ICredentialRepository.cs | 5 + .../Repositories/IDocumentRepository.cs | 1 + .../Entities/ProcessStepStatus.cs | 4 +- .../Entities/ProcessStepType.cs | 4 +- .../Entities/ProcessType.cs | 4 +- .../Enums/ProcessStepTypeId.cs | 7 +- .../Enums/ProcessTypeId.cs | 1 + .../Enums/VerifiedCredentialExternalTypeId.cs | 15 +- .../Enums/VerifiedCredentialTypeId.cs | 15 +- .../20240424121211_1.0.0-rc.3.Designer.cs | 1637 +++++++++++++++++ .../Migrations/20240424121211_1.0.0-rc.3.cs | 170 ++ .../IssuerDbContextModelSnapshot.cs | 57 +- .../Seeder/Data/use_cases.json | 22 +- ...ternal_type_detail_versions.consortia.json | 36 +- ...dential_external_type_detail_versions.json | 34 +- ...edential_type_assigned_external_types.json | 12 + ...rified_credential_type_assigned_kinds.json | 12 + ...ed_credential_type_assigned_use_cases.json | 16 +- .../Portal.Service/Models/MailData.cs | 7 +- .../Portal.Service/Services/IPortalService.cs | 2 +- .../Portal.Service/Services/PortalService.cs | 10 +- .../Models/GetCredentialResponse.cs | 3 +- .../Models/RevokeCredentialRequest.cs | 30 + .../Services/BasicAuthTokenService.cs | 7 +- .../Services/IBasicAuthTokenService.cs | 2 +- .../Wallet.Service/Services/IWalletService.cs | 1 + .../Wallet.Service/Services/WalletService.cs | 18 +- .../BusinessLogic/CredentialBusinessLogic.cs | 62 + .../ICredentialBusinessLogic.cs} | 11 +- .../BusinessLogic/IRevocationBusinessLogic.cs | 25 + .../BusinessLogic/IssuerBusinessLogic.cs | 120 +- .../BusinessLogic/RevocationBusinessLogic.cs | 82 + .../Controllers/CredentialController.cs | 50 + .../Controllers/RevocationController.cs | 67 + .../ServiceCollectionExtensions.cs | 44 + .../CredentialErrorMessageContainer.cs | 14 +- .../IssuerErrorMessageContainer.cs | 98 + .../RevocationErrorMessageContainer.cs | 44 + .../Models/CredentialData.cs | 6 +- .../SsiCredentialIssuer.Service/Program.cs | 10 +- .../appsettings.json | 21 +- .../CredentialCreationProcessHandler.cs} | 16 +- .../ICredentialCreationProcessHandler.cs} | 4 +- .../CredentialProcess.Library.csproj | 1 + .../CredentialHandlerExtensions.cs | 15 +- .../Expiry/CredentialExpiryProcessHandler.cs | 119 ++ .../Expiry/ICredentialExpiryProcessHandler.cs | 29 + .../CredentialCreationProcessTypeExecutor.cs} | 26 +- .../CredentialProcessCollectionExtensions.cs | 12 +- .../CredentialExpiryProcessTypeExecutor.cs | 109 ++ .../Processes.Library.csproj | 4 - .../ProcessExecutionServiceExtensions.cs | 1 - src/processes/Processes.Worker/Program.cs | 5 +- .../Processes.Worker/appsettings.json | 11 +- .../ExpiryCheckServiceTests.cs | 19 +- .../CompanySsiDetailsRepositoryTests.cs | 32 +- .../CredentialRepositoryTests.cs | 33 + .../DocumentRepositoryTests.cs | 31 + .../IssuerRepositoriesTests.cs | 1 - ...al_external_type_detail_versions.test.json | 32 +- ...edential_type_assigned_use_cases.test.json | 4 - .../CallbackServiceTests.cs | 2 - .../PortalServiceTests.cs | 5 +- .../Services/BasicAuthTokenServiceTests.cs | 5 +- .../Services/WalletServiceTests.cs | 72 +- .../CredentialBusinessLogicTests.cs | 127 ++ .../BusinessLogic/IssuerBusinessLogicTests.cs | 217 ++- .../RevocationBusinessLogicTests.cs | 161 ++ .../appsettings.IntegrationTests.json | 19 + ... CredentialCreationProcessHandlerTests.cs} | 49 +- .../CredentialExpiryProcessHandlerTests.cs | 209 +++ ...entialCreationProcessTypeExecutorTests.cs} | 55 +- ...redentialExpiryProcessTypeExecutorTests.cs | 234 +++ .../ProcessExecutorTests.cs | 1 - 82 files changed, 4172 insertions(+), 421 deletions(-) create mode 100644 src/database/SsiCredentialIssuer.Migrations/Migrations/20240424121211_1.0.0-rc.3.Designer.cs create mode 100644 src/database/SsiCredentialIssuer.Migrations/Migrations/20240424121211_1.0.0-rc.3.cs create mode 100644 src/externalservices/Wallet.Service/Models/RevokeCredentialRequest.cs create mode 100644 src/issuer/SsiCredentialIssuer.Service/BusinessLogic/CredentialBusinessLogic.cs rename src/issuer/SsiCredentialIssuer.Service/{DependencyInjection/CredentialServiceCollectionExtensions.cs => BusinessLogic/ICredentialBusinessLogic.cs} (65%) create mode 100644 src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IRevocationBusinessLogic.cs create mode 100644 src/issuer/SsiCredentialIssuer.Service/BusinessLogic/RevocationBusinessLogic.cs create mode 100644 src/issuer/SsiCredentialIssuer.Service/Controllers/CredentialController.cs create mode 100644 src/issuer/SsiCredentialIssuer.Service/Controllers/RevocationController.cs create mode 100644 src/issuer/SsiCredentialIssuer.Service/DependencyInjection/ServiceCollectionExtensions.cs create mode 100644 src/issuer/SsiCredentialIssuer.Service/ErrorHandling/IssuerErrorMessageContainer.cs create mode 100644 src/issuer/SsiCredentialIssuer.Service/ErrorHandling/RevocationErrorMessageContainer.cs rename src/processes/CredentialProcess.Library/{CredentialProcessHandler.cs => Creation/CredentialCreationProcessHandler.cs} (90%) rename src/processes/CredentialProcess.Library/{ICredentialProcessHandler.cs => Creation/ICredentialCreationProcessHandler.cs} (96%) create mode 100644 src/processes/CredentialProcess.Library/Expiry/CredentialExpiryProcessHandler.cs create mode 100644 src/processes/CredentialProcess.Library/Expiry/ICredentialExpiryProcessHandler.cs rename src/processes/CredentialProcess.Worker/{CredentialProcessTypeExecutor.cs => Creation/CredentialCreationProcessTypeExecutor.cs} (84%) create mode 100644 src/processes/CredentialProcess.Worker/Expiry/CredentialExpiryProcessTypeExecutor.cs create mode 100644 tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/CredentialBusinessLogicTests.cs create mode 100644 tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/RevocationBusinessLogicTests.cs rename tests/processes/CredentialProcess.Library.Tests/{CredentialProcessHandlerTests.cs => CredentialCreationProcessHandlerTests.cs} (81%) create mode 100644 tests/processes/CredentialProcess.Library.Tests/CredentialExpiryProcessHandlerTests.cs rename tests/processes/CredentialProcess.Worker.Tests/{CredentialProcessTypeExecutorTests.cs => CredentialCreationProcessTypeExecutorTests.cs} (81%) create mode 100644 tests/processes/CredentialProcess.Worker.Tests/CredentialExpiryProcessTypeExecutorTests.cs diff --git a/DEPENDENCIES b/DEPENDENCIES index fcae7a8a..ea71b550 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -15,7 +15,6 @@ nuget/nuget/-/JsonSchema.Net/6.0.3, MIT AND OFL-1.1 AND CC-BY-SA-4.0, approved, nuget/nuget/-/Laraue.EfCoreTriggers.Common/7.1.0, MIT, approved, #10247 nuget/nuget/-/Laraue.EfCoreTriggers.PostgreSql/7.1.0, MIT, approved, #10248 nuget/nuget/-/Mono.TextTemplating/2.2.1, MIT, approved, clearlydefined -nuget/nuget/-/Newtonsoft.Json/12.0.2, MIT AND BSD-3-Clause, approved, #11114 nuget/nuget/-/Newtonsoft.Json/13.0.1, MIT AND BSD-3-Clause, approved, #3266 nuget/nuget/-/Newtonsoft.Json/13.0.3, MIT AND BSD-3-Clause, approved, #3266 nuget/nuget/-/Npgsql.EntityFrameworkCore.PostgreSQL/7.0.11, PostgreSQL AND MIT AND Apache-2.0, approved, #10081 diff --git a/charts/ssi-credential-issuer/templates/deployment-issuer-service.yaml b/charts/ssi-credential-issuer/templates/deployment-issuer-service.yaml index 2bb435ef..7266260c 100644 --- a/charts/ssi-credential-issuer/templates/deployment-issuer-service.yaml +++ b/charts/ssi-credential-issuer/templates/deployment-issuer-service.yaml @@ -131,6 +131,38 @@ spec: secretKeyRef: name: "{{ template "issuer.secretName" . }}" key: "credential-encryption-key0" + - name: "WALLET__BASEADDRESS" + value: "{{ .Values.walletAddress }}" + - name: "WALLET__CLIENTID" + value: "{{ .Values.processesworker.wallet.clientId }}" + - name: "WALLET__CLIENTSECRET" + valueFrom: + secretKeyRef: + name: "{{ template "issuer.secretName" . }}" + key: "wallet-client-secret" + - name: "WALLET__GRANTTYPE" + value: "{{ .Values.processesworker.wallet.grantType }}" + - name: "WALLET__TOKENADDRESS" + value: "{{ .Values.walletTokenAddress }}" + - name: "WALLET__PASSWORD" + value: "empty" + - name: "WALLET__SCOPE" + value: "{{ .Values.processesworker.wallet.scope }}" + - name: "WALLET__USERNAME" + value: "empty" + - name: "WALLET__ENCRYPTIONCONFIG__ENCRYPTIONCONFIGINDEX" + value: "{{ .Values.processesworker.wallet.encryptionConfigIndex }}" + - name: "WALLET__ENCRYPTIONCONFIGS__0__INDEX" + value: "{{ .Values.processesworker.wallet.encryptionConfigs.index0.index}}" + - name: "WALLET__ENCRYPTIONCONFIGS__0__CIPHERMODE" + value: "{{ .Values.processesworker.wallet.encryptionConfigs.index0.cipherMode}}" + - name: "WALLET__ENCRYPTIONCONFIGS__0__PADDINGMODE" + value: "{{ .Values.processesworker.wallet.encryptionConfigs.index0.paddingMode}}" + - name: "WALLET__ENCRYPTIONCONFIGS__0__ENCRYPTIONKEY" + valueFrom: + secretKeyRef: + name: "{{ template "issuer.secretName" . }}" + key: "process-wallet-encryption-key0" ports: - name: http containerPort: {{ .Values.portContainer }} diff --git a/src/credentials/SsiCredentialIssuer.Expiry.App/ExpiryCheckService.cs b/src/credentials/SsiCredentialIssuer.Expiry.App/ExpiryCheckService.cs index 49649986..106e0cbf 100644 --- a/src/credentials/SsiCredentialIssuer.Expiry.App/ExpiryCheckService.cs +++ b/src/credentials/SsiCredentialIssuer.Expiry.App/ExpiryCheckService.cs @@ -80,6 +80,7 @@ public async Task ExecuteAsync(CancellationToken stoppingToken) var now = dateTimeProvider.OffsetNow; var companySsiDetailsRepository = repositories.GetInstance(); + var processStepRepository = repositories.GetInstance(); var inactiveVcsToDelete = now.AddDays(-(_settings.InactiveVcsToDeleteInWeeks * 7)); var expiredVcsToDelete = now.AddMonths(-_settings.ExpiredVcsToDeleteInMonth); @@ -87,8 +88,7 @@ public async Task ExecuteAsync(CancellationToken stoppingToken) .GetExpiryData(now, inactiveVcsToDelete, expiredVcsToDelete); await foreach (var credential in credentials.WithCancellation(stoppingToken).ConfigureAwait(false)) { - await ProcessCredentials(credential, companySsiDetailsRepository, repositories, portalService, - stoppingToken).ConfigureAwait(false); + await ProcessCredentials(credential, companySsiDetailsRepository, repositories, portalService, processStepRepository, stoppingToken).ConfigureAwait(false); } } catch (Exception ex) @@ -104,6 +104,7 @@ private static async Task ProcessCredentials( ICompanySsiDetailsRepository companySsiDetailsRepository, IIssuerRepositories repositories, IPortalService portalService, + IProcessStepRepository processStepRepository, CancellationToken cancellationToken) { if (data.ScheduleData.IsVcToDelete) @@ -112,7 +113,7 @@ private static async Task ProcessCredentials( } else if (data.ScheduleData.IsVcToDecline) { - await HandleDecline(data, companySsiDetailsRepository, portalService, cancellationToken).ConfigureAwait(false); + HandleDecline(data.Id, companySsiDetailsRepository, processStepRepository); } else { @@ -123,34 +124,21 @@ private static async Task ProcessCredentials( await repositories.SaveAsync().ConfigureAwait(false); } - private static async ValueTask HandleDecline( - CredentialExpiryData data, + private static void HandleDecline( + Guid credentialId, ICompanySsiDetailsRepository companySsiDetailsRepository, - IPortalService portalService, - CancellationToken cancellationToken) + IProcessStepRepository processStepRepository) { - companySsiDetailsRepository.AttachAndModifyCompanySsiDetails(data.Id, c => + var processId = processStepRepository.CreateProcess(ProcessTypeId.DECLINE_CREDENTIAL).Id; + processStepRepository.CreateProcessStep(ProcessStepTypeId.REVOKE_CREDENTIAL, ProcessStepStatusId.TODO, processId); + companySsiDetailsRepository.AttachAndModifyCompanySsiDetails(credentialId, c => { - c.CompanySsiDetailStatusId = data.CompanySsiDetailStatusId; + c.ProcessId = null; }, c => { - c.CompanySsiDetailStatusId = CompanySsiDetailStatusId.INACTIVE; + c.ProcessId = processId; }); - - if (Guid.TryParse(data.RequesterId, out var requesterId)) - { - var content = JsonSerializer.Serialize(new { Type = data.VerifiedCredentialTypeId, CredentialId = data.Id }, Options); - await portalService.AddNotification(content, requesterId, NotificationTypeId.CREDENTIAL_REJECTED, cancellationToken).ConfigureAwait(false); - - var typeValue = data.VerifiedCredentialTypeId.GetEnumValue() ?? throw new UnexpectedConditionException($"VerifiedCredentialType {data.VerifiedCredentialTypeId} does not exists"); - var mailParameters = new Dictionary - { - { "requestName", typeValue }, - { "reason", "The credential is already expired" } - }; - await portalService.TriggerMail("CredentialRejected", requesterId, mailParameters, cancellationToken).ConfigureAwait(false); - } } private static async ValueTask HandleNotification( @@ -189,15 +177,17 @@ private static async ValueTask HandleNotification( if (Guid.TryParse(data.RequesterId, out var requesterId)) { - await portalService.AddNotification(content, requesterId, NotificationTypeId.CREDENTIAL_EXPIRY, cancellationToken).ConfigureAwait(false); - var typeValue = data.VerifiedCredentialTypeId.GetEnumValue() ?? throw new UnexpectedConditionException($"VerifiedCredentialType {data.VerifiedCredentialTypeId} does not exists"); - var mailParameters = new Dictionary + await portalService.AddNotification(content, requesterId, NotificationTypeId.CREDENTIAL_EXPIRY, + cancellationToken).ConfigureAwait(false); + var typeValue = data.VerifiedCredentialTypeId.GetEnumValue() ?? + throw new UnexpectedConditionException( + $"VerifiedCredentialType {data.VerifiedCredentialTypeId} does not exists"); + var mailParameters = new MailParameter[] { - { "typeId", typeValue }, - { "version", data.DetailVersion ?? "no version" }, - { "expiryDate", data.ExpiryDate?.ToString("dd MMMM yyyy") ?? throw new ConflictException("Expiry Date must be set here") } + new("typeId", typeValue), new("version", data.DetailVersion ?? "no version"), + new("expiryDate", + data.ExpiryDate?.ToString("dd MMMM yyyy") ?? throw new ConflictException("Expiry Date must be set here")) }; - await portalService.TriggerMail("CredentialExpiry", requesterId, mailParameters, cancellationToken).ConfigureAwait(false); } } diff --git a/src/database/SsiCredentialIssuer.DbAccess/Models/SsiApprovalData.cs b/src/database/SsiCredentialIssuer.DbAccess/Models/SsiApprovalData.cs index 2180ec38..0daf4b1a 100644 --- a/src/database/SsiCredentialIssuer.DbAccess/Models/SsiApprovalData.cs +++ b/src/database/SsiCredentialIssuer.DbAccess/Models/SsiApprovalData.cs @@ -18,6 +18,7 @@ ********************************************************************************/ using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; +using System.Text.Json; namespace Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Models; @@ -27,6 +28,7 @@ public record SsiApprovalData( Guid? ProcessId, VerifiedCredentialTypeKindId? Kind, string? Bpn, + JsonDocument? Schema, DetailData? DetailData ); diff --git a/src/database/SsiCredentialIssuer.DbAccess/Repositories/CompanySsiDetailsRepository.cs b/src/database/SsiCredentialIssuer.DbAccess/Repositories/CompanySsiDetailsRepository.cs index baf127a3..93633a60 100644 --- a/src/database/SsiCredentialIssuer.DbAccess/Repositories/CompanySsiDetailsRepository.cs +++ b/src/database/SsiCredentialIssuer.DbAccess/Repositories/CompanySsiDetailsRepository.cs @@ -144,16 +144,16 @@ public Task CheckSsiDetailsExistsForCompany(string bpnl, VerifiedCredentia (verifiedCredentialExternalTypeUseCaseDetailId == null || x.VerifiedCredentialExternalTypeDetailVersionId == verifiedCredentialExternalTypeUseCaseDetailId)); /// - public Task<(bool Exists, string? Version, string? Template, IEnumerable UseCase, DateTimeOffset Expiry)> CheckCredentialTypeIdExistsForExternalTypeDetailVersionId(Guid verifiedCredentialExternalTypeUseCaseDetailId, VerifiedCredentialTypeId verifiedCredentialTypeId) => + public Task<(bool Exists, string? Version, string? Template, IEnumerable ExternalTypeIds, DateTimeOffset Expiry)> CheckCredentialTypeIdExistsForExternalTypeDetailVersionId(Guid verifiedCredentialExternalTypeUseCaseDetailId, VerifiedCredentialTypeId verifiedCredentialTypeId) => _context.VerifiedCredentialExternalTypeDetailVersions .Where(x => x.Id == verifiedCredentialExternalTypeUseCaseDetailId && x.VerifiedCredentialExternalType!.VerifiedCredentialTypeAssignedExternalTypes.Any(y => y.VerifiedCredentialTypeId == verifiedCredentialTypeId)) - .Select(x => new ValueTuple, DateTimeOffset>( + .Select(x => new ValueTuple, DateTimeOffset>( true, x.Version, x.Template, - x.VerifiedCredentialExternalType!.VerifiedCredentialTypeAssignedExternalTypes.Select(y => y.VerifiedCredentialType!.VerifiedCredentialTypeAssignedUseCase!.UseCase!.Shortname), + x.VerifiedCredentialExternalType!.VerifiedCredentialTypeAssignedExternalTypes.Select(y => y.VerifiedCredentialExternalTypeId), x.Expiry)) .SingleOrDefaultAsync(); @@ -188,6 +188,7 @@ public IQueryable GetAllCredentialDetails(CompanySsiDetailStat x.ProcessId, x.VerifiedCredentialType!.VerifiedCredentialTypeAssignedKind == null ? null : x.VerifiedCredentialType!.VerifiedCredentialTypeAssignedKind!.VerifiedCredentialTypeKindId, x.Bpnl, + x.CompanySsiProcessData!.Schema, x.VerifiedCredentialExternalTypeDetailVersion == null ? null : new DetailData( diff --git a/src/database/SsiCredentialIssuer.DbAccess/Repositories/CredentialRepository.cs b/src/database/SsiCredentialIssuer.DbAccess/Repositories/CredentialRepository.cs index 719103c5..7fca89d2 100644 --- a/src/database/SsiCredentialIssuer.DbAccess/Repositories/CredentialRepository.cs +++ b/src/database/SsiCredentialIssuer.DbAccess/Repositories/CredentialRepository.cs @@ -20,6 +20,7 @@ using Microsoft.EntityFrameworkCore; using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Models; using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities; using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; using System.Text.Json; @@ -76,4 +77,39 @@ public CredentialRepository(IssuerDbContext dbContext) .Where(x => x.CompanySsiDetailId == credentialId) .Select(x => new ValueTuple(x.CompanySsiDetail!.Bpnl, x.CallbackUrl)) .SingleOrDefaultAsync(); + + public Task<(bool Exists, bool IsSameBpnl, Guid? ExternalCredentialId, CompanySsiDetailStatusId StatusId, IEnumerable<(Guid DocumentId, DocumentStatusId DocumentStatusId)> Documents)> GetRevocationDataById(Guid credentialId, string bpnl) => + _dbContext.CompanySsiDetails + .Where(x => + x.Id == credentialId) + .Select(x => new ValueTuple>( + true, + x.Bpnl == bpnl, + x.ExternalCredentialId, + x.CompanySsiDetailStatusId, + x.Documents.Select(d => new ValueTuple(d.Id, d.DocumentStatusId)))) + .SingleOrDefaultAsync(); + + public void AttachAndModifyCredential(Guid credentialId, Action? initialize, Action modify) + { + var entity = new CompanySsiDetail(credentialId, string.Empty, default!, default!, null!, null!, default!); + initialize?.Invoke(entity); + _dbContext.CompanySsiDetails.Attach(entity); + modify(entity); + } + + public Task<(VerifiedCredentialTypeId TypeId, string RequesterId)> GetCredentialNotificationData(Guid credentialId) => + _dbContext.CompanySsiDetails + .Where(x => x.Id == credentialId) + .Select(x => new ValueTuple(x.VerifiedCredentialTypeId, x.CreatorUserId)) + .SingleOrDefaultAsync(); + + public Task<(bool Exists, bool IsSameCompany, IEnumerable<(DocumentStatusId StatusId, byte[] Content)> Documents)> GetSignedCredentialForCredentialId(Guid credentialId, string bpnl) => + _dbContext.CompanySsiDetails + .Where(x => x.Id == credentialId) + .Select(x => new ValueTuple>>( + true, + x.Bpnl == bpnl, + x.Documents.Where(d => d.DocumentTypeId == DocumentTypeId.VERIFIED_CREDENTIAL).Select(d => new ValueTuple(d.DocumentStatusId, d.DocumentContent)))) + .SingleOrDefaultAsync(); } diff --git a/src/database/SsiCredentialIssuer.DbAccess/Repositories/DocumentRepository.cs b/src/database/SsiCredentialIssuer.DbAccess/Repositories/DocumentRepository.cs index b6bf1b6d..95a94f74 100644 --- a/src/database/SsiCredentialIssuer.DbAccess/Repositories/DocumentRepository.cs +++ b/src/database/SsiCredentialIssuer.DbAccess/Repositories/DocumentRepository.cs @@ -34,7 +34,7 @@ public class DocumentRepository : IDocumentRepository /// PortalDb context. public DocumentRepository(IssuerDbContext dbContext) { - this._dbContext = dbContext; + _dbContext = dbContext; } /// @@ -60,4 +60,17 @@ public void AssignDocumentToCompanySsiDetails(Guid documentId, Guid companySsiDe var document = new CompanySsiDetailAssignedDocument(documentId, companySsiDetailId); _dbContext.CompanySsiDetailAssignedDocuments.Add(document); } + + public void AttachAndModifyDocuments(IEnumerable<(Guid DocumentId, Action? Initialize, Action Modify)> documentData) + { + var initial = documentData.Select(x => + { + var document = new Document(x.DocumentId, null!, null!, null!, default, default, default, default); + x.Initialize?.Invoke(document); + return (Document: document, x.Modify); + } + ).ToList(); + _dbContext.AttachRange(initial.Select(x => x.Document)); + initial.ForEach(x => x.Modify(x.Document)); + } } diff --git a/src/database/SsiCredentialIssuer.DbAccess/Repositories/ICompanySsiDetailsRepository.cs b/src/database/SsiCredentialIssuer.DbAccess/Repositories/ICompanySsiDetailsRepository.cs index 38135954..18ec666c 100644 --- a/src/database/SsiCredentialIssuer.DbAccess/Repositories/ICompanySsiDetailsRepository.cs +++ b/src/database/SsiCredentialIssuer.DbAccess/Repositories/ICompanySsiDetailsRepository.cs @@ -70,7 +70,7 @@ public interface ICompanySsiDetailsRepository /// Id of vc external type use case detail id /// Id of the vc type /// Returns a valueTuple with identifiers if the externalTypeUseCaseDetailId exists and the corresponding credentialTypeId - Task<(bool Exists, string? Version, string? Template, IEnumerable UseCase, DateTimeOffset Expiry)> CheckCredentialTypeIdExistsForExternalTypeDetailVersionId(Guid verifiedCredentialExternalTypeUseCaseDetailId, VerifiedCredentialTypeId verifiedCredentialTypeId); + Task<(bool Exists, string? Version, string? Template, IEnumerable ExternalTypeIds, DateTimeOffset Expiry)> CheckCredentialTypeIdExistsForExternalTypeDetailVersionId(Guid verifiedCredentialExternalTypeUseCaseDetailId, VerifiedCredentialTypeId verifiedCredentialTypeId); /// /// Checks whether the given credentialTypeId is a Certificate diff --git a/src/database/SsiCredentialIssuer.DbAccess/Repositories/ICredentialRepository.cs b/src/database/SsiCredentialIssuer.DbAccess/Repositories/ICredentialRepository.cs index 3902ad2e..b1c0236e 100644 --- a/src/database/SsiCredentialIssuer.DbAccess/Repositories/ICredentialRepository.cs +++ b/src/database/SsiCredentialIssuer.DbAccess/Repositories/ICredentialRepository.cs @@ -18,6 +18,7 @@ ********************************************************************************/ using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Models; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities; using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; using System.Text.Json; @@ -31,4 +32,8 @@ public interface ICredentialRepository Task<(VerifiedCredentialTypeKindId CredentialTypeKindId, JsonDocument Schema)> GetCredentialStorageInformationById(Guid credentialId); Task<(Guid? ExternalCredentialId, VerifiedCredentialTypeKindId KindId, bool HasEncryptionInformation, string? CallbackUrl)> GetExternalCredentialAndKindId(Guid credentialId); Task<(string Bpn, string? CallbackUrl)> GetCallbackUrl(Guid credentialId); + Task<(bool Exists, bool IsSameBpnl, Guid? ExternalCredentialId, CompanySsiDetailStatusId StatusId, IEnumerable<(Guid DocumentId, DocumentStatusId DocumentStatusId)> Documents)> GetRevocationDataById(Guid credentialId, string bpnl); + void AttachAndModifyCredential(Guid credentialId, Action? initialize, Action modify); + Task<(VerifiedCredentialTypeId TypeId, string RequesterId)> GetCredentialNotificationData(Guid credentialId); + Task<(bool Exists, bool IsSameCompany, IEnumerable<(DocumentStatusId StatusId, byte[] Content)> Documents)> GetSignedCredentialForCredentialId(Guid credentialId, string bpnl); } diff --git a/src/database/SsiCredentialIssuer.DbAccess/Repositories/IDocumentRepository.cs b/src/database/SsiCredentialIssuer.DbAccess/Repositories/IDocumentRepository.cs index 5b5c105b..e447f0de 100644 --- a/src/database/SsiCredentialIssuer.DbAccess/Repositories/IDocumentRepository.cs +++ b/src/database/SsiCredentialIssuer.DbAccess/Repositories/IDocumentRepository.cs @@ -40,4 +40,5 @@ public interface IDocumentRepository Document CreateDocument(string documentName, byte[] documentContent, byte[] hash, MediaTypeId mediaTypeId, DocumentTypeId documentTypeId, Action? setupOptionalFields); void AssignDocumentToCompanySsiDetails(Guid documentId, Guid companySsiDetailId); + void AttachAndModifyDocuments(IEnumerable<(Guid DocumentId, Action? Initialize, Action Modify)> documentData); } diff --git a/src/database/SsiCredentialIssuer.Entities/Entities/ProcessStepStatus.cs b/src/database/SsiCredentialIssuer.Entities/Entities/ProcessStepStatus.cs index a62480b7..d8bf8ac7 100644 --- a/src/database/SsiCredentialIssuer.Entities/Entities/ProcessStepStatus.cs +++ b/src/database/SsiCredentialIssuer.Entities/Entities/ProcessStepStatus.cs @@ -26,8 +26,8 @@ public class ProcessStepStatus { private ProcessStepStatus() { - this.Label = null!; - this.ProcessSteps = new HashSet(); + Label = null!; + ProcessSteps = new HashSet(); } public ProcessStepStatus(ProcessStepStatusId processStepStatusId) : this() diff --git a/src/database/SsiCredentialIssuer.Entities/Entities/ProcessStepType.cs b/src/database/SsiCredentialIssuer.Entities/Entities/ProcessStepType.cs index d175f667..dfc72b4d 100644 --- a/src/database/SsiCredentialIssuer.Entities/Entities/ProcessStepType.cs +++ b/src/database/SsiCredentialIssuer.Entities/Entities/ProcessStepType.cs @@ -26,8 +26,8 @@ public class ProcessStepType { private ProcessStepType() { - this.Label = null!; - this.ProcessSteps = new HashSet(); + Label = null!; + ProcessSteps = new HashSet(); } public ProcessStepType(ProcessStepTypeId processStepTypeId) : this() diff --git a/src/database/SsiCredentialIssuer.Entities/Entities/ProcessType.cs b/src/database/SsiCredentialIssuer.Entities/Entities/ProcessType.cs index 87c8860a..387bde4e 100644 --- a/src/database/SsiCredentialIssuer.Entities/Entities/ProcessType.cs +++ b/src/database/SsiCredentialIssuer.Entities/Entities/ProcessType.cs @@ -26,8 +26,8 @@ public class ProcessType { private ProcessType() { - this.Label = null!; - this.Processes = new HashSet(); + Label = null!; + Processes = new HashSet(); } public ProcessType(ProcessTypeId processTypeId) : this() diff --git a/src/database/SsiCredentialIssuer.Entities/Enums/ProcessStepTypeId.cs b/src/database/SsiCredentialIssuer.Entities/Enums/ProcessStepTypeId.cs index a44fed17..e870cf07 100644 --- a/src/database/SsiCredentialIssuer.Entities/Enums/ProcessStepTypeId.cs +++ b/src/database/SsiCredentialIssuer.Entities/Enums/ProcessStepTypeId.cs @@ -21,10 +21,15 @@ namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; public enum ProcessStepTypeId { - // Issuer Process + // CREATE CREDENTIAL PROCESS CREATE_CREDENTIAL = 1, SIGN_CREDENTIAL = 2, SAVE_CREDENTIAL_DOCUMENT = 3, CREATE_CREDENTIAL_FOR_HOLDER = 4, TRIGGER_CALLBACK = 5, + + // DECLINE PROCESS + REVOKE_CREDENTIAL = 100, + TRIGGER_NOTIFICATION = 101, + TRIGGER_MAIL = 102 } diff --git a/src/database/SsiCredentialIssuer.Entities/Enums/ProcessTypeId.cs b/src/database/SsiCredentialIssuer.Entities/Enums/ProcessTypeId.cs index a07c1bca..faedae91 100644 --- a/src/database/SsiCredentialIssuer.Entities/Enums/ProcessTypeId.cs +++ b/src/database/SsiCredentialIssuer.Entities/Enums/ProcessTypeId.cs @@ -22,4 +22,5 @@ namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; public enum ProcessTypeId { CREATE_CREDENTIAL = 1, + DECLINE_CREDENTIAL = 2 } diff --git a/src/database/SsiCredentialIssuer.Entities/Enums/VerifiedCredentialExternalTypeId.cs b/src/database/SsiCredentialIssuer.Entities/Enums/VerifiedCredentialExternalTypeId.cs index fbb6178c..a0e5fb13 100644 --- a/src/database/SsiCredentialIssuer.Entities/Enums/VerifiedCredentialExternalTypeId.cs +++ b/src/database/SsiCredentialIssuer.Entities/Enums/VerifiedCredentialExternalTypeId.cs @@ -35,12 +35,21 @@ public enum VerifiedCredentialExternalTypeId [EnumMember(Value = "vehicleDismantle")] VEHICLE_DISMANTLE = 4, - [EnumMember(Value = "SustainabilityCredential")] - SUSTAINABILITY_CREDENTIAL = 5, + [EnumMember(Value = "CircularEconomyCredential")] + CIRCULAR_ECONOMY = 5, [EnumMember(Value = "QualityCredential")] QUALITY_CREDENTIAL = 6, [EnumMember(Value = "BusinessPartnerCredential")] - BUSINESS_PARTNER_NUMBER = 7 + BUSINESS_PARTNER_NUMBER = 7, + + [EnumMember(Value = "DemandCapacityCredential")] + DEMAND_AND_CAPACITY_MANAGEMENT = 8, + + [EnumMember(Value = "DemandCapacityCredential")] + DEMAND_AND_CAPACITY_MANAGEMENT_PURIS = 9, + + [EnumMember(Value = "BusinessPartnerCredential")] + BUSINESS_PARTNER_DATA_MANAGEMENT = 10 } diff --git a/src/database/SsiCredentialIssuer.Entities/Enums/VerifiedCredentialTypeId.cs b/src/database/SsiCredentialIssuer.Entities/Enums/VerifiedCredentialTypeId.cs index 725f9d22..46d94ab7 100644 --- a/src/database/SsiCredentialIssuer.Entities/Enums/VerifiedCredentialTypeId.cs +++ b/src/database/SsiCredentialIssuer.Entities/Enums/VerifiedCredentialTypeId.cs @@ -35,12 +35,21 @@ public enum VerifiedCredentialTypeId [EnumMember(Value = "Dismantler Certificate")] DISMANTLER_CERTIFICATE = 4, - [EnumMember(Value = "Sustainability Framework")] - SUSTAINABILITY_FRAMEWORK = 5, + [EnumMember(Value = "Circular Economy")] + CIRCULAR_ECONOMY = 5, [EnumMember(Value = "frameworkAgreement.quality")] FRAMEWORK_AGREEMENT_QUALITY = 6, [EnumMember(Value = "BusinessPartnerCredential")] - BUSINESS_PARTNER_NUMBER = 7 + BUSINESS_PARTNER_NUMBER = 7, + + [EnumMember(Value = "Demand and Capacity Management")] + DEMAND_AND_CAPACITY_MANAGEMENT = 8, + + [EnumMember(Value = "Demand and Capacity Management")] + DEMAND_AND_CAPACITY_MANAGEMENT_PURIS = 9, + + [EnumMember(Value = "Business Partner Data Management")] + BUSINESS_PARTNER_DATA_MANAGEMENT = 10 } diff --git a/src/database/SsiCredentialIssuer.Migrations/Migrations/20240424121211_1.0.0-rc.3.Designer.cs b/src/database/SsiCredentialIssuer.Migrations/Migrations/20240424121211_1.0.0-rc.3.Designer.cs new file mode 100644 index 00000000..9711c734 --- /dev/null +++ b/src/database/SsiCredentialIssuer.Migrations/Migrations/20240424121211_1.0.0-rc.3.Designer.cs @@ -0,0 +1,1637 @@ +/******************************************************************************** + * Copyright (c) 2024 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 Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities; +using System.Text.Json; + +#nullable disable + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Migrations.Migrations +{ + [DbContext(typeof(IssuerDbContext))] + [Migration("20240424121211_1.0.0-rc.3")] + partial class _100rc3 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasDefaultSchema("issuer") + .UseCollation("en_US.utf8") + .HasAnnotation("ProductVersion", "7.0.13") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.AuditEntities.AuditCompanySsiDetail20240228", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("Bpnl") + .IsRequired() + .HasColumnType("text") + .HasColumnName("bpnl"); + + b.Property("CompanySsiDetailStatusId") + .HasColumnType("integer") + .HasColumnName("company_ssi_detail_status_id"); + + b.Property("CreatorUserId") + .HasColumnType("uuid") + .HasColumnName("creator_user_id"); + + b.Property("Credential") + .HasColumnType("text") + .HasColumnName("credential"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("ExpiryCheckTypeId") + .HasColumnType("integer") + .HasColumnName("expiry_check_type_id"); + + b.Property("ExpiryDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiry_date"); + + b.Property("ExternalCredentialId") + .HasColumnType("uuid") + .HasColumnName("external_credential_id"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("IssuerBpn") + .IsRequired() + .HasColumnType("text") + .HasColumnName("issuer_bpn"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("ProcessId") + .HasColumnType("uuid") + .HasColumnName("process_id"); + + b.Property("VerifiedCredentialExternalTypeDetailVersionId") + .HasColumnType("uuid") + .HasColumnName("verified_credential_external_type_detail_version_id"); + + b.Property("VerifiedCredentialTypeId") + .HasColumnType("integer") + .HasColumnName("verified_credential_type_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_company_ssi_detail20240228"); + + b.ToTable("audit_company_ssi_detail20240228", "issuer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.AuditEntities.AuditCompanySsiDetail20240419", b => + { + b.Property("AuditV2Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v2id"); + + b.Property("AuditV2DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v2date_last_changed"); + + b.Property("AuditV2LastEditorId") + .HasColumnType("text") + .HasColumnName("audit_v2last_editor_id"); + + b.Property("AuditV2OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v2operation_id"); + + b.Property("Bpnl") + .IsRequired() + .HasColumnType("text") + .HasColumnName("bpnl"); + + b.Property("CompanySsiDetailStatusId") + .HasColumnType("integer") + .HasColumnName("company_ssi_detail_status_id"); + + b.Property("CreatorUserId") + .IsRequired() + .HasColumnType("text") + .HasColumnName("creator_user_id"); + + b.Property("Credential") + .HasColumnType("text") + .HasColumnName("credential"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("ExpiryCheckTypeId") + .HasColumnType("integer") + .HasColumnName("expiry_check_type_id"); + + b.Property("ExpiryDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiry_date"); + + b.Property("ExternalCredentialId") + .HasColumnType("uuid") + .HasColumnName("external_credential_id"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("IssuerBpn") + .IsRequired() + .HasColumnType("text") + .HasColumnName("issuer_bpn"); + + b.Property("LastEditorId") + .HasColumnType("text") + .HasColumnName("last_editor_id"); + + b.Property("ProcessId") + .HasColumnType("uuid") + .HasColumnName("process_id"); + + b.Property("VerifiedCredentialExternalTypeDetailVersionId") + .HasColumnType("uuid") + .HasColumnName("verified_credential_external_type_detail_version_id"); + + b.Property("VerifiedCredentialTypeId") + .HasColumnType("integer") + .HasColumnName("verified_credential_type_id"); + + b.HasKey("AuditV2Id") + .HasName("pk_audit_company_ssi_detail20240419"); + + b.ToTable("audit_company_ssi_detail20240419", "issuer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.AuditEntities.AuditDocument20240305", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyUserId") + .HasColumnType("uuid") + .HasColumnName("company_user_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("DocumentContent") + .HasColumnType("bytea") + .HasColumnName("document_content"); + + b.Property("DocumentHash") + .HasColumnType("bytea") + .HasColumnName("document_hash"); + + b.Property("DocumentName") + .HasColumnType("text") + .HasColumnName("document_name"); + + b.Property("DocumentStatusId") + .HasColumnType("integer") + .HasColumnName("document_status_id"); + + b.Property("DocumentTypeId") + .HasColumnType("integer") + .HasColumnName("document_type_id"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("MediaTypeId") + .HasColumnType("integer") + .HasColumnName("media_type_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_document20240305"); + + b.ToTable("audit_document20240305", "issuer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.AuditEntities.AuditDocument20240419", b => + { + b.Property("AuditV2Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v2id"); + + b.Property("AuditV2DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v2date_last_changed"); + + b.Property("AuditV2LastEditorId") + .HasColumnType("text") + .HasColumnName("audit_v2last_editor_id"); + + b.Property("AuditV2OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v2operation_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("DocumentContent") + .HasColumnType("bytea") + .HasColumnName("document_content"); + + b.Property("DocumentHash") + .HasColumnType("bytea") + .HasColumnName("document_hash"); + + b.Property("DocumentName") + .HasColumnType("text") + .HasColumnName("document_name"); + + b.Property("DocumentStatusId") + .HasColumnType("integer") + .HasColumnName("document_status_id"); + + b.Property("DocumentTypeId") + .HasColumnType("integer") + .HasColumnName("document_type_id"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("IdentityId") + .HasColumnType("text") + .HasColumnName("identity_id"); + + b.Property("LastEditorId") + .HasColumnType("text") + .HasColumnName("last_editor_id"); + + b.Property("MediaTypeId") + .HasColumnType("integer") + .HasColumnName("media_type_id"); + + b.HasKey("AuditV2Id") + .HasName("pk_audit_document20240419"); + + b.ToTable("audit_document20240419", "issuer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.CompanySsiDetail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Bpnl") + .IsRequired() + .HasColumnType("text") + .HasColumnName("bpnl"); + + b.Property("CompanySsiDetailStatusId") + .HasColumnType("integer") + .HasColumnName("company_ssi_detail_status_id"); + + b.Property("CreatorUserId") + .IsRequired() + .HasColumnType("text") + .HasColumnName("creator_user_id"); + + b.Property("Credential") + .HasColumnType("text") + .HasColumnName("credential"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("ExpiryCheckTypeId") + .HasColumnType("integer") + .HasColumnName("expiry_check_type_id"); + + b.Property("ExpiryDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiry_date"); + + b.Property("ExternalCredentialId") + .HasColumnType("uuid") + .HasColumnName("external_credential_id"); + + b.Property("IssuerBpn") + .IsRequired() + .HasColumnType("text") + .HasColumnName("issuer_bpn"); + + b.Property("LastEditorId") + .HasColumnType("text") + .HasColumnName("last_editor_id"); + + b.Property("ProcessId") + .HasColumnType("uuid") + .HasColumnName("process_id"); + + b.Property("VerifiedCredentialExternalTypeDetailVersionId") + .HasColumnType("uuid") + .HasColumnName("verified_credential_external_type_detail_version_id"); + + b.Property("VerifiedCredentialTypeId") + .HasColumnType("integer") + .HasColumnName("verified_credential_type_id"); + + b.HasKey("Id") + .HasName("pk_company_ssi_details"); + + b.HasIndex("CompanySsiDetailStatusId") + .HasDatabaseName("ix_company_ssi_details_company_ssi_detail_status_id"); + + b.HasIndex("ExpiryCheckTypeId") + .HasDatabaseName("ix_company_ssi_details_expiry_check_type_id"); + + b.HasIndex("ProcessId") + .HasDatabaseName("ix_company_ssi_details_process_id"); + + b.HasIndex("VerifiedCredentialExternalTypeDetailVersionId") + .HasDatabaseName("ix_company_ssi_details_verified_credential_external_type_detai"); + + b.HasIndex("VerifiedCredentialTypeId") + .HasDatabaseName("ix_company_ssi_details_verified_credential_type_id"); + + b.ToTable("company_ssi_details", "issuer", t => + { + t.HasTrigger("LC_TRIGGER_AFTER_INSERT_COMPANYSSIDETAIL"); + + t.HasTrigger("LC_TRIGGER_AFTER_UPDATE_COMPANYSSIDETAIL"); + }); + + b + .HasAnnotation("LC_TRIGGER_AFTER_INSERT_COMPANYSSIDETAIL", "CREATE FUNCTION \"issuer\".\"LC_TRIGGER_AFTER_INSERT_COMPANYSSIDETAIL\"() RETURNS trigger as $LC_TRIGGER_AFTER_INSERT_COMPANYSSIDETAIL$\r\nBEGIN\r\n INSERT INTO \"issuer\".\"audit_company_ssi_detail20240419\" (\"id\", \"bpnl\", \"issuer_bpn\", \"verified_credential_type_id\", \"company_ssi_detail_status_id\", \"date_created\", \"creator_user_id\", \"expiry_date\", \"verified_credential_external_type_detail_version_id\", \"expiry_check_type_id\", \"process_id\", \"external_credential_id\", \"credential\", \"date_last_changed\", \"last_editor_id\", \"audit_v2id\", \"audit_v2operation_id\", \"audit_v2date_last_changed\", \"audit_v2last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"bpnl\", \r\n NEW.\"issuer_bpn\", \r\n NEW.\"verified_credential_type_id\", \r\n NEW.\"company_ssi_detail_status_id\", \r\n NEW.\"date_created\", \r\n NEW.\"creator_user_id\", \r\n NEW.\"expiry_date\", \r\n NEW.\"verified_credential_external_type_detail_version_id\", \r\n NEW.\"expiry_check_type_id\", \r\n NEW.\"process_id\", \r\n NEW.\"external_credential_id\", \r\n NEW.\"credential\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 1, \r\n CURRENT_DATE, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_INSERT_COMPANYSSIDETAIL$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_INSERT_COMPANYSSIDETAIL AFTER INSERT\r\nON \"issuer\".\"company_ssi_details\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"issuer\".\"LC_TRIGGER_AFTER_INSERT_COMPANYSSIDETAIL\"();") + .HasAnnotation("LC_TRIGGER_AFTER_UPDATE_COMPANYSSIDETAIL", "CREATE FUNCTION \"issuer\".\"LC_TRIGGER_AFTER_UPDATE_COMPANYSSIDETAIL\"() RETURNS trigger as $LC_TRIGGER_AFTER_UPDATE_COMPANYSSIDETAIL$\r\nBEGIN\r\n INSERT INTO \"issuer\".\"audit_company_ssi_detail20240419\" (\"id\", \"bpnl\", \"issuer_bpn\", \"verified_credential_type_id\", \"company_ssi_detail_status_id\", \"date_created\", \"creator_user_id\", \"expiry_date\", \"verified_credential_external_type_detail_version_id\", \"expiry_check_type_id\", \"process_id\", \"external_credential_id\", \"credential\", \"date_last_changed\", \"last_editor_id\", \"audit_v2id\", \"audit_v2operation_id\", \"audit_v2date_last_changed\", \"audit_v2last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"bpnl\", \r\n NEW.\"issuer_bpn\", \r\n NEW.\"verified_credential_type_id\", \r\n NEW.\"company_ssi_detail_status_id\", \r\n NEW.\"date_created\", \r\n NEW.\"creator_user_id\", \r\n NEW.\"expiry_date\", \r\n NEW.\"verified_credential_external_type_detail_version_id\", \r\n NEW.\"expiry_check_type_id\", \r\n NEW.\"process_id\", \r\n NEW.\"external_credential_id\", \r\n NEW.\"credential\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 2, \r\n CURRENT_DATE, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_UPDATE_COMPANYSSIDETAIL$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_UPDATE_COMPANYSSIDETAIL AFTER UPDATE\r\nON \"issuer\".\"company_ssi_details\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"issuer\".\"LC_TRIGGER_AFTER_UPDATE_COMPANYSSIDETAIL\"();"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.CompanySsiDetailAssignedDocument", b => + { + b.Property("DocumentId") + .HasColumnType("uuid") + .HasColumnName("document_id"); + + b.Property("CompanySsiDetailId") + .HasColumnType("uuid") + .HasColumnName("company_ssi_detail_id"); + + b.HasKey("DocumentId", "CompanySsiDetailId") + .HasName("pk_company_ssi_detail_assigned_documents"); + + b.HasIndex("CompanySsiDetailId") + .HasDatabaseName("ix_company_ssi_detail_assigned_documents_company_ssi_detail_id"); + + b.ToTable("company_ssi_detail_assigned_documents", "issuer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.CompanySsiDetailStatus", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_company_ssi_detail_statuses"); + + b.ToTable("company_ssi_detail_statuses", "issuer"); + + b.HasData( + new + { + Id = 1, + Label = "PENDING" + }, + new + { + Id = 2, + Label = "ACTIVE" + }, + new + { + Id = 3, + Label = "REVOKED" + }, + new + { + Id = 4, + Label = "INACTIVE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.CompanySsiProcessData", b => + { + b.Property("CompanySsiDetailId") + .HasColumnType("uuid") + .HasColumnName("company_ssi_detail_id"); + + b.Property("CallbackUrl") + .HasColumnType("text") + .HasColumnName("callback_url"); + + b.Property("ClientId") + .HasColumnType("text") + .HasColumnName("client_id"); + + b.Property("ClientSecret") + .HasColumnType("bytea") + .HasColumnName("client_secret"); + + b.Property("CredentialTypeKindId") + .HasColumnType("integer") + .HasColumnName("credential_type_kind_id"); + + b.Property("EncryptionMode") + .HasColumnType("integer") + .HasColumnName("encryption_mode"); + + b.Property("HolderWalletUrl") + .HasColumnType("text") + .HasColumnName("holder_wallet_url"); + + b.Property("InitializationVector") + .HasColumnType("bytea") + .HasColumnName("initialization_vector"); + + b.Property("Schema") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("schema"); + + b.HasKey("CompanySsiDetailId") + .HasName("pk_company_ssi_process_data"); + + b.HasIndex("CredentialTypeKindId") + .HasDatabaseName("ix_company_ssi_process_data_credential_type_kind_id"); + + b.ToTable("company_ssi_process_data", "issuer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.Document", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("DocumentContent") + .IsRequired() + .HasColumnType("bytea") + .HasColumnName("document_content"); + + b.Property("DocumentHash") + .IsRequired() + .HasColumnType("bytea") + .HasColumnName("document_hash"); + + b.Property("DocumentName") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("document_name"); + + b.Property("DocumentStatusId") + .HasColumnType("integer") + .HasColumnName("document_status_id"); + + b.Property("DocumentTypeId") + .HasColumnType("integer") + .HasColumnName("document_type_id"); + + b.Property("IdentityId") + .HasColumnType("text") + .HasColumnName("identity_id"); + + b.Property("LastEditorId") + .HasColumnType("text") + .HasColumnName("last_editor_id"); + + b.Property("MediaTypeId") + .HasColumnType("integer") + .HasColumnName("media_type_id"); + + b.HasKey("Id") + .HasName("pk_documents"); + + b.HasIndex("DocumentStatusId") + .HasDatabaseName("ix_documents_document_status_id"); + + b.HasIndex("DocumentTypeId") + .HasDatabaseName("ix_documents_document_type_id"); + + b.HasIndex("MediaTypeId") + .HasDatabaseName("ix_documents_media_type_id"); + + b.ToTable("documents", "issuer", t => + { + t.HasTrigger("LC_TRIGGER_AFTER_INSERT_DOCUMENT"); + + t.HasTrigger("LC_TRIGGER_AFTER_UPDATE_DOCUMENT"); + }); + + b + .HasAnnotation("LC_TRIGGER_AFTER_INSERT_DOCUMENT", "CREATE FUNCTION \"issuer\".\"LC_TRIGGER_AFTER_INSERT_DOCUMENT\"() RETURNS trigger as $LC_TRIGGER_AFTER_INSERT_DOCUMENT$\r\nBEGIN\r\n INSERT INTO \"issuer\".\"audit_document20240419\" (\"id\", \"date_created\", \"document_hash\", \"document_content\", \"document_name\", \"media_type_id\", \"document_type_id\", \"document_status_id\", \"identity_id\", \"date_last_changed\", \"last_editor_id\", \"audit_v2id\", \"audit_v2operation_id\", \"audit_v2date_last_changed\", \"audit_v2last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"date_created\", \r\n NEW.\"document_hash\", \r\n NEW.\"document_content\", \r\n NEW.\"document_name\", \r\n NEW.\"media_type_id\", \r\n NEW.\"document_type_id\", \r\n NEW.\"document_status_id\", \r\n NEW.\"identity_id\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 1, \r\n CURRENT_DATE, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_INSERT_DOCUMENT$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_INSERT_DOCUMENT AFTER INSERT\r\nON \"issuer\".\"documents\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"issuer\".\"LC_TRIGGER_AFTER_INSERT_DOCUMENT\"();") + .HasAnnotation("LC_TRIGGER_AFTER_UPDATE_DOCUMENT", "CREATE FUNCTION \"issuer\".\"LC_TRIGGER_AFTER_UPDATE_DOCUMENT\"() RETURNS trigger as $LC_TRIGGER_AFTER_UPDATE_DOCUMENT$\r\nBEGIN\r\n INSERT INTO \"issuer\".\"audit_document20240419\" (\"id\", \"date_created\", \"document_hash\", \"document_content\", \"document_name\", \"media_type_id\", \"document_type_id\", \"document_status_id\", \"identity_id\", \"date_last_changed\", \"last_editor_id\", \"audit_v2id\", \"audit_v2operation_id\", \"audit_v2date_last_changed\", \"audit_v2last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"date_created\", \r\n NEW.\"document_hash\", \r\n NEW.\"document_content\", \r\n NEW.\"document_name\", \r\n NEW.\"media_type_id\", \r\n NEW.\"document_type_id\", \r\n NEW.\"document_status_id\", \r\n NEW.\"identity_id\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 2, \r\n CURRENT_DATE, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_UPDATE_DOCUMENT$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_UPDATE_DOCUMENT AFTER UPDATE\r\nON \"issuer\".\"documents\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"issuer\".\"LC_TRIGGER_AFTER_UPDATE_DOCUMENT\"();"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.DocumentStatus", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_document_status"); + + b.ToTable("document_status", "issuer"); + + b.HasData( + new + { + Id = 2, + Label = "ACTIVE" + }, + new + { + Id = 3, + Label = "INACTIVE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.DocumentType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_document_types"); + + b.ToTable("document_types", "issuer"); + + b.HasData( + new + { + Id = 1, + Label = "PRESENTATION" + }, + new + { + Id = 2, + Label = "CREDENTIAL" + }, + new + { + Id = 3, + Label = "VERIFIED_CREDENTIAL" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.ExpiryCheckType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_expiry_check_types"); + + b.ToTable("expiry_check_types", "issuer"); + + b.HasData( + new + { + Id = 1, + Label = "ONE_MONTH" + }, + new + { + Id = 2, + Label = "TWO_WEEKS" + }, + new + { + Id = 3, + Label = "ONE_DAY" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.MediaType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_media_types"); + + b.ToTable("media_types", "issuer"); + + b.HasData( + new + { + Id = 1, + Label = "JPEG" + }, + new + { + Id = 2, + Label = "GIF" + }, + new + { + Id = 3, + Label = "PNG" + }, + new + { + Id = 4, + Label = "SVG" + }, + new + { + Id = 5, + Label = "TIFF" + }, + new + { + Id = 6, + Label = "PDF" + }, + new + { + Id = 7, + Label = "JSON" + }, + new + { + Id = 8, + Label = "PEM" + }, + new + { + Id = 9, + Label = "CA_CERT" + }, + new + { + Id = 10, + Label = "PKX_CER" + }, + new + { + Id = 11, + Label = "OCTET" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.Process", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LockExpiryDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("lock_expiry_date"); + + b.Property("ProcessTypeId") + .HasColumnType("integer") + .HasColumnName("process_type_id"); + + b.Property("Version") + .IsConcurrencyToken() + .HasColumnType("uuid") + .HasColumnName("version"); + + b.HasKey("Id") + .HasName("pk_processes"); + + b.HasIndex("ProcessTypeId") + .HasDatabaseName("ix_processes_process_type_id"); + + b.ToTable("processes", "issuer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.ProcessStep", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("Message") + .HasColumnType("text") + .HasColumnName("message"); + + b.Property("ProcessId") + .HasColumnType("uuid") + .HasColumnName("process_id"); + + b.Property("ProcessStepStatusId") + .HasColumnType("integer") + .HasColumnName("process_step_status_id"); + + b.Property("ProcessStepTypeId") + .HasColumnType("integer") + .HasColumnName("process_step_type_id"); + + b.HasKey("Id") + .HasName("pk_process_steps"); + + b.HasIndex("ProcessId") + .HasDatabaseName("ix_process_steps_process_id"); + + b.HasIndex("ProcessStepStatusId") + .HasDatabaseName("ix_process_steps_process_step_status_id"); + + b.HasIndex("ProcessStepTypeId") + .HasDatabaseName("ix_process_steps_process_step_type_id"); + + b.ToTable("process_steps", "issuer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.ProcessStepStatus", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_process_step_statuses"); + + b.ToTable("process_step_statuses", "issuer"); + + b.HasData( + new + { + Id = 1, + Label = "TODO" + }, + new + { + Id = 2, + Label = "DONE" + }, + new + { + Id = 3, + Label = "SKIPPED" + }, + new + { + Id = 4, + Label = "FAILED" + }, + new + { + Id = 5, + Label = "DUPLICATE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.ProcessStepType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_process_step_types"); + + b.ToTable("process_step_types", "issuer"); + + b.HasData( + new + { + Id = 1, + Label = "CREATE_CREDENTIAL" + }, + new + { + Id = 2, + Label = "SIGN_CREDENTIAL" + }, + new + { + Id = 3, + Label = "SAVE_CREDENTIAL_DOCUMENT" + }, + new + { + Id = 4, + Label = "CREATE_CREDENTIAL_FOR_HOLDER" + }, + new + { + Id = 5, + Label = "TRIGGER_CALLBACK" + }, + new + { + Id = 100, + Label = "REVOKE_CREDENTIAL" + }, + new + { + Id = 101, + Label = "TRIGGER_NOTIFICATION" + }, + new + { + Id = 102, + Label = "TRIGGER_MAIL" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.ProcessType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_process_types"); + + b.ToTable("process_types", "issuer"); + + b.HasData( + new + { + Id = 1, + Label = "CREATE_CREDENTIAL" + }, + new + { + Id = 2, + Label = "DECLINE_CREDENTIAL" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.UseCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name"); + + b.Property("Shortname") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("shortname"); + + b.HasKey("Id") + .HasName("pk_use_cases"); + + b.ToTable("use_cases", "issuer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialExternalType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasColumnType("text") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_verified_credential_external_types"); + + b.ToTable("verified_credential_external_types", "issuer"); + + b.HasData( + new + { + Id = 1, + Label = "TRACEABILITY_CREDENTIAL" + }, + new + { + Id = 2, + Label = "PCF_CREDENTIAL" + }, + new + { + Id = 3, + Label = "BEHAVIOR_TWIN_CREDENTIAL" + }, + new + { + Id = 4, + Label = "VEHICLE_DISMANTLE" + }, + new + { + Id = 5, + Label = "CIRCULAR_ECONOMY" + }, + new + { + Id = 6, + Label = "QUALITY_CREDENTIAL" + }, + new + { + Id = 7, + Label = "BUSINESS_PARTNER_NUMBER" + }, + new + { + Id = 8, + Label = "DEMAND_AND_CAPACITY_MANAGEMENT" + }, + new + { + Id = 9, + Label = "DEMAND_AND_CAPACITY_MANAGEMENT_PURIS" + }, + new + { + Id = 10, + Label = "BUSINESS_PARTNER_DATA_MANAGEMENT" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialExternalTypeDetailVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Expiry") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiry"); + + b.Property("Template") + .HasColumnType("text") + .HasColumnName("template"); + + b.Property("ValidFrom") + .HasColumnType("timestamp with time zone") + .HasColumnName("valid_from"); + + b.Property("VerifiedCredentialExternalTypeId") + .HasColumnType("integer") + .HasColumnName("verified_credential_external_type_id"); + + b.Property("Version") + .HasColumnType("text") + .HasColumnName("version"); + + b.HasKey("Id") + .HasName("pk_verified_credential_external_type_detail_versions"); + + b.HasIndex("VerifiedCredentialExternalTypeId", "Version") + .IsUnique() + .HasDatabaseName("ix_verified_credential_external_type_detail_versions_verified_"); + + b.ToTable("verified_credential_external_type_detail_versions", "issuer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_verified_credential_types"); + + b.ToTable("verified_credential_types", "issuer"); + + b.HasData( + new + { + Id = 1, + Label = "TRACEABILITY_FRAMEWORK" + }, + new + { + Id = 2, + Label = "PCF_FRAMEWORK" + }, + new + { + Id = 3, + Label = "BEHAVIOR_TWIN_FRAMEWORK" + }, + new + { + Id = 4, + Label = "DISMANTLER_CERTIFICATE" + }, + new + { + Id = 5, + Label = "CIRCULAR_ECONOMY" + }, + new + { + Id = 6, + Label = "FRAMEWORK_AGREEMENT_QUALITY" + }, + new + { + Id = 7, + Label = "BUSINESS_PARTNER_NUMBER" + }, + new + { + Id = 8, + Label = "DEMAND_AND_CAPACITY_MANAGEMENT" + }, + new + { + Id = 9, + Label = "DEMAND_AND_CAPACITY_MANAGEMENT_PURIS" + }, + new + { + Id = 10, + Label = "BUSINESS_PARTNER_DATA_MANAGEMENT" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialTypeAssignedExternalType", b => + { + b.Property("VerifiedCredentialTypeId") + .HasColumnType("integer") + .HasColumnName("verified_credential_type_id"); + + b.Property("VerifiedCredentialExternalTypeId") + .HasColumnType("integer") + .HasColumnName("verified_credential_external_type_id"); + + b.HasKey("VerifiedCredentialTypeId", "VerifiedCredentialExternalTypeId") + .HasName("pk_verified_credential_type_assigned_external_types"); + + b.HasIndex("VerifiedCredentialExternalTypeId") + .HasDatabaseName("ix_verified_credential_type_assigned_external_types_verified_c"); + + b.HasIndex("VerifiedCredentialTypeId") + .IsUnique() + .HasDatabaseName("ix_verified_credential_type_assigned_external_types_verified_c1"); + + b.ToTable("verified_credential_type_assigned_external_types", "issuer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialTypeAssignedKind", b => + { + b.Property("VerifiedCredentialTypeId") + .HasColumnType("integer") + .HasColumnName("verified_credential_type_id"); + + b.Property("VerifiedCredentialTypeKindId") + .HasColumnType("integer") + .HasColumnName("verified_credential_type_kind_id"); + + b.HasKey("VerifiedCredentialTypeId", "VerifiedCredentialTypeKindId") + .HasName("pk_verified_credential_type_assigned_kinds"); + + b.HasIndex("VerifiedCredentialTypeId") + .HasDatabaseName("ix_verified_credential_type_assigned_kinds_verified_credential"); + + b.HasIndex("VerifiedCredentialTypeKindId") + .HasDatabaseName("ix_verified_credential_type_assigned_kinds_verified_credential1"); + + b.ToTable("verified_credential_type_assigned_kinds", "issuer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialTypeAssignedUseCase", b => + { + b.Property("VerifiedCredentialTypeId") + .HasColumnType("integer") + .HasColumnName("verified_credential_type_id"); + + b.Property("UseCaseId") + .HasColumnType("uuid") + .HasColumnName("use_case_id"); + + b.HasKey("VerifiedCredentialTypeId", "UseCaseId") + .HasName("pk_verified_credential_type_assigned_use_cases"); + + b.HasIndex("UseCaseId") + .IsUnique() + .HasDatabaseName("ix_verified_credential_type_assigned_use_cases_use_case_id"); + + b.HasIndex("VerifiedCredentialTypeId") + .IsUnique() + .HasDatabaseName("ix_verified_credential_type_assigned_use_cases_verified_creden"); + + b.ToTable("verified_credential_type_assigned_use_cases", "issuer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialTypeKind", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_verified_credential_type_kinds"); + + b.ToTable("verified_credential_type_kinds", "issuer"); + + b.HasData( + new + { + Id = 1, + Label = "FRAMEWORK" + }, + new + { + Id = 2, + Label = "MEMBERSHIP" + }, + new + { + Id = 3, + Label = "BPN" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.CompanySsiDetail", b => + { + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.CompanySsiDetailStatus", "CompanySsiDetailStatus") + .WithMany("CompanySsiDetails") + .HasForeignKey("CompanySsiDetailStatusId") + .IsRequired() + .HasConstraintName("fk_company_ssi_details_company_ssi_detail_statuses_company_ssi"); + + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.ExpiryCheckType", "ExpiryCheckType") + .WithMany("CompanySsiDetails") + .HasForeignKey("ExpiryCheckTypeId") + .HasConstraintName("fk_company_ssi_details_expiry_check_types_expiry_check_type_id"); + + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.Process", "Process") + .WithMany("CompanySsiDetails") + .HasForeignKey("ProcessId") + .HasConstraintName("fk_company_ssi_details_processes_process_id"); + + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialExternalTypeDetailVersion", "VerifiedCredentialExternalTypeDetailVersion") + .WithMany("CompanySsiDetails") + .HasForeignKey("VerifiedCredentialExternalTypeDetailVersionId") + .HasConstraintName("fk_company_ssi_details_verified_credential_external_type_detai"); + + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialType", "VerifiedCredentialType") + .WithMany("CompanySsiDetails") + .HasForeignKey("VerifiedCredentialTypeId") + .IsRequired() + .HasConstraintName("fk_company_ssi_details_verified_credential_types_verified_cred"); + + b.Navigation("CompanySsiDetailStatus"); + + b.Navigation("ExpiryCheckType"); + + b.Navigation("Process"); + + b.Navigation("VerifiedCredentialExternalTypeDetailVersion"); + + b.Navigation("VerifiedCredentialType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.CompanySsiDetailAssignedDocument", b => + { + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.CompanySsiDetail", "CompanySsiDetail") + .WithMany() + .HasForeignKey("CompanySsiDetailId") + .IsRequired() + .HasConstraintName("fk_company_ssi_detail_assigned_documents_company_ssi_details_c"); + + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .IsRequired() + .HasConstraintName("fk_company_ssi_detail_assigned_documents_documents_document_id"); + + b.Navigation("CompanySsiDetail"); + + b.Navigation("Document"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.CompanySsiProcessData", b => + { + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.CompanySsiDetail", "CompanySsiDetail") + .WithOne("CompanySsiProcessData") + .HasForeignKey("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.CompanySsiProcessData", "CompanySsiDetailId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_company_ssi_process_data_company_ssi_details_company_ssi_de"); + + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialTypeKind", "CredentialTypeKind") + .WithMany("CompanySsiProcessData") + .HasForeignKey("CredentialTypeKindId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_company_ssi_process_data_verified_credential_type_kinds_cre"); + + b.Navigation("CompanySsiDetail"); + + b.Navigation("CredentialTypeKind"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.Document", b => + { + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.DocumentStatus", "DocumentStatus") + .WithMany("Documents") + .HasForeignKey("DocumentStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_documents_document_status_document_status_id"); + + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.DocumentType", "DocumentType") + .WithMany("Documents") + .HasForeignKey("DocumentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_documents_document_types_document_type_id"); + + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.MediaType", "MediaType") + .WithMany("Documents") + .HasForeignKey("MediaTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_documents_media_types_media_type_id"); + + b.Navigation("DocumentStatus"); + + b.Navigation("DocumentType"); + + b.Navigation("MediaType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.Process", b => + { + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.ProcessType", "ProcessType") + .WithMany("Processes") + .HasForeignKey("ProcessTypeId") + .IsRequired() + .HasConstraintName("fk_processes_process_types_process_type_id"); + + b.Navigation("ProcessType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.ProcessStep", b => + { + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.Process", "Process") + .WithMany("ProcessSteps") + .HasForeignKey("ProcessId") + .IsRequired() + .HasConstraintName("fk_process_steps_processes_process_id"); + + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.ProcessStepStatus", "ProcessStepStatus") + .WithMany("ProcessSteps") + .HasForeignKey("ProcessStepStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_process_steps_process_step_statuses_process_step_status_id"); + + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.ProcessStepType", "ProcessStepType") + .WithMany("ProcessSteps") + .HasForeignKey("ProcessStepTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_process_steps_process_step_types_process_step_type_id"); + + b.Navigation("Process"); + + b.Navigation("ProcessStepStatus"); + + b.Navigation("ProcessStepType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialExternalTypeDetailVersion", b => + { + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialExternalType", "VerifiedCredentialExternalType") + .WithMany("VerifiedCredentialExternalTypeDetailVersions") + .HasForeignKey("VerifiedCredentialExternalTypeId") + .IsRequired() + .HasConstraintName("fk_verified_credential_external_type_detail_versions_verified_"); + + b.Navigation("VerifiedCredentialExternalType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialTypeAssignedExternalType", b => + { + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialExternalType", "VerifiedCredentialExternalType") + .WithMany("VerifiedCredentialTypeAssignedExternalTypes") + .HasForeignKey("VerifiedCredentialExternalTypeId") + .IsRequired() + .HasConstraintName("fk_verified_credential_type_assigned_external_types_verified_c"); + + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialType", "VerifiedCredentialType") + .WithOne("VerifiedCredentialTypeAssignedExternalType") + .HasForeignKey("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialTypeAssignedExternalType", "VerifiedCredentialTypeId") + .IsRequired() + .HasConstraintName("fk_verified_credential_type_assigned_external_types_verified_c1"); + + b.Navigation("VerifiedCredentialExternalType"); + + b.Navigation("VerifiedCredentialType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialTypeAssignedKind", b => + { + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialType", "VerifiedCredentialType") + .WithOne("VerifiedCredentialTypeAssignedKind") + .HasForeignKey("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialTypeAssignedKind", "VerifiedCredentialTypeId") + .IsRequired() + .HasConstraintName("fk_verified_credential_type_assigned_kinds_verified_credential"); + + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialTypeKind", "VerifiedCredentialTypeKind") + .WithMany("VerifiedCredentialTypeAssignedKinds") + .HasForeignKey("VerifiedCredentialTypeKindId") + .IsRequired() + .HasConstraintName("fk_verified_credential_type_assigned_kinds_verified_credential1"); + + b.Navigation("VerifiedCredentialType"); + + b.Navigation("VerifiedCredentialTypeKind"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialTypeAssignedUseCase", b => + { + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.UseCase", "UseCase") + .WithOne("VerifiedCredentialAssignedUseCase") + .HasForeignKey("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialTypeAssignedUseCase", "UseCaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_verified_credential_type_assigned_use_cases_use_cases_use_c"); + + b.HasOne("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialType", "VerifiedCredentialType") + .WithOne("VerifiedCredentialTypeAssignedUseCase") + .HasForeignKey("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialTypeAssignedUseCase", "VerifiedCredentialTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_verified_credential_type_assigned_use_cases_verified_creden"); + + b.Navigation("UseCase"); + + b.Navigation("VerifiedCredentialType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.CompanySsiDetail", b => + { + b.Navigation("CompanySsiProcessData"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.CompanySsiDetailStatus", b => + { + b.Navigation("CompanySsiDetails"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.DocumentStatus", b => + { + b.Navigation("Documents"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.DocumentType", b => + { + b.Navigation("Documents"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.ExpiryCheckType", b => + { + b.Navigation("CompanySsiDetails"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.MediaType", b => + { + b.Navigation("Documents"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.Process", b => + { + b.Navigation("CompanySsiDetails"); + + b.Navigation("ProcessSteps"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.ProcessStepStatus", b => + { + b.Navigation("ProcessSteps"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.ProcessStepType", b => + { + b.Navigation("ProcessSteps"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.ProcessType", b => + { + b.Navigation("Processes"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.UseCase", b => + { + b.Navigation("VerifiedCredentialAssignedUseCase"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialExternalType", b => + { + b.Navigation("VerifiedCredentialExternalTypeDetailVersions"); + + b.Navigation("VerifiedCredentialTypeAssignedExternalTypes"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialExternalTypeDetailVersion", b => + { + b.Navigation("CompanySsiDetails"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialType", b => + { + b.Navigation("CompanySsiDetails"); + + b.Navigation("VerifiedCredentialTypeAssignedExternalType"); + + b.Navigation("VerifiedCredentialTypeAssignedKind"); + + b.Navigation("VerifiedCredentialTypeAssignedUseCase"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities.VerifiedCredentialTypeKind", b => + { + b.Navigation("CompanySsiProcessData"); + + b.Navigation("VerifiedCredentialTypeAssignedKinds"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/database/SsiCredentialIssuer.Migrations/Migrations/20240424121211_1.0.0-rc.3.cs b/src/database/SsiCredentialIssuer.Migrations/Migrations/20240424121211_1.0.0-rc.3.cs new file mode 100644 index 00000000..ab59b64a --- /dev/null +++ b/src/database/SsiCredentialIssuer.Migrations/Migrations/20240424121211_1.0.0-rc.3.cs @@ -0,0 +1,170 @@ +/******************************************************************************** + * Copyright (c) 2024 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 Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Migrations.Migrations +{ + /// + public partial class _100rc3 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.InsertData( + schema: "issuer", + table: "process_step_types", + columns: new[] { "id", "label" }, + values: new object[,] + { + { 100, "REVOKE_CREDENTIAL" }, + { 101, "TRIGGER_NOTIFICATION" }, + { 102, "TRIGGER_MAIL" } + }); + + migrationBuilder.InsertData( + schema: "issuer", + table: "process_types", + columns: new[] { "id", "label" }, + values: new object[] { 2, "DECLINE_CREDENTIAL" }); + + migrationBuilder.UpdateData( + schema: "issuer", + table: "verified_credential_external_types", + keyColumn: "id", + keyValue: 5, + column: "label", + value: "CIRCULAR_ECONOMY"); + + migrationBuilder.InsertData( + schema: "issuer", + table: "verified_credential_external_types", + columns: new[] { "id", "label" }, + values: new object[,] + { + { 8, "DEMAND_AND_CAPACITY_MANAGEMENT" }, + { 9, "DEMAND_AND_CAPACITY_MANAGEMENT_PURIS" }, + { 10, "BUSINESS_PARTNER_DATA_MANAGEMENT" } + }); + + migrationBuilder.UpdateData( + schema: "issuer", + table: "verified_credential_types", + keyColumn: "id", + keyValue: 5, + column: "label", + value: "CIRCULAR_ECONOMY"); + + migrationBuilder.InsertData( + schema: "issuer", + table: "verified_credential_types", + columns: new[] { "id", "label" }, + values: new object[,] + { + { 8, "DEMAND_AND_CAPACITY_MANAGEMENT" }, + { 9, "DEMAND_AND_CAPACITY_MANAGEMENT_PURIS" }, + { 10, "BUSINESS_PARTNER_DATA_MANAGEMENT" } + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DeleteData( + schema: "issuer", + table: "process_step_types", + keyColumn: "id", + keyValue: 100); + + migrationBuilder.DeleteData( + schema: "issuer", + table: "process_step_types", + keyColumn: "id", + keyValue: 101); + + migrationBuilder.DeleteData( + schema: "issuer", + table: "process_step_types", + keyColumn: "id", + keyValue: 102); + + migrationBuilder.DeleteData( + schema: "issuer", + table: "process_types", + keyColumn: "id", + keyValue: 2); + + migrationBuilder.DeleteData( + schema: "issuer", + table: "verified_credential_external_types", + keyColumn: "id", + keyValue: 8); + + migrationBuilder.DeleteData( + schema: "issuer", + table: "verified_credential_external_types", + keyColumn: "id", + keyValue: 9); + + migrationBuilder.DeleteData( + schema: "issuer", + table: "verified_credential_external_types", + keyColumn: "id", + keyValue: 10); + + migrationBuilder.DeleteData( + schema: "issuer", + table: "verified_credential_types", + keyColumn: "id", + keyValue: 8); + + migrationBuilder.DeleteData( + schema: "issuer", + table: "verified_credential_types", + keyColumn: "id", + keyValue: 9); + + migrationBuilder.DeleteData( + schema: "issuer", + table: "verified_credential_types", + keyColumn: "id", + keyValue: 10); + + migrationBuilder.UpdateData( + schema: "issuer", + table: "verified_credential_external_types", + keyColumn: "id", + keyValue: 5, + column: "label", + value: "SUSTAINABILITY_CREDENTIAL"); + + migrationBuilder.UpdateData( + schema: "issuer", + table: "verified_credential_types", + keyColumn: "id", + keyValue: 5, + column: "label", + value: "SUSTAINABILITY_FRAMEWORK"); + } + } +} diff --git a/src/database/SsiCredentialIssuer.Migrations/Migrations/IssuerDbContextModelSnapshot.cs b/src/database/SsiCredentialIssuer.Migrations/Migrations/IssuerDbContextModelSnapshot.cs index d55dec90..04a75321 100644 --- a/src/database/SsiCredentialIssuer.Migrations/Migrations/IssuerDbContextModelSnapshot.cs +++ b/src/database/SsiCredentialIssuer.Migrations/Migrations/IssuerDbContextModelSnapshot.cs @@ -18,13 +18,12 @@ ********************************************************************************/ // + using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities; using System.Text.Json; -#nullable disable - namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Migrations.Migrations { [DbContext(typeof(IssuerDbContext))] @@ -969,6 +968,21 @@ protected override void BuildModel(ModelBuilder modelBuilder) { Id = 5, Label = "TRIGGER_CALLBACK" + }, + new + { + Id = 100, + Label = "REVOKE_CREDENTIAL" + }, + new + { + Id = 101, + Label = "TRIGGER_NOTIFICATION" + }, + new + { + Id = 102, + Label = "TRIGGER_MAIL" }); }); @@ -994,6 +1008,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) { Id = 1, Label = "CREATE_CREDENTIAL" + }, + new + { + Id = 2, + Label = "DECLINE_CREDENTIAL" }); }); @@ -1062,7 +1081,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) new { Id = 5, - Label = "SUSTAINABILITY_CREDENTIAL" + Label = "CIRCULAR_ECONOMY" }, new { @@ -1073,6 +1092,21 @@ protected override void BuildModel(ModelBuilder modelBuilder) { Id = 7, Label = "BUSINESS_PARTNER_NUMBER" + }, + new + { + Id = 8, + Label = "DEMAND_AND_CAPACITY_MANAGEMENT" + }, + new + { + Id = 9, + Label = "DEMAND_AND_CAPACITY_MANAGEMENT_PURIS" + }, + new + { + Id = 10, + Label = "BUSINESS_PARTNER_DATA_MANAGEMENT" }); }); @@ -1154,7 +1188,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) new { Id = 5, - Label = "SUSTAINABILITY_FRAMEWORK" + Label = "CIRCULAR_ECONOMY" }, new { @@ -1165,6 +1199,21 @@ protected override void BuildModel(ModelBuilder modelBuilder) { Id = 7, Label = "BUSINESS_PARTNER_NUMBER" + }, + new + { + Id = 8, + Label = "DEMAND_AND_CAPACITY_MANAGEMENT" + }, + new + { + Id = 9, + Label = "DEMAND_AND_CAPACITY_MANAGEMENT_PURIS" + }, + new + { + Id = 10, + Label = "BUSINESS_PARTNER_DATA_MANAGEMENT" }); }); diff --git a/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/use_cases.json b/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/use_cases.json index 6c33df1d..e780a810 100644 --- a/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/use_cases.json +++ b/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/use_cases.json @@ -4,16 +4,6 @@ "name": "Traceability", "shortname": "T" }, - { - "id": "06b243a4-ba51-4bf3-bc40-5d79a2231b87", - "name": "Sustainability & CO2-Footprint", - "shortname": "CO2" - }, - { - "id": "06b243a4-ba51-4bf3-bc40-5d79a2231b88", - "name": "Manufacturing as a Service", - "shortname": "MaaS" - }, { "id": "06b243a4-ba51-4bf3-bc40-5d79a2231b89", "name": "Real-Time Control", @@ -29,11 +19,6 @@ "name": "Circular Economy", "shortname": "CE" }, - { - "id": "1aacde78-35ec-4df3-ba1e-f988cddcbbd9", - "name": "None", - "shortname": "None" - }, { "id": "41e4a4c0-aae4-41c0-97c9-ebafde410de4", "name": "Demand and Capacity Management", @@ -41,7 +26,7 @@ }, { "id": "6909ccc7-37c8-4088-99ab-790f20702460", - "name": "Business Partner Management", + "name": "Business Partner Data Management", "shortname": "BPDM" }, { @@ -53,5 +38,10 @@ "id": "b3948771-3372-4568-9e0e-acca4e674098", "name": "Behavior Twin", "shortname": "BT" + }, + { + "id": "3793a2d9-6bc5-44f0-b952-7d3f6b747dd7", + "name": "Demand and Capacity Management", + "shortname": "Puris" } ] \ No newline at end of file diff --git a/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_external_type_detail_versions.consortia.json b/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_external_type_detail_versions.consortia.json index 58bb092c..c622324c 100644 --- a/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_external_type_detail_versions.consortia.json +++ b/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_external_type_detail_versions.consortia.json @@ -1,42 +1,34 @@ [ - { - "id": "1268a76a-ca19-4dd8-b932-01f24071d562", - "verified_credential_external_type_id": 3, - "version": "1.0.0", - "template": null, - "valid_from": "2023-06-01 00:00:00.000000 +00:00", - "expiry": "2023-09-30 00:00:00.000000 +00:00" - }, { "id": "1268a76a-ca19-4dd8-b932-01f24071d563", "verified_credential_external_type_id": 1, - "version": "2.0.0", - "template": null, + "version": "2.0", + "template": "https://catena-x.net/fileadmin/user_upload/04_Einfuehren_und_umsetzen/Governance_Framework/231016_Catena-X_Use_Case_Framework_Traceability.pdf", "valid_from": "2023-06-01 00:00:00.000000 +00:00", "expiry": "2023-12-23 00:00:00.000000 +00:00" }, { "id": "1268a76a-ca19-4dd8-b932-01f24071d564", "verified_credential_external_type_id": 1, - "version": "3.0.0", - "template": null, + "version": "3.0", + "template": "https://catena-x.net/fileadmin/user_upload/04_Einfuehren_und_umsetzen/Governance_Framework/231016_Catena-X_Use_Case_Framework_Traceability.pdf", "valid_from": "2024-01-01 00:00:00.000000 +00:00", "expiry": "2024-12-31 00:00:00.000000 +00:00" }, { - "id": "1268a76a-ca19-4dd8-b932-01f24071d565", - "verified_credential_external_type_id": 5, - "version": "1.0.0", + "id": "1268a76a-ca19-4dd8-b932-01f24071d562", + "verified_credential_external_type_id": 3, + "version": "1.0", "template": null, - "valid_from": "2024-01-01 00:00:00.000000 +00:00", - "expiry": "2024-12-31 00:00:00.000000 +00:00" + "valid_from": "2023-06-01 00:00:00.000000 +00:00", + "expiry": "2023-09-30 00:00:00.000000 +00:00" }, { - "id": "df3bd7d2-3349-410b-9b30-9a5238eb605e", - "verified_credential_external_type_id": 4, - "version": null, - "template": null, + "id": "1268a76a-ca19-4dd8-b932-01f24071d565", + "verified_credential_external_type_id": 5, + "version": "1.0", + "template": " https://catena-x.net/fileadmin/user_upload/04_Einfuehren_und_umsetzen/Governance_Framework/231016_Catena-X_Use_Case_Framework_CircularEconomy.pdf", "valid_from": "2024-01-01 00:00:00.000000 +00:00", - "expiry": "2999-12-31 23:59:59.000000 +00:00" + "expiry": "2024-12-31 00:00:00.000000 +00:00" } ] diff --git a/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_external_type_detail_versions.json b/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_external_type_detail_versions.json index ee5ccd40..7aa80f1b 100644 --- a/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_external_type_detail_versions.json +++ b/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_external_type_detail_versions.json @@ -2,7 +2,7 @@ { "id": "1268a76a-ca19-4dd8-b932-01f24071d560", "verified_credential_external_type_id": 1, - "version": "1.0.0", + "version": "1.0", "template": "https://catena-x.net/fileadmin/user_upload/04_Einfuehren_und_umsetzen/Governance_Framework/231016_Catena-X_Use_Case_Framework_Traceability.pdf", "valid_from": "2023-06-01 00:00:00.000000 +00:00", "expiry": "2023-09-30 00:00:00.000000 +00:00" @@ -10,7 +10,7 @@ { "id": "1268a76a-ca19-4dd8-b932-01f24071d561", "verified_credential_external_type_id": 2, - "version": "1.0.0", + "version": "1.0", "template": "https://catena-x.net/fileadmin/user_upload/04_Einfuehren_und_umsetzen/Governance_Framework/231016_Catena-X_Use_Case_Framework_PCF.pdf", "valid_from": "2023-06-01 00:00:00.000000 +00:00", "expiry": "2023-09-30 00:00:00.000000 +00:00" @@ -18,9 +18,33 @@ { "id": "37aa6259-b452-4d50-b09e-827929dcfa15", "verified_credential_external_type_id": 6, - "version": "1.0.0", + "version": "1.0", "template": "https://catena-x.net/fileadmin/user_upload/04_Einfuehren_und_umsetzen/Governance_Framework/231016_Catena-X_Use_Case_Framework_PCF.pdf", - "valid_from": "2023-10-16 00:00:00.000000 +00:00", - "expiry": "2023-10-16 00:00:00.000000 +00:00" + "valid_from": "2024-03-27 00:00:00.000000 +00:00", + "expiry": "2024-12-31 00:00:00.000000 +00:00" + }, + { + "id": "27d12475-c970-4979-892b-8f88e819018f", + "verified_credential_external_type_id": 8, + "version": "1.0", + "template": "https://catena-x.net/fileadmin/user_upload/04_Einfuehren_und_umsetzen/Governance_Framework/231016_Catena-X_Use_Case_Framework_DemanAndCapacity.pdf", + "valid_from": "2024-03-27 00:00:00.000000 +00:00", + "expiry": "2024-12-31 00:00:00.000000 +00:00" + }, + { + "id": "a7585e82-4789-47ce-9184-5788086b1943", + "verified_credential_external_type_id": 9, + "version": "1.0", + "template": "https://catena-x.net/fileadmin/user_upload/04_Einfuehren_und_umsetzen/Governance_Framework/231016_Catena-X_Use_Case_Framework_Puris.pdf", + "valid_from": "2024-03-27 00:00:00.000000 +00:00", + "expiry": "2024-12-31 00:00:00.000000 +00:00" + }, + { + "id": "0077addf-f50d-4f5e-bc41-26c45d407104", + "verified_credential_external_type_id": 10, + "version": "1.0", + "template": "https://catena-x.net/fileadmin/user_upload/04_Einfuehren_und_umsetzen/Governance_Framework/231016_Catena-X_Use_Case_Framework_BPDM.pdf", + "valid_from": "2024-03-27 00:00:00.000000 +00:00", + "expiry": "2024-12-31 00:00:00.000000 +00:00" } ] diff --git a/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_type_assigned_external_types.json b/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_type_assigned_external_types.json index c07dc64e..5451b105 100644 --- a/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_type_assigned_external_types.json +++ b/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_type_assigned_external_types.json @@ -22,5 +22,17 @@ { "verified_credential_external_type_id": 6, "verified_credential_type_id": 6 + }, + { + "verified_credential_external_type_id": 8, + "verified_credential_type_id": 8 + }, + { + "verified_credential_external_type_id": 9, + "verified_credential_type_id": 9 + }, + { + "verified_credential_external_type_id": 10, + "verified_credential_type_id": 10 } ] diff --git a/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_type_assigned_kinds.json b/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_type_assigned_kinds.json index 365789bd..4880da7a 100644 --- a/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_type_assigned_kinds.json +++ b/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_type_assigned_kinds.json @@ -26,5 +26,17 @@ { "verified_credential_type_id": 7, "verified_credential_type_kind_id": 3 + }, + { + "verified_credential_type_id": 8, + "verified_credential_type_kind_id": 1 + }, + { + "verified_credential_type_id": 9, + "verified_credential_type_kind_id": 1 + }, + { + "verified_credential_type_id": 10, + "verified_credential_type_kind_id": 1 } ] diff --git a/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_type_assigned_use_cases.json b/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_type_assigned_use_cases.json index 92d3a49f..5d034bca 100644 --- a/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_type_assigned_use_cases.json +++ b/src/database/SsiCredentialIssuer.Migrations/Seeder/Data/verified_credential_type_assigned_use_cases.json @@ -3,10 +3,6 @@ "verified_credential_type_id": 1, "use_case_id": "06b243a4-ba51-4bf3-bc40-5d79a2231b86" }, - { - "verified_credential_type_id": 2, - "use_case_id": "06b243a4-ba51-4bf3-bc40-5d79a2231b87" - }, { "verified_credential_type_id": 3, "use_case_id": "b3948771-3372-4568-9e0e-acca4e674098" @@ -18,5 +14,17 @@ { "verified_credential_type_id": 6, "use_case_id": "c065a349-f649-47f8-94d5-1a504a855419" + }, + { + "verified_credential_type_id": 8, + "use_case_id": "41e4a4c0-aae4-41c0-97c9-ebafde410de4" + }, + { + "verified_credential_type_id": 9, + "use_case_id": "3793a2d9-6bc5-44f0-b952-7d3f6b747dd7" + }, + { + "verified_credential_type_id": 10, + "use_case_id": "6909ccc7-37c8-4088-99ab-790f20702460" } ] diff --git a/src/externalservices/Portal.Service/Models/MailData.cs b/src/externalservices/Portal.Service/Models/MailData.cs index b3834531..c82c13cd 100644 --- a/src/externalservices/Portal.Service/Models/MailData.cs +++ b/src/externalservices/Portal.Service/Models/MailData.cs @@ -24,5 +24,10 @@ namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Portal.Service.Models; public record MailData( [property: JsonPropertyName("requester")] Guid Requester, [property: JsonPropertyName("template")] string Template, - [property: JsonPropertyName("mailParameters")] IDictionary MailParameters + [property: JsonPropertyName("mailParameters")] IEnumerable MailParameters +); + +public record MailParameter( + [property: JsonPropertyName("key")] string Key, + [property: JsonPropertyName("value")] string Value ); diff --git a/src/externalservices/Portal.Service/Services/IPortalService.cs b/src/externalservices/Portal.Service/Services/IPortalService.cs index c09725cd..bacc5e0d 100644 --- a/src/externalservices/Portal.Service/Services/IPortalService.cs +++ b/src/externalservices/Portal.Service/Services/IPortalService.cs @@ -24,5 +24,5 @@ namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Portal.Service.Services; public interface IPortalService { Task AddNotification(string content, Guid requester, NotificationTypeId notificationTypeId, CancellationToken cancellationToken); - Task TriggerMail(string template, Guid requester, IDictionary mailParameters, CancellationToken cancellationToken); + Task TriggerMail(string template, Guid requester, IEnumerable mailParameters, CancellationToken cancellationToken); } diff --git a/src/externalservices/Portal.Service/Services/PortalService.cs b/src/externalservices/Portal.Service/Services/PortalService.cs index fb63a2a7..6160047e 100644 --- a/src/externalservices/Portal.Service/Services/PortalService.cs +++ b/src/externalservices/Portal.Service/Services/PortalService.cs @@ -42,18 +42,18 @@ public PortalService(ITokenService tokenService, IOptions option public async Task AddNotification(string content, Guid requester, NotificationTypeId notificationTypeId, CancellationToken cancellationToken) { - var client = await _tokenService.GetAuthorizedClient(_settings, cancellationToken).ConfigureAwait(false); + using var client = await _tokenService.GetAuthorizedClient(_settings, cancellationToken).ConfigureAwait(false); var data = new NotificationRequest(requester, content, notificationTypeId); - await client.PostAsJsonAsync("api/notifications/management", data, Options, cancellationToken) + await client.PostAsJsonAsync("api/notifications/ssi-credentials", data, Options, cancellationToken) .CatchingIntoServiceExceptionFor("notification", HttpAsyncResponseMessageExtension.RecoverOptions.REQUEST_EXCEPTION) .ConfigureAwait(false); } - public async Task TriggerMail(string template, Guid requester, IDictionary mailParameters, CancellationToken cancellationToken) + public async Task TriggerMail(string template, Guid requester, IEnumerable mailParameters, CancellationToken cancellationToken) { - var client = await _tokenService.GetAuthorizedClient(_settings, cancellationToken).ConfigureAwait(false); + using var client = await _tokenService.GetAuthorizedClient(_settings, cancellationToken).ConfigureAwait(false); var data = new MailData(requester, template, mailParameters); - await client.PostAsJsonAsync("api/administration/mail", data, Options, cancellationToken) + await client.PostAsJsonAsync("api/administration/mail/ssi-credentials", data, Options, cancellationToken) .CatchingIntoServiceExceptionFor("mail", HttpAsyncResponseMessageExtension.RecoverOptions.REQUEST_EXCEPTION) .ConfigureAwait(false); } diff --git a/src/externalservices/Wallet.Service/Models/GetCredentialResponse.cs b/src/externalservices/Wallet.Service/Models/GetCredentialResponse.cs index 19a6902c..15569a95 100644 --- a/src/externalservices/Wallet.Service/Models/GetCredentialResponse.cs +++ b/src/externalservices/Wallet.Service/Models/GetCredentialResponse.cs @@ -6,5 +6,6 @@ namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Models; public record GetCredentialResponse( [property: JsonPropertyName("verifiableCredential")] string VerifiableCredential, [property: JsonPropertyName("credential")] JsonDocument Credential, - [property: JsonPropertyName("signing_key_id")] string SigningKeyId + [property: JsonPropertyName("signing_key_id")] string SigningKeyId, + [property: JsonPropertyName("revocationStatus")] string RevocationStatus ); diff --git a/src/externalservices/Wallet.Service/Models/RevokeCredentialRequest.cs b/src/externalservices/Wallet.Service/Models/RevokeCredentialRequest.cs new file mode 100644 index 00000000..5c565baf --- /dev/null +++ b/src/externalservices/Wallet.Service/Models/RevokeCredentialRequest.cs @@ -0,0 +1,30 @@ +/******************************************************************************** + * Copyright (c) 2024 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.Json.Serialization; + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Models; + +public record RevokeCredentialRequest( + [property: JsonPropertyName("payload")] RevokePayload Payload +); + +public record RevokePayload( + [property: JsonPropertyName("revoke")] bool Revoke +); diff --git a/src/externalservices/Wallet.Service/Services/BasicAuthTokenService.cs b/src/externalservices/Wallet.Service/Services/BasicAuthTokenService.cs index fae20579..a3d90473 100644 --- a/src/externalservices/Wallet.Service/Services/BasicAuthTokenService.cs +++ b/src/externalservices/Wallet.Service/Services/BasicAuthTokenService.cs @@ -21,6 +21,7 @@ using Org.Eclipse.TractusX.Portal.Backend.Framework.Token; using System.Net.Http.Headers; using System.Net.Http.Json; +using System.Text; using System.Text.Json; namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Services; @@ -43,7 +44,7 @@ public async Task GetBasicAuthorizedClient(BasicAuthSettings sett settings.ClientSecret, settings.TokenAddress); - var token = await this.GetBasicTokenAsync(tokenParameters, cancellationToken).ConfigureAwait(false); + var token = await GetBasicTokenAsync(tokenParameters, cancellationToken).ConfigureAwait(false); var httpClient = _httpClientFactory.CreateClient(typeof(T).Name); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); @@ -57,9 +58,9 @@ public async Task GetBasicAuthorizedClient(BasicAuthSettings sett { "grant_type", "client_credentials" } }; using var content = new FormUrlEncodedContent(formParameters); - var authClient = _httpClientFactory.CreateClient(settings.HttpClientName); + using var authClient = _httpClientFactory.CreateClient(settings.HttpClientName); var authenticationString = $"{settings.ClientId}:{settings.ClientSecret}"; - var base64String = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(authenticationString)); + var base64String = Convert.ToBase64String(Encoding.ASCII.GetBytes(authenticationString)); authClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", base64String); diff --git a/src/externalservices/Wallet.Service/Services/IBasicAuthTokenService.cs b/src/externalservices/Wallet.Service/Services/IBasicAuthTokenService.cs index e379cb34..693cd234 100644 --- a/src/externalservices/Wallet.Service/Services/IBasicAuthTokenService.cs +++ b/src/externalservices/Wallet.Service/Services/IBasicAuthTokenService.cs @@ -21,5 +21,5 @@ namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Services; public interface IBasicAuthTokenService { - Task GetBasicAuthorizedClient(BasicAuthSettings settings, CancellationToken cancellationToken); + Task GetBasicAuthorizedClient(BasicAuthSettings settings, CancellationToken cancellationToken = default); } diff --git a/src/externalservices/Wallet.Service/Services/IWalletService.cs b/src/externalservices/Wallet.Service/Services/IWalletService.cs index 27365f47..8e0533e5 100644 --- a/src/externalservices/Wallet.Service/Services/IWalletService.cs +++ b/src/externalservices/Wallet.Service/Services/IWalletService.cs @@ -27,4 +27,5 @@ public interface IWalletService Task SignCredential(Guid credentialId, CancellationToken cancellationToken); Task CreateCredentialForHolder(string holderWalletUrl, string clientId, string clientSecret, string credential, CancellationToken cancellationToken); Task GetCredential(Guid externalCredentialId, CancellationToken cancellationToken); + Task RevokeCredentialForIssuer(Guid externalCredentialId, CancellationToken cancellationToken); } diff --git a/src/externalservices/Wallet.Service/Services/WalletService.cs b/src/externalservices/Wallet.Service/Services/WalletService.cs index e5fb59ff..ed69daad 100644 --- a/src/externalservices/Wallet.Service/Services/WalletService.cs +++ b/src/externalservices/Wallet.Service/Services/WalletService.cs @@ -43,7 +43,7 @@ public WalletService(IBasicAuthTokenService basicAuthTokenService, IOptions CreateCredential(JsonDocument payload, CancellationToken cancellationToken) { - var client = await _basicAuthTokenService.GetBasicAuthorizedClient(_settings, cancellationToken); + using var client = await _basicAuthTokenService.GetBasicAuthorizedClient(_settings, cancellationToken); var data = new CreateCredentialRequest("catena-x-portal", new CredentialPayload(payload)); var result = await client.PostAsJsonAsync("api/v2.0.0/credentials", data, Options, cancellationToken) .CatchingIntoServiceExceptionFor("create-credential", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, @@ -60,7 +60,7 @@ public async Task CreateCredential(JsonDocument payload, CancellationToken public async Task SignCredential(Guid credentialId, CancellationToken cancellationToken) { - var client = await _basicAuthTokenService.GetBasicAuthorizedClient(_settings, cancellationToken); + using var client = await _basicAuthTokenService.GetBasicAuthorizedClient(_settings, cancellationToken); var data = new SignCredentialRequest(new SignPayload(new SignUpdate("external", "jwt"))); var result = await client.PatchAsJsonAsync($"/api/v2.0.0/credentials/{credentialId}", data, Options, cancellationToken) .CatchingIntoServiceExceptionFor("sign-credential", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, @@ -77,7 +77,7 @@ public async Task SignCredential(Guid credentialId, CancellationToken ca public async Task GetCredential(Guid externalCredentialId, CancellationToken cancellationToken) { - var client = await _basicAuthTokenService.GetBasicAuthorizedClient(_settings, cancellationToken); + using var client = await _basicAuthTokenService.GetBasicAuthorizedClient(_settings, cancellationToken); var result = await client.GetAsync($"/api/v2.0.0/credentials/{externalCredentialId}", cancellationToken) .CatchingIntoServiceExceptionFor("get-credential", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(false))) @@ -99,7 +99,7 @@ public async Task CreateCredentialForHolder(string holderWalletUrl, string ClientSecret = clientSecret, TokenAddress = $"{holderWalletUrl}/oauth/token" }; - var client = await _basicAuthTokenService.GetBasicAuthorizedClient(authSettings, cancellationToken); + using var client = await _basicAuthTokenService.GetBasicAuthorizedClient(authSettings, cancellationToken); var data = new DeriveCredentialData("catena-x-portal", new DeriveCredentialPayload(new DeriveCredential(credential))); var result = await client.PostAsJsonAsync("/api/v2.0.0/credentials", data, Options, cancellationToken) .CatchingIntoServiceExceptionFor("create-holder-credential", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, @@ -113,4 +113,14 @@ public async Task CreateCredentialForHolder(string holderWalletUrl, string return response.Id; } + + public async Task RevokeCredentialForIssuer(Guid externalCredentialId, CancellationToken cancellationToken) + { + using var client = await _basicAuthTokenService.GetBasicAuthorizedClient(_settings, cancellationToken); + var data = new RevokeCredentialRequest(new RevokePayload(true)); + await client.PatchAsJsonAsync($"/api/v2.0.0/credentials/{externalCredentialId}", data, Options, cancellationToken) + .CatchingIntoServiceExceptionFor("revoke-credential", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, + async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(false))) + .ConfigureAwait(false); + } } diff --git a/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/CredentialBusinessLogic.cs b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/CredentialBusinessLogic.cs new file mode 100644 index 00000000..ab533261 --- /dev/null +++ b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/CredentialBusinessLogic.cs @@ -0,0 +1,62 @@ +/******************************************************************************** + * Copyright (c) 2024 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 Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Repositories; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.ErrorHandling; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Identity; +using System.Text.Json; + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Service.BusinessLogic; + +public class CredentialBusinessLogic : ICredentialBusinessLogic +{ + private readonly IIssuerRepositories _repositories; + private readonly IIdentityData _identityData; + + public CredentialBusinessLogic(IIssuerRepositories repositories, IIdentityService identityService) + { + _repositories = repositories; + _identityData = identityService.IdentityData; + } + + public async Task GetCredentialDocument(Guid credentialId) + { + var (exists, isSameCompany, documents) = await _repositories.GetInstance().GetSignedCredentialForCredentialId(credentialId, _identityData.Bpnl).ConfigureAwait(false); + if (!exists) + { + throw NotFoundException.Create(CredentialErrors.CREDENTIAL_NOT_FOUND, new[] { new ErrorParameter("credentialId", credentialId.ToString()) }); + } + + if (!isSameCompany) + { + throw ForbiddenException.Create(CredentialErrors.COMPANY_NOT_ALLOWED); + } + + if (documents.Count() != 1) + { + throw ConflictException.Create(CredentialErrors.SIGNED_CREDENTIAL_NOT_FOUND); + } + + var (_, credentialContent) = documents.Single(); + using var stream = new MemoryStream(credentialContent); + return await JsonDocument.ParseAsync(stream).ConfigureAwait(false); + } +} diff --git a/src/issuer/SsiCredentialIssuer.Service/DependencyInjection/CredentialServiceCollectionExtensions.cs b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/ICredentialBusinessLogic.cs similarity index 65% rename from src/issuer/SsiCredentialIssuer.Service/DependencyInjection/CredentialServiceCollectionExtensions.cs rename to src/issuer/SsiCredentialIssuer.Service/BusinessLogic/ICredentialBusinessLogic.cs index e983c6a4..5d937718 100644 --- a/src/issuer/SsiCredentialIssuer.Service/DependencyInjection/CredentialServiceCollectionExtensions.cs +++ b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/ICredentialBusinessLogic.cs @@ -17,14 +17,11 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.BusinessLogic; +using System.Text.Json; -namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Service.DependencyInjection; +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Service.BusinessLogic; -public static class CredentialServiceCollectionExtensions +public interface ICredentialBusinessLogic { - public static IServiceCollection AddCredentialService(this IServiceCollection services, IConfigurationSection section) => - services - .ConfigureCredentialSettings(section) - .AddTransient(); + Task GetCredentialDocument(Guid credentialId); } diff --git a/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IRevocationBusinessLogic.cs b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IRevocationBusinessLogic.cs new file mode 100644 index 00000000..12c603ae --- /dev/null +++ b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IRevocationBusinessLogic.cs @@ -0,0 +1,25 @@ +/******************************************************************************** + * Copyright (c) 2024 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 + ********************************************************************************/ + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Service.BusinessLogic; + +public interface IRevocationBusinessLogic +{ + Task RevokeCredential(Guid credentialId, bool revokeForIssuer, CancellationToken cancellationToken); +} diff --git a/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IssuerBusinessLogic.cs b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IssuerBusinessLogic.cs index 63999d76..45e5f7cc 100644 --- a/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IssuerBusinessLogic.cs +++ b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IssuerBusinessLogic.cs @@ -37,6 +37,7 @@ using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Models; using System.Globalization; using System.Security.Cryptography; +using System.Text; using System.Text.Json; using System.Text.RegularExpressions; using ErrorParameter = Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling.ErrorParameter; @@ -103,7 +104,7 @@ await _repositories d.ExpiryDate, d.Documents)) .SingleOrDefault(), - (InvalidOperationException _) => throw ConflictException.Create(CredentialErrors.MULTIPLE_SSI_DETAIL)))) + (InvalidOperationException _) => throw ConflictException.Create(IssuerErrors.MULTIPLE_SSI_DETAIL)))) .ToList())) .ToListAsync() .ConfigureAwait(false); @@ -127,7 +128,7 @@ await _repositories d.ExpiryDate, d.Documents)) .SingleOrDefault(), - (InvalidOperationException _) => throw ConflictException.Create(CredentialErrors.MULTIPLE_SSI_DETAIL)))) + (InvalidOperationException _) => throw ConflictException.Create(IssuerErrors.MULTIPLE_SSI_DETAIL)))) .ToList())) .ToListAsync() .ConfigureAwait(false); @@ -188,6 +189,7 @@ public async Task ApproveCredential(Guid credentialId, CancellationToken cancell var processId = CreateProcess(); var expiry = GetExpiryDate(data.DetailData?.ExpiryDate); + UpdateIssuanceDate(credentialId, data, companySsiRepository); companySsiRepository.AttachAndModifyCompanySsiDetails(credentialId, c => { c.CompanySsiDetailStatusId = data.Status; @@ -201,19 +203,35 @@ public async Task ApproveCredential(Guid credentialId, CancellationToken cancell c.ExpiryDate = expiry; c.ProcessId = processId; }); - var typeValue = data.Type.GetEnumValue() ?? throw UnexpectedConditionException.Create(CredentialErrors.CREDENTIAL_TYPE_NOT_FOUND, new ErrorParameter[] { new("verifiedCredentialType", data.Type.ToString()) }); - var content = JsonSerializer.Serialize(new { data.Type, CredentialId = credentialId }, Options); - await _portalService.AddNotification(content, _identity.CompanyUserId.Value, NotificationTypeId.CREDENTIAL_APPROVAL, cancellationToken).ConfigureAwait(false); - var mailParameters = new Dictionary + var typeValue = data.Type.GetEnumValue() ?? throw UnexpectedConditionException.Create(IssuerErrors.CREDENTIAL_TYPE_NOT_FOUND, new ErrorParameter[] { new("verifiedCredentialType", data.Type.ToString()) }); + var mailParameters = new MailParameter[] { - { "requestName", typeValue }, - { "credentialType", typeValue }, - { "expiryDate", expiry.ToString("o", CultureInfo.InvariantCulture) } + new("requestName", typeValue), + new("credentialType", typeValue), + new("expiryDate", expiry.ToString("o", CultureInfo.InvariantCulture)) }; await _portalService.TriggerMail("CredentialApproval", _identity.CompanyUserId.Value, mailParameters, cancellationToken).ConfigureAwait(false); + var content = JsonSerializer.Serialize(new { data.Type, CredentialId = credentialId }, Options); + await _portalService.AddNotification(content, _identity.CompanyUserId.Value, NotificationTypeId.CREDENTIAL_APPROVAL, cancellationToken).ConfigureAwait(false); await _repositories.SaveAsync().ConfigureAwait(false); } + private void UpdateIssuanceDate(Guid credentialId, SsiApprovalData data, + ICompanySsiDetailsRepository companySsiRepository) + { + var frameworkCredential = data.Schema!.Deserialize(); + if (frameworkCredential == null) + { + throw UnexpectedConditionException.Create(IssuerErrors.SCHEMA_NOT_FRAMEWORK); + } + + var newCredential = frameworkCredential with { IssuanceDate = _dateTimeProvider.OffsetNow }; + companySsiRepository.AttachAndModifyProcessData( + credentialId, + c => c.Schema = JsonSerializer.SerializeToDocument(frameworkCredential, Options), + c => c.Schema = JsonSerializer.SerializeToDocument(newCredential, Options)); + } + private Guid CreateProcess() { var processStepRepository = _repositories.GetInstance(); @@ -226,37 +244,52 @@ private static void ValidateApprovalData(Guid credentialId, bool exists, SsiAppr { if (!exists) { - throw NotFoundException.Create(CredentialErrors.SSI_DETAILS_NOT_FOUND, new ErrorParameter[] { new("credentialId", credentialId.ToString()) }); + throw NotFoundException.Create(IssuerErrors.SSI_DETAILS_NOT_FOUND, new ErrorParameter[] { new("credentialId", credentialId.ToString()) }); } if (data.Status != CompanySsiDetailStatusId.PENDING) { - throw ConflictException.Create(CredentialErrors.CREDENTIAL_NOT_PENDING, new ErrorParameter[] { new("credentialId", credentialId.ToString()), new("status", CompanySsiDetailStatusId.PENDING.ToString()) }); + throw ConflictException.Create(IssuerErrors.CREDENTIAL_NOT_PENDING, new ErrorParameter[] { new("credentialId", credentialId.ToString()), new("status", CompanySsiDetailStatusId.PENDING.ToString()) }); } if (string.IsNullOrWhiteSpace(data.Bpn)) { - throw UnexpectedConditionException.Create(CredentialErrors.BPN_NOT_SET); + throw UnexpectedConditionException.Create(IssuerErrors.BPN_NOT_SET); + } + + ValidateFrameworkCredential(data); + + if (Enum.GetValues().All(x => x != data.Kind)) + { + throw ConflictException.Create(IssuerErrors.KIND_NOT_SUPPORTED, new ErrorParameter[] { new("kind", data.Kind != null ? data.Kind.Value.ToString() : "empty kind") }); } - if (data.DetailData == null && data.Kind == VerifiedCredentialTypeKindId.FRAMEWORK) + if (data.ProcessId is not null) { - throw ConflictException.Create(CredentialErrors.EXTERNAL_TYPE_DETAIL_ID_NOT_SET); + throw UnexpectedConditionException.Create(IssuerErrors.ALREADY_LINKED_PROCESS); } - if (data.Kind != VerifiedCredentialTypeKindId.FRAMEWORK && data.Kind != VerifiedCredentialTypeKindId.MEMBERSHIP && data.Kind != VerifiedCredentialTypeKindId.BPN) + if (data.Schema is null) { - throw ConflictException.Create(CredentialErrors.KIND_NOT_SUPPORTED, new ErrorParameter[] { new("kind", data.Kind != null ? data.Kind.Value.ToString() : "empty kind") }); + throw UnexpectedConditionException.Create(IssuerErrors.SCHEMA_NOT_SET); } + } - if (data.Kind == VerifiedCredentialTypeKindId.FRAMEWORK && string.IsNullOrWhiteSpace(data.DetailData!.Version)) + private static void ValidateFrameworkCredential(SsiApprovalData data) + { + if (data.Kind != VerifiedCredentialTypeKindId.FRAMEWORK) { - throw ConflictException.Create(CredentialErrors.EMPTY_VERSION); + return; } - if (data.ProcessId is not null) + if (data.DetailData == null) { - throw UnexpectedConditionException.Create(CredentialErrors.ALREADY_LINKED_PROCESS); + throw ConflictException.Create(IssuerErrors.EXTERNAL_TYPE_DETAIL_ID_NOT_SET); + } + + if (string.IsNullOrWhiteSpace(data.DetailData!.Version)) + { + throw ConflictException.Create(IssuerErrors.EMPTY_VERSION); } } @@ -268,7 +301,7 @@ private DateTimeOffset GetExpiryDate(DateTimeOffset? expiryDate) if (expiry < now) { - throw ConflictException.Create(CredentialErrors.EXPIRY_DATE_IN_PAST); + throw ConflictException.Create(IssuerErrors.EXPIRY_DATE_IN_PAST); } return expiry > future ? future : expiry; @@ -286,22 +319,22 @@ public async Task RejectCredential(Guid credentialId, CancellationToken cancella var (exists, status, type, processId, processStepIds) = await companySsiRepository.GetSsiRejectionData(credentialId).ConfigureAwait(false); if (!exists) { - throw NotFoundException.Create(CredentialErrors.SSI_DETAILS_NOT_FOUND, new ErrorParameter[] { new("credentialId", credentialId.ToString()) }); + throw NotFoundException.Create(IssuerErrors.SSI_DETAILS_NOT_FOUND, new ErrorParameter[] { new("credentialId", credentialId.ToString()) }); } if (status != CompanySsiDetailStatusId.PENDING) { - throw ConflictException.Create(CredentialErrors.CREDENTIAL_NOT_PENDING, new ErrorParameter[] { new("credentialId", credentialId.ToString()), new("status", CompanySsiDetailStatusId.PENDING.ToString()) }); + throw ConflictException.Create(IssuerErrors.CREDENTIAL_NOT_PENDING, new ErrorParameter[] { new("credentialId", credentialId.ToString()), new("status", CompanySsiDetailStatusId.PENDING.ToString()) }); } - var typeValue = type.GetEnumValue() ?? throw UnexpectedConditionException.Create(CredentialErrors.CREDENTIAL_TYPE_NOT_FOUND, new ErrorParameter[] { new("verifiedCredentialType", type.ToString()) }); + var typeValue = type.GetEnumValue() ?? throw UnexpectedConditionException.Create(IssuerErrors.CREDENTIAL_TYPE_NOT_FOUND, new ErrorParameter[] { new("verifiedCredentialType", type.ToString()) }); var content = JsonSerializer.Serialize(new { Type = type, CredentialId = credentialId }, Options); await _portalService.AddNotification(content, _identity.CompanyUserId.Value, NotificationTypeId.CREDENTIAL_REJECTED, cancellationToken).ConfigureAwait(false); - var mailParameters = new Dictionary + var mailParameters = new MailParameter[] { - { "requestName", typeValue }, - { "reason", "Declined by the Operator" } + new("requestName", typeValue), + new("reason", "Declined by the Operator") }; await _portalService.TriggerMail("CredentialRejected", _identity.CompanyUserId.Value, mailParameters, cancellationToken).ConfigureAwait(false); @@ -392,37 +425,42 @@ public async Task CreateFrameworkCredential(CreateFrameworkCredentialReque var result = await companyCredentialDetailsRepository.CheckCredentialTypeIdExistsForExternalTypeDetailVersionId(requestData.UseCaseFrameworkVersionId, requestData.UseCaseFrameworkId).ConfigureAwait(false); if (!result.Exists) { - throw ControllerArgumentException.Create(CredentialErrors.EXTERNAL_TYPE_DETAIL_NOT_FOUND, new ErrorParameter[] { new("verifiedCredentialExternalTypeDetailId", requestData.UseCaseFrameworkId.ToString()) }); + throw ControllerArgumentException.Create(IssuerErrors.EXTERNAL_TYPE_DETAIL_NOT_FOUND, new ErrorParameter[] { new("verifiedCredentialExternalTypeDetailId", requestData.UseCaseFrameworkId.ToString()) }); } if (result.Expiry < _dateTimeProvider.OffsetNow) { - throw ControllerArgumentException.Create(CredentialErrors.EXPIRY_DATE_IN_PAST); + throw ControllerArgumentException.Create(IssuerErrors.EXPIRY_DATE_IN_PAST); } if (string.IsNullOrWhiteSpace(result.Version)) { - throw ControllerArgumentException.Create(CredentialErrors.EMPTY_VERSION); + throw ControllerArgumentException.Create(IssuerErrors.EMPTY_VERSION); } if (string.IsNullOrWhiteSpace(result.Template)) { - throw ControllerArgumentException.Create(CredentialErrors.EMPTY_TEMPLATE); + throw ControllerArgumentException.Create(IssuerErrors.EMPTY_TEMPLATE); + } + + if (result.ExternalTypeIds.Count() != 1) + { + throw ControllerArgumentException.Create(IssuerErrors.MULTIPLE_USE_CASES); } - if (result.UseCase.Count() != 1) + var externalTypeId = result.ExternalTypeIds.Single().GetEnumValue(); + if (externalTypeId is null) { - throw ControllerArgumentException.Create(CredentialErrors.MULTIPLE_USE_CASES); + throw ControllerArgumentException.Create(IssuerErrors.EMPTY_EXTERNAL_TYPE_ID); } - var useCase = result.UseCase.Single(); var holderDid = await GetHolderInformation(requestData.Holder, cancellationToken).ConfigureAwait(false); var schemaData = new FrameworkCredential( Guid.NewGuid(), Context, - new[] { "VerifiableCredential", $"{useCase}Credential" }, - $"{useCase}Credential", - $"Framework Credential for UseCase {useCase}", + new[] { "VerifiableCredential", $"{externalTypeId}Credential" }, + $"{externalTypeId}Credential", + $"Framework Credential for UseCase {externalTypeId}", DateTimeOffset.UtcNow, result.Expiry, _settings.IssuerDid, @@ -430,7 +468,7 @@ public async Task CreateFrameworkCredential(CreateFrameworkCredentialReque holderDid, requestData.HolderBpn, "UseCaseFramework", - useCase, + externalTypeId, result.Template!, result.Version! ), @@ -446,7 +484,7 @@ private async Task GetHolderInformation(string didDocumentLocation, Canc { if (!Uri.TryCreate(didDocumentLocation, UriKind.Absolute, out var uri) || uri.Scheme != "https" || !string.IsNullOrEmpty(uri.Query) || !string.IsNullOrEmpty(uri.Fragment) || UrlPathInvalidCharsRegex.IsMatch(uri.AbsolutePath)) { - throw ControllerArgumentException.Create(CredentialErrors.INVALID_DID_LOCATION, null, nameof(didDocumentLocation)); + throw ControllerArgumentException.Create(IssuerErrors.INVALID_DID_LOCATION, null, nameof(didDocumentLocation)); } var client = _clientFactory.CreateClient("didDocumentDownload"); @@ -455,7 +493,7 @@ private async Task GetHolderInformation(string didDocumentLocation, Canc var did = await result.Content.ReadFromJsonAsync(Options, cancellationToken).ConfigureAwait(false); if (did == null) { - throw ConflictException.Create(CredentialErrors.DID_NOT_SET); + throw ConflictException.Create(IssuerErrors.DID_NOT_SET); } return did.Id; @@ -471,7 +509,7 @@ private async Task HandleCredentialProcessCreation( string? callbackUrl, ICompanySsiDetailsRepository companyCredentialDetailsRepository) { - var documentContent = System.Text.Encoding.UTF8.GetBytes(schema); + var documentContent = Encoding.UTF8.GetBytes(schema); var hash = SHA512.HashData(documentContent); var documentRepository = _repositories.GetInstance(); var docId = documentRepository.CreateDocument("schema.json", documentContent, diff --git a/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/RevocationBusinessLogic.cs b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/RevocationBusinessLogic.cs new file mode 100644 index 00000000..b63cfdf4 --- /dev/null +++ b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/RevocationBusinessLogic.cs @@ -0,0 +1,82 @@ +/******************************************************************************** + * Copyright (c) 2024 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 Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Repositories; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.ErrorHandling; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Identity; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Services; + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Service.BusinessLogic; + +public class RevocationBusinessLogic : IRevocationBusinessLogic +{ + private readonly IIssuerRepositories _repositories; + private readonly IWalletService _walletService; + private readonly IIdentityData _identityData; + + public RevocationBusinessLogic(IIssuerRepositories repositories, IWalletService walletService, IIdentityService identityService) + { + _repositories = repositories; + _walletService = walletService; + _identityData = identityService.IdentityData; + } + + public async Task RevokeCredential(Guid credentialId, bool revokeForIssuer, CancellationToken cancellationToken) + { + var credentialRepository = _repositories.GetInstance(); + var data = await credentialRepository.GetRevocationDataById(credentialId, _identityData.Bpnl) + .ConfigureAwait(false); + if (!data.Exists) + { + throw NotFoundException.Create(RevocationDataErrors.CREDENTIAL_NOT_FOUND, new ErrorParameter[] { new("credentialId", credentialId.ToString()) }); + } + + if (!revokeForIssuer && !data.IsSameBpnl) + { + throw ForbiddenException.Create(RevocationDataErrors.NOT_ALLOWED_TO_REVOKE_CREDENTIAL); + } + + if (data.ExternalCredentialId is null) + { + throw ConflictException.Create(RevocationDataErrors.EXTERNAL_CREDENTIAL_ID_NOT_SET, new ErrorParameter[] { new("credentialId", credentialId.ToString()) }); + } + + if (data.StatusId != CompanySsiDetailStatusId.ACTIVE) + { + return; + } + + // call walletService + await _walletService.RevokeCredentialForIssuer(data.ExternalCredentialId.Value, cancellationToken).ConfigureAwait(false); + _repositories.GetInstance().AttachAndModifyDocuments( + data.Documents.Select(d => new ValueTuple?, Action>( + d.DocumentId, + document => document.DocumentStatusId = d.DocumentStatusId, + document => document.DocumentStatusId = DocumentStatusId.INACTIVE + ))); + + credentialRepository.AttachAndModifyCredential(credentialId, + x => x.CompanySsiDetailStatusId = data.StatusId, + x => x.CompanySsiDetailStatusId = CompanySsiDetailStatusId.REVOKED); + } +} diff --git a/src/issuer/SsiCredentialIssuer.Service/Controllers/CredentialController.cs b/src/issuer/SsiCredentialIssuer.Service/Controllers/CredentialController.cs new file mode 100644 index 00000000..2474365d --- /dev/null +++ b/src/issuer/SsiCredentialIssuer.Service/Controllers/CredentialController.cs @@ -0,0 +1,50 @@ +/******************************************************************************** + * Copyright (c) 2024 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 Microsoft.AspNetCore.Mvc; +using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling.Web; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.BusinessLogic; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Extensions; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Identity; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Models; +using System.Text.Json; + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Controllers; + +public static class CredentialController +{ + public static RouteGroupBuilder MapCredentialApi(this RouteGroupBuilder group) + { + var issuer = group.MapGroup("/credential"); + + issuer.MapGet("{credentialId}", ([FromRoute] Guid credentialId, [FromServices] ICredentialBusinessLogic logic) => logic.GetCredentialDocument(credentialId)) + .WithSwaggerDescription("The endpoint enables users to download the credential (full json) of their own company.", + "Example: GET: api/credential/{credentialId}") + .RequireAuthorization(r => + { + r.RequireRole("view_credential"); + r.AddRequirements(new MandatoryIdentityClaimRequirement(PolicyTypeId.ValidBpn)); + }) + .WithDefaultResponses() + .Produces(StatusCodes.Status200OK, typeof(JsonDocument), Constants.JsonContentType) + .Produces(StatusCodes.Status409Conflict, typeof(ErrorResponse), Constants.JsonContentType); + + return issuer; + } +} diff --git a/src/issuer/SsiCredentialIssuer.Service/Controllers/RevocationController.cs b/src/issuer/SsiCredentialIssuer.Service/Controllers/RevocationController.cs new file mode 100644 index 00000000..4bb091a4 --- /dev/null +++ b/src/issuer/SsiCredentialIssuer.Service/Controllers/RevocationController.cs @@ -0,0 +1,67 @@ +/******************************************************************************** + * Copyright (c) 2024 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 Microsoft.AspNetCore.Mvc; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Models; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.BusinessLogic; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Extensions; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Identity; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Models; + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Controllers; + +/// +/// Creates a new instance of +/// +public static class RevocationController +{ + public static RouteGroupBuilder MapRevocationApi(this RouteGroupBuilder group) + { + var revocation = group.MapGroup("/revocation"); + + revocation.MapPost("issuer/credentials/{credentialId}", ([FromRoute] Guid credentialId, CancellationToken cancellationToken, [FromServices] IRevocationBusinessLogic logic) => logic.RevokeCredential(credentialId, true, cancellationToken)) + .WithSwaggerDescription("Revokes an credential which was issued by the given issuer", + "POST: api/revocation/issuer/credentials/{credentialId}", + "Id of the credential that should be revoked") + .RequireAuthorization(r => + { + // r.RequireRole("revoke_credentials_issuer"); + r.AddRequirements(new MandatoryIdentityClaimRequirement(PolicyTypeId.ValidBpn)); + r.AddRequirements(new MandatoryIdentityClaimRequirement(PolicyTypeId.ValidIdentity)); + }) + .WithDefaultResponses() + .Produces(StatusCodes.Status200OK, typeof(Guid)); + revocation.MapPost("credentials/{credentialId}", ([FromRoute] Guid credentialId, CancellationToken cancellationToken, [FromServices] IRevocationBusinessLogic logic) => logic.RevokeCredential(credentialId, false, cancellationToken)) + .WithSwaggerDescription("Revokes an credential of an holder", + "POST: api/revocation/credentials/{credentialId}", + "Id of the credential that should be revoked", + "The information for the holder wallet", + "CancellationToken") + .RequireAuthorization(r => + { + r.RequireRole("revoke_credential"); + r.AddRequirements(new MandatoryIdentityClaimRequirement(PolicyTypeId.ValidBpn)); + r.AddRequirements(new MandatoryIdentityClaimRequirement(PolicyTypeId.ValidIdentity)); + }) + .WithDefaultResponses() + .Produces(StatusCodes.Status200OK, typeof(Guid), contentType: Constants.JsonContentType); + + return group; + } +} diff --git a/src/issuer/SsiCredentialIssuer.Service/DependencyInjection/ServiceCollectionExtensions.cs b/src/issuer/SsiCredentialIssuer.Service/DependencyInjection/ServiceCollectionExtensions.cs new file mode 100644 index 00000000..35f71627 --- /dev/null +++ b/src/issuer/SsiCredentialIssuer.Service/DependencyInjection/ServiceCollectionExtensions.cs @@ -0,0 +1,44 @@ +/******************************************************************************** + * Copyright (c) 2024 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 Org.Eclipse.TractusX.SsiCredentialIssuer.Service.BusinessLogic; + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Service.DependencyInjection; + +public static class ServiceCollectionExtensions +{ + internal static IServiceCollection AddServices(this IServiceCollection services, IConfiguration config) => + services + .AddIssuerService(config.GetSection("Credential")) + .AddRevocationService() + .AddCredentialService(); + + private static IServiceCollection AddIssuerService(this IServiceCollection services, IConfigurationSection section) => + services + .ConfigureCredentialSettings(section) + .AddTransient(); + + private static IServiceCollection AddRevocationService(this IServiceCollection services) => + services + .AddTransient(); + + private static IServiceCollection AddCredentialService(this IServiceCollection services) => + services + .AddTransient(); +} diff --git a/src/issuer/SsiCredentialIssuer.Service/ErrorHandling/CredentialErrorMessageContainer.cs b/src/issuer/SsiCredentialIssuer.Service/ErrorHandling/CredentialErrorMessageContainer.cs index 86015c51..a4f219bd 100644 --- a/src/issuer/SsiCredentialIssuer.Service/ErrorHandling/CredentialErrorMessageContainer.cs +++ b/src/issuer/SsiCredentialIssuer.Service/ErrorHandling/CredentialErrorMessageContainer.cs @@ -55,6 +55,12 @@ public class CredentialErrorMessageContainer : IErrorMessageContainer { CredentialErrors.ALREADY_LINKED_PROCESS, "Credential should not already be linked to a process" }, { CredentialErrors.INVALID_DID_LOCATION, "The did url location must be a valid url" }, { CredentialErrors.USER_MUST_NOT_BE_TECHNICAL_USER, "The endpoint can not be called by a technical user" }, + { CredentialErrors.EMPTY_EXTERNAL_TYPE_ID, "External Type ID must be set" }, + { CredentialErrors.SCHEMA_NOT_SET, "The json schema must be set when approving a credential" }, + { CredentialErrors.SCHEMA_NOT_FRAMEWORK, "The schema must be a framework credential" }, + { CredentialErrors.CREDENTIAL_NOT_FOUND, "Credential {credentialId} does not exist" }, + { CredentialErrors.COMPANY_NOT_ALLOWED, "Not allowed to display the credential" }, + { CredentialErrors.SIGNED_CREDENTIAL_NOT_FOUND, "There must be exactly one signed credential" } }.ToImmutableDictionary(x => (int)x.Key, x => x.Value); public Type Type { get => typeof(CredentialErrors); } @@ -90,5 +96,11 @@ public enum CredentialErrors DID_NOT_SET, ALREADY_LINKED_PROCESS, INVALID_DID_LOCATION, - USER_MUST_NOT_BE_TECHNICAL_USER + USER_MUST_NOT_BE_TECHNICAL_USER, + EMPTY_EXTERNAL_TYPE_ID, + SCHEMA_NOT_SET, + SCHEMA_NOT_FRAMEWORK, + CREDENTIAL_NOT_FOUND, + COMPANY_NOT_ALLOWED, + SIGNED_CREDENTIAL_NOT_FOUND } diff --git a/src/issuer/SsiCredentialIssuer.Service/ErrorHandling/IssuerErrorMessageContainer.cs b/src/issuer/SsiCredentialIssuer.Service/ErrorHandling/IssuerErrorMessageContainer.cs new file mode 100644 index 00000000..50832b96 --- /dev/null +++ b/src/issuer/SsiCredentialIssuer.Service/ErrorHandling/IssuerErrorMessageContainer.cs @@ -0,0 +1,98 @@ +/******************************************************************************** + * Copyright (c) 2024 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 Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling.Service; +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Service.ErrorHandling; + +[ExcludeFromCodeCoverage] +public class IssuerErrorMessageContainer : IErrorMessageContainer +{ + private static readonly IReadOnlyDictionary _messageContainer = new Dictionary { + { IssuerErrors.INVALID_COMPANY, "company {companyId} is not a valid company" }, + { IssuerErrors.INVALID_COMPANY_STATUS, "Company Status is Incorrect" }, + { IssuerErrors.USE_CASE_NOT_FOUND, "UseCaseId {useCaseId} is not available" }, + { IssuerErrors.INVALID_LANGUAGECODE, "language {languageShortName} is not a valid languagecode" }, + { IssuerErrors.COMPANY_NOT_FOUND, "company {companyId} does not exist" }, + { IssuerErrors.COMPANY_ROLE_IDS_CONSENT_STATUS_NULL, "neither CompanyRoleIds nor ConsentStatusDetails should ever be null here" }, + { IssuerErrors.MISSING_AGREEMENTS, "All agreements need to get signed as Active or InActive. Missing consents: [{missingConsents}]" }, + { IssuerErrors.UNASSIGN_ALL_ROLES, "Company can't unassign from all roles, Atleast one Company role need to signed as active" }, + { IssuerErrors.AGREEMENTS_NOT_ASSIGNED_WITH_ROLES, "Agreements not associated with requested companyRoles: [{companyRoles}]" }, + { IssuerErrors.MULTIPLE_SSI_DETAIL, "There should only be one pending or active ssi detail be assigne" }, + { IssuerErrors.EXTERNAL_TYPE_DETAIL_NOT_FOUND, "VerifiedCredentialExternalTypeDetail {verifiedCredentialExternalTypeDetailId} does not exist" }, + { IssuerErrors.EXPIRY_DATE_IN_PAST, "The expiry date must not be in the past" }, + { IssuerErrors.CREDENTIAL_NO_CERTIFICATE, "{credentialTypeId} is not assigned to a certificate" }, + { IssuerErrors.EXTERNAL_TYPE_DETAIL_ID_NOT_SET, "The VerifiedCredentialExternalTypeDetailId must be set" }, + { IssuerErrors.CREDENTIAL_ALREADY_EXISTING, "Credential request already existing" }, + { IssuerErrors.CREDENTIAL_TYPE_NOT_FOUND, "VerifiedCredentialType {verifiedCredentialType} does not exists" }, + { IssuerErrors.SSI_DETAILS_NOT_FOUND, "CompanySsiDetail {credentialId} does not exists" }, + { IssuerErrors.CREDENTIAL_NOT_PENDING, "Credential {credentialId} must be {status}" }, + { IssuerErrors.BPN_NOT_SET, "Bpn should be set for company" }, + { IssuerErrors.EXPIRY_DATE_NOT_SET, "Expiry date must always be set for use cases" }, + { IssuerErrors.EMPTY_VERSION, "External Detail Version must not be null" }, + { IssuerErrors.EMPTY_TEMPLATE, "Template must not be null" }, + { IssuerErrors.KIND_NOT_SUPPORTED, "{kind} is currently not supported" }, + { IssuerErrors.MULTIPLE_USE_CASES, "There must only be one use case" }, + { IssuerErrors.DID_NOT_SET, "Did must not be null" }, + { IssuerErrors.ALREADY_LINKED_PROCESS, "Credential should not already be linked to a process" }, + { IssuerErrors.INVALID_DID_LOCATION, "The did url location must be a valid url" }, + { IssuerErrors.EMPTY_EXTERNAL_TYPE_ID, "External Type ID must be set" }, + { IssuerErrors.SCHEMA_NOT_SET, "The json schema must be set when approving a credential" }, + { IssuerErrors.SCHEMA_NOT_FRAMEWORK, "The schema must be a framework credential" } + }.ToImmutableDictionary(x => (int)x.Key, x => x.Value); + + public Type Type { get => typeof(IssuerErrors); } + public IReadOnlyDictionary MessageContainer { get => _messageContainer; } +} + +public enum IssuerErrors +{ + INVALID_COMPANY, + INVALID_COMPANY_STATUS, + USE_CASE_NOT_FOUND, + INVALID_LANGUAGECODE, + COMPANY_NOT_FOUND, + COMPANY_ROLE_IDS_CONSENT_STATUS_NULL, + MISSING_AGREEMENTS, + UNASSIGN_ALL_ROLES, + AGREEMENTS_NOT_ASSIGNED_WITH_ROLES, + MULTIPLE_SSI_DETAIL, + EXTERNAL_TYPE_DETAIL_NOT_FOUND, + EXPIRY_DATE_IN_PAST, + CREDENTIAL_NO_CERTIFICATE, + EXTERNAL_TYPE_DETAIL_ID_NOT_SET, + CREDENTIAL_ALREADY_EXISTING, + CREDENTIAL_TYPE_NOT_FOUND, + SSI_DETAILS_NOT_FOUND, + CREDENTIAL_NOT_PENDING, + BPN_NOT_SET, + EXPIRY_DATE_NOT_SET, + EMPTY_VERSION, + EMPTY_TEMPLATE, + KIND_NOT_SUPPORTED, + MULTIPLE_USE_CASES, + DID_NOT_SET, + ALREADY_LINKED_PROCESS, + INVALID_DID_LOCATION, + EMPTY_EXTERNAL_TYPE_ID, + SCHEMA_NOT_SET, + SCHEMA_NOT_FRAMEWORK +} diff --git a/src/issuer/SsiCredentialIssuer.Service/ErrorHandling/RevocationErrorMessageContainer.cs b/src/issuer/SsiCredentialIssuer.Service/ErrorHandling/RevocationErrorMessageContainer.cs new file mode 100644 index 00000000..298c5de3 --- /dev/null +++ b/src/issuer/SsiCredentialIssuer.Service/ErrorHandling/RevocationErrorMessageContainer.cs @@ -0,0 +1,44 @@ +/******************************************************************************** + * Copyright (c) 2024 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 Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling.Service; +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Service.ErrorHandling; + +[ExcludeFromCodeCoverage] +public class RevocationErrorMessageContainer : IErrorMessageContainer +{ + private static readonly IReadOnlyDictionary _messageContainer = new Dictionary { + { RevocationDataErrors.CREDENTIAL_NOT_FOUND, "Credential {credentialId} does not exist" }, + { RevocationDataErrors.EXTERNAL_CREDENTIAL_ID_NOT_SET, "External Credential Id must be set for {credentialId}" }, + { RevocationDataErrors.NOT_ALLOWED_TO_REVOKE_CREDENTIAL, "Not allowed to revoke credential" } + }.ToImmutableDictionary(x => (int)x.Key, x => x.Value); + + public Type Type { get => typeof(RevocationDataErrors); } + public IReadOnlyDictionary MessageContainer { get => _messageContainer; } +} + +public enum RevocationDataErrors +{ + CREDENTIAL_NOT_FOUND, + EXTERNAL_CREDENTIAL_ID_NOT_SET, + NOT_ALLOWED_TO_REVOKE_CREDENTIAL +} diff --git a/src/issuer/SsiCredentialIssuer.Service/Models/CredentialData.cs b/src/issuer/SsiCredentialIssuer.Service/Models/CredentialData.cs index 378379d6..8bbd802d 100644 --- a/src/issuer/SsiCredentialIssuer.Service/Models/CredentialData.cs +++ b/src/issuer/SsiCredentialIssuer.Service/Models/CredentialData.cs @@ -35,7 +35,7 @@ public record FrameworkCredential( public record FrameworkCredentialSubject( [property: JsonPropertyName("id")] string Did, - [property: JsonPropertyName("holderIndentifier")] string HolderIndentifier, + [property: JsonPropertyName("holderIdentifier")] string HolderIdentifier, [property: JsonPropertyName("group")] string Group, [property: JsonPropertyName("useCase")] string UseCase, [property: JsonPropertyName("contractTemplate")] string ContractTemplate, @@ -56,7 +56,7 @@ public record MembershipCredential( public record MembershipCredentialSubject( [property: JsonPropertyName("id")] string Did, - [property: JsonPropertyName("holderIndentifier")] string HolderIndentifier, + [property: JsonPropertyName("holderIdentifier")] string HolderIdentifier, [property: JsonPropertyName("memberOf")] string MemberOf ); @@ -79,6 +79,6 @@ public record CredentialStatus( public record BpnCredentialSubject( [property: JsonPropertyName("id")] string Did, - [property: JsonPropertyName("holderIndentifier")] string HolderIndentifier, + [property: JsonPropertyName("holderIdentifier")] string HolderIdentifier, [property: JsonPropertyName("bpn")] string Bpn ); diff --git a/src/issuer/SsiCredentialIssuer.Service/Program.cs b/src/issuer/SsiCredentialIssuer.Service/Program.cs index 3b1dcd7f..6f1b8fa2 100644 --- a/src/issuer/SsiCredentialIssuer.Service/Program.cs +++ b/src/issuer/SsiCredentialIssuer.Service/Program.cs @@ -29,6 +29,7 @@ using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.DependencyInjection; using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.ErrorHandling; using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Identity; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.DependencyInjection; using System.Text.Json.Serialization; const string VERSION = "v1"; @@ -51,14 +52,19 @@ { options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); }) - .AddCredentialService(builder.Configuration.GetSection("Credential")) + .AddServices(builder.Configuration) + .AddWalletService(builder.Configuration) .AddPortalService(builder.Configuration.GetSection("Portal")) .AddSingleton() + .AddSingleton() + .AddSingleton() .AddSingleton(); }, (app, _) => { app.MapGroup("/api") .WithOpenApi() - .MapIssuerApi(); + .MapIssuerApi() + .MapRevocationApi() + .MapCredentialApi(); }); diff --git a/src/issuer/SsiCredentialIssuer.Service/appsettings.json b/src/issuer/SsiCredentialIssuer.Service/appsettings.json index 67731a38..191d8b6d 100644 --- a/src/issuer/SsiCredentialIssuer.Service/appsettings.json +++ b/src/issuer/SsiCredentialIssuer.Service/appsettings.json @@ -53,19 +53,24 @@ "KeycloakTokenAddress": "", "BaseAddress": "" }, + "Wallet": { + "Username": "", + "Password": "", + "ClientId": "", + "GrantType": "", + "ClientSecret": "", + "Scope": "", + "TokenAddress": "", + "BaseAddress": "", + "EncryptionConfigIndex": 0, + "EncryptionConfigs": [] + }, "Credential": { "IssuerDid": "", "IssuerBpn": "", "StatusListUrl": "", "MaxPageSize": 15, "EncryptionConfigIndex": 0, - "EncryptionConfigs": [ - { - "Index": 0, - "EncryptionKey": "", - "CipherMode": "", - "PaddingMode": "" - } - ] + "EncryptionConfigs": [] } } diff --git a/src/processes/CredentialProcess.Library/CredentialProcessHandler.cs b/src/processes/CredentialProcess.Library/Creation/CredentialCreationProcessHandler.cs similarity index 90% rename from src/processes/CredentialProcess.Library/CredentialProcessHandler.cs rename to src/processes/CredentialProcess.Library/Creation/CredentialCreationProcessHandler.cs index 0fa0f39a..9ff1588d 100644 --- a/src/processes/CredentialProcess.Library/CredentialProcessHandler.cs +++ b/src/processes/CredentialProcess.Library/Creation/CredentialCreationProcessHandler.cs @@ -26,15 +26,15 @@ using Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.BusinessLogic; using Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Models; -namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library; +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Creation; -public class CredentialProcessHandler : ICredentialProcessHandler +public class CredentialCreationProcessHandler : ICredentialCreationProcessHandler { private readonly IIssuerRepositories _issuerRepositories; private readonly IWalletBusinessLogic _walletBusinessLogic; private readonly ICallbackService _callbackService; - public CredentialProcessHandler(IIssuerRepositories issuerRepositories, IWalletBusinessLogic walletBusinessLogic, ICallbackService callbackService) + public CredentialCreationProcessHandler(IIssuerRepositories issuerRepositories, IWalletBusinessLogic walletBusinessLogic, ICallbackService callbackService) { _issuerRepositories = issuerRepositories; _walletBusinessLogic = walletBusinessLogic; @@ -45,7 +45,7 @@ public CredentialProcessHandler(IIssuerRepositories issuerRepositories, IWalletB { var data = await _issuerRepositories.GetInstance().GetCredentialStorageInformationById(credentialId).ConfigureAwait(false); await _walletBusinessLogic.CreateCredential(credentialId, data.Schema, cancellationToken).ConfigureAwait(false); - return new ValueTuple?, ProcessStepStatusId, bool, string?>( + return ( Enumerable.Repeat(ProcessStepTypeId.SIGN_CREDENTIAL, 1), ProcessStepStatusId.DONE, false, @@ -61,7 +61,7 @@ public CredentialProcessHandler(IIssuerRepositories issuerRepositories, IWalletB } await _walletBusinessLogic.SignCredential(credentialId, externalCredentialId!.Value, cancellationToken).ConfigureAwait(false); - return new ValueTuple?, ProcessStepStatusId, bool, string?>( + return ( Enumerable.Repeat(ProcessStepTypeId.SAVE_CREDENTIAL_DOCUMENT, 1), ProcessStepStatusId.DONE, false, @@ -78,7 +78,7 @@ public CredentialProcessHandler(IIssuerRepositories issuerRepositories, IWalletB await _walletBusinessLogic.GetCredential(credentialId, externalCredentialId.Value, kindId, cancellationToken).ConfigureAwait(false); var nextProcessStep = callbackUrl == null ? null : Enumerable.Repeat(ProcessStepTypeId.TRIGGER_CALLBACK, 1); - return new ValueTuple?, ProcessStepStatusId, bool, string?>( + return ( hasEncryptionInformation ? Enumerable.Repeat(ProcessStepTypeId.CREATE_CREDENTIAL_FOR_HOLDER, 1) : nextProcessStep, @@ -106,7 +106,7 @@ public CredentialProcessHandler(IIssuerRepositories issuerRepositories, IWalletB } await _walletBusinessLogic.CreateCredentialForHolder(credentialId, holderWalletData.WalletUrl, holderWalletData.ClientId, new EncryptionInformation(encryptionInformation.Secret, encryptionInformation.InitializationVector, encryptionInformation.EncryptionMode.Value), credential, cancellationToken).ConfigureAwait(false); - return new ValueTuple?, ProcessStepStatusId, bool, string?>( + return ( callbackUrl is null ? null : Enumerable.Repeat(ProcessStepTypeId.TRIGGER_CALLBACK, 1), ProcessStepStatusId.DONE, false, @@ -123,7 +123,7 @@ public CredentialProcessHandler(IIssuerRepositories issuerRepositories, IWalletB var issuerResponseData = new IssuerResponseData(bpn, IssuerResponseStatus.SUCCESSFUL, "Successfully created Credential"); await _callbackService.TriggerCallback(callbackUrl, issuerResponseData, cancellationToken).ConfigureAwait(false); - return new ValueTuple?, ProcessStepStatusId, bool, string?>( + return ( null, ProcessStepStatusId.DONE, false, diff --git a/src/processes/CredentialProcess.Library/ICredentialProcessHandler.cs b/src/processes/CredentialProcess.Library/Creation/ICredentialCreationProcessHandler.cs similarity index 96% rename from src/processes/CredentialProcess.Library/ICredentialProcessHandler.cs rename to src/processes/CredentialProcess.Library/Creation/ICredentialCreationProcessHandler.cs index d21b1c9e..f68c31ab 100644 --- a/src/processes/CredentialProcess.Library/ICredentialProcessHandler.cs +++ b/src/processes/CredentialProcess.Library/Creation/ICredentialCreationProcessHandler.cs @@ -19,9 +19,9 @@ using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; -namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library; +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Creation; -public interface ICredentialProcessHandler +public interface ICredentialCreationProcessHandler { Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> CreateCredential(Guid credentialId, CancellationToken cancellationToken); Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> SignCredential(Guid credentialId, CancellationToken cancellationToken); diff --git a/src/processes/CredentialProcess.Library/CredentialProcess.Library.csproj b/src/processes/CredentialProcess.Library/CredentialProcess.Library.csproj index 5a100318..bb58a792 100644 --- a/src/processes/CredentialProcess.Library/CredentialProcess.Library.csproj +++ b/src/processes/CredentialProcess.Library/CredentialProcess.Library.csproj @@ -30,6 +30,7 @@ + diff --git a/src/processes/CredentialProcess.Library/DependencyInjection/CredentialHandlerExtensions.cs b/src/processes/CredentialProcess.Library/DependencyInjection/CredentialHandlerExtensions.cs index 6296675f..ac774cbd 100644 --- a/src/processes/CredentialProcess.Library/DependencyInjection/CredentialHandlerExtensions.cs +++ b/src/processes/CredentialProcess.Library/DependencyInjection/CredentialHandlerExtensions.cs @@ -19,16 +19,27 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Creation; +using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Expiry; using Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.DependencyInjection; namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.DependencyInjection; public static class CredentialHandlerExtensions { - public static IServiceCollection AddCredentialProcessHandler(this IServiceCollection services, IConfiguration config) + public static IServiceCollection AddCredentialCreationProcessHandler(this IServiceCollection services, IConfiguration config) { services - .AddTransient() + .AddTransient() + .AddWalletService(config); + + return services; + } + + public static IServiceCollection AddCredentialExpiryProcessHandler(this IServiceCollection services, IConfiguration config) + { + services + .AddTransient() .AddWalletService(config); return services; diff --git a/src/processes/CredentialProcess.Library/Expiry/CredentialExpiryProcessHandler.cs b/src/processes/CredentialProcess.Library/Expiry/CredentialExpiryProcessHandler.cs new file mode 100644 index 00000000..c1fc6ed2 --- /dev/null +++ b/src/processes/CredentialProcess.Library/Expiry/CredentialExpiryProcessHandler.cs @@ -0,0 +1,119 @@ +/******************************************************************************** + * Copyright (c) 2024 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 Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; +using Org.Eclipse.TractusX.Portal.Backend.Framework.Models; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Repositories; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Portal.Service.Models; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Portal.Service.Services; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Services; +using System.Text.Json; + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Expiry; + +public class CredentialExpiryProcessHandler : ICredentialExpiryProcessHandler +{ + private static readonly JsonSerializerOptions Options = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; + private readonly IIssuerRepositories _repositories; + private readonly IWalletService _walletService; + private readonly IPortalService _portalService; + + public CredentialExpiryProcessHandler(IIssuerRepositories repositories, IWalletService walletService, IPortalService portalService) + { + _repositories = repositories; + _walletService = walletService; + _portalService = portalService; + } + + public async Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> RevokeCredential(Guid credentialId, CancellationToken cancellationToken) + { + var credentialRepository = _repositories.GetInstance(); + var data = await credentialRepository.GetRevocationDataById(credentialId, string.Empty) + .ConfigureAwait(false); + if (!data.Exists) + { + throw new NotFoundException($"Credential {credentialId} does not exist"); + } + + if (data.ExternalCredentialId is null) + { + throw new ConflictException($"External Credential Id must be set for {credentialId}"); + } + + // call walletService + await _walletService.RevokeCredentialForIssuer(data.ExternalCredentialId.Value, cancellationToken).ConfigureAwait(false); + + _repositories.GetInstance().AttachAndModifyDocuments( + data.Documents.Select(d => new ValueTuple?, Action>( + d.DocumentId, + document => document.DocumentStatusId = d.DocumentStatusId, + document => document.DocumentStatusId = DocumentStatusId.INACTIVE + ))); + + credentialRepository.AttachAndModifyCredential(credentialId, + x => x.CompanySsiDetailStatusId = data.StatusId, + x => x.CompanySsiDetailStatusId = CompanySsiDetailStatusId.REVOKED); + + return ( + Enumerable.Repeat(ProcessStepTypeId.TRIGGER_NOTIFICATION, 1), + ProcessStepStatusId.DONE, + false, + null); + } + + public async Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> TriggerNotification(Guid credentialId, CancellationToken cancellationToken) + { + var (typeId, requesterId) = await _repositories.GetInstance().GetCredentialNotificationData(credentialId).ConfigureAwait(false); + if (Guid.TryParse(requesterId, out var companyUserId)) + { + var content = JsonSerializer.Serialize(new { Type = typeId, CredentialId = credentialId }, Options); + await _portalService.AddNotification(content, companyUserId, NotificationTypeId.CREDENTIAL_REJECTED, cancellationToken); + } + + return ( + Enumerable.Repeat(ProcessStepTypeId.TRIGGER_MAIL, 1), + ProcessStepStatusId.DONE, + false, + null); + } + + public async Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> TriggerMail(Guid credentialId, CancellationToken cancellationToken) + { + var (typeId, requesterId) = await _repositories.GetInstance().GetCredentialNotificationData(credentialId).ConfigureAwait(false); + + var typeValue = typeId.GetEnumValue() ?? throw new UnexpectedConditionException($"VerifiedCredentialType {typeId} does not exists"); + if (Guid.TryParse(requesterId, out var companyUserId)) + { + var mailParameters = new MailParameter[] + { + new("requestName", typeValue), new("reason", "The credential is already expired") + }; + await _portalService.TriggerMail("CredentialRejected", companyUserId, mailParameters, cancellationToken); + } + + return ( + null, + ProcessStepStatusId.DONE, + false, + null); + } +} diff --git a/src/processes/CredentialProcess.Library/Expiry/ICredentialExpiryProcessHandler.cs b/src/processes/CredentialProcess.Library/Expiry/ICredentialExpiryProcessHandler.cs new file mode 100644 index 00000000..33bcc790 --- /dev/null +++ b/src/processes/CredentialProcess.Library/Expiry/ICredentialExpiryProcessHandler.cs @@ -0,0 +1,29 @@ +/******************************************************************************** + * Copyright (c) 2024 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 Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Expiry; + +public interface ICredentialExpiryProcessHandler +{ + Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> RevokeCredential(Guid credentialId, CancellationToken cancellationToken); + Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> TriggerNotification(Guid credentialId, CancellationToken cancellationToken); + Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> TriggerMail(Guid credentialId, CancellationToken cancellationToken); +} diff --git a/src/processes/CredentialProcess.Worker/CredentialProcessTypeExecutor.cs b/src/processes/CredentialProcess.Worker/Creation/CredentialCreationProcessTypeExecutor.cs similarity index 84% rename from src/processes/CredentialProcess.Worker/CredentialProcessTypeExecutor.cs rename to src/processes/CredentialProcess.Worker/Creation/CredentialCreationProcessTypeExecutor.cs index b260f92d..745ef098 100644 --- a/src/processes/CredentialProcess.Worker/CredentialProcessTypeExecutor.cs +++ b/src/processes/CredentialProcess.Worker/Creation/CredentialCreationProcessTypeExecutor.cs @@ -18,19 +18,19 @@ ********************************************************************************/ using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; -using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library; +using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Creation; using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess; using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Repositories; using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; using Org.Eclipse.TractusX.SsiCredentialIssuer.Processes.Worker.Library; using System.Collections.Immutable; -namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Worker; +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Worker.Creation; -public class CredentialProcessTypeExecutor : IProcessTypeExecutor +public class CredentialCreationProcessTypeExecutor : IProcessTypeExecutor { private readonly IIssuerRepositories _issuerRepositories; - private readonly ICredentialProcessHandler _credentialProcessHandler; + private readonly ICredentialCreationProcessHandler _credentialCreationProcessHandler; private readonly IEnumerable _executableProcessSteps = ImmutableArray.Create( ProcessStepTypeId.CREATE_CREDENTIAL, @@ -41,18 +41,18 @@ public class CredentialProcessTypeExecutor : IProcessTypeExecutor private Guid _credentialId; - public CredentialProcessTypeExecutor( + public CredentialCreationProcessTypeExecutor( IIssuerRepositories issuerRepositories, - ICredentialProcessHandler credentialProcessHandler) + ICredentialCreationProcessHandler credentialCreationProcessHandler) { _issuerRepositories = issuerRepositories; - _credentialProcessHandler = credentialProcessHandler; + _credentialCreationProcessHandler = credentialCreationProcessHandler; } public ProcessTypeId GetProcessTypeId() => ProcessTypeId.CREATE_CREDENTIAL; public bool IsExecutableStepTypeId(ProcessStepTypeId processStepTypeId) => _executableProcessSteps.Contains(processStepTypeId); public IEnumerable GetExecutableStepTypeIds() => _executableProcessSteps; - public ValueTask IsLockRequested(ProcessStepTypeId processStepTypeId) => new(false); + public ValueTask IsLockRequested(ProcessStepTypeId processStepTypeId) => ValueTask.FromResult(false); public async ValueTask InitializeProcess(Guid processId, IEnumerable processStepTypeIds) { @@ -82,15 +82,15 @@ public CredentialProcessTypeExecutor( { (nextStepTypeIds, stepStatusId, modified, processMessage) = processStepTypeId switch { - ProcessStepTypeId.CREATE_CREDENTIAL => await _credentialProcessHandler.CreateCredential(_credentialId, cancellationToken) + ProcessStepTypeId.CREATE_CREDENTIAL => await _credentialCreationProcessHandler.CreateCredential(_credentialId, cancellationToken) .ConfigureAwait(false), - ProcessStepTypeId.SIGN_CREDENTIAL => await _credentialProcessHandler.SignCredential(_credentialId, cancellationToken) + ProcessStepTypeId.SIGN_CREDENTIAL => await _credentialCreationProcessHandler.SignCredential(_credentialId, cancellationToken) .ConfigureAwait(false), - ProcessStepTypeId.SAVE_CREDENTIAL_DOCUMENT => await _credentialProcessHandler.SaveCredentialDocument(_credentialId, cancellationToken) + ProcessStepTypeId.SAVE_CREDENTIAL_DOCUMENT => await _credentialCreationProcessHandler.SaveCredentialDocument(_credentialId, cancellationToken) .ConfigureAwait(false), - ProcessStepTypeId.CREATE_CREDENTIAL_FOR_HOLDER => await _credentialProcessHandler.CreateCredentialForHolder(_credentialId, cancellationToken) + ProcessStepTypeId.CREATE_CREDENTIAL_FOR_HOLDER => await _credentialCreationProcessHandler.CreateCredentialForHolder(_credentialId, cancellationToken) .ConfigureAwait(false), - ProcessStepTypeId.TRIGGER_CALLBACK => await _credentialProcessHandler.TriggerCallback(_credentialId, cancellationToken) + ProcessStepTypeId.TRIGGER_CALLBACK => await _credentialCreationProcessHandler.TriggerCallback(_credentialId, cancellationToken) .ConfigureAwait(false), _ => (null, ProcessStepStatusId.TODO, false, null) }; diff --git a/src/processes/CredentialProcess.Worker/DependencyInjection/CredentialProcessCollectionExtensions.cs b/src/processes/CredentialProcess.Worker/DependencyInjection/CredentialProcessCollectionExtensions.cs index ba49a183..503203d7 100644 --- a/src/processes/CredentialProcess.Worker/DependencyInjection/CredentialProcessCollectionExtensions.cs +++ b/src/processes/CredentialProcess.Worker/DependencyInjection/CredentialProcessCollectionExtensions.cs @@ -20,14 +20,20 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.DependencyInjection; +using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Worker.Expiry; using Org.Eclipse.TractusX.SsiCredentialIssuer.Processes.Worker.Library; namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Worker.DependencyInjection; public static class CredentialProcessCollectionExtensions { - public static IServiceCollection AddCredentialProcessExecutor(this IServiceCollection services, IConfiguration config) => + public static IServiceCollection AddCredentialCreationProcessExecutor(this IServiceCollection services, IConfiguration config) => services - .AddTransient() - .AddCredentialProcessHandler(config); + .AddTransient() + .AddCredentialCreationProcessHandler(config); + + public static IServiceCollection AddCredentialExpiryProcessExecutor(this IServiceCollection services, IConfiguration config) => + services + .AddTransient() + .AddCredentialExpiryProcessHandler(config); } diff --git a/src/processes/CredentialProcess.Worker/Expiry/CredentialExpiryProcessTypeExecutor.cs b/src/processes/CredentialProcess.Worker/Expiry/CredentialExpiryProcessTypeExecutor.cs new file mode 100644 index 00000000..d73586cc --- /dev/null +++ b/src/processes/CredentialProcess.Worker/Expiry/CredentialExpiryProcessTypeExecutor.cs @@ -0,0 +1,109 @@ +/******************************************************************************** + * Copyright (c) 2024 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 Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; +using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Expiry; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Repositories; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Processes.Worker.Library; +using System.Collections.Immutable; + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Worker.Expiry; + +public class CredentialExpiryProcessTypeExecutor : IProcessTypeExecutor +{ + private readonly IIssuerRepositories _issuerRepositories; + private readonly ICredentialExpiryProcessHandler _credentialExpiryProcessHandler; + + private readonly IEnumerable _executableProcessSteps = ImmutableArray.Create( + ProcessStepTypeId.REVOKE_CREDENTIAL, + ProcessStepTypeId.TRIGGER_NOTIFICATION, + ProcessStepTypeId.TRIGGER_MAIL); + + private Guid _credentialId; + + public CredentialExpiryProcessTypeExecutor( + IIssuerRepositories issuerRepositories, + ICredentialExpiryProcessHandler credentialExpiryProcessHandler) + { + _issuerRepositories = issuerRepositories; + _credentialExpiryProcessHandler = credentialExpiryProcessHandler; + } + + public ProcessTypeId GetProcessTypeId() => ProcessTypeId.DECLINE_CREDENTIAL; + public bool IsExecutableStepTypeId(ProcessStepTypeId processStepTypeId) => _executableProcessSteps.Contains(processStepTypeId); + public IEnumerable GetExecutableStepTypeIds() => _executableProcessSteps; + public ValueTask IsLockRequested(ProcessStepTypeId processStepTypeId) => ValueTask.FromResult(false); + + public async ValueTask InitializeProcess(Guid processId, IEnumerable processStepTypeIds) + { + var (exists, credentialId) = await _issuerRepositories.GetInstance().GetDataForProcessId(processId).ConfigureAwait(false); + if (!exists) + { + throw new NotFoundException($"process {processId} does not exist or is not associated with an credential"); + } + + _credentialId = credentialId; + return new IProcessTypeExecutor.InitializationResult(false, null); + } + + public async ValueTask ExecuteProcessStep(ProcessStepTypeId processStepTypeId, IEnumerable processStepTypeIds, CancellationToken cancellationToken) + { + if (_credentialId == Guid.Empty) + { + throw new UnexpectedConditionException("credentialId should never be empty here"); + } + + IEnumerable? nextStepTypeIds; + ProcessStepStatusId stepStatusId; + bool modified; + string? processMessage; + + try + { + (nextStepTypeIds, stepStatusId, modified, processMessage) = processStepTypeId switch + { + ProcessStepTypeId.REVOKE_CREDENTIAL => await _credentialExpiryProcessHandler.RevokeCredential(_credentialId, cancellationToken) + .ConfigureAwait(false), + ProcessStepTypeId.TRIGGER_NOTIFICATION => await _credentialExpiryProcessHandler.TriggerNotification(_credentialId, cancellationToken) + .ConfigureAwait(false), + ProcessStepTypeId.TRIGGER_MAIL => await _credentialExpiryProcessHandler.TriggerMail(_credentialId, cancellationToken) + .ConfigureAwait(false), + _ => (null, ProcessStepStatusId.TODO, false, null) + }; + } + catch (Exception ex) when (ex is not SystemException) + { + (stepStatusId, processMessage, nextStepTypeIds) = ProcessError(ex); + modified = true; + } + + return new IProcessTypeExecutor.StepExecutionResult(modified, stepStatusId, nextStepTypeIds, null, processMessage); + } + + private static (ProcessStepStatusId StatusId, string? ProcessMessage, IEnumerable? nextSteps) ProcessError(Exception ex) + { + return ex switch + { + ServiceException { IsRecoverable: true } => (ProcessStepStatusId.TODO, ex.Message, null), + _ => (ProcessStepStatusId.FAILED, ex.Message, null) + }; + } +} diff --git a/src/processes/Processes.Library/Processes.Library.csproj b/src/processes/Processes.Library/Processes.Library.csproj index 56ca7374..bbb4fd76 100644 --- a/src/processes/Processes.Library/Processes.Library.csproj +++ b/src/processes/Processes.Library/Processes.Library.csproj @@ -33,8 +33,4 @@ - - - - diff --git a/src/processes/Processes.Worker.Library/ProcessExecutionServiceExtensions.cs b/src/processes/Processes.Worker.Library/ProcessExecutionServiceExtensions.cs index 5bf7e36d..7259b881 100644 --- a/src/processes/Processes.Worker.Library/ProcessExecutionServiceExtensions.cs +++ b/src/processes/Processes.Worker.Library/ProcessExecutionServiceExtensions.cs @@ -20,7 +20,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Org.Eclipse.TractusX.Portal.Backend.Framework.DateTimeProvider; -using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Auditing.Identity; using Org.Eclipse.TractusX.SsiCredentialIssuer.Processes.Worker.Library.DependencyInjection; namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Processes.Worker.Library; diff --git a/src/processes/Processes.Worker/Program.cs b/src/processes/Processes.Worker/Program.cs index 125aee70..396cddb3 100644 --- a/src/processes/Processes.Worker/Program.cs +++ b/src/processes/Processes.Worker/Program.cs @@ -42,14 +42,15 @@ .AddProcessExecutionService(hostContext.Configuration.GetSection("Processes")) .AddPortalService(hostContext.Configuration.GetSection("Portal")) .AddCallbackService(hostContext.Configuration.GetSection("Callback")) - .AddCredentialProcessExecutor(hostContext.Configuration); + .AddCredentialCreationProcessExecutor(hostContext.Configuration) + .AddCredentialExpiryProcessExecutor(hostContext.Configuration); }) .AddLogging() .Build(); Log.Information("Building worker completed"); using var tokenSource = new CancellationTokenSource(); - Console.CancelKeyPress += (s, e) => + Console.CancelKeyPress += (_, e) => { Log.Information("Canceling..."); tokenSource.Cancel(); diff --git a/src/processes/Processes.Worker/appsettings.json b/src/processes/Processes.Worker/appsettings.json index 50b53b47..db783398 100644 --- a/src/processes/Processes.Worker/appsettings.json +++ b/src/processes/Processes.Worker/appsettings.json @@ -46,14 +46,7 @@ "Scope": "", "TokenAddress": "", "BaseAddress": "", - "EncrptionConfigIndex": 0, - "EncryptionConfigs": [ - { - "Index": 0, - "EncryptionKey": "", - "CipherMode": "", - "PaddingMode": "" - } - ] + "EncryptionConfigIndex": 0, + "EncryptionConfigs": [] } } diff --git a/tests/credentials/SsiCredentialIssuer.Expiry.App.Tests/ExpiryCheckServiceTests.cs b/tests/credentials/SsiCredentialIssuer.Expiry.App.Tests/ExpiryCheckServiceTests.cs index f454e8a4..ef896cea 100644 --- a/tests/credentials/SsiCredentialIssuer.Expiry.App.Tests/ExpiryCheckServiceTests.cs +++ b/tests/credentials/SsiCredentialIssuer.Expiry.App.Tests/ExpiryCheckServiceTests.cs @@ -40,6 +40,7 @@ public class ExpiryCheckServiceTests private readonly IDateTimeProvider _dateTimeProvider; private readonly IIssuerRepositories _issuerRepositories; + private readonly IProcessStepRepository _processStepRepository; private readonly IPortalService _portalService; private readonly ICompanySsiDetailsRepository _companySsiDetailsRepository; private readonly ExpiryCheckServiceSettings _settings; @@ -56,9 +57,12 @@ public ExpiryCheckServiceTests() _fixture.Behaviors.Add(new OmitOnRecursionBehavior()); _issuerRepositories = A.Fake(); _companySsiDetailsRepository = A.Fake(); + _processStepRepository = A.Fake(); A.CallTo(() => _issuerRepositories.GetInstance()) .Returns(_companySsiDetailsRepository); + A.CallTo(() => _issuerRepositories.GetInstance()) + .Returns(_processStepRepository); _dateTimeProvider = A.Fake(); _portalService = A.Fake(); @@ -128,13 +132,6 @@ public async Task ExecuteAsync_WithPendingAndExpiryBeforeNow_DeclinesRequest() A.CallTo(() => _dateTimeProvider.OffsetNow).Returns(now); A.CallTo(() => _companySsiDetailsRepository.GetExpiryData(A._, A._, A._)) .Returns(data.ToAsyncEnumerable()); - A.CallTo(() => _companySsiDetailsRepository.AttachAndModifyCompanySsiDetails(A._, - A>._, A>._)) - .Invokes((Guid _, Action? initialize, Action updateFields) => - { - initialize?.Invoke(ssiDetail); - updateFields.Invoke(ssiDetail); - }); // Act await _sut.ExecuteAsync(CancellationToken.None).ConfigureAwait(false); @@ -142,10 +139,8 @@ public async Task ExecuteAsync_WithPendingAndExpiryBeforeNow_DeclinesRequest() // Assert A.CallTo(() => _companySsiDetailsRepository.RemoveSsiDetail(ssiDetail.Id)).MustNotHaveHappened(); A.CallTo(() => _issuerRepositories.SaveAsync()).MustHaveHappenedOnceExactly(); - A.CallTo(() => _portalService.AddNotification(A._, creatorUserId, NotificationTypeId.CREDENTIAL_REJECTED, A._)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _portalService.TriggerMail("CredentialRejected", creatorUserId, A>._, A._)).MustHaveHappenedOnceExactly(); - - ssiDetail.CompanySsiDetailStatusId.Should().Be(CompanySsiDetailStatusId.INACTIVE); + A.CallTo(() => _processStepRepository.CreateProcess(ProcessTypeId.DECLINE_CREDENTIAL)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _processStepRepository.CreateProcessStep(ProcessStepTypeId.REVOKE_CREDENTIAL, ProcessStepStatusId.TODO, A._)).MustHaveHappenedOnceExactly(); } [Theory] @@ -191,7 +186,7 @@ public async Task ExecuteAsync_WithActiveCloseToExpiry_NotifiesCreator(int days, A.CallTo(() => _companySsiDetailsRepository.RemoveSsiDetail(ssiDetail.Id)).MustNotHaveHappened(); A.CallTo(() => _issuerRepositories.SaveAsync()).MustHaveHappenedOnceExactly(); A.CallTo(() => _portalService.AddNotification(A._, creatorUserId, NotificationTypeId.CREDENTIAL_EXPIRY, A._)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _portalService.TriggerMail("CredentialExpiry", creatorUserId, A>._, A._)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _portalService.TriggerMail("CredentialExpiry", creatorUserId, A>._, A._)).MustHaveHappenedOnceExactly(); ssiDetail.ExpiryCheckTypeId.Should().Be(expiryCheckTypeId); } diff --git a/tests/database/SsiCredentialIssuer.DbAccess.Tests/CompanySsiDetailsRepositoryTests.cs b/tests/database/SsiCredentialIssuer.DbAccess.Tests/CompanySsiDetailsRepositoryTests.cs index 0674bd99..4bfc98d7 100644 --- a/tests/database/SsiCredentialIssuer.DbAccess.Tests/CompanySsiDetailsRepositoryTests.cs +++ b/tests/database/SsiCredentialIssuer.DbAccess.Tests/CompanySsiDetailsRepositoryTests.cs @@ -59,18 +59,20 @@ public async Task GetDetailsForCompany_WithValidData_ReturnsExpected() var result = await sut.GetUseCaseParticipationForCompany(ValidBpnl, DateTimeOffset.MinValue).ToListAsync().ConfigureAwait(false); // Assert - result.Should().HaveCount(5); - result.Where(x => x.Description != null).Should().HaveCount(5).And.Satisfy( + result.Should().HaveCount(8); + result.Where(x => x.Description != null).Should().HaveCount(7).And.Satisfy( x => x.Description == "T", - x => x.Description == "CO2", x => x.Description == "BT", x => x.Description == "CE", - x => x.Description == "QM"); + x => x.Description == "QM", + x => x.Description == "DCM", + x => x.Description == "Puris", + x => x.Description == "BPDM"); var traceability = result.Single(x => x.CredentialType == VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK); traceability.VerifiedCredentials.Should().HaveCount(3).And.Satisfy( - x => x.ExternalDetailData.Version == "1.0.0" && x.SsiDetailData.Single().ParticipationStatus == CompanySsiDetailStatusId.PENDING, - x => x.ExternalDetailData.Version == "2.0.0" && !x.SsiDetailData.Any(), - x => x.ExternalDetailData.Version == "3.0.0" && !x.SsiDetailData.Any()); + x => x.ExternalDetailData.Version == "1.0" && x.SsiDetailData.Single().ParticipationStatus == CompanySsiDetailStatusId.PENDING, + x => x.ExternalDetailData.Version == "2.0" && !x.SsiDetailData.Any(), + x => x.ExternalDetailData.Version == "3.0" && !x.SsiDetailData.Any()); } [Fact] @@ -84,18 +86,20 @@ public async Task GetDetailsForCompany_WithExpiryFilter_ReturnsExpected() var result = await sut.GetUseCaseParticipationForCompany(ValidBpnl, dt).ToListAsync().ConfigureAwait(false); // Assert - result.Should().HaveCount(5); - result.Where(x => x.Description != null).Should().HaveCount(5).And.Satisfy( + result.Should().HaveCount(8); + result.Where(x => x.Description != null).Should().HaveCount(7).And.Satisfy( x => x.Description == "T", - x => x.Description == "CO2", x => x.Description == "BT", x => x.Description == "CE", - x => x.Description == "QM"); + x => x.Description == "QM", + x => x.Description == "DCM", + x => x.Description == "Puris", + x => x.Description == "BPDM"); var traceability = result.Single(x => x.CredentialType == VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK); traceability.VerifiedCredentials.Should().HaveCount(3).And.Satisfy( - x => x.ExternalDetailData.Version == "1.0.0" && x.SsiDetailData.Count() == 1, - x => x.ExternalDetailData.Version == "2.0.0" && !x.SsiDetailData.Any(), - x => x.ExternalDetailData.Version == "3.0.0" && !x.SsiDetailData.Any()); + x => x.ExternalDetailData.Version == "1.0" && x.SsiDetailData.Count() == 1, + x => x.ExternalDetailData.Version == "2.0" && !x.SsiDetailData.Any(), + x => x.ExternalDetailData.Version == "3.0" && !x.SsiDetailData.Any()); } #endregion diff --git a/tests/database/SsiCredentialIssuer.DbAccess.Tests/CredentialRepositoryTests.cs b/tests/database/SsiCredentialIssuer.DbAccess.Tests/CredentialRepositoryTests.cs index 8b31a0ea..a306588a 100644 --- a/tests/database/SsiCredentialIssuer.DbAccess.Tests/CredentialRepositoryTests.cs +++ b/tests/database/SsiCredentialIssuer.DbAccess.Tests/CredentialRepositoryTests.cs @@ -20,8 +20,11 @@ using AutoFixture; using AutoFixture.AutoFakeItEasy; using FluentAssertions; +using Microsoft.EntityFrameworkCore; using Org.Eclipse.TractusX.SsiCredentialIssuer.DbAccess.Tests.Setup; using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Repositories; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities; using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; using Xunit; using Xunit.Extensions.AssemblyFixture; @@ -135,6 +138,29 @@ public async Task GetExternalCredentialAndKindId_ReturnsExpectedDocument() #endregion + #region AttachAndModifyCredential + + [Fact] + public async Task AttachAndModifyCredential_ReturnsExpectedResult() + { + // Arrange + var (sut, context) = await CreateSutWithContext().ConfigureAwait(false); + + // Act + sut.AttachAndModifyCredential(Guid.NewGuid(), x => x.CompanySsiDetailStatusId = CompanySsiDetailStatusId.ACTIVE, x => x.CompanySsiDetailStatusId = CompanySsiDetailStatusId.PENDING); + + // Assert + var changeTracker = context.ChangeTracker; + var changedEntries = changeTracker.Entries().ToList(); + changeTracker.HasChanges().Should().BeTrue(); + changedEntries.Should().ContainSingle(); + var entity = changedEntries.Single(); + entity.State.Should().Be(EntityState.Modified); + ((CompanySsiDetail)entity.Entity).CompanySsiDetailStatusId.Should().Be(CompanySsiDetailStatusId.PENDING); + } + + #endregion + #region Setup private async Task CreateSut() @@ -144,5 +170,12 @@ private async Task CreateSut() return sut; } + private async Task<(CredentialRepository Sut, IssuerDbContext Context)> CreateSutWithContext() + { + var context = await _dbTestDbFixture.GetDbContext().ConfigureAwait(false); + var sut = new CredentialRepository(context); + return (sut, context); + } + #endregion } diff --git a/tests/database/SsiCredentialIssuer.DbAccess.Tests/DocumentRepositoryTests.cs b/tests/database/SsiCredentialIssuer.DbAccess.Tests/DocumentRepositoryTests.cs index 2d24a59f..a33be766 100644 --- a/tests/database/SsiCredentialIssuer.DbAccess.Tests/DocumentRepositoryTests.cs +++ b/tests/database/SsiCredentialIssuer.DbAccess.Tests/DocumentRepositoryTests.cs @@ -24,6 +24,7 @@ using Org.Eclipse.TractusX.SsiCredentialIssuer.DbAccess.Tests.Setup; using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Repositories; using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities; using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; using System.Text; using Xunit; @@ -103,6 +104,36 @@ public async Task AssignDocumentToCompanySsiDetails_ReturnsExpectedDocument() #endregion + #region AttachAndModifyDocuments + + [Fact] + public async Task AttachAndModifyDocuments_ReturnsExpectedResult() + { + // Arrange + var (sut, context) = await CreateSut().ConfigureAwait(false); + + var documentData = new (Guid DocumentId, Action?, Action)[] { + (Guid.NewGuid(), null, document => document.DocumentStatusId = DocumentStatusId.INACTIVE), + (Guid.NewGuid(), document => document.DocumentStatusId = DocumentStatusId.INACTIVE, document => document.DocumentStatusId = DocumentStatusId.INACTIVE), + (Guid.NewGuid(), document => document.DocumentStatusId = DocumentStatusId.ACTIVE, document => document.DocumentStatusId = DocumentStatusId.INACTIVE), + }; + + // Act + sut.AttachAndModifyDocuments(documentData); + + // Assert + var changeTracker = context.ChangeTracker; + var changedEntries = changeTracker.Entries().ToList(); + changeTracker.HasChanges().Should().BeTrue(); + changedEntries.Should().HaveCount(3).And.AllSatisfy(x => x.Entity.Should().BeOfType()).And.Satisfy( + x => x.State == EntityState.Modified && ((Document)x.Entity).Id == documentData[0].DocumentId && ((Document)x.Entity).DocumentStatusId == DocumentStatusId.INACTIVE, + x => x.State == EntityState.Unchanged && ((Document)x.Entity).Id == documentData[1].DocumentId && ((Document)x.Entity).DocumentStatusId == DocumentStatusId.INACTIVE, + x => x.State == EntityState.Modified && ((Document)x.Entity).Id == documentData[2].DocumentId && ((Document)x.Entity).DocumentStatusId == DocumentStatusId.INACTIVE + ); + } + + #endregion + #region Setup private async Task<(DocumentRepository, IssuerDbContext)> CreateSut() diff --git a/tests/database/SsiCredentialIssuer.DbAccess.Tests/IssuerRepositoriesTests.cs b/tests/database/SsiCredentialIssuer.DbAccess.Tests/IssuerRepositoriesTests.cs index 9757b7d0..f836deaf 100644 --- a/tests/database/SsiCredentialIssuer.DbAccess.Tests/IssuerRepositoriesTests.cs +++ b/tests/database/SsiCredentialIssuer.DbAccess.Tests/IssuerRepositoriesTests.cs @@ -27,7 +27,6 @@ using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities; using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities; using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; -using System.Collections.Immutable; using Xunit; using Xunit.Extensions.AssemblyFixture; diff --git a/tests/database/SsiCredentialIssuer.DbAccess.Tests/Seeder/Data/verified_credential_external_type_detail_versions.test.json b/tests/database/SsiCredentialIssuer.DbAccess.Tests/Seeder/Data/verified_credential_external_type_detail_versions.test.json index 02688638..b12c0a51 100644 --- a/tests/database/SsiCredentialIssuer.DbAccess.Tests/Seeder/Data/verified_credential_external_type_detail_versions.test.json +++ b/tests/database/SsiCredentialIssuer.DbAccess.Tests/Seeder/Data/verified_credential_external_type_detail_versions.test.json @@ -1,28 +1,28 @@ [ - { - "id": "1268a76a-ca19-4dd8-b932-01f24071d562", - "verified_credential_external_type_id": 3, - "version": "1.0.0", - "template": "https://catena-x.net/.._Policies_Trace_3.0_EN.pdf", - "valid_from": "2023-06-01 00:00:00.000000 +00:00", - "expiry": "2023-09-30 00:00:00.000000 +00:00" - }, { "id": "1268a76a-ca19-4dd8-b932-01f24071d563", "verified_credential_external_type_id": 1, - "version": "2.0.0", - "template": "https://catena-x.net/.._Policies_Trace_3.0_EN.pdf", + "version": "2.0", + "template": "https://catena-x.net/fileadmin/user_upload/04_Einfuehren_und_umsetzen/Governance_Framework/231016_Catena-X_Use_Case_Framework_Traceability.pdf", "valid_from": "2023-06-01 00:00:00.000000 +00:00", "expiry": "2023-12-23 00:00:00.000000 +00:00" }, { "id": "1268a76a-ca19-4dd8-b932-01f24071d564", "verified_credential_external_type_id": 1, - "version": "3.0.0", - "template": "https://catena-x.net/.._Policies_Trace_3.0_EN.pdf", + "version": "3.0", + "template": "https://catena-x.net/fileadmin/user_upload/04_Einfuehren_und_umsetzen/Governance_Framework/231016_Catena-X_Use_Case_Framework_Traceability.pdf", "valid_from": "2024-01-01 00:00:00.000000 +00:00", "expiry": "2024-12-31 00:00:00.000000 +00:00" }, + { + "id": "1268a76a-ca19-4dd8-b932-01f24071d562", + "verified_credential_external_type_id": 3, + "version": "1.0", + "template": null, + "valid_from": "2023-06-01 00:00:00.000000 +00:00", + "expiry": "2023-09-30 00:00:00.000000 +00:00" + }, { "id": "df3bd7d2-3349-410b-9b30-9a5238eb605e", "verified_credential_external_type_id": 4, @@ -30,5 +30,13 @@ "template": null, "valid_from": "2024-01-01 00:00:00.000000 +00:00", "expiry": "2999-12-31 23:59:59.000000 +00:00" + }, + { + "id": "1268a76a-ca19-4dd8-b932-01f24071d565", + "verified_credential_external_type_id": 5, + "version": "1.0", + "template": " https://catena-x.net/fileadmin/user_upload/04_Einfuehren_und_umsetzen/Governance_Framework/231016_Catena-X_Use_Case_Framework_CircularEconomy.pdf", + "valid_from": "2024-01-01 00:00:00.000000 +00:00", + "expiry": "2024-12-31 00:00:00.000000 +00:00" } ] diff --git a/tests/database/SsiCredentialIssuer.DbAccess.Tests/Seeder/Data/verified_credential_type_assigned_use_cases.test.json b/tests/database/SsiCredentialIssuer.DbAccess.Tests/Seeder/Data/verified_credential_type_assigned_use_cases.test.json index b66a8edc..e45dd47e 100644 --- a/tests/database/SsiCredentialIssuer.DbAccess.Tests/Seeder/Data/verified_credential_type_assigned_use_cases.test.json +++ b/tests/database/SsiCredentialIssuer.DbAccess.Tests/Seeder/Data/verified_credential_type_assigned_use_cases.test.json @@ -2,9 +2,5 @@ { "company_credential_detail_id": "9f5b9934-4014-4099-91e9-7b1aee696b03", "use_case_id": "06b243a4-ba51-4bf3-bc40-5d79a2231b86" - }, - { - "company_credential_detail_id": "9f5b9934-4014-4099-91e9-7b1aee696b04", - "use_case_id": "06b243a4-ba51-4bf3-bc40-5d79a2231b87" } ] diff --git a/tests/externalservices/Callback.Service.Tests/CallbackServiceTests.cs b/tests/externalservices/Callback.Service.Tests/CallbackServiceTests.cs index 70543600..f0654226 100644 --- a/tests/externalservices/Callback.Service.Tests/CallbackServiceTests.cs +++ b/tests/externalservices/Callback.Service.Tests/CallbackServiceTests.cs @@ -27,8 +27,6 @@ using Org.Eclipse.TractusX.SsiCredentialIssuer.Callback.Service.DependencyInjection; using Org.Eclipse.TractusX.SsiCredentialIssuer.Callback.Service.Models; using Org.Eclipse.TractusX.SsiCredentialIssuer.Callback.Service.Services; -using Org.Eclipse.TractusX.SsiCredentialIssuer.Portal.Service.Models; -using Org.Eclipse.TractusX.SsiCredentialIssuer.Portal.Service.Services; using Org.Eclipse.TractusX.SsiCredentialIssuer.Tests.Shared; using System.Net; using System.Net.Http.Json; diff --git a/tests/externalservices/Portal.Service.Tests/PortalServiceTests.cs b/tests/externalservices/Portal.Service.Tests/PortalServiceTests.cs index 65fb167f..9e5ff4a4 100644 --- a/tests/externalservices/Portal.Service.Tests/PortalServiceTests.cs +++ b/tests/externalservices/Portal.Service.Tests/PortalServiceTests.cs @@ -30,7 +30,6 @@ using Org.Eclipse.TractusX.SsiCredentialIssuer.Tests.Shared; using System.Net; using System.Net.Http.Json; -using System.Text.Json; using Xunit; namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Portal.Service.Tests; @@ -137,7 +136,7 @@ public async Task TriggerMail_WithValid_DoesNotThrowException() var sut = new PortalService(_tokenService, _options); // Act - await sut.TriggerMail("Test", requesterId, new Dictionary(), CancellationToken.None).ConfigureAwait(false); + await sut.TriggerMail("Test", requesterId, Enumerable.Empty(), CancellationToken.None).ConfigureAwait(false); // Assert httpMessageHandlerMock.RequestMessage.Should().Match(x => @@ -166,7 +165,7 @@ public async Task TriggerMail_WithConflict_ThrowsServiceExceptionWithErrorConten var sut = new PortalService(_tokenService, _options); // Act - async Task Act() => await sut.TriggerMail("Test", requesterId, new Dictionary(), CancellationToken.None).ConfigureAwait(false); + async Task Act() => await sut.TriggerMail("Test", requesterId, Enumerable.Empty(), CancellationToken.None).ConfigureAwait(false); // Assert var ex = await Assert.ThrowsAsync(Act); diff --git a/tests/externalservices/Wallet.Service.Tests/Services/BasicAuthTokenServiceTests.cs b/tests/externalservices/Wallet.Service.Tests/Services/BasicAuthTokenServiceTests.cs index 37117803..8a72afdd 100644 --- a/tests/externalservices/Wallet.Service.Tests/Services/BasicAuthTokenServiceTests.cs +++ b/tests/externalservices/Wallet.Service.Tests/Services/BasicAuthTokenServiceTests.cs @@ -22,7 +22,6 @@ using FakeItEasy; using FluentAssertions; using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; -using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling.Web; using Org.Eclipse.TractusX.Portal.Backend.Framework.Token; using Org.Eclipse.TractusX.SsiCredentialIssuer.Tests.Shared; using Org.Eclipse.TractusX.SsiCredentialIssuer.Tests.Shared.Extensions; @@ -82,9 +81,9 @@ public async Task GetAuthorizedClient_HttpClientThrows_Throws() var sut = new BasicAuthTokenService(_httpClientFactory); - var act = () => sut.GetBasicAuthorizedClient(settings, _cancellationToken); + Task Act() => sut.GetBasicAuthorizedClient(settings, _cancellationToken); - var error = await Assert.ThrowsAsync(act).ConfigureAwait(false); + var error = await Assert.ThrowsAsync(Act).ConfigureAwait(false); error.Should().NotBeNull(); error.InnerException.Should().Be(_testException); diff --git a/tests/externalservices/Wallet.Service.Tests/Services/WalletServiceTests.cs b/tests/externalservices/Wallet.Service.Tests/Services/WalletServiceTests.cs index 7c72d5ca..8ad94af4 100644 --- a/tests/externalservices/Wallet.Service.Tests/Services/WalletServiceTests.cs +++ b/tests/externalservices/Wallet.Service.Tests/Services/WalletServiceTests.cs @@ -52,7 +52,7 @@ public async Task CreateCredential_WithValid_DoesNotThrowException() var id = Guid.NewGuid(); var response = new CreateCredentialResponse(id); var httpMessageHandlerMock = new HttpMessageHandlerMock(HttpStatusCode.OK, new StringContent(JsonSerializer.Serialize(response))); - var httpClient = new HttpClient(httpMessageHandlerMock) + using var httpClient = new HttpClient(httpMessageHandlerMock) { BaseAddress = new Uri("https://base.address.com") }; @@ -83,7 +83,7 @@ public async Task CreateCredential_WithConflict_ThrowsServiceExceptionWithErrorC var httpMessageHandlerMock = content == null ? new HttpMessageHandlerMock(statusCode) : new HttpMessageHandlerMock(statusCode, new StringContent(content)); - var httpClient = new HttpClient(httpMessageHandlerMock) + using var httpClient = new HttpClient(httpMessageHandlerMock) { BaseAddress = new Uri("https://base.address.com") }; @@ -110,7 +110,7 @@ public async Task SignCredential_WithValid_DoesNotThrowException() const string jwt = "thisisonlyatestexample"; var response = new SignCredentialResponse(jwt); var httpMessageHandlerMock = new HttpMessageHandlerMock(HttpStatusCode.OK, new StringContent(JsonSerializer.Serialize(response))); - var httpClient = new HttpClient(httpMessageHandlerMock) + using var httpClient = new HttpClient(httpMessageHandlerMock) { BaseAddress = new Uri("https://base.address.com") }; @@ -142,7 +142,7 @@ public async Task SignCredential_WithConflict_ThrowsServiceExceptionWithErrorCon var httpMessageHandlerMock = content == null ? new HttpMessageHandlerMock(statusCode) : new HttpMessageHandlerMock(statusCode, new StringContent(content)); - var httpClient = new HttpClient(httpMessageHandlerMock) + using var httpClient = new HttpClient(httpMessageHandlerMock) { BaseAddress = new Uri("https://base.address.com") }; @@ -171,9 +171,9 @@ public async Task GetCredential_WithValid_DoesNotThrowException() "root": "123" } """; - var response = new GetCredentialResponse("test", JsonDocument.Parse(json), "test123"); + var response = new GetCredentialResponse("test", JsonDocument.Parse(json), "test123", "VALID"); var httpMessageHandlerMock = new HttpMessageHandlerMock(HttpStatusCode.OK, new StringContent(JsonSerializer.Serialize(response))); - var httpClient = new HttpClient(httpMessageHandlerMock) + using var httpClient = new HttpClient(httpMessageHandlerMock) { BaseAddress = new Uri("https://base.address.com") }; @@ -199,7 +199,7 @@ public async Task GetCredential_WithConflict_ThrowsServiceExceptionWithErrorCont var httpMessageHandlerMock = content == null ? new HttpMessageHandlerMock(statusCode) : new HttpMessageHandlerMock(statusCode, new StringContent(content)); - var httpClient = new HttpClient(httpMessageHandlerMock) + using var httpClient = new HttpClient(httpMessageHandlerMock) { BaseAddress = new Uri("https://base.address.com") }; @@ -225,7 +225,7 @@ public async Task CreateCredentialForHolder_WithValid_DoesNotThrowException() var id = Guid.NewGuid(); var response = new CreateCredentialResponse(id); var httpMessageHandlerMock = new HttpMessageHandlerMock(HttpStatusCode.OK, new StringContent(JsonSerializer.Serialize(response))); - var httpClient = new HttpClient(httpMessageHandlerMock) + using var httpClient = new HttpClient(httpMessageHandlerMock) { BaseAddress = new Uri("https://base.address.com") }; @@ -255,7 +255,7 @@ public async Task CreateCredentialForHolder_WithConflict_ThrowsServiceExceptionW var httpMessageHandlerMock = content == null ? new HttpMessageHandlerMock(statusCode) : new HttpMessageHandlerMock(statusCode, new StringContent(content)); - var httpClient = new HttpClient(httpMessageHandlerMock) + using var httpClient = new HttpClient(httpMessageHandlerMock) { BaseAddress = new Uri("https://base.address.com") }; @@ -271,4 +271,58 @@ public async Task CreateCredentialForHolder_WithConflict_ThrowsServiceExceptionW } #endregion + + #region RevokeCredentialForIssuer + + [Fact] + public async Task RevokeCredentialForIssuer_WithValid_DoesNotThrowException() + { + // Arrange + var id = Guid.NewGuid(); + var response = new CreateCredentialResponse(id); + var httpMessageHandlerMock = new HttpMessageHandlerMock(HttpStatusCode.OK, new StringContent(JsonSerializer.Serialize(response))); + using var httpClient = new HttpClient(httpMessageHandlerMock) + { + BaseAddress = new Uri("https://base.address.com") + }; + A.CallTo(() => _basicAuthTokenService.GetBasicAuthorizedClient(A._, A._)) + .Returns(httpClient); + + // Act + await _sut.RevokeCredentialForIssuer(Guid.NewGuid(), CancellationToken.None).ConfigureAwait(false); + + // Assert + httpMessageHandlerMock.RequestMessage.Should().Match(x => + x.Content is JsonContent && + (x.Content as JsonContent)!.ObjectType == typeof(RevokeCredentialRequest) && + ((x.Content as JsonContent)!.Value as RevokeCredentialRequest)!.Payload.Revoke); + } + + [Theory] + [InlineData(HttpStatusCode.Conflict, "{ \"message\": \"Framework test!\" }", "call to external system revoke-credential failed with statuscode 409 - Message: { \"message\": \"Framework test!\" }")] + [InlineData(HttpStatusCode.BadRequest, "{ \"test\": \"123\" }", "call to external system revoke-credential failed with statuscode 400 - Message: { \"test\": \"123\" }")] + [InlineData(HttpStatusCode.BadRequest, "this is no json", "call to external system revoke-credential failed with statuscode 400 - Message: this is no json")] + [InlineData(HttpStatusCode.Forbidden, null, "call to external system revoke-credential failed with statuscode 403")] + public async Task RevokeCredentialForIssuer_WithConflict_ThrowsServiceExceptionWithErrorContent(HttpStatusCode statusCode, string? content, string message) + { + // Arrange + var httpMessageHandlerMock = content == null + ? new HttpMessageHandlerMock(statusCode) + : new HttpMessageHandlerMock(statusCode, new StringContent(content)); + using var httpClient = new HttpClient(httpMessageHandlerMock) + { + BaseAddress = new Uri("https://base.address.com") + }; + A.CallTo(() => _basicAuthTokenService.GetBasicAuthorizedClient(A._, A._)).Returns(httpClient); + + // Act + async Task Act() => await _sut.RevokeCredentialForIssuer(Guid.NewGuid(), CancellationToken.None).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be(message); + ex.StatusCode.Should().Be(statusCode); + } + + #endregion } diff --git a/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/CredentialBusinessLogicTests.cs b/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/CredentialBusinessLogicTests.cs new file mode 100644 index 00000000..f140e1a9 --- /dev/null +++ b/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/CredentialBusinessLogicTests.cs @@ -0,0 +1,127 @@ +/******************************************************************************** + * Copyright (c) 2024 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 Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Repositories; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.BusinessLogic; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.ErrorHandling; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Identity; +using System.Text; +using System.Text.Json; + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Tests.BusinessLogic; + +public class CredentialBusinessLogicTests +{ + private static readonly string Bpnl = "BPNL00000001TEST"; + private readonly Guid CredentialId = Guid.NewGuid(); + + private readonly IFixture _fixture; + + private readonly ICredentialBusinessLogic _sut; + private readonly IIdentityService _identityService; + private readonly IIssuerRepositories _issuerRepositories; + private readonly IIdentityData _identity; + private readonly ICredentialRepository _credentialRepository; + + public CredentialBusinessLogicTests() + { + _fixture = new Fixture().Customize(new AutoFakeItEasyCustomization { ConfigureMembers = true }); + _fixture.Behaviors.OfType().ToList() + .ForEach(b => _fixture.Behaviors.Remove(b)); + _fixture.Behaviors.Add(new OmitOnRecursionBehavior()); + _fixture.Customize(x => x.FromFactory(() => JsonDocument.Parse("{}"))); + + _issuerRepositories = A.Fake(); + _credentialRepository = A.Fake(); + _identity = A.Fake(); + + _identityService = A.Fake(); + A.CallTo(() => _issuerRepositories.GetInstance()).Returns(_credentialRepository); + + A.CallTo(() => _identity.IdentityId).Returns(Guid.NewGuid().ToString()); + A.CallTo(() => _identity.Bpnl).Returns(Bpnl); + A.CallTo(() => _identityService.IdentityData).Returns(_identity); + + _sut = new CredentialBusinessLogic(_issuerRepositories, _identityService); + } + + [Fact] + public async Task GetCredentialDocument_WithNotExisting_ThrowsNotFoundException() + { + // Arrange + A.CallTo(() => _credentialRepository.GetSignedCredentialForCredentialId(CredentialId, Bpnl)) + .Returns(default((bool, bool, IEnumerable<(DocumentStatusId, byte[])>))); + async Task Act() => await _sut.GetCredentialDocument(CredentialId); + + // Act + var ex = await Assert.ThrowsAsync(Act); + + // Assert + ex.Message.Should().Be(CredentialErrors.CREDENTIAL_NOT_FOUND.ToString()); + } + + [Fact] + public async Task GetCredentialDocument_WithDifferentCompany_ThrowsForbiddenException() + { + // Arrange + A.CallTo(() => _credentialRepository.GetSignedCredentialForCredentialId(CredentialId, Bpnl)) + .Returns((true, false, Enumerable.Empty>())); + async Task Act() => await _sut.GetCredentialDocument(CredentialId); + + // Act + var ex = await Assert.ThrowsAsync(Act); + + // Assert + ex.Message.Should().Be(CredentialErrors.COMPANY_NOT_ALLOWED.ToString()); + } + + [Fact] + public async Task GetCredentialDocument_WithoutSignedCredential_ThrowsConflictException() + { + // Arrange + A.CallTo(() => _credentialRepository.GetSignedCredentialForCredentialId(CredentialId, Bpnl)) + .Returns((true, true, Enumerable.Empty>())); + async Task Act() => await _sut.GetCredentialDocument(CredentialId); + + // Act + var ex = await Assert.ThrowsAsync(Act); + + // Assert + ex.Message.Should().Be(CredentialErrors.SIGNED_CREDENTIAL_NOT_FOUND.ToString()); + } + + [Fact] + public async Task GetCredentialDocument_WithValid_ReturnsExpected() + { + // Arrange + var json = JsonDocument.Parse("{\"test\":\"test\"}"); + var schema = JsonSerializer.Serialize(json, JsonSerializerOptions.Default); + A.CallTo(() => _credentialRepository.GetSignedCredentialForCredentialId(CredentialId, Bpnl)) + .Returns((true, true, Enumerable.Repeat((DocumentStatusId.ACTIVE, Encoding.UTF8.GetBytes(schema)), 1))); + + // Act + var doc = await _sut.GetCredentialDocument(CredentialId); + + // Assert + doc.RootElement.GetRawText().Should().Be("{\"test\":\"test\"}"); + } +} diff --git a/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/IssuerBusinessLogicTests.cs b/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/IssuerBusinessLogicTests.cs index add24e71..e5ca2e60 100644 --- a/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/IssuerBusinessLogicTests.cs +++ b/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/IssuerBusinessLogicTests.cs @@ -40,6 +40,8 @@ namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Tests.BusinessLogic; public class IssuerBusinessLogicTests { + private static readonly IEnumerable Context = new[] { "https://www.w3.org/2018/credentials/v1", "https://w3id.org/catenax/credentials/v1.0.0" }; + private static readonly JsonSerializerOptions Options = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; private static readonly Guid CredentialId = Guid.NewGuid(); private static readonly string Bpnl = "BPNL00000001TEST"; private static readonly string IssuerBpnl = "BPNL000001ISSUER"; @@ -63,6 +65,7 @@ public IssuerBusinessLogicTests() _fixture.Behaviors.OfType().ToList() .ForEach(b => _fixture.Behaviors.Remove(b)); _fixture.Behaviors.Add(new OmitOnRecursionBehavior()); + _fixture.Customize(x => x.FromFactory(() => JsonDocument.Parse("{}"))); _issuerRepositories = A.Fake(); _companySsiDetailsRepository = A.Fake(); @@ -116,7 +119,7 @@ public async Task GetUseCaseParticipationAsync_ReturnsExpected() Setup_GetUseCaseParticipationAsync(); // Act - var result = await _sut.GetUseCaseParticipationAsync().ConfigureAwait(false); + var result = await _sut.GetUseCaseParticipationAsync(); // Assert result.Should().HaveCount(5); @@ -133,7 +136,7 @@ public async Task GetSsiCertificatesAsync_ReturnsExpected() Setup_GetSsiCertificatesAsync(); // Act - var result = await _sut.GetSsiCertificatesAsync().ConfigureAwait(false); + var result = await _sut.GetSsiCertificatesAsync(); // Assert result.Should().HaveCount(5); @@ -149,15 +152,15 @@ public async Task ApproveCredential_WithoutExistingSsiDetail_ThrowsNotFoundExcep // Arrange var notExistingId = Guid.NewGuid(); A.CallTo(() => _companySsiDetailsRepository.GetSsiApprovalData(notExistingId)) - .Returns(new ValueTuple()); - async Task Act() => await _sut.ApproveCredential(notExistingId, CancellationToken.None).ConfigureAwait(false); + .Returns(default((bool, SsiApprovalData))); + Task Act() => _sut.ApproveCredential(notExistingId, CancellationToken.None); // Act - var ex = await Assert.ThrowsAsync(Act).ConfigureAwait(false); + var ex = await Assert.ThrowsAsync(Act); // Assert - ex.Message.Should().Be(CredentialErrors.SSI_DETAILS_NOT_FOUND.ToString()); - A.CallTo(() => _portalService.TriggerMail("CredentialApproval", A._, A>._, A._)).MustNotHaveHappened(); + ex.Message.Should().Be(IssuerErrors.SSI_DETAILS_NOT_FOUND.ToString()); + A.CallTo(() => _portalService.TriggerMail("CredentialApproval", A._, A>._, A._)).MustNotHaveHappened(); A.CallTo(() => _issuerRepositories.SaveAsync()).MustNotHaveHappened(); } @@ -172,15 +175,15 @@ public async Task ApproveCredential_WithStatusNotPending_ThrowsConflictException .With(x => x.Status, statusId) .Create(); A.CallTo(() => _companySsiDetailsRepository.GetSsiApprovalData(alreadyActiveId)) - .Returns(new ValueTuple(true, approvalData)); - async Task Act() => await _sut.ApproveCredential(alreadyActiveId, CancellationToken.None).ConfigureAwait(false); + .Returns((true, approvalData)); + Task Act() => _sut.ApproveCredential(alreadyActiveId, CancellationToken.None); // Act - var ex = await Assert.ThrowsAsync(Act).ConfigureAwait(false); + var ex = await Assert.ThrowsAsync(Act); // Assert - ex.Message.Should().Be(CredentialErrors.CREDENTIAL_NOT_PENDING.ToString()); - A.CallTo(() => _portalService.TriggerMail("CredentialApproval", A._, A>._, A._)).MustNotHaveHappened(); + ex.Message.Should().Be(IssuerErrors.CREDENTIAL_NOT_PENDING.ToString()); + A.CallTo(() => _portalService.TriggerMail("CredentialApproval", A._, A>._, A._)).MustNotHaveHappened(); A.CallTo(() => _issuerRepositories.SaveAsync()).MustNotHaveHappened(); } @@ -194,15 +197,15 @@ public async Task ApproveCredential_WithBpnNotSetActiveSsiDetail_ThrowsConflictE .With(x => x.Bpn, (string?)null) .Create(); A.CallTo(() => _companySsiDetailsRepository.GetSsiApprovalData(alreadyActiveId)) - .Returns(new ValueTuple(true, approvalData)); - async Task Act() => await _sut.ApproveCredential(alreadyActiveId, CancellationToken.None).ConfigureAwait(false); + .Returns((true, approvalData)); + Task Act() => _sut.ApproveCredential(alreadyActiveId, CancellationToken.None); // Act - var ex = await Assert.ThrowsAsync(Act).ConfigureAwait(false); + var ex = await Assert.ThrowsAsync(Act); // Assert - ex.Message.Should().Be(CredentialErrors.BPN_NOT_SET.ToString()); - A.CallTo(() => _portalService.TriggerMail("CredentialApproval", A._, A>._, A._)).MustNotHaveHappened(); + ex.Message.Should().Be(IssuerErrors.BPN_NOT_SET.ToString()); + A.CallTo(() => _portalService.TriggerMail("CredentialApproval", A._, A>._, A._)).MustNotHaveHappened(); A.CallTo(() => _issuerRepositories.SaveAsync()).MustNotHaveHappened(); } @@ -219,27 +222,29 @@ public async Task ApproveCredential_WithExpiryInThePast_ReturnsExpected() DateTimeOffset.Now.AddDays(-5) ); + var schema = CreateSchema(); var data = new SsiApprovalData( CompanySsiDetailStatusId.PENDING, typeId, null, VerifiedCredentialTypeKindId.FRAMEWORK, Bpnl, + JsonDocument.Parse(schema), detailData ); A.CallTo(() => _dateTimeProvider.OffsetNow).Returns(now); A.CallTo(() => _companySsiDetailsRepository.GetSsiApprovalData(CredentialId)) - .Returns(new ValueTuple(true, data)); - async Task Act() => await _sut.ApproveCredential(CredentialId, CancellationToken.None).ConfigureAwait(false); + .Returns((true, data)); + Task Act() => _sut.ApproveCredential(CredentialId, CancellationToken.None); // Act var ex = await Assert.ThrowsAsync(Act); // Assert - ex.Message.Should().Be(CredentialErrors.EXPIRY_DATE_IN_PAST.ToString()); + ex.Message.Should().Be(IssuerErrors.EXPIRY_DATE_IN_PAST.ToString()); - A.CallTo(() => _portalService.TriggerMail("CredentialApproval", A._, A>._, A._)).MustNotHaveHappened(); + A.CallTo(() => _portalService.TriggerMail("CredentialApproval", A._, A>._, A._)).MustNotHaveHappened(); A.CallTo(() => _portalService.AddNotification(A._, A._, A._, A._)).MustNotHaveHappened(); A.CallTo(() => _issuerRepositories.SaveAsync()).MustNotHaveHappened(); } @@ -256,25 +261,27 @@ public async Task ApproveCredential_WithInvalidCredentialType_ThrowsException() DateTimeOffset.UtcNow ); + var schema = CreateSchema(); var data = new SsiApprovalData( CompanySsiDetailStatusId.PENDING, default, null, VerifiedCredentialTypeKindId.FRAMEWORK, Bpnl, + JsonDocument.Parse(schema), useCaseData ); A.CallTo(() => _dateTimeProvider.OffsetNow).Returns(now); A.CallTo(() => _companySsiDetailsRepository.GetSsiApprovalData(CredentialId)) - .Returns(new ValueTuple(true, data)); + .Returns((true, data)); // Act - async Task Act() => await _sut.ApproveCredential(CredentialId, CancellationToken.None).ConfigureAwait(false); + Task Act() => _sut.ApproveCredential(CredentialId, CancellationToken.None); // Assert - var ex = await Assert.ThrowsAsync(Act).ConfigureAwait(false); - ex.Message.Should().Be(CredentialErrors.CREDENTIAL_TYPE_NOT_FOUND.ToString()); + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be(IssuerErrors.CREDENTIAL_TYPE_NOT_FOUND.ToString()); } [Fact] @@ -288,24 +295,25 @@ public async Task ApproveCredential_WithDetailVersionNotSet_ThrowsConflictExcept null, VerifiedCredentialTypeKindId.FRAMEWORK, Bpnl, + null, null ); A.CallTo(() => _dateTimeProvider.OffsetNow).Returns(now); A.CallTo(() => _companySsiDetailsRepository.GetSsiApprovalData(CredentialId)) - .Returns(new ValueTuple(true, data)); - async Task Act() => await _sut.ApproveCredential(CredentialId, CancellationToken.None).ConfigureAwait(false); + .Returns((true, data)); + Task Act() => _sut.ApproveCredential(CredentialId, CancellationToken.None); // Act var ex = await Assert.ThrowsAsync(Act); // Assert - A.CallTo(() => _portalService.TriggerMail("CredentialApproval", A._, A>._, A._)).MustNotHaveHappened(); + A.CallTo(() => _portalService.TriggerMail("CredentialApproval", A._, A>._, A._)).MustNotHaveHappened(); A.CallTo(() => _issuerRepositories.SaveAsync()).MustNotHaveHappened(); A.CallTo(() => _processStepRepository.CreateProcess(ProcessTypeId.CREATE_CREDENTIAL)) .MustNotHaveHappened(); - ex.Message.Should().Be(CredentialErrors.EXTERNAL_TYPE_DETAIL_ID_NOT_SET.ToString()); + ex.Message.Should().Be(IssuerErrors.EXTERNAL_TYPE_DETAIL_ID_NOT_SET.ToString()); } [Fact] @@ -319,6 +327,7 @@ public async Task ApproveCredential_WithAlreadyLinkedProcess_ThrowsConflictExcep Guid.NewGuid(), VerifiedCredentialTypeKindId.FRAMEWORK, Bpnl, + null, new DetailData( VerifiedCredentialExternalTypeId.TRACEABILITY_CREDENTIAL, "test", @@ -329,28 +338,28 @@ public async Task ApproveCredential_WithAlreadyLinkedProcess_ThrowsConflictExcep A.CallTo(() => _dateTimeProvider.OffsetNow).Returns(now); A.CallTo(() => _companySsiDetailsRepository.GetSsiApprovalData(CredentialId)) - .Returns(new ValueTuple(true, data)); - async Task Act() => await _sut.ApproveCredential(CredentialId, CancellationToken.None).ConfigureAwait(false); + .Returns((true, data)); + Task Act() => _sut.ApproveCredential(CredentialId, CancellationToken.None); // Act var ex = await Assert.ThrowsAsync(Act); // Assert - A.CallTo(() => _portalService.TriggerMail("CredentialApproval", A._, A>._, A._)).MustNotHaveHappened(); + A.CallTo(() => _portalService.TriggerMail("CredentialApproval", A._, A>._, A._)).MustNotHaveHappened(); A.CallTo(() => _issuerRepositories.SaveAsync()).MustNotHaveHappened(); A.CallTo(() => _processStepRepository.CreateProcess(ProcessTypeId.CREATE_CREDENTIAL)) .MustNotHaveHappened(); - ex.Message.Should().Be(CredentialErrors.ALREADY_LINKED_PROCESS.ToString()); + ex.Message.Should().Be(IssuerErrors.ALREADY_LINKED_PROCESS.ToString()); } [Theory] [InlineData(VerifiedCredentialTypeKindId.FRAMEWORK, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, VerifiedCredentialExternalTypeId.TRACEABILITY_CREDENTIAL)] - [InlineData(VerifiedCredentialTypeKindId.MEMBERSHIP, VerifiedCredentialTypeId.DISMANTLER_CERTIFICATE, VerifiedCredentialExternalTypeId.VEHICLE_DISMANTLE)] - [InlineData(VerifiedCredentialTypeKindId.BPN, VerifiedCredentialTypeId.BUSINESS_PARTNER_NUMBER, VerifiedCredentialExternalTypeId.BUSINESS_PARTNER_NUMBER)] public async Task ApproveCredential_WithValid_ReturnsExpected(VerifiedCredentialTypeKindId kindId, VerifiedCredentialTypeId typeId, VerifiedCredentialExternalTypeId externalTypeId) { // Arrange + var schema = CreateSchema(); + var processData = new CompanySsiProcessData(CredentialId, JsonDocument.Parse(schema), VerifiedCredentialTypeKindId.FRAMEWORK); var now = DateTimeOffset.UtcNow; var detailData = new DetailData( externalTypeId, @@ -365,32 +374,68 @@ public async Task ApproveCredential_WithValid_ReturnsExpected(VerifiedCredential null, kindId, Bpnl, + JsonDocument.Parse(schema), detailData ); var detail = new CompanySsiDetail(CredentialId, _identity.Bpnl, typeId, CompanySsiDetailStatusId.PENDING, "", Guid.NewGuid().ToString(), DateTimeOffset.Now); A.CallTo(() => _dateTimeProvider.OffsetNow).Returns(now); A.CallTo(() => _companySsiDetailsRepository.GetSsiApprovalData(CredentialId)) - .Returns(new ValueTuple(true, data)); + .Returns((true, data)); A.CallTo(() => _companySsiDetailsRepository.AttachAndModifyCompanySsiDetails(CredentialId, A?>._, A>._!)) .Invokes((Guid _, Action? initialize, Action updateFields) => { initialize?.Invoke(detail); updateFields.Invoke(detail); }); + A.CallTo(() => _companySsiDetailsRepository.AttachAndModifyProcessData(CredentialId, A?>._, A>._!)) + .Invokes((Guid _, Action? initialize, Action updateFields) => + { + initialize?.Invoke(processData); + updateFields.Invoke(processData); + }); // Act - await _sut.ApproveCredential(CredentialId, CancellationToken.None).ConfigureAwait(false); + await _sut.ApproveCredential(CredentialId, CancellationToken.None); // Assert A.CallTo(() => _portalService.AddNotification(A._, A._, NotificationTypeId.CREDENTIAL_APPROVAL, A._)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _portalService.TriggerMail("CredentialApproval", A._, A>._, A._)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _portalService.TriggerMail("CredentialApproval", A._, A>._, A._)).MustHaveHappenedOnceExactly(); A.CallTo(() => _issuerRepositories.SaveAsync()).MustHaveHappenedOnceExactly(); A.CallTo(() => _processStepRepository.CreateProcess(ProcessTypeId.CREATE_CREDENTIAL)) .MustHaveHappenedOnceExactly(); detail.CompanySsiDetailStatusId.Should().Be(CompanySsiDetailStatusId.ACTIVE); detail.DateLastChanged.Should().Be(now); + processData.Schema.Deserialize()!.IssuanceDate.Should().Be(now); + } + + private static string CreateSchema() + { + var schemaData = new FrameworkCredential( + Guid.NewGuid(), + Context, + new[] { "VerifiableCredential", VerifiedCredentialExternalTypeId.TRACEABILITY_CREDENTIAL.ToString() }, + VerifiedCredentialExternalTypeId.TRACEABILITY_CREDENTIAL.ToString(), + $"Framework Credential for UseCase {VerifiedCredentialExternalTypeId.TRACEABILITY_CREDENTIAL}", + DateTimeOffset.UtcNow, + DateTimeOffset.UtcNow, + "issuer", + new FrameworkCredentialSubject( + "test", + "123", + "UseCaseFramework", + VerifiedCredentialExternalTypeId.TRACEABILITY_CREDENTIAL.ToString(), + "template", + "1.0" + ), + new CredentialStatus( + "https://example.com/statusList", + "StatusList2021") + ); + + var schema = JsonSerializer.Serialize(schemaData, Options); + return schema; } #endregion @@ -403,15 +448,15 @@ public async Task RejectCredential_WithoutExistingSsiDetail_ThrowsNotFoundExcept // Arrange var notExistingId = Guid.NewGuid(); A.CallTo(() => _companySsiDetailsRepository.GetSsiRejectionData(notExistingId)) - .Returns(new ValueTuple>()); - async Task Act() => await _sut.RejectCredential(notExistingId, CancellationToken.None).ConfigureAwait(false); + .Returns(default((bool, CompanySsiDetailStatusId, VerifiedCredentialTypeId, Guid?, IEnumerable))); + Task Act() => _sut.RejectCredential(notExistingId, CancellationToken.None); // Act - var ex = await Assert.ThrowsAsync(Act).ConfigureAwait(false); + var ex = await Assert.ThrowsAsync(Act); // Assert - ex.Message.Should().Be(CredentialErrors.SSI_DETAILS_NOT_FOUND.ToString()); - A.CallTo(() => _portalService.TriggerMail("CredentialRejected", A._, A>._, A._)).MustNotHaveHappened(); + ex.Message.Should().Be(IssuerErrors.SSI_DETAILS_NOT_FOUND.ToString()); + A.CallTo(() => _portalService.TriggerMail("CredentialRejected", A._, A>._, A._)).MustNotHaveHappened(); A.CallTo(() => _issuerRepositories.SaveAsync()).MustNotHaveHappened(); } @@ -423,21 +468,21 @@ public async Task RejectCredential_WithNotPendingSsiDetail_ThrowsNotFoundExcepti // Arrange var alreadyInactiveId = Guid.NewGuid(); A.CallTo(() => _companySsiDetailsRepository.GetSsiRejectionData(alreadyInactiveId)) - .Returns(new ValueTuple>( + .Returns(( true, status, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, null, Enumerable.Empty() )); - async Task Act() => await _sut.RejectCredential(alreadyInactiveId, CancellationToken.None).ConfigureAwait(false); + Task Act() => _sut.RejectCredential(alreadyInactiveId, CancellationToken.None); // Act - var ex = await Assert.ThrowsAsync(Act).ConfigureAwait(false); + var ex = await Assert.ThrowsAsync(Act); // Assert - ex.Message.Should().Be(CredentialErrors.CREDENTIAL_NOT_PENDING.ToString()); - A.CallTo(() => _portalService.TriggerMail("CredentialRejected", A._, A>._, A._)).MustNotHaveHappened(); + ex.Message.Should().Be(IssuerErrors.CREDENTIAL_NOT_PENDING.ToString()); + A.CallTo(() => _portalService.TriggerMail("CredentialRejected", A._, A>._, A._)).MustNotHaveHappened(); A.CallTo(() => _issuerRepositories.SaveAsync()).MustNotHaveHappened(); } @@ -449,7 +494,7 @@ public async Task RejectCredential_WithValidRequest_ReturnsExpected() var detail = new CompanySsiDetail(CredentialId, _identity.Bpnl, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, CompanySsiDetailStatusId.PENDING, IssuerBpnl, Guid.NewGuid().ToString(), DateTimeOffset.Now); A.CallTo(() => _dateTimeProvider.OffsetNow).Returns(now); A.CallTo(() => _companySsiDetailsRepository.GetSsiRejectionData(CredentialId)) - .Returns(new ValueTuple>( + .Returns(( true, CompanySsiDetailStatusId.PENDING, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, @@ -463,10 +508,10 @@ public async Task RejectCredential_WithValidRequest_ReturnsExpected() }); // Act - await _sut.RejectCredential(CredentialId, CancellationToken.None).ConfigureAwait(false); + await _sut.RejectCredential(CredentialId, CancellationToken.None); // Assert - A.CallTo(() => _portalService.TriggerMail("CredentialRejected", A._, A>._, A._)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _portalService.TriggerMail("CredentialRejected", A._, A>._, A._)).MustHaveHappenedOnceExactly(); A.CallTo(() => _portalService.AddNotification(A._, A._, NotificationTypeId.CREDENTIAL_REJECTED, A._)).MustHaveHappenedOnceExactly(); A.CallTo(() => _issuerRepositories.SaveAsync()).MustHaveHappenedOnceExactly(); @@ -482,7 +527,7 @@ public async Task RejectCredential_WithValidRequestAndPendingProcessStepIds_Retu var detail = new CompanySsiDetail(CredentialId, _identity.Bpnl, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, CompanySsiDetailStatusId.PENDING, IssuerBpnl, Guid.NewGuid().ToString(), DateTimeOffset.Now); A.CallTo(() => _dateTimeProvider.OffsetNow).Returns(now); A.CallTo(() => _companySsiDetailsRepository.GetSsiRejectionData(CredentialId)) - .Returns(new ValueTuple>( + .Returns(( true, CompanySsiDetailStatusId.PENDING, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, @@ -496,10 +541,10 @@ public async Task RejectCredential_WithValidRequestAndPendingProcessStepIds_Retu }); // Act - await _sut.RejectCredential(CredentialId, CancellationToken.None).ConfigureAwait(false); + await _sut.RejectCredential(CredentialId, CancellationToken.None); // Assert - A.CallTo(() => _portalService.TriggerMail("CredentialRejected", A._, A>._, A._)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _portalService.TriggerMail("CredentialRejected", A._, A>._, A._)).MustHaveHappenedOnceExactly(); A.CallTo(() => _portalService.AddNotification(A._, A._, NotificationTypeId.CREDENTIAL_REJECTED, A._)).MustHaveHappenedOnceExactly(); A.CallTo(() => _issuerRepositories.SaveAsync()).MustHaveHappenedOnceExactly(); A.CallTo(() => _processStepRepository.AttachAndModifyProcessSteps(A? Initialize, Action Modify)>>._)).MustHaveHappenedOnceExactly(); @@ -520,10 +565,10 @@ public async Task GetCertificateTypes_ReturnsExpected() .Returns(Enum.GetValues().ToAsyncEnumerable()); // Act - var result = await _sut.GetCertificateTypes().ToListAsync().ConfigureAwait(false); + var result = await _sut.GetCertificateTypes().ToListAsync(); // Assert - result.Should().HaveCount(7); + result.Should().HaveCount(10); } #endregion @@ -545,7 +590,7 @@ public async Task CreateBpnCredential_ReturnsExpected() }, requestMessage => request = requestMessage); // Act - await _sut.CreateBpnCredential(data, CancellationToken.None).ConfigureAwait(false); + await _sut.CreateBpnCredential(data, CancellationToken.None); // Assert A.CallTo(() => _documentRepository.CreateDocument("schema.json", A._, A._, MediaTypeId.JSON, DocumentTypeId.PRESENTATION, A>._)) @@ -579,13 +624,13 @@ public async Task CreateBpnCredential_WithInvalidUri_ReturnsExpected(string hold StatusCode = HttpStatusCode.OK, Content = new StringContent(JsonSerializer.Serialize(didDocument)) }, requestMessage => request = requestMessage); - async Task Act() => await _sut.CreateBpnCredential(data, CancellationToken.None).ConfigureAwait(false); + Task Act() => _sut.CreateBpnCredential(data, CancellationToken.None); // Act var ex = await Assert.ThrowsAsync(Act); // Assert - ex.Message.Should().Be(CredentialErrors.INVALID_DID_LOCATION.ToString()); + ex.Message.Should().Be(IssuerErrors.INVALID_DID_LOCATION.ToString()); ex.ParamName.Should().Be("didDocumentLocation"); A.CallTo(() => _documentRepository.CreateDocument("schema.json", A._, A._, MediaTypeId.JSON, DocumentTypeId.PRESENTATION, A>._)) .MustNotHaveHappened(); @@ -617,7 +662,7 @@ public async Task CreateMembershipCredential_ReturnsExpected() }, requestMessage => request = requestMessage); // Act - await _sut.CreateMembershipCredential(data, CancellationToken.None).ConfigureAwait(false); + await _sut.CreateMembershipCredential(data, CancellationToken.None); // Assert A.CallTo(() => _documentRepository.CreateDocument("schema.json", A._, A._, MediaTypeId.JSON, DocumentTypeId.PRESENTATION, A>._)) @@ -640,14 +685,14 @@ public async Task CreateFrameworkCredential_WithVersionNotExisting_ThrowsControl var useCaseId = Guid.NewGuid(); var data = new CreateFrameworkCredentialRequest("BPNL0012HOLDER", Bpnl, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, useCaseId, null, null); A.CallTo(() => _companySsiDetailsRepository.CheckCredentialTypeIdExistsForExternalTypeDetailVersionId(useCaseId, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK)) - .Returns(new ValueTuple, DateTimeOffset>()); - async Task Act() => await _sut.CreateFrameworkCredential(data, CancellationToken.None).ConfigureAwait(false); + .Returns(default((bool, string?, string?, IEnumerable, DateTimeOffset))); + Task Act() => _sut.CreateFrameworkCredential(data, CancellationToken.None); // Act - var ex = await Assert.ThrowsAsync(Act).ConfigureAwait(false); + var ex = await Assert.ThrowsAsync(Act); // Assert - ex.Message.Should().Be(CredentialErrors.EXTERNAL_TYPE_DETAIL_NOT_FOUND.ToString()); + ex.Message.Should().Be(IssuerErrors.EXTERNAL_TYPE_DETAIL_NOT_FOUND.ToString()); } [Fact] @@ -659,14 +704,14 @@ public async Task CreateFrameworkCredential_WithExpiryInPast_ThrowsControllerArg A.CallTo(() => _dateTimeProvider.OffsetNow).Returns(now); var data = new CreateFrameworkCredentialRequest("BPNL0012HOLDER", Bpnl, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, useCaseId, null, null); A.CallTo(() => _companySsiDetailsRepository.CheckCredentialTypeIdExistsForExternalTypeDetailVersionId(useCaseId, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK)) - .Returns(new ValueTuple, DateTimeOffset>(true, null, null, Enumerable.Empty(), now.AddDays(-5))); - async Task Act() => await _sut.CreateFrameworkCredential(data, CancellationToken.None).ConfigureAwait(false); + .Returns((true, null, null, Enumerable.Empty(), now.AddDays(-5))); + Task Act() => _sut.CreateFrameworkCredential(data, CancellationToken.None); // Act - var ex = await Assert.ThrowsAsync(Act).ConfigureAwait(false); + var ex = await Assert.ThrowsAsync(Act); // Assert - ex.Message.Should().Be(CredentialErrors.EXPIRY_DATE_IN_PAST.ToString()); + ex.Message.Should().Be(IssuerErrors.EXPIRY_DATE_IN_PAST.ToString()); } [Fact] @@ -678,14 +723,14 @@ public async Task CreateFrameworkCredential_WithEmptyVersion_ThrowsControllerArg A.CallTo(() => _dateTimeProvider.OffsetNow).Returns(now); var data = new CreateFrameworkCredentialRequest("BPNL0012HOLDER", Bpnl, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, useCaseId, null, null); A.CallTo(() => _companySsiDetailsRepository.CheckCredentialTypeIdExistsForExternalTypeDetailVersionId(useCaseId, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK)) - .Returns(new ValueTuple, DateTimeOffset>(true, null, null, Enumerable.Empty(), now.AddDays(5))); - async Task Act() => await _sut.CreateFrameworkCredential(data, CancellationToken.None).ConfigureAwait(false); + .Returns((true, null, null, Enumerable.Empty(), now.AddDays(5))); + Task Act() => _sut.CreateFrameworkCredential(data, CancellationToken.None); // Act - var ex = await Assert.ThrowsAsync(Act).ConfigureAwait(false); + var ex = await Assert.ThrowsAsync(Act); // Assert - ex.Message.Should().Be(CredentialErrors.EMPTY_VERSION.ToString()); + ex.Message.Should().Be(IssuerErrors.EMPTY_VERSION.ToString()); } [Fact] @@ -697,14 +742,14 @@ public async Task CreateFrameworkCredential_WithEmptyTemplate_ThrowsControllerAr A.CallTo(() => _dateTimeProvider.OffsetNow).Returns(now); var data = new CreateFrameworkCredentialRequest("BPNL0012HOLDER", Bpnl, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, useCaseId, null, null); A.CallTo(() => _companySsiDetailsRepository.CheckCredentialTypeIdExistsForExternalTypeDetailVersionId(useCaseId, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK)) - .Returns(new ValueTuple, DateTimeOffset>(true, "1.0.0", null, Enumerable.Empty(), now.AddDays(5))); - async Task Act() => await _sut.CreateFrameworkCredential(data, CancellationToken.None).ConfigureAwait(false); + .Returns((true, "1.0.0", null, Enumerable.Empty(), now.AddDays(5))); + Task Act() => _sut.CreateFrameworkCredential(data, CancellationToken.None); // Act - var ex = await Assert.ThrowsAsync(Act).ConfigureAwait(false); + var ex = await Assert.ThrowsAsync(Act); // Assert - ex.Message.Should().Be(CredentialErrors.EMPTY_TEMPLATE.ToString()); + ex.Message.Should().Be(IssuerErrors.EMPTY_TEMPLATE.ToString()); } [Fact] @@ -716,14 +761,14 @@ public async Task CreateFrameworkCredential_WithMoreThanOneUseCase_ThrowsControl A.CallTo(() => _dateTimeProvider.OffsetNow).Returns(now); var data = new CreateFrameworkCredentialRequest("BPNL0012HOLDER", Bpnl, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, useCaseId, null, null); A.CallTo(() => _companySsiDetailsRepository.CheckCredentialTypeIdExistsForExternalTypeDetailVersionId(useCaseId, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK)) - .Returns(new ValueTuple, DateTimeOffset>(true, "1.0.0", "https://example.org/tempalte", new[] { "test", "test" }, now.AddDays(5))); - async Task Act() => await _sut.CreateFrameworkCredential(data, CancellationToken.None).ConfigureAwait(false); + .Returns((true, "1.0.0", "https://example.org/tempalte", new[] { VerifiedCredentialExternalTypeId.TRACEABILITY_CREDENTIAL, VerifiedCredentialExternalTypeId.TRACEABILITY_CREDENTIAL }, now.AddDays(5))); + Task Act() => _sut.CreateFrameworkCredential(data, CancellationToken.None); // Act - var ex = await Assert.ThrowsAsync(Act).ConfigureAwait(false); + var ex = await Assert.ThrowsAsync(Act); // Assert - ex.Message.Should().Be(CredentialErrors.MULTIPLE_USE_CASES.ToString()); + ex.Message.Should().Be(IssuerErrors.MULTIPLE_USE_CASES.ToString()); } [Fact] @@ -735,14 +780,14 @@ public async Task CreateFrameworkCredential_WithNoUseCase_ThrowsControllerArgume A.CallTo(() => _dateTimeProvider.OffsetNow).Returns(now); var data = new CreateFrameworkCredentialRequest("BPNL0012HOLDER", Bpnl, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, useCaseId, null, null); A.CallTo(() => _companySsiDetailsRepository.CheckCredentialTypeIdExistsForExternalTypeDetailVersionId(useCaseId, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK)) - .Returns(new ValueTuple, DateTimeOffset>(true, "1.0.0", "https://example.org/tempalte", Enumerable.Empty(), now.AddDays(5))); - async Task Act() => await _sut.CreateFrameworkCredential(data, CancellationToken.None).ConfigureAwait(false); + .Returns((true, "1.0.0", "https://example.org/tempalte", Enumerable.Empty(), now.AddDays(5))); + Task Act() => _sut.CreateFrameworkCredential(data, CancellationToken.None); // Act - var ex = await Assert.ThrowsAsync(Act).ConfigureAwait(false); + var ex = await Assert.ThrowsAsync(Act); // Assert - ex.Message.Should().Be(CredentialErrors.MULTIPLE_USE_CASES.ToString()); + ex.Message.Should().Be(IssuerErrors.MULTIPLE_USE_CASES.ToString()); } [Fact] @@ -757,7 +802,7 @@ public async Task CreateFrameworkCredential_ReturnsExpected() var data = new CreateFrameworkCredentialRequest("https://example.org/holder/BPNL12343546/did.json", Bpnl, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, useCaseId, null, null); HttpRequestMessage? request = null; A.CallTo(() => _companySsiDetailsRepository.CheckCredentialTypeIdExistsForExternalTypeDetailVersionId(useCaseId, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK)) - .Returns(new ValueTuple, DateTimeOffset>(true, "1.0.0", "https://example.org/tempalte", Enumerable.Repeat("Test", 1), now.AddDays(5))); + .Returns((true, "1.0.0", "https://example.org/tempalte", Enumerable.Repeat(VerifiedCredentialExternalTypeId.TRACEABILITY_CREDENTIAL, 1), now.AddDays(5))); ConfigureHttpClientFactoryFixture(new HttpResponseMessage { StatusCode = HttpStatusCode.OK, @@ -765,7 +810,7 @@ public async Task CreateFrameworkCredential_ReturnsExpected() }, requestMessage => request = requestMessage); // Act - await _sut.CreateFrameworkCredential(data, CancellationToken.None).ConfigureAwait(false); + await _sut.CreateFrameworkCredential(data, CancellationToken.None); // Assert A.CallTo(() => _documentRepository.CreateDocument("schema.json", A._, A._, MediaTypeId.JSON, DocumentTypeId.PRESENTATION, A>._)) diff --git a/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/RevocationBusinessLogicTests.cs b/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/RevocationBusinessLogicTests.cs new file mode 100644 index 00000000..1386b206 --- /dev/null +++ b/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/RevocationBusinessLogicTests.cs @@ -0,0 +1,161 @@ +using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Models; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Repositories; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.BusinessLogic; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.ErrorHandling; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Identity; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Services; +using System.Collections.Immutable; + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Tests.BusinessLogic; + +public class RevocationBusinessLogicTests +{ + private static readonly Guid CredentialId = Guid.NewGuid(); + private static readonly string Bpnl = "BPNL00000001TEST"; + private readonly IFixture _fixture; + private readonly IDocumentRepository _documentRepository; + private readonly ICredentialRepository _credentialRepository; + + private readonly IRevocationBusinessLogic _sut; + private readonly IWalletService _walletService; + private readonly IIdentityService _identityService; + private readonly IIdentityData _identityData; + + public RevocationBusinessLogicTests() + { + _fixture = new Fixture().Customize(new AutoFakeItEasyCustomization { ConfigureMembers = true }); + _fixture.Behaviors.OfType().ToList() + .ForEach(b => _fixture.Behaviors.Remove(b)); + _fixture.Behaviors.Add(new OmitOnRecursionBehavior()); + + var issuerRepositories = A.Fake(); + _documentRepository = A.Fake(); + _credentialRepository = A.Fake(); + _walletService = A.Fake(); + _identityService = A.Fake(); + _identityData = A.Fake(); + A.CallTo(() => _identityData.Bpnl).Returns(Bpnl); + A.CallTo(() => _identityService.IdentityData).Returns(_identityData); + + A.CallTo(() => issuerRepositories.GetInstance()).Returns(_documentRepository); + A.CallTo(() => issuerRepositories.GetInstance()).Returns(_credentialRepository); + + _sut = new RevocationBusinessLogic(issuerRepositories, _walletService, _identityService); + } + + #region RevokeIssuerCredential + + [Fact] + public async Task RevokeIssuerCredential_WithNotExisting_ThrowsNotFoundException() + { + // Arrange + A.CallTo(() => _credentialRepository.GetRevocationDataById(CredentialId, Bpnl)) + .Returns(default((bool, bool, Guid?, CompanySsiDetailStatusId, IEnumerable<(Guid, DocumentStatusId)>))); + Task Act() => _sut.RevokeCredential(CredentialId, true, CancellationToken.None); + + // Act + var ex = await Assert.ThrowsAsync(Act); + + // Assert + ex.Message.Should().Be(RevocationDataErrors.CREDENTIAL_NOT_FOUND.ToString()); + } + + [Fact] + public async Task RevokeIssuerCredential_WithNotAllowed_ThrowsForbiddenException() + { + // Arrange + A.CallTo(() => _credentialRepository.GetRevocationDataById(CredentialId, Bpnl)) + .Returns((true, false, null, default, null!)); + Task Act() => _sut.RevokeCredential(CredentialId, false, CancellationToken.None); + + // Act + var ex = await Assert.ThrowsAsync(Act); + + // Assert + ex.Message.Should().Be(RevocationDataErrors.NOT_ALLOWED_TO_REVOKE_CREDENTIAL.ToString()); + } + + [Fact] + public async Task RevokeIssuerCredential_WithExternalCredentialIdNotSet_ThrowsConflictException() + { + // Arrange + A.CallTo(() => _credentialRepository.GetRevocationDataById(CredentialId, Bpnl)) + .Returns((true, true, null, default, null!)); + Task Act() => _sut.RevokeCredential(CredentialId, true, CancellationToken.None); + + // Act + var ex = await Assert.ThrowsAsync(Act); + + // Assert + ex.Message.Should().Be(RevocationDataErrors.EXTERNAL_CREDENTIAL_ID_NOT_SET.ToString()); + } + + [Theory] + [InlineData(CompanySsiDetailStatusId.PENDING)] + [InlineData(CompanySsiDetailStatusId.REVOKED)] + [InlineData(CompanySsiDetailStatusId.INACTIVE)] + public async Task RevokeIssuerCredential_WithStatusNotActiveRevoked_DoesNothing(CompanySsiDetailStatusId statusId) + { + // Arrange + A.CallTo(() => _credentialRepository.GetRevocationDataById(CredentialId, Bpnl)) + .Returns((true, true, Guid.NewGuid(), statusId, null!)); + + // Act + await _sut.RevokeCredential(CredentialId, true, CancellationToken.None); + + // Assert + A.CallTo(() => _walletService.RevokeCredentialForIssuer(A._, A._)).MustNotHaveHappened(); + } + + [Fact] + public async Task RevokeIssuerCredential_WithValid_CallsExpected() + { + // Arrange + var credential = new CompanySsiDetail(CredentialId, "Test", VerifiedCredentialTypeId.BUSINESS_PARTNER_NUMBER, CompanySsiDetailStatusId.ACTIVE, "Test123", Guid.NewGuid().ToString(), DateTimeOffset.UtcNow) + { + ExternalCredentialId = Guid.NewGuid() + }; + var document = _fixture + .Build() + .With(x => x.DocumentStatusId, DocumentStatusId.ACTIVE) + .Create(); + A.CallTo(() => _credentialRepository.GetRevocationDataById(CredentialId, Bpnl)) + .Returns((true, true, credential.ExternalCredentialId, CompanySsiDetailStatusId.ACTIVE, Enumerable.Repeat((document.Id, document.DocumentStatusId), 1))); + A.CallTo(() => _documentRepository.AttachAndModifyDocuments(A? Initialize, Action Modify)>>._)) + .Invokes((IEnumerable<(Guid DocumentId, Action? Initialize, Action Modify)> data) => + { + data.Select(x => + { + x.Initialize?.Invoke(document); + return document; + } + ).ToImmutableArray(); + data.Select(x => + { + x.Modify(document); + return document; + } + ).ToImmutableArray(); + }); + A.CallTo(() => _credentialRepository.AttachAndModifyCredential(credential.Id, A>._, A>._)) + .Invokes((Guid _, Action? initialize, Action modify) => + { + initialize?.Invoke(credential); + modify(credential); + }); + + // Act + await _sut.RevokeCredential(CredentialId, true, CancellationToken.None); + + // Assert + A.CallTo(() => _walletService.RevokeCredentialForIssuer(A._, A._)).MustHaveHappenedOnceExactly(); + document.DocumentStatusId.Should().Be(DocumentStatusId.INACTIVE); + credential.CompanySsiDetailStatusId.Should().Be(CompanySsiDetailStatusId.REVOKED); + } + + #endregion +} diff --git a/tests/issuer/SsiCredentialIssuer.Service.Tests/appsettings.IntegrationTests.json b/tests/issuer/SsiCredentialIssuer.Service.Tests/appsettings.IntegrationTests.json index 32a29359..845532d3 100644 --- a/tests/issuer/SsiCredentialIssuer.Service.Tests/appsettings.IntegrationTests.json +++ b/tests/issuer/SsiCredentialIssuer.Service.Tests/appsettings.IntegrationTests.json @@ -44,5 +44,24 @@ "PaddingMode": "PKCS7" } ] + }, + "Wallet": { + "Username": "empty", + "Password": "empty", + "ClientId": "sa-cl-test", + "GrantType": "client_credentials", + "ClientSecret": "test", + "Scope": "openid", + "TokenAddress": "https://example.org/auth/realms/xy/protocol/openid-connect/token", + "BaseAddress": "https://localhost:5001", + "EncryptionConfigIndex": 0, + "EncryptionConfigs": [ + { + "Index": 0, + "EncryptionKey": "9b1503084ab5638260079cb61b8ed2d1fde462b5a7608556516a1659aeb3f541", + "CipherMode": "CBC", + "PaddingMode": "PKCS7" + } + ] } } diff --git a/tests/processes/CredentialProcess.Library.Tests/CredentialProcessHandlerTests.cs b/tests/processes/CredentialProcess.Library.Tests/CredentialCreationProcessHandlerTests.cs similarity index 81% rename from tests/processes/CredentialProcess.Library.Tests/CredentialProcessHandlerTests.cs rename to tests/processes/CredentialProcess.Library.Tests/CredentialCreationProcessHandlerTests.cs index d580a86b..57862757 100644 --- a/tests/processes/CredentialProcess.Library.Tests/CredentialProcessHandlerTests.cs +++ b/tests/processes/CredentialProcess.Library.Tests/CredentialCreationProcessHandlerTests.cs @@ -24,6 +24,7 @@ using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; using Org.Eclipse.TractusX.SsiCredentialIssuer.Callback.Service.Models; using Org.Eclipse.TractusX.SsiCredentialIssuer.Callback.Service.Services; +using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Creation; using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess; using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Models; using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Repositories; @@ -35,7 +36,7 @@ namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Tests; -public class CredentialProcessHandlerTests +public class CredentialCreationProcessHandlerTests { private readonly Guid _credentialId = Guid.NewGuid(); @@ -43,11 +44,11 @@ public class CredentialProcessHandlerTests private readonly IIssuerRepositories _issuerRepositories; private readonly ICredentialRepository _credentialRepository; - private readonly CredentialProcessHandler _sut; + private readonly CredentialCreationProcessHandler _sut; private readonly IFixture _fixture; private readonly ICallbackService _callbackService; - public CredentialProcessHandlerTests() + public CredentialCreationProcessHandlerTests() { _fixture = new Fixture().Customize(new AutoFakeItEasyCustomization { ConfigureMembers = true }); _fixture.Behaviors.OfType().ToList() @@ -62,7 +63,7 @@ public CredentialProcessHandlerTests() _walletBusinessLogic = A.Fake(); _callbackService = A.Fake(); - _sut = new CredentialProcessHandler(_issuerRepositories, _walletBusinessLogic, _callbackService); + _sut = new CredentialCreationProcessHandler(_issuerRepositories, _walletBusinessLogic, _callbackService); } #region CreateCredential @@ -72,10 +73,10 @@ public async Task CreateCredential_WithValidData_ReturnsExpected() { // Arrange A.CallTo(() => _credentialRepository.GetCredentialStorageInformationById(_credentialId)) - .Returns(new ValueTuple()); + .Returns(default((VerifiedCredentialTypeKindId, JsonDocument))); // Act - var result = await _sut.CreateCredential(_credentialId, CancellationToken.None).ConfigureAwait(false); + var result = await _sut.CreateCredential(_credentialId, CancellationToken.None); // Assert A.CallTo(() => _walletBusinessLogic.CreateCredential(_credentialId, A._, A._)) @@ -97,7 +98,7 @@ public async Task SignCredential_WithNotExisting_ReturnsExpected() // Arrange A.CallTo(() => _credentialRepository.GetWalletCredentialId(_credentialId)) .Returns(null); - async Task Act() => await _sut.SignCredential(_credentialId, CancellationToken.None).ConfigureAwait(false); + Task Act() => _sut.SignCredential(_credentialId, CancellationToken.None); // Act var ex = await Assert.ThrowsAsync(Act); @@ -115,7 +116,7 @@ public async Task SignCredential_WithValidData_ReturnsExpected() .Returns(externalCredentialId); // Act - var result = await _sut.SignCredential(_credentialId, CancellationToken.None).ConfigureAwait(false); + var result = await _sut.SignCredential(_credentialId, CancellationToken.None); // Assert A.CallTo(() => _walletBusinessLogic.SignCredential(_credentialId, externalCredentialId, A._)) @@ -137,7 +138,7 @@ public async Task SaveCredentialDocument_WithNotExisting_ReturnsExpected() // Arrange A.CallTo(() => _credentialRepository.GetExternalCredentialAndKindId(_credentialId)) .Returns(default((Guid?, VerifiedCredentialTypeKindId, bool, string?))); - async Task Act() => await _sut.SaveCredentialDocument(_credentialId, CancellationToken.None).ConfigureAwait(false); + Task Act() => _sut.SaveCredentialDocument(_credentialId, CancellationToken.None); // Act var ex = await Assert.ThrowsAsync(Act); @@ -155,7 +156,7 @@ public async Task SaveCredentialDocument_WithValidData_ReturnsExpected() .Returns((externalCredentialId, VerifiedCredentialTypeKindId.BPN, true, "https://example.org")); // Act - var result = await _sut.SaveCredentialDocument(_credentialId, CancellationToken.None).ConfigureAwait(false); + var result = await _sut.SaveCredentialDocument(_credentialId, CancellationToken.None); // Assert A.CallTo(() => _walletBusinessLogic.GetCredential(_credentialId, externalCredentialId, VerifiedCredentialTypeKindId.BPN, A._)) @@ -176,8 +177,8 @@ public async Task CreateCredentialForHolder_WithCredentialNotSet_SkipsStep() { // Arrange A.CallTo(() => _credentialRepository.GetCredentialData(_credentialId)) - .Returns(new ValueTuple()); - async Task Act() => await _sut.CreateCredentialForHolder(_credentialId, CancellationToken.None).ConfigureAwait(false); + .Returns(default((HolderWalletData, string?, EncryptionTransformationData, string?))); + Task Act() => _sut.CreateCredentialForHolder(_credentialId, CancellationToken.None); // Act var ex = await Assert.ThrowsAsync(Act); @@ -191,8 +192,8 @@ public async Task CreateCredentialForHolder_WithClientIdNull_SkipsStep() { // Arrange A.CallTo(() => _credentialRepository.GetCredentialData(_credentialId)) - .Returns(new ValueTuple(new HolderWalletData(null, null), "test", _fixture.Create(), "https://example.org")); - async Task Act() => await _sut.CreateCredentialForHolder(_credentialId, CancellationToken.None).ConfigureAwait(false); + .Returns((new HolderWalletData(null, null), "test", _fixture.Create(), "https://example.org")); + Task Act() => _sut.CreateCredentialForHolder(_credentialId, CancellationToken.None); // Act var ex = await Assert.ThrowsAsync(Act); @@ -206,8 +207,8 @@ public async Task CreateCredentialForHolder_WithWalletUrlNull_SkipsStep() { // Arrange A.CallTo(() => _credentialRepository.GetCredentialData(_credentialId)) - .Returns(new ValueTuple(new HolderWalletData(null, "c1"), "test", _fixture.Create(), "https://example.org")); - async Task Act() => await _sut.CreateCredentialForHolder(_credentialId, CancellationToken.None).ConfigureAwait(false); + .Returns((new HolderWalletData(null, "c1"), "test", _fixture.Create(), "https://example.org")); + Task Act() => _sut.CreateCredentialForHolder(_credentialId, CancellationToken.None); // Act var ex = await Assert.ThrowsAsync(Act); @@ -221,14 +222,14 @@ public async Task CreateCredentialForHolder_WithEncryptionNotSet_SkipsStep() { // Arrange A.CallTo(() => _credentialRepository.GetCredentialData(_credentialId)) - .Returns(new ValueTuple( + .Returns(( new HolderWalletData("https://example.org", "c1"), "test", new EncryptionTransformationData("test"u8.ToArray(), "test"u8.ToArray(), 0), "https://example.org")); // Act - var result = await _sut.CreateCredentialForHolder(_credentialId, CancellationToken.None).ConfigureAwait(false); + var result = await _sut.CreateCredentialForHolder(_credentialId, CancellationToken.None); // Assert result.modified.Should().BeFalse(); @@ -242,14 +243,14 @@ public async Task CreateCredentialForHolder_WithValidData_ReturnsExpected() { // Arrange A.CallTo(() => _credentialRepository.GetCredentialData(_credentialId)) - .Returns(new ValueTuple( + .Returns(( new HolderWalletData("https://example.org", "c1"), "test", _fixture.Create(), "https://example.org")); // Act - var result = await _sut.CreateCredentialForHolder(_credentialId, CancellationToken.None).ConfigureAwait(false); + var result = await _sut.CreateCredentialForHolder(_credentialId, CancellationToken.None); // Assert A.CallTo(() => _walletBusinessLogic.CreateCredentialForHolder(_credentialId, "https://example.org", "c1", A._, "test", A._)) @@ -270,8 +271,8 @@ public async Task TriggerCallback_WithCallbackUrlNotSet_ThrowsConflictException( { // Arrange A.CallTo(() => _credentialRepository.GetCallbackUrl(_credentialId)) - .Returns(new ValueTuple("BPNL000001234", null)); - async Task Act() => await _sut.TriggerCallback(_credentialId, CancellationToken.None).ConfigureAwait(false); + .Returns(("BPNL000001234", null)); + Task Act() => _sut.TriggerCallback(_credentialId, CancellationToken.None); // Act var ex = await Assert.ThrowsAsync(Act); @@ -285,10 +286,10 @@ public async Task TriggerCallback_WithValid_CallsExpected() { // Arrange A.CallTo(() => _credentialRepository.GetCallbackUrl(_credentialId)) - .Returns(new ValueTuple("BPNL00000123456", "https://example.org")); + .Returns(("BPNL00000123456", "https://example.org")); // Act - var result = await _sut.TriggerCallback(_credentialId, CancellationToken.None).ConfigureAwait(false); + var result = await _sut.TriggerCallback(_credentialId, CancellationToken.None); // Assert A.CallTo(() => _callbackService.TriggerCallback("https://example.org", A._, A._)) diff --git a/tests/processes/CredentialProcess.Library.Tests/CredentialExpiryProcessHandlerTests.cs b/tests/processes/CredentialProcess.Library.Tests/CredentialExpiryProcessHandlerTests.cs new file mode 100644 index 00000000..7b28ac83 --- /dev/null +++ b/tests/processes/CredentialProcess.Library.Tests/CredentialExpiryProcessHandlerTests.cs @@ -0,0 +1,209 @@ +/******************************************************************************** + * Copyright (c) 2024 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 AutoFixture; +using AutoFixture.AutoFakeItEasy; +using FakeItEasy; +using FluentAssertions; +using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; +using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Expiry; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Repositories; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Portal.Service.Models; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Portal.Service.Services; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Services; +using System.Collections.Immutable; +using Xunit; + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Tests; + +public class CredentialExpiryProcessHandlerTests +{ + private readonly Guid _credentialId = Guid.NewGuid(); + + private readonly IWalletService _walletService; + private readonly IIssuerRepositories _issuerRepositories; + private readonly ICredentialRepository _credentialRepository; + private readonly IPortalService _portalService; + + private readonly CredentialExpiryProcessHandler _sut; + private readonly IFixture _fixture; + private readonly IDocumentRepository _documentRepository; + + public CredentialExpiryProcessHandlerTests() + { + _fixture = new Fixture().Customize(new AutoFakeItEasyCustomization { ConfigureMembers = true }); + _fixture.Behaviors.OfType().ToList() + .ForEach(b => _fixture.Behaviors.Remove(b)); + _fixture.Behaviors.Add(new OmitOnRecursionBehavior()); + + _issuerRepositories = A.Fake(); + _credentialRepository = A.Fake(); + _documentRepository = A.Fake(); + + A.CallTo(() => _issuerRepositories.GetInstance()).Returns(_credentialRepository); + A.CallTo(() => _issuerRepositories.GetInstance()).Returns(_documentRepository); + + _walletService = A.Fake(); + _portalService = A.Fake(); + + _sut = new CredentialExpiryProcessHandler(_issuerRepositories, _walletService, _portalService); + } + + #region RevokeCredential + + [Fact] + public async Task RevokeCredential_WithValidData_ReturnsExpected() + { + // Arrange + var externalCredentialId = Guid.NewGuid(); + var credential = new CompanySsiDetail(_credentialId, "Test", VerifiedCredentialTypeId.BUSINESS_PARTNER_NUMBER, CompanySsiDetailStatusId.ACTIVE, "Test123", Guid.NewGuid().ToString(), DateTimeOffset.UtcNow); + var document = _fixture + .Build() + .With(x => x.DocumentStatusId, DocumentStatusId.ACTIVE) + .Create(); + A.CallTo(() => _credentialRepository.GetRevocationDataById(_credentialId, string.Empty)) + .Returns((true, false, externalCredentialId, credential.CompanySsiDetailStatusId, Enumerable.Repeat((document.Id, document.DocumentStatusId), 1))); + A.CallTo(() => _credentialRepository.AttachAndModifyCredential(credential.Id, A>._, A>._)) + .Invokes((Guid _, Action? initialize, Action modify) => + { + initialize?.Invoke(credential); + modify(credential); + }); + + A.CallTo(() => _documentRepository.AttachAndModifyDocuments(A? Initialize, Action Modify)>>._)) + .Invokes((IEnumerable<(Guid DocumentId, Action? Initialize, Action Modify)> data) => + { + data.Select(x => + { + x.Initialize?.Invoke(document); + return document; + } + ).ToImmutableArray(); + data.Select(x => + { + x.Modify(document); + return document; + } + ).ToImmutableArray(); + }); + + // Act + var result = await _sut.RevokeCredential(_credentialId, CancellationToken.None); + + // Assert + A.CallTo(() => _walletService.RevokeCredentialForIssuer(externalCredentialId, A._)) + .MustHaveHappenedOnceExactly(); + + credential.CompanySsiDetailStatusId.Should().Be(CompanySsiDetailStatusId.REVOKED); + document.DocumentStatusId.Should().Be(DocumentStatusId.INACTIVE); + result.modified.Should().BeFalse(); + result.processMessage.Should().BeNull(); + result.stepStatusId.Should().Be(ProcessStepStatusId.DONE); + result.nextStepTypeIds.Should().ContainSingle().Which.Should().Be(ProcessStepTypeId.TRIGGER_NOTIFICATION); + } + + [Fact] + public async Task RevokeCredential_WithNotExisting_ThrowsNotFoundException() + { + // Arrange + var externalCredentialId = Guid.NewGuid(); + A.CallTo(() => _credentialRepository.GetRevocationDataById(_credentialId, string.Empty)) + .Returns((false, false, null, default, Enumerable.Empty>())); + Task Act() => _sut.RevokeCredential(_credentialId, CancellationToken.None); + + // Act + var ex = await Assert.ThrowsAsync(Act); + + // Assert + ex.Message.Should().Be($"Credential {_credentialId} does not exist"); + A.CallTo(() => _walletService.RevokeCredentialForIssuer(externalCredentialId, A._)) + .MustNotHaveHappened(); + } + + [Fact] + public async Task RevokeCredential_WithEmptyExternalCredentialId_ThrowsConflictException() + { + // Arrange + var externalCredentialId = Guid.NewGuid(); + A.CallTo(() => _credentialRepository.GetRevocationDataById(_credentialId, string.Empty)) + .Returns((true, true, null, default, Enumerable.Empty>())); + Task Act() => _sut.RevokeCredential(_credentialId, CancellationToken.None); + + // Act + var ex = await Assert.ThrowsAsync(Act); + + // Assert + ex.Message.Should().Be($"External Credential Id must be set for {_credentialId}"); + A.CallTo(() => _walletService.RevokeCredentialForIssuer(externalCredentialId, A._)) + .MustNotHaveHappened(); + } + + #endregion + + #region TriggerNotification + + [Fact] + public async Task TriggerNotification_WithValid_CallsExpected() + { + // Arrange + var requesterId = Guid.NewGuid(); + A.CallTo(() => _credentialRepository.GetCredentialNotificationData(_credentialId)) + .Returns((VerifiedCredentialTypeId.PCF_FRAMEWORK, requesterId.ToString())); + + // Act + var result = await _sut.TriggerNotification(_credentialId, CancellationToken.None); + + // Assert + A.CallTo(() => _portalService.AddNotification(A._, requesterId, NotificationTypeId.CREDENTIAL_REJECTED, A._)) + .MustHaveHappenedOnceExactly(); + result.modified.Should().BeFalse(); + result.processMessage.Should().BeNull(); + result.stepStatusId.Should().Be(ProcessStepStatusId.DONE); + result.nextStepTypeIds.Should().ContainSingle().Which.Should().Be(ProcessStepTypeId.TRIGGER_MAIL); + } + + #endregion + + #region TriggerMail + + [Fact] + public async Task TriggerMail_WithValid_CallsExpected() + { + // Arrange + var requesterId = Guid.NewGuid(); + A.CallTo(() => _credentialRepository.GetCredentialNotificationData(_credentialId)) + .Returns((VerifiedCredentialTypeId.PCF_FRAMEWORK, requesterId.ToString())); + + // Act + var result = await _sut.TriggerMail(_credentialId, CancellationToken.None); + + // Assert + A.CallTo(() => _portalService.TriggerMail("CredentialRejected", requesterId, A>._, A._)) + .MustHaveHappenedOnceExactly(); + result.modified.Should().BeFalse(); + result.processMessage.Should().BeNull(); + result.stepStatusId.Should().Be(ProcessStepStatusId.DONE); + result.nextStepTypeIds.Should().BeNull(); + } + + #endregion +} diff --git a/tests/processes/CredentialProcess.Worker.Tests/CredentialProcessTypeExecutorTests.cs b/tests/processes/CredentialProcess.Worker.Tests/CredentialCreationProcessTypeExecutorTests.cs similarity index 81% rename from tests/processes/CredentialProcess.Worker.Tests/CredentialProcessTypeExecutorTests.cs rename to tests/processes/CredentialProcess.Worker.Tests/CredentialCreationProcessTypeExecutorTests.cs index 761d2289..16a6220d 100644 --- a/tests/processes/CredentialProcess.Worker.Tests/CredentialProcessTypeExecutorTests.cs +++ b/tests/processes/CredentialProcess.Worker.Tests/CredentialCreationProcessTypeExecutorTests.cs @@ -22,21 +22,22 @@ using FakeItEasy; using FluentAssertions; using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; -using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Worker; +using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Creation; +using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Worker.Creation; using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess; using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Repositories; using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; using Xunit; -namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Tests; +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Worker.Tests; -public class CredentialProcessTypeExecutorTests +public class CredentialCreationProcessTypeExecutorTests { - private readonly CredentialProcessTypeExecutor _sut; - private readonly ICredentialProcessHandler _credentialProcessHandler; + private readonly CredentialCreationProcessTypeExecutor _sut; + private readonly ICredentialCreationProcessHandler _credentialCreationProcessHandler; private readonly ICredentialRepository _credentialRepository; - public CredentialProcessTypeExecutorTests() + public CredentialCreationProcessTypeExecutorTests() { var fixture = new Fixture().Customize(new AutoFakeItEasyCustomization { ConfigureMembers = true }); fixture.Behaviors.OfType().ToList() @@ -44,13 +45,13 @@ public CredentialProcessTypeExecutorTests() fixture.Behaviors.Add(new OmitOnRecursionBehavior()); var issuerRepositories = A.Fake(); - _credentialProcessHandler = A.Fake(); + _credentialCreationProcessHandler = A.Fake(); _credentialRepository = A.Fake(); A.CallTo(() => issuerRepositories.GetInstance()).Returns(_credentialRepository); - _sut = new CredentialProcessTypeExecutor(issuerRepositories, _credentialProcessHandler); + _sut = new CredentialCreationProcessTypeExecutor(issuerRepositories, _credentialCreationProcessHandler); } [Fact] @@ -83,7 +84,7 @@ public void GetExecutableStepTypeIds_ReturnsExpected() public async Task IsLockRequested_ReturnsExpected() { // Act - var result = await _sut.IsLockRequested(ProcessStepTypeId.SIGN_CREDENTIAL).ConfigureAwait(false); + var result = await _sut.IsLockRequested(ProcessStepTypeId.SIGN_CREDENTIAL); // Assert result.Should().BeFalse(); @@ -97,10 +98,10 @@ public async Task InitializeProcess_WithExistingProcess_ReturnsExpected() // Arrange var validProcessId = Guid.NewGuid(); A.CallTo(() => _credentialRepository.GetDataForProcessId(validProcessId)) - .Returns(new ValueTuple(true, Guid.NewGuid())); + .Returns((true, Guid.NewGuid())); // Act - var result = await _sut.InitializeProcess(validProcessId, Enumerable.Empty()).ConfigureAwait(false); + var result = await _sut.InitializeProcess(validProcessId, Enumerable.Empty()); // Assert result.Modified.Should().BeFalse(); @@ -113,10 +114,10 @@ public async Task InitializeProcess_WithNotExistingProcess_ThrowsNotFoundExcepti // Arrange var validProcessId = Guid.NewGuid(); A.CallTo(() => _credentialRepository.GetDataForProcessId(validProcessId)) - .Returns(new ValueTuple(false, Guid.Empty)); + .Returns(default((bool, Guid))); // Act - async Task Act() => await _sut.InitializeProcess(validProcessId, Enumerable.Empty()).ConfigureAwait(false); + async Task Act() => await _sut.InitializeProcess(validProcessId, Enumerable.Empty()); // Assert var ex = await Assert.ThrowsAsync(Act); @@ -131,7 +132,7 @@ public async Task InitializeProcess_WithNotExistingProcess_ThrowsNotFoundExcepti public async Task ExecuteProcessStep_WithoutRegistrationId_ThrowsUnexpectedConditionException() { // Act - async Task Act() => await _sut.ExecuteProcessStep(ProcessStepTypeId.SIGN_CREDENTIAL, Enumerable.Empty(), CancellationToken.None).ConfigureAwait(false); + async Task Act() => await _sut.ExecuteProcessStep(ProcessStepTypeId.SIGN_CREDENTIAL, Enumerable.Empty(), CancellationToken.None); // Assert var ex = await Assert.ThrowsAsync(Act); @@ -145,21 +146,21 @@ public async Task ExecuteProcessStep_WithValidData_CallsExpected() var validProcessId = Guid.NewGuid(); var credentialId = Guid.NewGuid(); A.CallTo(() => _credentialRepository.GetDataForProcessId(validProcessId)) - .Returns(new ValueTuple(true, credentialId)); + .Returns((true, credentialId)); // Act InitializeProcess - var initializeResult = await _sut.InitializeProcess(validProcessId, Enumerable.Empty()).ConfigureAwait(false); + var initializeResult = await _sut.InitializeProcess(validProcessId, Enumerable.Empty()); // Assert InitializeProcess initializeResult.Modified.Should().BeFalse(); initializeResult.ScheduleStepTypeIds.Should().BeNull(); // Arrange - A.CallTo(() => _credentialProcessHandler.CreateCredential(credentialId, A._)) - .Returns(new ValueTuple?, ProcessStepStatusId, bool, string?>(null, ProcessStepStatusId.DONE, false, null)); + A.CallTo(() => _credentialCreationProcessHandler.CreateCredential(credentialId, A._)) + .Returns((null, ProcessStepStatusId.DONE, false, null)); // Act - var result = await _sut.ExecuteProcessStep(ProcessStepTypeId.CREATE_CREDENTIAL, Enumerable.Empty(), CancellationToken.None).ConfigureAwait(false); + var result = await _sut.ExecuteProcessStep(ProcessStepTypeId.CREATE_CREDENTIAL, Enumerable.Empty(), CancellationToken.None); // Assert result.Modified.Should().BeFalse(); @@ -176,21 +177,21 @@ public async Task ExecuteProcessStep_WithRecoverableServiceException_ReturnsToDo var validProcessId = Guid.NewGuid(); var credentialId = Guid.NewGuid(); A.CallTo(() => _credentialRepository.GetDataForProcessId(validProcessId)) - .Returns(new ValueTuple(true, credentialId)); + .Returns((true, credentialId)); // Act InitializeProcess - var initializeResult = await _sut.InitializeProcess(validProcessId, Enumerable.Empty()).ConfigureAwait(false); + var initializeResult = await _sut.InitializeProcess(validProcessId, Enumerable.Empty()); // Assert InitializeProcess initializeResult.Modified.Should().BeFalse(); initializeResult.ScheduleStepTypeIds.Should().BeNull(); // Arrange - A.CallTo(() => _credentialProcessHandler.CreateCredential(credentialId, A._)) + A.CallTo(() => _credentialCreationProcessHandler.CreateCredential(credentialId, A._)) .Throws(new ServiceException("this is a test", true)); // Act - var result = await _sut.ExecuteProcessStep(ProcessStepTypeId.CREATE_CREDENTIAL, Enumerable.Empty(), CancellationToken.None).ConfigureAwait(false); + var result = await _sut.ExecuteProcessStep(ProcessStepTypeId.CREATE_CREDENTIAL, Enumerable.Empty(), CancellationToken.None); // Assert result.Modified.Should().BeTrue(); @@ -207,21 +208,21 @@ public async Task ExecuteProcessStep_WithServiceException_ReturnsFailedAndRetrig var validProcessId = Guid.NewGuid(); var credentialId = Guid.NewGuid(); A.CallTo(() => _credentialRepository.GetDataForProcessId(validProcessId)) - .Returns(new ValueTuple(true, credentialId)); + .Returns((true, credentialId)); // Act InitializeProcess - var initializeResult = await _sut.InitializeProcess(validProcessId, Enumerable.Empty()).ConfigureAwait(false); + var initializeResult = await _sut.InitializeProcess(validProcessId, Enumerable.Empty()); // Assert InitializeProcess initializeResult.Modified.Should().BeFalse(); initializeResult.ScheduleStepTypeIds.Should().BeNull(); // Arrange - A.CallTo(() => _credentialProcessHandler.CreateCredential(credentialId, A._)) + A.CallTo(() => _credentialCreationProcessHandler.CreateCredential(credentialId, A._)) .Throws(new ServiceException("this is a test")); // Act - var result = await _sut.ExecuteProcessStep(ProcessStepTypeId.CREATE_CREDENTIAL, Enumerable.Empty(), CancellationToken.None).ConfigureAwait(false); + var result = await _sut.ExecuteProcessStep(ProcessStepTypeId.CREATE_CREDENTIAL, Enumerable.Empty(), CancellationToken.None); // Assert result.Modified.Should().BeTrue(); diff --git a/tests/processes/CredentialProcess.Worker.Tests/CredentialExpiryProcessTypeExecutorTests.cs b/tests/processes/CredentialProcess.Worker.Tests/CredentialExpiryProcessTypeExecutorTests.cs new file mode 100644 index 00000000..5fc861fd --- /dev/null +++ b/tests/processes/CredentialProcess.Worker.Tests/CredentialExpiryProcessTypeExecutorTests.cs @@ -0,0 +1,234 @@ +/******************************************************************************** + * Copyright (c) 2024 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 AutoFixture; +using AutoFixture.AutoFakeItEasy; +using FakeItEasy; +using FluentAssertions; +using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; +using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Expiry; +using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Worker.Expiry; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess; +using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Repositories; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; +using Xunit; + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Worker.Tests; + +public class CredentialExpiryProcessTypeExecutorTests +{ + private readonly CredentialExpiryProcessTypeExecutor _sut; + private readonly ICredentialExpiryProcessHandler _credentialExpiryProcessHandler; + private readonly ICredentialRepository _credentialRepository; + + public CredentialExpiryProcessTypeExecutorTests() + { + var fixture = new Fixture().Customize(new AutoFakeItEasyCustomization { ConfigureMembers = true }); + fixture.Behaviors.OfType().ToList() + .ForEach(b => fixture.Behaviors.Remove(b)); + fixture.Behaviors.Add(new OmitOnRecursionBehavior()); + + var issuerRepositories = A.Fake(); + _credentialExpiryProcessHandler = A.Fake(); + + _credentialRepository = A.Fake(); + + A.CallTo(() => issuerRepositories.GetInstance()).Returns(_credentialRepository); + + _sut = new CredentialExpiryProcessTypeExecutor(issuerRepositories, _credentialExpiryProcessHandler); + } + + [Fact] + public void GetProcessTypeId_ReturnsExpected() + { + // Assert + _sut.GetProcessTypeId().Should().Be(ProcessTypeId.DECLINE_CREDENTIAL); + } + + [Fact] + public void IsExecutableStepTypeId_WithValid_ReturnsExpected() + { + // Assert + _sut.IsExecutableStepTypeId(ProcessStepTypeId.REVOKE_CREDENTIAL).Should().BeTrue(); + } + + [Fact] + public void GetExecutableStepTypeIds_ReturnsExpected() + { + // Assert + _sut.GetExecutableStepTypeIds().Should().HaveCount(3).And.Satisfy( + x => x == ProcessStepTypeId.REVOKE_CREDENTIAL, + x => x == ProcessStepTypeId.TRIGGER_MAIL, + x => x == ProcessStepTypeId.TRIGGER_NOTIFICATION); + } + + [Fact] + public async Task IsLockRequested_ReturnsExpected() + { + // Act + var result = await _sut.IsLockRequested(ProcessStepTypeId.REVOKE_CREDENTIAL); + + // Assert + result.Should().BeFalse(); + } + + #region InitializeProcess + + [Fact] + public async Task InitializeProcess_WithExistingProcess_ReturnsExpected() + { + // Arrange + var validProcessId = Guid.NewGuid(); + A.CallTo(() => _credentialRepository.GetDataForProcessId(validProcessId)) + .Returns((true, Guid.NewGuid())); + + // Act + var result = await _sut.InitializeProcess(validProcessId, Enumerable.Empty()); + + // Assert + result.Modified.Should().BeFalse(); + result.ScheduleStepTypeIds.Should().BeNull(); + } + + [Fact] + public async Task InitializeProcess_WithNotExistingProcess_ThrowsNotFoundException() + { + // Arrange + var validProcessId = Guid.NewGuid(); + A.CallTo(() => _credentialRepository.GetDataForProcessId(validProcessId)) + .Returns(default((bool, Guid))); + + // Act + async Task Act() => await _sut.InitializeProcess(validProcessId, Enumerable.Empty()); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"process {validProcessId} does not exist or is not associated with an credential"); + } + + #endregion + + #region ExecuteProcessStep + + [Fact] + public async Task ExecuteProcessStep_WithoutRegistrationId_ThrowsUnexpectedConditionException() + { + // Act + async Task Act() => await _sut.ExecuteProcessStep(ProcessStepTypeId.SIGN_CREDENTIAL, Enumerable.Empty(), CancellationToken.None); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be("credentialId should never be empty here"); + } + + [Fact] + public async Task ExecuteProcessStep_WithValidData_CallsExpected() + { + // Arrange InitializeProcess + var validProcessId = Guid.NewGuid(); + var credentialId = Guid.NewGuid(); + A.CallTo(() => _credentialRepository.GetDataForProcessId(validProcessId)) + .Returns((true, credentialId)); + + // Act InitializeProcess + var initializeResult = await _sut.InitializeProcess(validProcessId, Enumerable.Empty()); + + // Assert InitializeProcess + initializeResult.Modified.Should().BeFalse(); + initializeResult.ScheduleStepTypeIds.Should().BeNull(); + + // Arrange + A.CallTo(() => _credentialExpiryProcessHandler.RevokeCredential(credentialId, A._)) + .Returns((null, ProcessStepStatusId.DONE, false, null)); + + // Act + var result = await _sut.ExecuteProcessStep(ProcessStepTypeId.REVOKE_CREDENTIAL, Enumerable.Empty(), CancellationToken.None); + + // Assert + result.Modified.Should().BeFalse(); + result.ScheduleStepTypeIds.Should().BeNull(); + result.ProcessStepStatusId.Should().Be(ProcessStepStatusId.DONE); + result.ProcessMessage.Should().BeNull(); + result.SkipStepTypeIds.Should().BeNull(); + } + + [Fact] + public async Task ExecuteProcessStep_WithRecoverableServiceException_ReturnsToDo() + { + // Arrange InitializeProcess + var validProcessId = Guid.NewGuid(); + var credentialId = Guid.NewGuid(); + A.CallTo(() => _credentialRepository.GetDataForProcessId(validProcessId)) + .Returns((true, credentialId)); + + // Act InitializeProcess + var initializeResult = await _sut.InitializeProcess(validProcessId, Enumerable.Empty()); + + // Assert InitializeProcess + initializeResult.Modified.Should().BeFalse(); + initializeResult.ScheduleStepTypeIds.Should().BeNull(); + + // Arrange + A.CallTo(() => _credentialExpiryProcessHandler.RevokeCredential(credentialId, A._)) + .Throws(new ServiceException("this is a test", true)); + + // Act + var result = await _sut.ExecuteProcessStep(ProcessStepTypeId.REVOKE_CREDENTIAL, Enumerable.Empty(), CancellationToken.None); + + // Assert + result.Modified.Should().BeTrue(); + result.ScheduleStepTypeIds.Should().BeNull(); + result.ProcessStepStatusId.Should().Be(ProcessStepStatusId.TODO); + result.ProcessMessage.Should().Be("this is a test"); + result.SkipStepTypeIds.Should().BeNull(); + } + + [Fact] + public async Task ExecuteProcessStep_WithServiceException_ReturnsFailedAndRetriggerStep() + { + // Arrange InitializeProcess + var validProcessId = Guid.NewGuid(); + var credentialId = Guid.NewGuid(); + A.CallTo(() => _credentialRepository.GetDataForProcessId(validProcessId)) + .Returns((true, credentialId)); + + // Act InitializeProcess + var initializeResult = await _sut.InitializeProcess(validProcessId, Enumerable.Empty()); + + // Assert InitializeProcess + initializeResult.Modified.Should().BeFalse(); + initializeResult.ScheduleStepTypeIds.Should().BeNull(); + + // Arrange + A.CallTo(() => _credentialExpiryProcessHandler.RevokeCredential(credentialId, A._)) + .Throws(new ServiceException("this is a test")); + + // Act + var result = await _sut.ExecuteProcessStep(ProcessStepTypeId.REVOKE_CREDENTIAL, Enumerable.Empty(), CancellationToken.None); + + // Assert + result.Modified.Should().BeTrue(); + result.ScheduleStepTypeIds.Should().BeNull(); + result.ProcessStepStatusId.Should().Be(ProcessStepStatusId.FAILED); + result.ProcessMessage.Should().Be("this is a test"); + result.SkipStepTypeIds.Should().BeNull(); + } + + #endregion +} diff --git a/tests/processes/Processes.Worker.Library.Tests/ProcessExecutorTests.cs b/tests/processes/Processes.Worker.Library.Tests/ProcessExecutorTests.cs index 2c444016..a9806209 100644 --- a/tests/processes/Processes.Worker.Library.Tests/ProcessExecutorTests.cs +++ b/tests/processes/Processes.Worker.Library.Tests/ProcessExecutorTests.cs @@ -24,7 +24,6 @@ using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Entities; using Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; using System.Collections.Immutable; -using System.Linq.Expressions; using ProcessTypeId = Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums.ProcessTypeId; namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Processes.Worker.Library.Tests; From e32ec3a47e94133294a8e7035f81e5d8fbe305e3 Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Fri, 26 Apr 2024 17:11:44 +0200 Subject: [PATCH 02/13] fix: adjust bpn schema (#84) Reviewed-By: Evelyn Gurschler --- DEPENDENCIES | 1 - .../Wallet.Service/Schemas/BPNCredential.schema.json | 4 ++-- .../BusinessLogic/WalletBusinessLogicTests.cs | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/DEPENDENCIES b/DEPENDENCIES index ea71b550..8965f9a8 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -6,7 +6,6 @@ nuget/nuget/-/EFCore.NamingConventions/7.0.2, Apache-2.0, approved, #10067 nuget/nuget/-/FakeItEasy/7.4.0, MIT, approved, #10080 nuget/nuget/-/Fare/2.1.1, MIT, approved, clearlydefined nuget/nuget/-/FluentAssertions/6.11.0, Apache-2.0 AND MIT, approved, #10061 -nuget/nuget/-/Flurl.Http.Signed/3.2.4, MIT, approved, #3503 nuget/nuget/-/Flurl.Signed/3.0.6, MIT, approved, #3501 nuget/nuget/-/Humanizer.Core/2.14.1, MIT, approved, #10060 nuget/nuget/-/Json.More.Net/2.0.0, MIT, approved, clearlydefined diff --git a/src/externalservices/Wallet.Service/Schemas/BPNCredential.schema.json b/src/externalservices/Wallet.Service/Schemas/BPNCredential.schema.json index ba43ad65..ad697276 100644 --- a/src/externalservices/Wallet.Service/Schemas/BPNCredential.schema.json +++ b/src/externalservices/Wallet.Service/Schemas/BPNCredential.schema.json @@ -58,11 +58,11 @@ "bpn": { "type": "string" }, - "holderIndentifier": { + "holderIdentifier": { "type": "string" } }, - "required": ["id", "bpn", "holderIndentifier"] + "required": ["id", "bpn", "holderIdentifier"] } }, "required": ["id", "@context", "type", "issuanceDate", "expirationDate", "issuer", "credentialSubject"] diff --git a/tests/externalservices/Wallet.Service.Tests/BusinessLogic/WalletBusinessLogicTests.cs b/tests/externalservices/Wallet.Service.Tests/BusinessLogic/WalletBusinessLogicTests.cs index 1ed9d7db..21ef99cf 100644 --- a/tests/externalservices/Wallet.Service.Tests/BusinessLogic/WalletBusinessLogicTests.cs +++ b/tests/externalservices/Wallet.Service.Tests/BusinessLogic/WalletBusinessLogicTests.cs @@ -188,7 +188,7 @@ public async Task GetCredential_CallsExpected() "credentialSubject": { "id": "did:web:example.org:api:administration:staticdata:did:BPNL000001PS0000", "bpn": "BPNL000001PS0000", - "holderIndentifier": "BPNL000001PS0000" + "holderIdentifier": "BPNL000001PS0000" } } """; From 9f79c541873c951eb6335aba6b5b1adda0ee25e9 Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Sat, 27 Apr 2024 14:54:33 +0200 Subject: [PATCH 03/13] fix(callback): set the correct base address for the callback (#83) * fix(callback): set the correct base address for the callback * fix(schema): adjust membership and framework schemas * feat(api): add new endpoint to fetch own credentials * add endpoint /api/issuer/owned-credentials to fetch all credentials for a specific company * fix: adjust wallet configuration Refs: #71 Reviewed-By: Norbert Truchsess --- .../templates/cronjob-issuer-processes.yaml | 2 +- .../Models/OwnedVerifiedCredentialData.cs | 29 +++++++++++++ .../CompanySsiDetailsRepository.cs | 11 +++++ .../ICompanySsiDetailsRepository.cs | 6 +++ .../DependencyInjection/CallbackSettings.cs | 3 ++ .../ServiceCollectionExtensions.cs | 5 ++- .../DependencyInjection/WalletSettings.cs | 2 +- .../Schemas/FRAMEWORKCredential.schema.json | 17 ++++++-- .../Schemas/MEMBERSHIPCredential.schema.json | 26 ++++++++---- .../BusinessLogic/IIssuerBusinessLogic.cs | 1 + .../BusinessLogic/IssuerBusinessLogic.cs | 5 +++ .../Controllers/IssuerController.cs | 12 ++++++ .../CredentialHandlerExtensions.cs | 12 ++---- .../CredentialProcessCollectionExtensions.cs | 9 ++-- src/processes/Processes.Worker/Program.cs | 6 ++- .../CompanySsiDetailsRepositoryTests.cs | 38 +++++++++++++++++ .../CallbackServiceTests.cs | 42 ++++++++++++------- .../BusinessLogic/WalletBusinessLogicTests.cs | 2 +- .../Services/WalletServiceTests.cs | 2 +- .../BusinessLogic/IssuerBusinessLogicTests.cs | 30 +++++++++++-- 20 files changed, 211 insertions(+), 49 deletions(-) create mode 100644 src/database/SsiCredentialIssuer.DbAccess/Models/OwnedVerifiedCredentialData.cs diff --git a/charts/ssi-credential-issuer/templates/cronjob-issuer-processes.yaml b/charts/ssi-credential-issuer/templates/cronjob-issuer-processes.yaml index 46d92ca3..816d15ce 100644 --- a/charts/ssi-credential-issuer/templates/cronjob-issuer-processes.yaml +++ b/charts/ssi-credential-issuer/templates/cronjob-issuer-processes.yaml @@ -123,7 +123,7 @@ spec: value: "{{ .Values.processesworker.wallet.scope }}" - name: "WALLET__USERNAME" value: "empty" - - name: "WALLET__ENCRYPTIONCONFIG__ENCRYPTIONCONFIGINDEX" + - name: "WALLET__ENCRYPTIONCONFIGINDEX" value: "{{ .Values.processesworker.wallet.encryptionConfigIndex }}" - name: "WALLET__ENCRYPTIONCONFIGS__0__INDEX" value: "{{ .Values.processesworker.wallet.encryptionConfigs.index0.index}}" diff --git a/src/database/SsiCredentialIssuer.DbAccess/Models/OwnedVerifiedCredentialData.cs b/src/database/SsiCredentialIssuer.DbAccess/Models/OwnedVerifiedCredentialData.cs new file mode 100644 index 00000000..62d6b1ef --- /dev/null +++ b/src/database/SsiCredentialIssuer.DbAccess/Models/OwnedVerifiedCredentialData.cs @@ -0,0 +1,29 @@ +/******************************************************************************** + * Copyright (c) 2024 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 Org.Eclipse.TractusX.SsiCredentialIssuer.Entities.Enums; + +namespace Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Models; + +public record OwnedVerifiedCredentialData( + VerifiedCredentialTypeId CredentialType, + CompanySsiDetailStatusId Status, + DateTimeOffset? ExpiryDate, + string Authority +); diff --git a/src/database/SsiCredentialIssuer.DbAccess/Repositories/CompanySsiDetailsRepository.cs b/src/database/SsiCredentialIssuer.DbAccess/Repositories/CompanySsiDetailsRepository.cs index 93633a60..6bbdb837 100644 --- a/src/database/SsiCredentialIssuer.DbAccess/Repositories/CompanySsiDetailsRepository.cs +++ b/src/database/SsiCredentialIssuer.DbAccess/Repositories/CompanySsiDetailsRepository.cs @@ -176,6 +176,17 @@ public IQueryable GetAllCredentialDetails(CompanySsiDetailStat (!companySsiDetailStatusId.HasValue || c.CompanySsiDetailStatusId == companySsiDetailStatusId.Value) && (!credentialTypeId.HasValue || c.VerifiedCredentialTypeId == credentialTypeId)); + /// + public IAsyncEnumerable GetOwnCredentialDetails(string bpnl) => + _context.CompanySsiDetails.AsNoTracking() + .Where(c => c.Bpnl == bpnl) + .Select(c => new OwnedVerifiedCredentialData( + c.VerifiedCredentialTypeId, + c.CompanySsiDetailStatusId, + c.ExpiryDate, + c.IssuerBpn)) + .ToAsyncEnumerable(); + /// public Task<(bool exists, SsiApprovalData data)> GetSsiApprovalData(Guid credentialId) => _context.CompanySsiDetails diff --git a/src/database/SsiCredentialIssuer.DbAccess/Repositories/ICompanySsiDetailsRepository.cs b/src/database/SsiCredentialIssuer.DbAccess/Repositories/ICompanySsiDetailsRepository.cs index 18ec666c..1f96bc84 100644 --- a/src/database/SsiCredentialIssuer.DbAccess/Repositories/ICompanySsiDetailsRepository.cs +++ b/src/database/SsiCredentialIssuer.DbAccess/Repositories/ICompanySsiDetailsRepository.cs @@ -87,6 +87,12 @@ public interface ICompanySsiDetailsRepository /// Returns data to create the pagination IQueryable GetAllCredentialDetails(CompanySsiDetailStatusId? companySsiDetailStatusId, VerifiedCredentialTypeId? credentialTypeId); + /// + /// Gets all credentials for a specific bpn + /// + /// The bpn to filter the credentials for + IAsyncEnumerable GetOwnCredentialDetails(string bpnl); + Task<(bool exists, SsiApprovalData data)> GetSsiApprovalData(Guid credentialId); Task<(bool Exists, CompanySsiDetailStatusId Status, VerifiedCredentialTypeId Type, Guid? ProcessId, IEnumerable ProcessStepIds)> GetSsiRejectionData(Guid credentialId); void AttachAndModifyCompanySsiDetails(Guid id, Action? initialize, Action updateFields); diff --git a/src/externalservices/Callback.Service/DependencyInjection/CallbackSettings.cs b/src/externalservices/Callback.Service/DependencyInjection/CallbackSettings.cs index 6857e041..13e99808 100644 --- a/src/externalservices/Callback.Service/DependencyInjection/CallbackSettings.cs +++ b/src/externalservices/Callback.Service/DependencyInjection/CallbackSettings.cs @@ -18,9 +18,12 @@ ********************************************************************************/ using Org.Eclipse.TractusX.Portal.Backend.Framework.Token; +using System.ComponentModel.DataAnnotations; namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Callback.Service.DependencyInjection; public class CallbackSettings : KeyVaultAuthSettings { + [Required(AllowEmptyStrings = false)] + public string BaseAddress { get; set; } = null!; } diff --git a/src/externalservices/Callback.Service/DependencyInjection/ServiceCollectionExtensions.cs b/src/externalservices/Callback.Service/DependencyInjection/ServiceCollectionExtensions.cs index c49024bc..0035ba1e 100644 --- a/src/externalservices/Callback.Service/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/externalservices/Callback.Service/DependencyInjection/ServiceCollectionExtensions.cs @@ -19,6 +19,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Org.Eclipse.TractusX.Portal.Backend.Framework.HttpClientExtensions; using Org.Eclipse.TractusX.SsiCredentialIssuer.Callback.Service.Services; @@ -35,8 +36,10 @@ public static IServiceCollection AddCallbackService(this IServiceCollection serv services.AddTransient>(); + var sp = services.BuildServiceProvider(); + var settings = sp.GetRequiredService>(); return services .AddScoped() - .AddCustomHttpClientWithAuthentication(null); + .AddCustomHttpClientWithAuthentication(settings.Value.BaseAddress); } } diff --git a/src/externalservices/Wallet.Service/DependencyInjection/WalletSettings.cs b/src/externalservices/Wallet.Service/DependencyInjection/WalletSettings.cs index a802bd45..ca1f17cc 100644 --- a/src/externalservices/Wallet.Service/DependencyInjection/WalletSettings.cs +++ b/src/externalservices/Wallet.Service/DependencyInjection/WalletSettings.cs @@ -32,5 +32,5 @@ public class WalletSettings : BasicAuthSettings public IEnumerable EncryptionConfigs { get; set; } = null!; [Required] - public int EncrptionConfigIndex { get; set; } + public int EncryptionConfigIndex { get; set; } } diff --git a/src/externalservices/Wallet.Service/Schemas/FRAMEWORKCredential.schema.json b/src/externalservices/Wallet.Service/Schemas/FRAMEWORKCredential.schema.json index 024ebff5..34eace09 100644 --- a/src/externalservices/Wallet.Service/Schemas/FRAMEWORKCredential.schema.json +++ b/src/externalservices/Wallet.Service/Schemas/FRAMEWORKCredential.schema.json @@ -2,6 +2,16 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://eclipse-tractusx.github.io/FrameworkCredential.schema.json", "type": "object", + "required": [ + "id", + "type", + "issuer", + "@context", + "issuanceDate", + "expirationDate", + "credentialStatus", + "credentialSubject" + ], "properties": { "id": { "type": "string" @@ -51,6 +61,7 @@ }, "credentialSubject": { "type": "object", + "required": ["id", "holderIdentifier", "group", "useCase", "contractTemplate", "contractVersion"], "properties": { "id": { "type": "string" @@ -71,9 +82,7 @@ "contractVersion": { "type": "string" } - }, - "required": ["id", "holderIdentifier", "group", "useCase", "contractTemplate", "contractVersion"] + } } - }, - "required": ["id", "@context", "type", "issuanceDate", "expirationDate", "issuer", "credentialSubject"] + } } diff --git a/src/externalservices/Wallet.Service/Schemas/MEMBERSHIPCredential.schema.json b/src/externalservices/Wallet.Service/Schemas/MEMBERSHIPCredential.schema.json index 1e453e87..3d4d40f0 100644 --- a/src/externalservices/Wallet.Service/Schemas/MEMBERSHIPCredential.schema.json +++ b/src/externalservices/Wallet.Service/Schemas/MEMBERSHIPCredential.schema.json @@ -2,8 +2,17 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://eclipse-tractusx.github.io/MembershipCredential.schema.json", "type": "object", + "required": [ + "id", + "type", + "issuer", + "@context", + "issuanceDate", + "expirationDate", + "credentialStatus", + "credentialSubject" + ], "properties": { - "id": { "type": "string" }, @@ -52,19 +61,22 @@ }, "credentialSubject": { "type": "object", + "required": [ + "id", + "memberOf", + "holderIdentifier" + ], "properties": { "id": { "type": "string" }, - "holderIdentifier": { + "memberOf": { "type": "string" }, - "memberOf": { + "holderIdentifier": { "type": "string" } - }, - "required": ["id", "holderIdentifier", "memberOf"] + } } - }, - "required": ["id", "@context", "type", "issuanceDate", "expirationDate", "issuer", "credentialSubject"] + } } diff --git a/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IIssuerBusinessLogic.cs b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IIssuerBusinessLogic.cs index 1141396c..76bd083d 100644 --- a/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IIssuerBusinessLogic.cs +++ b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IIssuerBusinessLogic.cs @@ -31,6 +31,7 @@ public interface IIssuerBusinessLogic Task> GetSsiCertificatesAsync(); Task> GetCredentials(int page, int size, CompanySsiDetailStatusId? companySsiDetailStatusId, VerifiedCredentialTypeId? credentialTypeId, CompanySsiDetailSorting? sorting); + IAsyncEnumerable GetCredentialsForBpn(); Task ApproveCredential(Guid credentialId, CancellationToken cancellationToken); diff --git a/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IssuerBusinessLogic.cs b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IssuerBusinessLogic.cs index 45e5f7cc..bcf99ad8 100644 --- a/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IssuerBusinessLogic.cs +++ b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IssuerBusinessLogic.cs @@ -174,6 +174,11 @@ await _repositories )); } + public IAsyncEnumerable GetCredentialsForBpn() => + _repositories + .GetInstance() + .GetOwnCredentialDetails(_identity.Bpnl); + /// public async Task ApproveCredential(Guid credentialId, CancellationToken cancellationToken) { diff --git a/src/issuer/SsiCredentialIssuer.Service/Controllers/IssuerController.cs b/src/issuer/SsiCredentialIssuer.Service/Controllers/IssuerController.cs index 0f685e6d..b14c3545 100644 --- a/src/issuer/SsiCredentialIssuer.Service/Controllers/IssuerController.cs +++ b/src/issuer/SsiCredentialIssuer.Service/Controllers/IssuerController.cs @@ -36,6 +36,7 @@ public static class IssuerController { private const string RequestSsiRole = "request_ssicredential"; private const string DecisionSsiRole = "decision_ssicredential"; + private const string ViewCredentialRequestRole = "view_credential_requests"; public static RouteGroupBuilder MapIssuerApi(this RouteGroupBuilder group) { @@ -93,6 +94,17 @@ public static RouteGroupBuilder MapIssuerApi(this RouteGroupBuilder group) .WithDefaultResponses() .Produces(StatusCodes.Status200OK, typeof(IEnumerable), Constants.JsonContentType); + issuer.MapGet("owned-credentials", (IIssuerBusinessLogic logic) => logic.GetCredentialsForBpn()) + .WithSwaggerDescription("Gets all outstanding, existing and inactive credentials for the company of the user", + "Example: GET: /api/issuer/owned-credentials") + .RequireAuthorization(r => + { + r.RequireRole(ViewCredentialRequestRole); + r.AddRequirements(new MandatoryIdentityClaimRequirement(PolicyTypeId.ValidBpn)); + }) + .WithDefaultResponses() + .Produces(StatusCodes.Status200OK, typeof(IEnumerable), Constants.JsonContentType); + issuer.MapPost("bpn", ([FromBody] CreateBpnCredentialRequest requestData, CancellationToken cancellationToken, IIssuerBusinessLogic logic) => logic.CreateBpnCredential(requestData, cancellationToken)) .WithSwaggerDescription("Creates a bpn credential for the given data", "POST: api/issuer/bpn", diff --git a/src/processes/CredentialProcess.Library/DependencyInjection/CredentialHandlerExtensions.cs b/src/processes/CredentialProcess.Library/DependencyInjection/CredentialHandlerExtensions.cs index ac774cbd..e4d243eb 100644 --- a/src/processes/CredentialProcess.Library/DependencyInjection/CredentialHandlerExtensions.cs +++ b/src/processes/CredentialProcess.Library/DependencyInjection/CredentialHandlerExtensions.cs @@ -17,30 +17,26 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Creation; using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Expiry; -using Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.DependencyInjection; namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.DependencyInjection; public static class CredentialHandlerExtensions { - public static IServiceCollection AddCredentialCreationProcessHandler(this IServiceCollection services, IConfiguration config) + public static IServiceCollection AddCredentialCreationProcessHandler(this IServiceCollection services) { services - .AddTransient() - .AddWalletService(config); + .AddTransient(); return services; } - public static IServiceCollection AddCredentialExpiryProcessHandler(this IServiceCollection services, IConfiguration config) + public static IServiceCollection AddCredentialExpiryProcessHandler(this IServiceCollection services) { services - .AddTransient() - .AddWalletService(config); + .AddTransient(); return services; } diff --git a/src/processes/CredentialProcess.Worker/DependencyInjection/CredentialProcessCollectionExtensions.cs b/src/processes/CredentialProcess.Worker/DependencyInjection/CredentialProcessCollectionExtensions.cs index 503203d7..b6732f70 100644 --- a/src/processes/CredentialProcess.Worker/DependencyInjection/CredentialProcessCollectionExtensions.cs +++ b/src/processes/CredentialProcess.Worker/DependencyInjection/CredentialProcessCollectionExtensions.cs @@ -17,7 +17,6 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.DependencyInjection; using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Worker.Expiry; @@ -27,13 +26,13 @@ namespace Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Worker.Depe public static class CredentialProcessCollectionExtensions { - public static IServiceCollection AddCredentialCreationProcessExecutor(this IServiceCollection services, IConfiguration config) => + public static IServiceCollection AddCredentialCreationProcessExecutor(this IServiceCollection services) => services .AddTransient() - .AddCredentialCreationProcessHandler(config); + .AddCredentialCreationProcessHandler(); - public static IServiceCollection AddCredentialExpiryProcessExecutor(this IServiceCollection services, IConfiguration config) => + public static IServiceCollection AddCredentialExpiryProcessExecutor(this IServiceCollection services) => services .AddTransient() - .AddCredentialExpiryProcessHandler(config); + .AddCredentialExpiryProcessHandler(); } diff --git a/src/processes/Processes.Worker/Program.cs b/src/processes/Processes.Worker/Program.cs index 396cddb3..5b8cb16f 100644 --- a/src/processes/Processes.Worker/Program.cs +++ b/src/processes/Processes.Worker/Program.cs @@ -26,6 +26,7 @@ using Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess; using Org.Eclipse.TractusX.SsiCredentialIssuer.Portal.Service.DependencyInjection; using Org.Eclipse.TractusX.SsiCredentialIssuer.Processes.Worker.Library; +using Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.DependencyInjection; using Serilog; LoggingExtensions.EnsureInitialized(); @@ -42,8 +43,9 @@ .AddProcessExecutionService(hostContext.Configuration.GetSection("Processes")) .AddPortalService(hostContext.Configuration.GetSection("Portal")) .AddCallbackService(hostContext.Configuration.GetSection("Callback")) - .AddCredentialCreationProcessExecutor(hostContext.Configuration) - .AddCredentialExpiryProcessExecutor(hostContext.Configuration); + .AddWalletService(hostContext.Configuration) + .AddCredentialCreationProcessExecutor() + .AddCredentialExpiryProcessExecutor(); }) .AddLogging() .Build(); diff --git a/tests/database/SsiCredentialIssuer.DbAccess.Tests/CompanySsiDetailsRepositoryTests.cs b/tests/database/SsiCredentialIssuer.DbAccess.Tests/CompanySsiDetailsRepositoryTests.cs index 4bfc98d7..156cb5df 100644 --- a/tests/database/SsiCredentialIssuer.DbAccess.Tests/CompanySsiDetailsRepositoryTests.cs +++ b/tests/database/SsiCredentialIssuer.DbAccess.Tests/CompanySsiDetailsRepositoryTests.cs @@ -191,6 +191,44 @@ public async Task GetSsiCertificates_WithValidData_ReturnsExpected() #endregion + #region GetOwnCredentialDetails + + [Fact] + public async Task GetOwnCredentialDetails_WithValidData_ReturnsExpected() + { + // Arrange + var sut = await CreateSut(); + + // Act + var result = await sut.GetOwnCredentialDetails(ValidBpnl).ToListAsync().ConfigureAwait(false); + + // Assert + result.Should().HaveCount(6) + .And.Satisfy( + x => x.CredentialType == VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK && x.Status == CompanySsiDetailStatusId.PENDING, + x => x.CredentialType == VerifiedCredentialTypeId.PCF_FRAMEWORK && x.Status == CompanySsiDetailStatusId.PENDING, + x => x.CredentialType == VerifiedCredentialTypeId.DISMANTLER_CERTIFICATE && x.Status == CompanySsiDetailStatusId.PENDING, + x => x.CredentialType == VerifiedCredentialTypeId.BEHAVIOR_TWIN_FRAMEWORK && x.Status == CompanySsiDetailStatusId.INACTIVE, + x => x.CredentialType == VerifiedCredentialTypeId.DISMANTLER_CERTIFICATE && x.Status == CompanySsiDetailStatusId.INACTIVE, + x => x.CredentialType == VerifiedCredentialTypeId.DISMANTLER_CERTIFICATE && x.Status == CompanySsiDetailStatusId.INACTIVE + ); + } + + [Fact] + public async Task GetOwnCredentialDetails_WithBpnWithoutCredential_ReturnsExpected() + { + // Arrange + var sut = await CreateSut(); + + // Act + var result = await sut.GetOwnCredentialDetails("BPNL000000INVALID").ToListAsync().ConfigureAwait(false); + + // Assert + result.Should().BeEmpty(); + } + + #endregion + #region CreateSsiDetails [Fact] diff --git a/tests/externalservices/Callback.Service.Tests/CallbackServiceTests.cs b/tests/externalservices/Callback.Service.Tests/CallbackServiceTests.cs index f0654226..a4f2f5de 100644 --- a/tests/externalservices/Callback.Service.Tests/CallbackServiceTests.cs +++ b/tests/externalservices/Callback.Service.Tests/CallbackServiceTests.cs @@ -60,6 +60,8 @@ public CallbackServiceTests() TokenAddress = "https://example.org/token" }); _tokenService = A.Fake(); + // _fixture.Inject(_tokenService); + _fixture.Inject(_options); } #endregion @@ -71,24 +73,17 @@ public async Task TriggerCallback_WithValid_DoesNotThrowException() { // Arrange var data = new IssuerResponseData("Test1", IssuerResponseStatus.SUCCESSFUL, "test 123"); - var httpMessageHandlerMock = - new HttpMessageHandlerMock(HttpStatusCode.OK); - using var httpClient = new HttpClient(httpMessageHandlerMock); - httpClient.BaseAddress = new Uri("https://base.address.com"); - A.CallTo(() => _tokenService.GetAuthorizedClient(_options.Value, A._)) - .Returns(httpClient); - var sut = new CallbackService(_tokenService, _options); + HttpRequestMessage? request = null; + ConfigureTokenServiceFixture(new HttpResponseMessage(HttpStatusCode.OK), httpRequestMessage => request = httpRequestMessage); + var sut = _fixture.Create(); // Act - await sut.TriggerCallback("https://example.org/callback", data, CancellationToken.None).ConfigureAwait(false); + await sut.TriggerCallback("/callback", data, CancellationToken.None).ConfigureAwait(false); // Assert - httpMessageHandlerMock.RequestMessage.Should().Match(x => - x.Content is JsonContent && - (x.Content as JsonContent)!.ObjectType == typeof(IssuerResponseData) && - ((x.Content as JsonContent)!.Value as IssuerResponseData)!.Status == IssuerResponseStatus.SUCCESSFUL && - ((x.Content as JsonContent)!.Value as IssuerResponseData)!.Bpn == "Test1" - ); + request.Should().NotBeNull(); + request!.RequestUri.Should().Be("https://example.com/callback"); + request.Content.Should().BeOfType(); } [Theory] @@ -117,4 +112,23 @@ public async Task TriggerCallback_WithConflict_ThrowsServiceExceptionWithErrorCo } #endregion + + private void ConfigureTokenServiceFixture(HttpResponseMessage httpResponseMessage, Action? setMessage = null) + { + var messageHandler = A.Fake(); + A.CallTo(messageHandler) // mock protected method + .Where(x => x.Method.Name == "SendAsync") + .WithReturnType>() + .ReturnsLazily(call => + { + var message = call.Arguments.Get(0); + setMessage?.Invoke(message); + return Task.FromResult(httpResponseMessage); + }); + var httpClient = new HttpClient(messageHandler) { BaseAddress = new Uri("https://example.com") }; + _fixture.Inject(httpClient); + + var tokenService = _fixture.Freeze>(); + A.CallTo(() => tokenService.FakedObject.GetAuthorizedClient(A._, A._)).Returns(httpClient); + } } diff --git a/tests/externalservices/Wallet.Service.Tests/BusinessLogic/WalletBusinessLogicTests.cs b/tests/externalservices/Wallet.Service.Tests/BusinessLogic/WalletBusinessLogicTests.cs index 21ef99cf..f6a03d27 100644 --- a/tests/externalservices/Wallet.Service.Tests/BusinessLogic/WalletBusinessLogicTests.cs +++ b/tests/externalservices/Wallet.Service.Tests/BusinessLogic/WalletBusinessLogicTests.cs @@ -51,7 +51,7 @@ public WalletBusinessLogicTests() ClientSecret = "pass@Secret", TokenAddress = "https://example.org/token", EncryptionConfigs = Enumerable.Repeat(_encryptionModeConfig, 1), - EncrptionConfigIndex = 0 + EncryptionConfigIndex = 0 }); _walletService = A.Fake(); var issuerRepositories = A.Fake(); diff --git a/tests/externalservices/Wallet.Service.Tests/Services/WalletServiceTests.cs b/tests/externalservices/Wallet.Service.Tests/Services/WalletServiceTests.cs index 8ad94af4..3ddb3767 100644 --- a/tests/externalservices/Wallet.Service.Tests/Services/WalletServiceTests.cs +++ b/tests/externalservices/Wallet.Service.Tests/Services/WalletServiceTests.cs @@ -37,7 +37,7 @@ public WalletServiceTests() ClientId = "CatenaX", ClientSecret = "pass@Secret", TokenAddress = "https://example.org/token", - EncrptionConfigIndex = 0 + EncryptionConfigIndex = 0 }); _sut = new WalletService(_basicAuthTokenService, _options); } diff --git a/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/IssuerBusinessLogicTests.cs b/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/IssuerBusinessLogicTests.cs index e5ca2e60..bf29dd44 100644 --- a/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/IssuerBusinessLogicTests.cs +++ b/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/IssuerBusinessLogicTests.cs @@ -52,7 +52,6 @@ public class IssuerBusinessLogicTests private readonly IProcessStepRepository _processStepRepository; private readonly IIssuerBusinessLogic _sut; - private readonly IIdentityService _identityService; private readonly IDateTimeProvider _dateTimeProvider; private readonly IHttpClientFactory _clientFactory; private readonly IPortalService _portalService; @@ -73,7 +72,7 @@ public IssuerBusinessLogicTests() _processStepRepository = A.Fake(); _identity = A.Fake(); - _identityService = A.Fake(); + var identityService = A.Fake(); _dateTimeProvider = A.Fake(); _clientFactory = A.Fake(); _portalService = A.Fake(); @@ -88,7 +87,7 @@ public IssuerBusinessLogicTests() A.CallTo(() => _identity.CompanyUserId).Returns(identityId); A.CallTo(() => _identity.IsServiceAccount).Returns(false); A.CallTo(() => _identity.Bpnl).Returns(Bpnl); - A.CallTo(() => _identityService.IdentityData).Returns(_identity); + A.CallTo(() => identityService.IdentityData).Returns(_identity); var options = A.Fake>(); A.CallTo(() => options.Value).Returns(new IssuerSettings @@ -107,7 +106,7 @@ public IssuerBusinessLogicTests() StatusListUrl = "https://example.org/statuslist" }); - _sut = new IssuerBusinessLogic(_issuerRepositories, _identityService, _dateTimeProvider, _clientFactory, _portalService, options); + _sut = new IssuerBusinessLogic(_issuerRepositories, identityService, _dateTimeProvider, _clientFactory, _portalService, options); } #region GetUseCaseParticipationAsync @@ -144,6 +143,23 @@ public async Task GetSsiCertificatesAsync_ReturnsExpected() #endregion + #region GetCredentialsForBpn + + [Fact] + public async Task GetCredentialsForBpn_ReturnsExpected() + { + // Arrange + Setup_GetCredentialsForBpn(); + + // Act + var result = await _sut.GetCredentialsForBpn().ToListAsync().ConfigureAwait(false); + + // Assert + result.Should().HaveCount(5); + } + + #endregion + #region ApproveCredential [Fact] @@ -841,6 +857,12 @@ private void Setup_GetSsiCertificatesAsync() .Returns(_fixture.Build().With(x => x.Credentials, Enumerable.Repeat(new SsiCertificateExternalTypeDetailTransferData(_fixture.Create(), _fixture.CreateMany(1)), 1)).CreateMany(5).ToAsyncEnumerable()); } + private void Setup_GetCredentialsForBpn() + { + A.CallTo(() => _companySsiDetailsRepository.GetOwnCredentialDetails(Bpnl)) + .Returns(_fixture.Build().CreateMany(5).ToAsyncEnumerable()); + } + private void ConfigureHttpClientFactoryFixture(HttpResponseMessage httpResponseMessage, Action? setMessage = null) { var messageHandler = A.Fake(); From 9a05c92725b83b790981a0963d83ab24fcfe2208 Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Tue, 30 Apr 2024 11:36:43 +0200 Subject: [PATCH 04/13] chore: upgrade net8.0 (#88) Reviewed-By: Evelyn Gurschler --- .github/workflows/sonarcloud.yml | 2 +- .github/workflows/unit.tests-formatting.yml | 2 +- DEPENDENCIES | 34 +++++++------- README.md | 2 +- docker/Dockerfile-credential-expiry-app | 4 +- .../Dockerfile-credential-issuer-migrations | 4 +- ...kerfile-credential-issuer-processes-worker | 4 +- docker/Dockerfile-credential-issuer-service | 4 +- docker/notice-credential-expiry-app.md | 2 +- docker/notice-credential-issuer-migrations.md | 2 +- ...tice-credential-issuer-processes-worker.md | 2 +- docker/notice-credential-issuer-service.md | 2 +- .../ExpiryCheckService.cs | 8 ++-- .../SsiCredentialIssuer.Expiry.App/Program.cs | 2 +- .../SsiCredentialIssuer.Expiry.App.csproj | 20 ++++---- .../SsiCredentialIssuer.DbAccess.csproj | 11 ++--- .../SsiCredentialIssuer.Entities.csproj | 18 ++++---- .../Seeder/BatchInsertSeeder.cs | 28 +++++------ .../Seeder/BatchUpdateSeeder.cs | 6 +-- .../SsiCredentialIssuer.Migrations.csproj | 31 +++++++------ .../Callback.Service/Callback.Service.csproj | 8 ++-- .../Services/CallbackService.cs | 2 +- .../Portal.Service/Portal.Service.csproj | 8 ++-- .../Portal.Service/Services/PortalService.cs | 4 +- .../BusinessLogic/WalletBusinessLogic.cs | 14 +++--- .../DependencyInjection/WalletSettings.cs | 1 + .../Services/BasicAuthSettings.cs | 36 --------------- .../Services/BasicAuthTokenService.cs | 9 ++-- .../Services/IBasicAuthTokenService.cs | 2 + .../Wallet.Service/Services/WalletService.cs | 19 ++++---- .../Wallet.Service/Wallet.Service.csproj | 12 ++--- .../BusinessLogic/CredentialBusinessLogic.cs | 4 +- .../BusinessLogic/IssuerBusinessLogic.cs | 28 +++++------ .../BusinessLogic/RevocationBusinessLogic.cs | 4 +- .../Controllers/IssuerController.cs | 4 +- .../SsiCredentialIssuer.Service.csproj | 12 ++--- .../CredentialCreationProcessHandler.cs | 20 ++++---- .../CredentialProcess.Library.csproj | 2 +- .../Expiry/CredentialExpiryProcessHandler.cs | 8 ++-- .../CredentialCreationProcessTypeExecutor.cs | 12 ++--- .../CredentialProcess.Worker.csproj | 2 +- .../CredentialExpiryProcessTypeExecutor.cs | 8 ++-- .../Processes.Library.csproj | 2 +- .../ProcessExecutionService.cs | 4 +- .../Processes.Worker.Library.csproj | 18 ++++---- .../Processes.Worker/Processes.Worker.csproj | 8 ++-- src/processes/Processes.Worker/Program.cs | 2 +- .../Tests.Shared/Extensions/HttpExtensions.cs | 4 +- tests/Tests.Shared/Tests.Shared.csproj | 2 +- .../ExpiryCheckServiceTests.cs | 6 +-- ...siCredentialIssuer.Expiry.App.Tests.csproj | 11 ++--- .../CompanySsiDetailsRepositoryTests.cs | 46 +++++++++---------- .../CredentialRepositoryTests.cs | 16 +++---- .../DocumentRepositoryTests.cs | 8 ++-- .../IssuerDbContextTests.cs | 20 ++++---- .../IssuerRepositoriesTests.cs | 16 +++---- .../ProcessStepRepositoryTests.cs | 30 ++++++------ .../Setup/TestDbFixture.cs | 8 ++-- .../SsiCredentialIssuer.DbAccess.Tests.csproj | 13 ++---- .../Callback.Service.Tests.csproj | 11 ++--- .../CallbackServiceTests.cs | 4 +- .../Portal.Service.Tests.csproj | 11 ++--- .../PortalServiceTests.cs | 8 ++-- .../BusinessLogic/WalletBusinessLogicTests.cs | 12 ++--- .../Services/BasicAuthTokenServiceTests.cs | 4 +- .../Services/WalletServiceTests.cs | 21 +++++---- .../Wallet.Service.Tests.csproj | 13 ++---- .../KeycloakClaimsTransformationTests.cs | 6 +-- .../BusinessLogic/IssuerBusinessLogicTests.cs | 2 +- .../Controllers/IssuerControllerTests.cs | 4 +- .../MandatoryIdentityClaimHandlerTests.cs | 4 +- .../SsiCredentialIssuer.Service.Tests.csproj | 11 ++--- .../CredentialProcess.Library.Tests.csproj | 9 ++-- .../CredentialProcess.Worker.Tests.csproj | 9 ++-- .../Processes.Library.Tests.csproj | 9 ++-- .../ProcessExecutorTests.cs | 24 +++++----- .../Processes.Worker.Library.Tests.csproj | 9 ++-- 77 files changed, 358 insertions(+), 434 deletions(-) delete mode 100644 src/externalservices/Wallet.Service/Services/BasicAuthSettings.cs diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 15562a3f..da6edae3 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - dotnet-version: ['7.0'] + dotnet-version: ['8.0'] steps: - name: Set up JDK 17 diff --git a/.github/workflows/unit.tests-formatting.yml b/.github/workflows/unit.tests-formatting.yml index a778917f..8d2e8aa6 100644 --- a/.github/workflows/unit.tests-formatting.yml +++ b/.github/workflows/unit.tests-formatting.yml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - dotnet-version: ['7.0'] + dotnet-version: ['8.0'] steps: - uses: actions/checkout@v4 diff --git a/DEPENDENCIES b/DEPENDENCIES index 8965f9a8..08405a02 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -1,8 +1,7 @@ -nuget/nuget/-/AutoFixture.AutoFakeItEasy/4.18.0, MIT, approved, #10064 -nuget/nuget/-/AutoFixture.Xunit/4.18.0, MIT, approved, #10082 -nuget/nuget/-/AutoFixture/4.18.0, MIT, approved, #10057 +nuget/nuget/-/AutoFixture.AutoFakeItEasy/4.18.1, MIT, approved, #10064 +nuget/nuget/-/AutoFixture/4.18.1, MIT, approved, #10057 nuget/nuget/-/Castle.Core/4.3.1, Apache-2.0, approved, clearlydefined -nuget/nuget/-/EFCore.NamingConventions/7.0.2, Apache-2.0, approved, #10067 +nuget/nuget/-/EFCore.NamingConventions/8.0.3, Apache-2.0, approved, #13983 nuget/nuget/-/FakeItEasy/7.4.0, MIT, approved, #10080 nuget/nuget/-/Fare/2.1.1, MIT, approved, clearlydefined nuget/nuget/-/FluentAssertions/6.11.0, Apache-2.0 AND MIT, approved, #10061 @@ -10,31 +9,31 @@ nuget/nuget/-/Flurl.Signed/3.0.6, MIT, approved, #3501 nuget/nuget/-/Humanizer.Core/2.14.1, MIT, approved, #10060 nuget/nuget/-/Json.More.Net/2.0.0, MIT, approved, clearlydefined nuget/nuget/-/JsonPointer.Net/4.0.0, MIT, approved, clearlydefined -nuget/nuget/-/JsonSchema.Net/6.0.3, MIT AND OFL-1.1 AND CC-BY-SA-4.0, approved, #13370 -nuget/nuget/-/Laraue.EfCoreTriggers.Common/7.1.0, MIT, approved, #10247 -nuget/nuget/-/Laraue.EfCoreTriggers.PostgreSql/7.1.0, MIT, approved, #10248 +nuget/nuget/-/JsonSchema.Net/6.1.2, MIT AND OFL-1.1 AND CC-BY-SA-4.0, approved, #14591 +nuget/nuget/-/Laraue.EfCoreTriggers.Common/8.0.3, MIT, approved, #13968 +nuget/nuget/-/Laraue.EfCoreTriggers.PostgreSql/8.0.3, MIT, approved, #13984 nuget/nuget/-/Mono.TextTemplating/2.2.1, MIT, approved, clearlydefined nuget/nuget/-/Newtonsoft.Json/13.0.1, MIT AND BSD-3-Clause, approved, #3266 nuget/nuget/-/Newtonsoft.Json/13.0.3, MIT AND BSD-3-Clause, approved, #3266 -nuget/nuget/-/Npgsql.EntityFrameworkCore.PostgreSQL/7.0.11, PostgreSQL AND MIT AND Apache-2.0, approved, #10081 -nuget/nuget/-/Npgsql/7.0.6, PostgreSQL, approved, #10062 +nuget/nuget/-/Npgsql.EntityFrameworkCore.PostgreSQL/8.0.2, PostgreSQL AND MIT, approved, #13972 +nuget/nuget/-/Npgsql/8.0.2, PostgreSQL, approved, #13963 nuget/nuget/-/PasswordGenerator/2.1.0, MIT, approved, #3192 nuget/nuget/-/Portable.BouncyCastle/1.9.0, MIT, approved, clearlydefined nuget/nuget/-/SSH.NET/2020.0.2, MIT AND ISC AND LicenseRef-Public-domain AND (MIT AND MS-PL), approved, #10073 -nuget/nuget/-/Serilog.AspNetCore/7.0.0, Apache-2.0 AND MIT, approved, #10084 +nuget/nuget/-/Serilog.AspNetCore/8.0.1, Apache-2.0 AND MIT, approved, #13967 nuget/nuget/-/Serilog.Enrichers.CorrelationId/3.0.1, MIT, approved, clearlydefined -nuget/nuget/-/Serilog.Enrichers.Environment/2.2.0, Apache-2.0, approved, clearlydefined +nuget/nuget/-/Serilog.Enrichers.Environment/2.3.0, Apache-2.0, approved, #13959 nuget/nuget/-/Serilog.Enrichers.Process/2.0.2, Apache-2.0, approved, clearlydefined nuget/nuget/-/Serilog.Enrichers.Sensitive/1.7.3, MIT, approved, clearlydefined nuget/nuget/-/Serilog.Enrichers.Thread/3.1.0, Apache-2.0, approved, clearlydefined -nuget/nuget/-/Serilog.Extensions.Hosting/7.0.0, Apache-2.0, approved, #10078 -nuget/nuget/-/Serilog.Extensions.Logging/7.0.0, Apache-2.0, approved, #10070 -nuget/nuget/-/Serilog.Formatting.Compact/1.1.0, Apache-2.0, approved, #11115 -nuget/nuget/-/Serilog.Settings.Configuration/7.0.0, Apache-2.0, approved, #10069 -nuget/nuget/-/Serilog.Sinks.Console/4.1.0, Apache-2.0, approved, #8434 +nuget/nuget/-/Serilog.Extensions.Hosting/8.0.0, Apache-2.0, approved, #13962 +nuget/nuget/-/Serilog.Extensions.Logging/8.0.0, Apache-2.0, approved, #13985 +nuget/nuget/-/Serilog.Formatting.Compact/2.0.0, Apache-2.0, approved, #13981 +nuget/nuget/-/Serilog.Settings.Configuration/8.0.0, Apache-2.0, approved, #13988 +nuget/nuget/-/Serilog.Sinks.Console/5.0.1, Apache-2.0, approved, #13980 nuget/nuget/-/Serilog.Sinks.Debug/2.0.0, Apache-2.0, approved, clearlydefined nuget/nuget/-/Serilog.Sinks.File/5.0.0, Apache-2.0, approved, #11116 -nuget/nuget/-/Serilog/3.0.1, Apache-2.0, approved, #10063 +nuget/nuget/-/Serilog/3.1.1, Apache-2.0, approved, #13978 nuget/nuget/-/SharpZipLib/1.4.2, MIT AND GFDL-1.3-or-later AND (Apache-2.0 AND MIT) AND WTFPL AND bzip2-1.0.6 AND LicenseRef-Permissive-license-with-conditions AND LicenseRef-Permission-Notice, approved, #10058 nuget/nuget/-/SshNet.Security.Cryptography/1.3.0, MIT, approved, clearlydefined nuget/nuget/-/Swashbuckle.AspNetCore.Swagger/6.5.0, MIT AND Apache-2.0, approved, #7160 @@ -44,7 +43,6 @@ nuget/nuget/-/Swashbuckle.AspNetCore/6.5.0, MIT AND Apache-2.0, approved, #7159 nuget/nuget/-/Testcontainers.PostgreSql/3.4.0, MIT, approved, #10056 nuget/nuget/-/Testcontainers/3.4.0, MIT, approved, #10083 nuget/nuget/-/Xunit.Extensions.AssemblyFixture/2.4.1, MIT, approved, #3502 -nuget/nuget/-/coverlet.collector/6.0.0, MIT, approved, #10075 nuget/nuget/-/xunit.abstractions/2.0.3, Apache-2.0, approved, clearlydefined nuget/nuget/-/xunit.analyzers/1.2.0, Apache-2.0 AND MIT, approved, #10068 nuget/nuget/-/xunit.assert/2.5.0, Apache-2.0 AND MIT, approved, #10071 diff --git a/README.md b/README.md index a1e81d58..9e60314f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This repository contains the backend code for the SSI Credential Issuer written ## How to build and run -Install the [.NET 7.0 SDK](https://www.microsoft.com/net/download). +Install the [.NET 8.0 SDK](https://www.microsoft.com/net/download). Run the following command from the CLI: diff --git a/docker/Dockerfile-credential-expiry-app b/docker/Dockerfile-credential-expiry-app index 7749fff2..cd0e954f 100644 --- a/docker/Dockerfile-credential-expiry-app +++ b/docker/Dockerfile-credential-expiry-app @@ -17,9 +17,9 @@ # SPDX-License-Identifier: Apache-2.0 ############################################################### -FROM mcr.microsoft.com/dotnet/runtime:7.0-alpine AS base +FROM mcr.microsoft.com/dotnet/runtime:8.0-alpine AS base -FROM mcr.microsoft.com/dotnet/sdk:7.0-alpine-amd64 AS publish +FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine-amd64 AS publish WORKDIR / COPY LICENSE NOTICE.md DEPENDENCIES / COPY src/ src/ diff --git a/docker/Dockerfile-credential-issuer-migrations b/docker/Dockerfile-credential-issuer-migrations index c5fb1365..4ad007e7 100644 --- a/docker/Dockerfile-credential-issuer-migrations +++ b/docker/Dockerfile-credential-issuer-migrations @@ -17,9 +17,9 @@ # SPDX-License-Identifier: Apache-2.0 ############################################################### -FROM mcr.microsoft.com/dotnet/runtime:7.0-alpine AS base +FROM mcr.microsoft.com/dotnet/runtime:8.0-alpine AS base -FROM mcr.microsoft.com/dotnet/sdk:7.0-alpine-amd64 AS publish +FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine-amd64 AS publish WORKDIR / COPY LICENSE NOTICE.md DEPENDENCIES / COPY /src/database /src/database diff --git a/docker/Dockerfile-credential-issuer-processes-worker b/docker/Dockerfile-credential-issuer-processes-worker index d61ff7a7..5e637206 100644 --- a/docker/Dockerfile-credential-issuer-processes-worker +++ b/docker/Dockerfile-credential-issuer-processes-worker @@ -17,9 +17,9 @@ # SPDX-License-Identifier: Apache-2.0 ############################################################### -FROM mcr.microsoft.com/dotnet/runtime:7.0-alpine AS base +FROM mcr.microsoft.com/dotnet/runtime:8.0-alpine AS base -FROM mcr.microsoft.com/dotnet/sdk:7.0-alpine-amd64 AS publish +FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine-amd64 AS publish WORKDIR / COPY LICENSE NOTICE.md DEPENDENCIES / COPY src/ src/ diff --git a/docker/Dockerfile-credential-issuer-service b/docker/Dockerfile-credential-issuer-service index 6747b1e0..37470114 100644 --- a/docker/Dockerfile-credential-issuer-service +++ b/docker/Dockerfile-credential-issuer-service @@ -17,9 +17,9 @@ # SPDX-License-Identifier: Apache-2.0 ############################################################### -FROM mcr.microsoft.com/dotnet/aspnet:7.0-alpine AS base +FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine AS base -FROM mcr.microsoft.com/dotnet/sdk:7.0-alpine-amd64 AS publish +FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine-amd64 AS publish WORKDIR / COPY LICENSE NOTICE.md DEPENDENCIES / COPY src/ src/ diff --git a/docker/notice-credential-expiry-app.md b/docker/notice-credential-expiry-app.md index 2273a4a3..b1b48184 100644 --- a/docker/notice-credential-expiry-app.md +++ b/docker/notice-credential-expiry-app.md @@ -13,7 +13,7 @@ __Credential Expiry App__ __Used base images__ -- Dockerfile: [mcr.microsoft.com/dotnet/runtime:7.0-alpine](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime/7.0/alpine3.19/amd64/Dockerfile) +- Dockerfile: [mcr.microsoft.com/dotnet/runtime:8.0-alpine](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime/8.0/alpine3.19/amd64/Dockerfile) - GitHub project: [https://github.com/dotnet/dotnet-docker](https://github.com/dotnet/dotnet-docker) - DockerHub: [https://hub.docker.com/_/microsoft-dotnet-runtime](https://hub.docker.com/_/microsoft-dotnet-runtime) diff --git a/docker/notice-credential-issuer-migrations.md b/docker/notice-credential-issuer-migrations.md index 384c6a01..d3c54858 100644 --- a/docker/notice-credential-issuer-migrations.md +++ b/docker/notice-credential-issuer-migrations.md @@ -13,7 +13,7 @@ __Credential Issuer Migrations__ __Used base images__ -- Dockerfile: [mcr.microsoft.com/dotnet/runtime:7.0-alpine](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime/7.0/alpine3.19/amd64/Dockerfile) +- Dockerfile: [mcr.microsoft.com/dotnet/runtime:8.0-alpine](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime/8.0/alpine3.19/amd64/Dockerfile) - GitHub project: [https://github.com/dotnet/dotnet-docker](https://github.com/dotnet/dotnet-docker) - DockerHub: [https://hub.docker.com/_/microsoft-dotnet-runtime](https://hub.docker.com/_/microsoft-dotnet-runtime) diff --git a/docker/notice-credential-issuer-processes-worker.md b/docker/notice-credential-issuer-processes-worker.md index 11c091ed..a4684fc5 100644 --- a/docker/notice-credential-issuer-processes-worker.md +++ b/docker/notice-credential-issuer-processes-worker.md @@ -13,7 +13,7 @@ Issuer Checklist Worker__ __Used base images__ -- Dockerfile: [mcr.microsoft.com/dotnet/runtime:7.0-alpine](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime/7.0/alpine3.17/amd64/Dockerfile) +- Dockerfile: [mcr.microsoft.com/dotnet/runtime:8.0-alpine](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime/8.0/alpine3.17/amd64/Dockerfile) - GitHub project: [https://github.com/dotnet/dotnet-docker](https://github.com/dotnet/dotnet-docker) - DockerHub: [https://hub.docker.com/_/microsoft-dotnet-runtime](https://hub.docker.com/_/microsoft-dotnet-runtime) diff --git a/docker/notice-credential-issuer-service.md b/docker/notice-credential-issuer-service.md index 138a4597..baa55a8e 100644 --- a/docker/notice-credential-issuer-service.md +++ b/docker/notice-credential-issuer-service.md @@ -13,7 +13,7 @@ __Policy Hub Service__ __Used base images__ -- Dockerfile: [mcr.microsoft.com/dotnet/aspnet:7.0-alpine](https://github.com/dotnet/dotnet-docker/blob/main/src/aspnet/7.0/alpine3.19/amd64/Dockerfile) +- Dockerfile: [mcr.microsoft.com/dotnet/aspnet:8.0-alpine](https://github.com/dotnet/dotnet-docker/blob/main/src/aspnet/8.0/alpine3.19/amd64/Dockerfile) - GitHub project: [https://github.com/dotnet/dotnet-docker](https://github.com/dotnet/dotnet-docker) - DockerHub: [https://hub.docker.com/_/microsoft-dotnet-aspnet](https://hub.docker.com/_/microsoft-dotnet-aspnet) diff --git a/src/credentials/SsiCredentialIssuer.Expiry.App/ExpiryCheckService.cs b/src/credentials/SsiCredentialIssuer.Expiry.App/ExpiryCheckService.cs index 106e0cbf..96460a25 100644 --- a/src/credentials/SsiCredentialIssuer.Expiry.App/ExpiryCheckService.cs +++ b/src/credentials/SsiCredentialIssuer.Expiry.App/ExpiryCheckService.cs @@ -88,7 +88,7 @@ public async Task ExecuteAsync(CancellationToken stoppingToken) .GetExpiryData(now, inactiveVcsToDelete, expiredVcsToDelete); await foreach (var credential in credentials.WithCancellation(stoppingToken).ConfigureAwait(false)) { - await ProcessCredentials(credential, companySsiDetailsRepository, repositories, portalService, processStepRepository, stoppingToken).ConfigureAwait(false); + await ProcessCredentials(credential, companySsiDetailsRepository, repositories, portalService, processStepRepository, stoppingToken).ConfigureAwait(ConfigureAwaitOptions.None); } } catch (Exception ex) @@ -121,7 +121,7 @@ private static async Task ProcessCredentials( } // Saving here to make sure the each credential is handled by there own - await repositories.SaveAsync().ConfigureAwait(false); + await repositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None); } private static void HandleDecline( @@ -178,7 +178,7 @@ private static async ValueTask HandleNotification( if (Guid.TryParse(data.RequesterId, out var requesterId)) { await portalService.AddNotification(content, requesterId, NotificationTypeId.CREDENTIAL_EXPIRY, - cancellationToken).ConfigureAwait(false); + cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); var typeValue = data.VerifiedCredentialTypeId.GetEnumValue() ?? throw new UnexpectedConditionException( $"VerifiedCredentialType {data.VerifiedCredentialTypeId} does not exists"); @@ -188,7 +188,7 @@ await portalService.AddNotification(content, requesterId, NotificationTypeId.CRE new("expiryDate", data.ExpiryDate?.ToString("dd MMMM yyyy") ?? throw new ConflictException("Expiry Date must be set here")) }; - await portalService.TriggerMail("CredentialExpiry", requesterId, mailParameters, cancellationToken).ConfigureAwait(false); + await portalService.TriggerMail("CredentialExpiry", requesterId, mailParameters, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); } } } diff --git a/src/credentials/SsiCredentialIssuer.Expiry.App/Program.cs b/src/credentials/SsiCredentialIssuer.Expiry.App/Program.cs index b6bdd269..b440d12f 100644 --- a/src/credentials/SsiCredentialIssuer.Expiry.App/Program.cs +++ b/src/credentials/SsiCredentialIssuer.Expiry.App/Program.cs @@ -57,7 +57,7 @@ Log.Information("Start processing"); var workerInstance = host.Services.GetRequiredService(); - await workerInstance.ExecuteAsync(tokenSource.Token).ConfigureAwait(false); + await workerInstance.ExecuteAsync(tokenSource.Token).ConfigureAwait(ConfigureAwaitOptions.None); Log.Information("Execution finished shutting down"); } catch (Exception ex) when (!ex.GetType().Name.Equals("StopTheHostException", StringComparison.Ordinal)) diff --git a/src/credentials/SsiCredentialIssuer.Expiry.App/SsiCredentialIssuer.Expiry.App.csproj b/src/credentials/SsiCredentialIssuer.Expiry.App/SsiCredentialIssuer.Expiry.App.csproj index 45ffe379..29be6971 100644 --- a/src/credentials/SsiCredentialIssuer.Expiry.App/SsiCredentialIssuer.Expiry.App.csproj +++ b/src/credentials/SsiCredentialIssuer.Expiry.App/SsiCredentialIssuer.Expiry.App.csproj @@ -22,7 +22,7 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Expiry.App Org.Eclipse.TractusX.SsiCredentialIssuer.Expiry.App - net7.0 + net8.0 enable enable 37a22764-0a60-4c2e-a692-d59c4f14abbf @@ -33,18 +33,18 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - + + + + + + + + diff --git a/src/database/SsiCredentialIssuer.DbAccess/SsiCredentialIssuer.DbAccess.csproj b/src/database/SsiCredentialIssuer.DbAccess/SsiCredentialIssuer.DbAccess.csproj index 6cb5fa65..30cdd933 100644 --- a/src/database/SsiCredentialIssuer.DbAccess/SsiCredentialIssuer.DbAccess.csproj +++ b/src/database/SsiCredentialIssuer.DbAccess/SsiCredentialIssuer.DbAccess.csproj @@ -21,22 +21,19 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess - net7.0 + net8.0 enable enable - - + + + - - - - diff --git a/src/database/SsiCredentialIssuer.Entities/SsiCredentialIssuer.Entities.csproj b/src/database/SsiCredentialIssuer.Entities/SsiCredentialIssuer.Entities.csproj index 6d397738..56ad10c5 100644 --- a/src/database/SsiCredentialIssuer.Entities/SsiCredentialIssuer.Entities.csproj +++ b/src/database/SsiCredentialIssuer.Entities/SsiCredentialIssuer.Entities.csproj @@ -21,22 +21,22 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Entities Org.Eclipse.TractusX.SsiCredentialIssuer.Entities - net7.0 + net8.0 enable enable - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - - - + + + + + diff --git a/src/database/SsiCredentialIssuer.Migrations/Seeder/BatchInsertSeeder.cs b/src/database/SsiCredentialIssuer.Migrations/Seeder/BatchInsertSeeder.cs index 0c59abf8..dc841bbb 100644 --- a/src/database/SsiCredentialIssuer.Migrations/Seeder/BatchInsertSeeder.cs +++ b/src/database/SsiCredentialIssuer.Migrations/Seeder/BatchInsertSeeder.cs @@ -62,35 +62,35 @@ public async Task ExecuteAsync(CancellationToken cancellationToken) _logger.LogInformation("Start BaseEntityBatch Seeder"); await SeedBaseEntity(cancellationToken); - await SeedTable("company_ssi_process_datas", x => x.CompanySsiDetailId, cancellationToken).ConfigureAwait(false); - await SeedTable("verified_credential_type_assigned_kinds", x => new { x.VerifiedCredentialTypeId, x.VerifiedCredentialTypeKindId }, cancellationToken).ConfigureAwait(false); - await SeedTable("verified_credential_type_assigned_use_cases", x => new { x.VerifiedCredentialTypeId, x.UseCaseId }, cancellationToken).ConfigureAwait(false); - await SeedTable("verified_credential_type_assigned_external_types", x => new { x.VerifiedCredentialTypeId, x.VerifiedCredentialExternalTypeId }, cancellationToken).ConfigureAwait(false); + await SeedTable("company_ssi_process_datas", x => x.CompanySsiDetailId, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); + await SeedTable("verified_credential_type_assigned_kinds", x => new { x.VerifiedCredentialTypeId, x.VerifiedCredentialTypeKindId }, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); + await SeedTable("verified_credential_type_assigned_use_cases", x => new { x.VerifiedCredentialTypeId, x.UseCaseId }, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); + await SeedTable("verified_credential_type_assigned_external_types", x => new { x.VerifiedCredentialTypeId, x.VerifiedCredentialExternalTypeId }, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); - await _context.SaveChangesAsync(cancellationToken).ConfigureAwait(false); + await _context.SaveChangesAsync(cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); _logger.LogInformation("Finished BaseEntityBatch Seeder"); } private async Task SeedBaseEntity(CancellationToken cancellationToken) { - await SeedTableForBaseEntity("documents", cancellationToken).ConfigureAwait(false); - await SeedTableForBaseEntity("use_cases", cancellationToken).ConfigureAwait(false); - await SeedTableForBaseEntity("process_steps", cancellationToken).ConfigureAwait(false); - await SeedTableForBaseEntity("processes", cancellationToken).ConfigureAwait(false); - await SeedTableForBaseEntity("verified_credential_external_type_detail_versions", cancellationToken).ConfigureAwait(false); - await SeedTableForBaseEntity("company_ssi_details", cancellationToken).ConfigureAwait(false); + await SeedTableForBaseEntity("documents", cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); + await SeedTableForBaseEntity("use_cases", cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); + await SeedTableForBaseEntity("process_steps", cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); + await SeedTableForBaseEntity("processes", cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); + await SeedTableForBaseEntity("verified_credential_external_type_detail_versions", cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); + await SeedTableForBaseEntity("company_ssi_details", cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); } private async Task SeedTableForBaseEntity(string fileName, CancellationToken cancellationToken) where T : class, IBaseEntity { - await SeedTable(fileName, x => x.Id, cancellationToken).ConfigureAwait(false); + await SeedTable(fileName, x => x.Id, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); } private async Task SeedTable(string fileName, Func keySelector, CancellationToken cancellationToken) where T : class { _logger.LogInformation("Start seeding {Filename}", fileName); var additionalEnvironments = _settings.TestDataEnvironments ?? Enumerable.Empty(); - var data = await SeederHelper.GetSeedData(_logger, fileName, _settings.DataPaths, cancellationToken, additionalEnvironments.ToArray()).ConfigureAwait(false); + var data = await SeederHelper.GetSeedData(_logger, fileName, _settings.DataPaths, cancellationToken, additionalEnvironments.ToArray()).ConfigureAwait(ConfigureAwaitOptions.None); _logger.LogInformation("Found {ElementCount} data", data.Count); if (data.Any()) { @@ -101,7 +101,7 @@ private async Task SeedTable(string fileName, Func keySelector, Ca .Where(t => t.x == null) .Select(t => t.t.d).ToList(); _logger.LogInformation("Seeding {DataCount} {TableName}", data.Count, typeName); - await _context.Set().AddRangeAsync(data, cancellationToken).ConfigureAwait(false); + await _context.Set().AddRangeAsync(data, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); _logger.LogInformation("Seeded {TableName}", typeName); } } diff --git a/src/database/SsiCredentialIssuer.Migrations/Seeder/BatchUpdateSeeder.cs b/src/database/SsiCredentialIssuer.Migrations/Seeder/BatchUpdateSeeder.cs index 3fcc80a4..e42a5a43 100644 --- a/src/database/SsiCredentialIssuer.Migrations/Seeder/BatchUpdateSeeder.cs +++ b/src/database/SsiCredentialIssuer.Migrations/Seeder/BatchUpdateSeeder.cs @@ -69,9 +69,9 @@ await SeedTable("verified_credentia dbEntry.Template = entry.Template; dbEntry.Expiry = entry.Expiry; dbEntry.ValidFrom = entry.ValidFrom; - }, cancellationToken).ConfigureAwait(false); + }, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); - await _context.SaveChangesAsync(cancellationToken).ConfigureAwait(false); + await _context.SaveChangesAsync(cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); _logger.LogInformation("Finished BaseEntityBatch Seeder"); } @@ -79,7 +79,7 @@ private async Task SeedTable(string fileName, Func keySelector, Fu { _logger.LogInformation("Start seeding {Filename}", fileName); var additionalEnvironments = _settings.TestDataEnvironments ?? Enumerable.Empty(); - var data = await SeederHelper.GetSeedData(_logger, fileName, _settings.DataPaths, cancellationToken, additionalEnvironments.ToArray()).ConfigureAwait(false); + var data = await SeederHelper.GetSeedData(_logger, fileName, _settings.DataPaths, cancellationToken, additionalEnvironments.ToArray()).ConfigureAwait(ConfigureAwaitOptions.None); _logger.LogInformation("Found {ElementCount} data", data.Count); if (data.Any()) { diff --git a/src/database/SsiCredentialIssuer.Migrations/SsiCredentialIssuer.Migrations.csproj b/src/database/SsiCredentialIssuer.Migrations/SsiCredentialIssuer.Migrations.csproj index 7741e998..9129390e 100644 --- a/src/database/SsiCredentialIssuer.Migrations/SsiCredentialIssuer.Migrations.csproj +++ b/src/database/SsiCredentialIssuer.Migrations/SsiCredentialIssuer.Migrations.csproj @@ -21,7 +21,7 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Migrations Org.Eclipse.TractusX.SsiCredentialIssuer.Migrations - net7.0 + net8.0 enable enable 31645f70-6335-4833-b3b4-4826ca778084 @@ -33,23 +33,24 @@ true - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/externalservices/Callback.Service/Callback.Service.csproj b/src/externalservices/Callback.Service/Callback.Service.csproj index 6f0c33d9..e748e4c2 100644 --- a/src/externalservices/Callback.Service/Callback.Service.csproj +++ b/src/externalservices/Callback.Service/Callback.Service.csproj @@ -22,15 +22,15 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Callback.Service Org.Eclipse.TractusX.SsiCredentialIssuer.Callback.Service - net7.0 + net8.0 enable enable - - - + + + diff --git a/src/externalservices/Callback.Service/Services/CallbackService.cs b/src/externalservices/Callback.Service/Services/CallbackService.cs index 719f3609..8a10610c 100644 --- a/src/externalservices/Callback.Service/Services/CallbackService.cs +++ b/src/externalservices/Callback.Service/Services/CallbackService.cs @@ -47,7 +47,7 @@ public CallbackService(ITokenService tokenService, IOptions op public async Task TriggerCallback(string callbackUrl, IssuerResponseData responseData, CancellationToken cancellationToken) { - var client = await _tokenService.GetAuthorizedClient(_settings, cancellationToken).ConfigureAwait(false); + var client = await _tokenService.GetAuthorizedClient(_settings, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); await client.PostAsJsonAsync($"{callbackUrl}", responseData, Options, cancellationToken) .CatchingIntoServiceExceptionFor("callback", HttpAsyncResponseMessageExtension.RecoverOptions.REQUEST_EXCEPTION) .ConfigureAwait(false); diff --git a/src/externalservices/Portal.Service/Portal.Service.csproj b/src/externalservices/Portal.Service/Portal.Service.csproj index 76ede424..4091ad85 100644 --- a/src/externalservices/Portal.Service/Portal.Service.csproj +++ b/src/externalservices/Portal.Service/Portal.Service.csproj @@ -22,15 +22,15 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Portal.Service Org.Eclipse.TractusX.SsiCredentialIssuer.Portal.Service - net7.0 + net8.0 enable enable - - - + + + diff --git a/src/externalservices/Portal.Service/Services/PortalService.cs b/src/externalservices/Portal.Service/Services/PortalService.cs index 6160047e..3f0dc27c 100644 --- a/src/externalservices/Portal.Service/Services/PortalService.cs +++ b/src/externalservices/Portal.Service/Services/PortalService.cs @@ -42,7 +42,7 @@ public PortalService(ITokenService tokenService, IOptions option public async Task AddNotification(string content, Guid requester, NotificationTypeId notificationTypeId, CancellationToken cancellationToken) { - using var client = await _tokenService.GetAuthorizedClient(_settings, cancellationToken).ConfigureAwait(false); + using var client = await _tokenService.GetAuthorizedClient(_settings, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); var data = new NotificationRequest(requester, content, notificationTypeId); await client.PostAsJsonAsync("api/notifications/ssi-credentials", data, Options, cancellationToken) .CatchingIntoServiceExceptionFor("notification", HttpAsyncResponseMessageExtension.RecoverOptions.REQUEST_EXCEPTION) @@ -51,7 +51,7 @@ await client.PostAsJsonAsync("api/notifications/ssi-credentials", data, Options, public async Task TriggerMail(string template, Guid requester, IEnumerable mailParameters, CancellationToken cancellationToken) { - using var client = await _tokenService.GetAuthorizedClient(_settings, cancellationToken).ConfigureAwait(false); + using var client = await _tokenService.GetAuthorizedClient(_settings, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); var data = new MailData(requester, template, mailParameters); await client.PostAsJsonAsync("api/administration/mail/ssi-credentials", data, Options, cancellationToken) .CatchingIntoServiceExceptionFor("mail", HttpAsyncResponseMessageExtension.RecoverOptions.REQUEST_EXCEPTION) diff --git a/src/externalservices/Wallet.Service/BusinessLogic/WalletBusinessLogic.cs b/src/externalservices/Wallet.Service/BusinessLogic/WalletBusinessLogic.cs index 4695c193..cc88f181 100644 --- a/src/externalservices/Wallet.Service/BusinessLogic/WalletBusinessLogic.cs +++ b/src/externalservices/Wallet.Service/BusinessLogic/WalletBusinessLogic.cs @@ -48,25 +48,25 @@ public WalletBusinessLogic(IWalletService walletService, IIssuerRepositories rep public async Task CreateCredential(Guid companySsiDetailId, JsonDocument schema, CancellationToken cancellationToken) { - var credentialId = await _walletService.CreateCredential(schema, cancellationToken).ConfigureAwait(false); + var credentialId = await _walletService.CreateCredential(schema, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); _repositories.GetInstance().AttachAndModifyCompanySsiDetails(companySsiDetailId, c => c.ExternalCredentialId = null, c => c.ExternalCredentialId = credentialId); } public async Task SignCredential(Guid companySsiDetailId, Guid credentialId, CancellationToken cancellationToken) { - var credential = await _walletService.SignCredential(credentialId, cancellationToken).ConfigureAwait(false); + var credential = await _walletService.SignCredential(credentialId, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); _repositories.GetInstance().AttachAndModifyCompanySsiDetails(companySsiDetailId, c => c.Credential = null, c => c.Credential = credential); } public async Task GetCredential(Guid credentialId, Guid externalCredentialId, VerifiedCredentialTypeKindId kindId, CancellationToken cancellationToken) { - var credential = await _walletService.GetCredential(externalCredentialId, cancellationToken).ConfigureAwait(false); - await ValidateSchema(kindId, credential, cancellationToken).ConfigureAwait(false); + var credential = await _walletService.GetCredential(externalCredentialId, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); + await ValidateSchema(kindId, credential, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); using var stream = new MemoryStream(); using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }); credential.WriteTo(writer); - await writer.FlushAsync(cancellationToken).ConfigureAwait(false); + await writer.FlushAsync(cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); var documentContent = stream.ToArray(); var hash = SHA512.HashData(documentContent); var documentRepository = _repositories.GetInstance(); @@ -83,7 +83,7 @@ private static async Task ValidateSchema(VerifiedCredentialTypeKindId kindId, Js } var path = Path.Combine(location, "Schemas", $"{kindId}Credential.schema.json"); - var schemaJson = await File.ReadAllTextAsync(path, cancellationToken).ConfigureAwait(false); + var schemaJson = await File.ReadAllTextAsync(path, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); var schema = JsonSchema.FromText(schemaJson); SchemaRegistry.Global.Register(schema); @@ -101,7 +101,7 @@ public async Task CreateCredentialForHolder(Guid companySsiDetailId, string hold await _walletService .CreateCredentialForHolder(holderWalletUrl, clientId, secret, credential, cancellationToken) - .ConfigureAwait(false); + .ConfigureAwait(ConfigureAwaitOptions.None); _repositories.GetInstance().AttachAndModifyProcessData(companySsiDetailId, c => diff --git a/src/externalservices/Wallet.Service/DependencyInjection/WalletSettings.cs b/src/externalservices/Wallet.Service/DependencyInjection/WalletSettings.cs index ca1f17cc..ba5ad63f 100644 --- a/src/externalservices/Wallet.Service/DependencyInjection/WalletSettings.cs +++ b/src/externalservices/Wallet.Service/DependencyInjection/WalletSettings.cs @@ -18,6 +18,7 @@ ********************************************************************************/ using Org.Eclipse.TractusX.Portal.Backend.Framework.Models.Configuration; +using Org.Eclipse.TractusX.Portal.Backend.Framework.Token; using Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Services; using System.ComponentModel.DataAnnotations; diff --git a/src/externalservices/Wallet.Service/Services/BasicAuthSettings.cs b/src/externalservices/Wallet.Service/Services/BasicAuthSettings.cs deleted file mode 100644 index 3589d2c0..00000000 --- a/src/externalservices/Wallet.Service/Services/BasicAuthSettings.cs +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2024 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.ComponentModel.DataAnnotations; - -namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Services; - -public class BasicAuthSettings -{ - [Required(AllowEmptyStrings = false)] - public string ClientId { get; set; } = null!; - - [Required(AllowEmptyStrings = false)] - public string ClientSecret { get; set; } = null!; - - [Required(AllowEmptyStrings = false)] - public string TokenAddress { get; set; } = null!; -} - -public record GetBasicTokenSettings(string HttpClientName, string ClientId, string ClientSecret, string TokenAddress); diff --git a/src/externalservices/Wallet.Service/Services/BasicAuthTokenService.cs b/src/externalservices/Wallet.Service/Services/BasicAuthTokenService.cs index a3d90473..e38d8652 100644 --- a/src/externalservices/Wallet.Service/Services/BasicAuthTokenService.cs +++ b/src/externalservices/Wallet.Service/Services/BasicAuthTokenService.cs @@ -42,9 +42,10 @@ public async Task GetBasicAuthorizedClient(BasicAuthSettings sett $"{typeof(T).Name}Auth", settings.ClientId, settings.ClientSecret, - settings.TokenAddress); + settings.TokenAddress, + "client_credentials"); - var token = await GetBasicTokenAsync(tokenParameters, cancellationToken).ConfigureAwait(false); + var token = await GetBasicTokenAsync(tokenParameters, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); var httpClient = _httpClientFactory.CreateClient(typeof(T).Name); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); @@ -55,7 +56,7 @@ public async Task GetBasicAuthorizedClient(BasicAuthSettings sett { var formParameters = new Dictionary { - { "grant_type", "client_credentials" } + { "grant_type", settings.GrantType } }; using var content = new FormUrlEncodedContent(formParameters); using var authClient = _httpClientFactory.CreateClient(settings.HttpClientName); @@ -67,7 +68,7 @@ public async Task GetBasicAuthorizedClient(BasicAuthSettings sett var response = await authClient.PostAsync(settings.TokenAddress, content, cancellationToken) .CatchingIntoServiceExceptionFor("token-post", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE).ConfigureAwait(false); - var responseObject = await response.Content.ReadFromJsonAsync(Options, cancellationToken).ConfigureAwait(false); + var responseObject = await response.Content.ReadFromJsonAsync(Options, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); return responseObject?.AccessToken; } } diff --git a/src/externalservices/Wallet.Service/Services/IBasicAuthTokenService.cs b/src/externalservices/Wallet.Service/Services/IBasicAuthTokenService.cs index 693cd234..f8f92c17 100644 --- a/src/externalservices/Wallet.Service/Services/IBasicAuthTokenService.cs +++ b/src/externalservices/Wallet.Service/Services/IBasicAuthTokenService.cs @@ -17,6 +17,8 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ +using Org.Eclipse.TractusX.Portal.Backend.Framework.Token; + namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Services; public interface IBasicAuthTokenService diff --git a/src/externalservices/Wallet.Service/Services/WalletService.cs b/src/externalservices/Wallet.Service/Services/WalletService.cs index ed69daad..f0a132a7 100644 --- a/src/externalservices/Wallet.Service/Services/WalletService.cs +++ b/src/externalservices/Wallet.Service/Services/WalletService.cs @@ -20,6 +20,7 @@ using Microsoft.Extensions.Options; using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; using Org.Eclipse.TractusX.Portal.Backend.Framework.HttpClientExtensions; +using Org.Eclipse.TractusX.Portal.Backend.Framework.Token; using Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.DependencyInjection; using Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Models; using System.Net.Http.Json; @@ -47,9 +48,9 @@ public async Task CreateCredential(JsonDocument payload, CancellationToken var data = new CreateCredentialRequest("catena-x-portal", new CredentialPayload(payload)); var result = await client.PostAsJsonAsync("api/v2.0.0/credentials", data, Options, cancellationToken) .CatchingIntoServiceExceptionFor("create-credential", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, - async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(false))) + async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(ConfigureAwaitOptions.None))) .ConfigureAwait(false); - var response = await result.Content.ReadFromJsonAsync(Options, cancellationToken).ConfigureAwait(false); + var response = await result.Content.ReadFromJsonAsync(Options, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); if (response == null) { throw new ConflictException(NoIdErrorMessage); @@ -64,9 +65,9 @@ public async Task SignCredential(Guid credentialId, CancellationToken ca var data = new SignCredentialRequest(new SignPayload(new SignUpdate("external", "jwt"))); var result = await client.PatchAsJsonAsync($"/api/v2.0.0/credentials/{credentialId}", data, Options, cancellationToken) .CatchingIntoServiceExceptionFor("sign-credential", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, - async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(false))) + async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(ConfigureAwaitOptions.None))) .ConfigureAwait(false); - var response = await result.Content.ReadFromJsonAsync(Options, cancellationToken).ConfigureAwait(false); + var response = await result.Content.ReadFromJsonAsync(Options, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); if (response is null) { throw new ServiceException(NoIdErrorMessage, true); @@ -80,9 +81,9 @@ public async Task GetCredential(Guid externalCredentialId, Cancell using var client = await _basicAuthTokenService.GetBasicAuthorizedClient(_settings, cancellationToken); var result = await client.GetAsync($"/api/v2.0.0/credentials/{externalCredentialId}", cancellationToken) .CatchingIntoServiceExceptionFor("get-credential", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, - async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(false))) + async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(ConfigureAwaitOptions.None))) .ConfigureAwait(false); - var response = await result.Content.ReadFromJsonAsync(Options, cancellationToken).ConfigureAwait(false); + var response = await result.Content.ReadFromJsonAsync(Options, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); if (response is null) { throw new ServiceException(NoIdErrorMessage, true); @@ -103,9 +104,9 @@ public async Task CreateCredentialForHolder(string holderWalletUrl, string var data = new DeriveCredentialData("catena-x-portal", new DeriveCredentialPayload(new DeriveCredential(credential))); var result = await client.PostAsJsonAsync("/api/v2.0.0/credentials", data, Options, cancellationToken) .CatchingIntoServiceExceptionFor("create-holder-credential", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, - async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(false))) + async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(ConfigureAwaitOptions.None))) .ConfigureAwait(false); - var response = await result.Content.ReadFromJsonAsync(Options, cancellationToken).ConfigureAwait(false); + var response = await result.Content.ReadFromJsonAsync(Options, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); if (response is null) { throw new ServiceException(NoIdErrorMessage, true); @@ -120,7 +121,7 @@ public async Task RevokeCredentialForIssuer(Guid externalCredentialId, Cancellat var data = new RevokeCredentialRequest(new RevokePayload(true)); await client.PatchAsJsonAsync($"/api/v2.0.0/credentials/{externalCredentialId}", data, Options, cancellationToken) .CatchingIntoServiceExceptionFor("revoke-credential", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, - async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(false))) + async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(ConfigureAwaitOptions.None))) .ConfigureAwait(false); } } diff --git a/src/externalservices/Wallet.Service/Wallet.Service.csproj b/src/externalservices/Wallet.Service/Wallet.Service.csproj index 64436a01..d1e6720b 100644 --- a/src/externalservices/Wallet.Service/Wallet.Service.csproj +++ b/src/externalservices/Wallet.Service/Wallet.Service.csproj @@ -21,7 +21,7 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service - net7.0 + net8.0 enable enable @@ -30,11 +30,11 @@ - - - - - + + + + + diff --git a/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/CredentialBusinessLogic.cs b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/CredentialBusinessLogic.cs index ab533261..cc43ebae 100644 --- a/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/CredentialBusinessLogic.cs +++ b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/CredentialBusinessLogic.cs @@ -39,7 +39,7 @@ public CredentialBusinessLogic(IIssuerRepositories repositories, IIdentityServic public async Task GetCredentialDocument(Guid credentialId) { - var (exists, isSameCompany, documents) = await _repositories.GetInstance().GetSignedCredentialForCredentialId(credentialId, _identityData.Bpnl).ConfigureAwait(false); + var (exists, isSameCompany, documents) = await _repositories.GetInstance().GetSignedCredentialForCredentialId(credentialId, _identityData.Bpnl).ConfigureAwait(ConfigureAwaitOptions.None); if (!exists) { throw NotFoundException.Create(CredentialErrors.CREDENTIAL_NOT_FOUND, new[] { new ErrorParameter("credentialId", credentialId.ToString()) }); @@ -57,6 +57,6 @@ public async Task GetCredentialDocument(Guid credentialId) var (_, credentialContent) = documents.Single(); using var stream = new MemoryStream(credentialContent); - return await JsonDocument.ParseAsync(stream).ConfigureAwait(false); + return await JsonDocument.ParseAsync(stream).ConfigureAwait(ConfigureAwaitOptions.None); } } diff --git a/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IssuerBusinessLogic.cs b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IssuerBusinessLogic.cs index bcf99ad8..39423d0c 100644 --- a/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IssuerBusinessLogic.cs +++ b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/IssuerBusinessLogic.cs @@ -188,7 +188,7 @@ public async Task ApproveCredential(Guid credentialId, CancellationToken cancell } var companySsiRepository = _repositories.GetInstance(); - var (exists, data) = await companySsiRepository.GetSsiApprovalData(credentialId).ConfigureAwait(false); + var (exists, data) = await companySsiRepository.GetSsiApprovalData(credentialId).ConfigureAwait(ConfigureAwaitOptions.None); ValidateApprovalData(credentialId, exists, data); var processId = CreateProcess(); @@ -215,10 +215,10 @@ public async Task ApproveCredential(Guid credentialId, CancellationToken cancell new("credentialType", typeValue), new("expiryDate", expiry.ToString("o", CultureInfo.InvariantCulture)) }; - await _portalService.TriggerMail("CredentialApproval", _identity.CompanyUserId.Value, mailParameters, cancellationToken).ConfigureAwait(false); + await _portalService.TriggerMail("CredentialApproval", _identity.CompanyUserId.Value, mailParameters, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); var content = JsonSerializer.Serialize(new { data.Type, CredentialId = credentialId }, Options); - await _portalService.AddNotification(content, _identity.CompanyUserId.Value, NotificationTypeId.CREDENTIAL_APPROVAL, cancellationToken).ConfigureAwait(false); - await _repositories.SaveAsync().ConfigureAwait(false); + await _portalService.AddNotification(content, _identity.CompanyUserId.Value, NotificationTypeId.CREDENTIAL_APPROVAL, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); + await _repositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None); } private void UpdateIssuanceDate(Guid credentialId, SsiApprovalData data, @@ -321,7 +321,7 @@ public async Task RejectCredential(Guid credentialId, CancellationToken cancella } var companySsiRepository = _repositories.GetInstance(); - var (exists, status, type, processId, processStepIds) = await companySsiRepository.GetSsiRejectionData(credentialId).ConfigureAwait(false); + var (exists, status, type, processId, processStepIds) = await companySsiRepository.GetSsiRejectionData(credentialId).ConfigureAwait(ConfigureAwaitOptions.None); if (!exists) { throw NotFoundException.Create(IssuerErrors.SSI_DETAILS_NOT_FOUND, new ErrorParameter[] { new("credentialId", credentialId.ToString()) }); @@ -334,7 +334,7 @@ public async Task RejectCredential(Guid credentialId, CancellationToken cancella var typeValue = type.GetEnumValue() ?? throw UnexpectedConditionException.Create(IssuerErrors.CREDENTIAL_TYPE_NOT_FOUND, new ErrorParameter[] { new("verifiedCredentialType", type.ToString()) }); var content = JsonSerializer.Serialize(new { Type = type, CredentialId = credentialId }, Options); - await _portalService.AddNotification(content, _identity.CompanyUserId.Value, NotificationTypeId.CREDENTIAL_REJECTED, cancellationToken).ConfigureAwait(false); + await _portalService.AddNotification(content, _identity.CompanyUserId.Value, NotificationTypeId.CREDENTIAL_REJECTED, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); var mailParameters = new MailParameter[] { @@ -342,7 +342,7 @@ public async Task RejectCredential(Guid credentialId, CancellationToken cancella new("reason", "Declined by the Operator") }; - await _portalService.TriggerMail("CredentialRejected", _identity.CompanyUserId.Value, mailParameters, cancellationToken).ConfigureAwait(false); + await _portalService.TriggerMail("CredentialRejected", _identity.CompanyUserId.Value, mailParameters, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); companySsiRepository.AttachAndModifyCompanySsiDetails(credentialId, c => { @@ -364,7 +364,7 @@ public async Task RejectCredential(Guid credentialId, CancellationToken cancella ))); } - await _repositories.SaveAsync().ConfigureAwait(false); + await _repositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None); } /// @@ -374,7 +374,7 @@ public IAsyncEnumerable GetCertificateTypes() => public async Task CreateBpnCredential(CreateBpnCredentialRequest requestData, CancellationToken cancellationToken) { var companyCredentialDetailsRepository = _repositories.GetInstance(); - var holderDid = await GetHolderInformation(requestData.Holder, cancellationToken).ConfigureAwait(false); + var holderDid = await GetHolderInformation(requestData.Holder, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); var schemaData = new BpnCredential( Guid.NewGuid(), Context, @@ -401,7 +401,7 @@ public async Task CreateMembershipCredential(CreateMembershipCredentialReq { var companyCredentialDetailsRepository = _repositories.GetInstance(); - var holderDid = await GetHolderInformation(requestData.Holder, cancellationToken).ConfigureAwait(false); + var holderDid = await GetHolderInformation(requestData.Holder, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); var schemaData = new MembershipCredential( Guid.NewGuid(), Context, @@ -427,7 +427,7 @@ public async Task CreateMembershipCredential(CreateMembershipCredentialReq public async Task CreateFrameworkCredential(CreateFrameworkCredentialRequest requestData, CancellationToken cancellationToken) { var companyCredentialDetailsRepository = _repositories.GetInstance(); - var result = await companyCredentialDetailsRepository.CheckCredentialTypeIdExistsForExternalTypeDetailVersionId(requestData.UseCaseFrameworkVersionId, requestData.UseCaseFrameworkId).ConfigureAwait(false); + var result = await companyCredentialDetailsRepository.CheckCredentialTypeIdExistsForExternalTypeDetailVersionId(requestData.UseCaseFrameworkVersionId, requestData.UseCaseFrameworkId).ConfigureAwait(ConfigureAwaitOptions.None); if (!result.Exists) { throw ControllerArgumentException.Create(IssuerErrors.EXTERNAL_TYPE_DETAIL_NOT_FOUND, new ErrorParameter[] { new("verifiedCredentialExternalTypeDetailId", requestData.UseCaseFrameworkId.ToString()) }); @@ -459,7 +459,7 @@ public async Task CreateFrameworkCredential(CreateFrameworkCredentialReque throw ControllerArgumentException.Create(IssuerErrors.EMPTY_EXTERNAL_TYPE_ID); } - var holderDid = await GetHolderInformation(requestData.Holder, cancellationToken).ConfigureAwait(false); + var holderDid = await GetHolderInformation(requestData.Holder, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); var schemaData = new FrameworkCredential( Guid.NewGuid(), Context, @@ -495,7 +495,7 @@ private async Task GetHolderInformation(string didDocumentLocation, Canc var client = _clientFactory.CreateClient("didDocumentDownload"); var result = await client.GetAsync(uri, cancellationToken) .CatchingIntoServiceExceptionFor("get-did-document").ConfigureAwait(false); - var did = await result.Content.ReadFromJsonAsync(Options, cancellationToken).ConfigureAwait(false); + var did = await result.Content.ReadFromJsonAsync(Options, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); if (did == null) { throw ConflictException.Create(IssuerErrors.DID_NOT_SET); @@ -564,7 +564,7 @@ private async Task HandleCredentialProcessCreation( c.CallbackUrl = callbackUrl; }); - await _repositories.SaveAsync().ConfigureAwait(false); + await _repositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None); return ssiDetailId; } } diff --git a/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/RevocationBusinessLogic.cs b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/RevocationBusinessLogic.cs index b63cfdf4..85aef268 100644 --- a/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/RevocationBusinessLogic.cs +++ b/src/issuer/SsiCredentialIssuer.Service/BusinessLogic/RevocationBusinessLogic.cs @@ -45,7 +45,7 @@ public async Task RevokeCredential(Guid credentialId, bool revokeForIssuer, Canc { var credentialRepository = _repositories.GetInstance(); var data = await credentialRepository.GetRevocationDataById(credentialId, _identityData.Bpnl) - .ConfigureAwait(false); + .ConfigureAwait(ConfigureAwaitOptions.None); if (!data.Exists) { throw NotFoundException.Create(RevocationDataErrors.CREDENTIAL_NOT_FOUND, new ErrorParameter[] { new("credentialId", credentialId.ToString()) }); @@ -67,7 +67,7 @@ public async Task RevokeCredential(Guid credentialId, bool revokeForIssuer, Canc } // call walletService - await _walletService.RevokeCredentialForIssuer(data.ExternalCredentialId.Value, cancellationToken).ConfigureAwait(false); + await _walletService.RevokeCredentialForIssuer(data.ExternalCredentialId.Value, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); _repositories.GetInstance().AttachAndModifyDocuments( data.Documents.Select(d => new ValueTuple?, Action>( d.DocumentId, diff --git a/src/issuer/SsiCredentialIssuer.Service/Controllers/IssuerController.cs b/src/issuer/SsiCredentialIssuer.Service/Controllers/IssuerController.cs index b14c3545..584f90bd 100644 --- a/src/issuer/SsiCredentialIssuer.Service/Controllers/IssuerController.cs +++ b/src/issuer/SsiCredentialIssuer.Service/Controllers/IssuerController.cs @@ -143,7 +143,7 @@ public static RouteGroupBuilder MapIssuerApi(this RouteGroupBuilder group) issuer.MapPut("{credentialId}/approval", async ([FromRoute] Guid credentialId, CancellationToken cancellationToken, IIssuerBusinessLogic logic) => { - await logic.ApproveCredential(credentialId, cancellationToken).ConfigureAwait(false); + await logic.ApproveCredential(credentialId, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); return Results.NoContent(); }) .WithSwaggerDescription("Approves the given credential and triggers the verified credential creation", @@ -163,7 +163,7 @@ public static RouteGroupBuilder MapIssuerApi(this RouteGroupBuilder group) issuer.MapPut("{credentialId}/reject", async ([FromRoute] Guid credentialId, CancellationToken cancellationToken, IIssuerBusinessLogic logic) => { - await logic.RejectCredential(credentialId, cancellationToken).ConfigureAwait(false); + await logic.RejectCredential(credentialId, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); return Results.NoContent(); }) .WithSwaggerDescription("Rejects the given credential", diff --git a/src/issuer/SsiCredentialIssuer.Service/SsiCredentialIssuer.Service.csproj b/src/issuer/SsiCredentialIssuer.Service/SsiCredentialIssuer.Service.csproj index fd3e5742..e4d25cee 100644 --- a/src/issuer/SsiCredentialIssuer.Service/SsiCredentialIssuer.Service.csproj +++ b/src/issuer/SsiCredentialIssuer.Service/SsiCredentialIssuer.Service.csproj @@ -22,7 +22,7 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Service Org.Eclipse.TractusX.SsiCredentialIssuer.Service - net7.0 + net8.0 enable enable 1c25fec6-9663-495e-9c65-3212002d71ab @@ -33,14 +33,14 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + diff --git a/src/processes/CredentialProcess.Library/Creation/CredentialCreationProcessHandler.cs b/src/processes/CredentialProcess.Library/Creation/CredentialCreationProcessHandler.cs index 9ff1588d..e898ea10 100644 --- a/src/processes/CredentialProcess.Library/Creation/CredentialCreationProcessHandler.cs +++ b/src/processes/CredentialProcess.Library/Creation/CredentialCreationProcessHandler.cs @@ -43,8 +43,8 @@ public CredentialCreationProcessHandler(IIssuerRepositories issuerRepositories, public async Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> CreateCredential(Guid credentialId, CancellationToken cancellationToken) { - var data = await _issuerRepositories.GetInstance().GetCredentialStorageInformationById(credentialId).ConfigureAwait(false); - await _walletBusinessLogic.CreateCredential(credentialId, data.Schema, cancellationToken).ConfigureAwait(false); + var data = await _issuerRepositories.GetInstance().GetCredentialStorageInformationById(credentialId).ConfigureAwait(ConfigureAwaitOptions.None); + await _walletBusinessLogic.CreateCredential(credentialId, data.Schema, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); return ( Enumerable.Repeat(ProcessStepTypeId.SIGN_CREDENTIAL, 1), ProcessStepStatusId.DONE, @@ -54,13 +54,13 @@ public CredentialCreationProcessHandler(IIssuerRepositories issuerRepositories, public async Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> SignCredential(Guid credentialId, CancellationToken cancellationToken) { - var externalCredentialId = await _issuerRepositories.GetInstance().GetWalletCredentialId(credentialId).ConfigureAwait(false); + var externalCredentialId = await _issuerRepositories.GetInstance().GetWalletCredentialId(credentialId).ConfigureAwait(ConfigureAwaitOptions.None); if (externalCredentialId is null) { throw new ConflictException("ExternalCredentialId must be set here"); } - await _walletBusinessLogic.SignCredential(credentialId, externalCredentialId!.Value, cancellationToken).ConfigureAwait(false); + await _walletBusinessLogic.SignCredential(credentialId, externalCredentialId!.Value, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); return ( Enumerable.Repeat(ProcessStepTypeId.SAVE_CREDENTIAL_DOCUMENT, 1), ProcessStepStatusId.DONE, @@ -70,13 +70,13 @@ public CredentialCreationProcessHandler(IIssuerRepositories issuerRepositories, public async Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> SaveCredentialDocument(Guid credentialId, CancellationToken cancellationToken) { - var (externalCredentialId, kindId, hasEncryptionInformation, callbackUrl) = await _issuerRepositories.GetInstance().GetExternalCredentialAndKindId(credentialId).ConfigureAwait(false); + var (externalCredentialId, kindId, hasEncryptionInformation, callbackUrl) = await _issuerRepositories.GetInstance().GetExternalCredentialAndKindId(credentialId).ConfigureAwait(ConfigureAwaitOptions.None); if (externalCredentialId == null) { throw new ConflictException("ExternalCredentialId must be set here"); } - await _walletBusinessLogic.GetCredential(credentialId, externalCredentialId.Value, kindId, cancellationToken).ConfigureAwait(false); + await _walletBusinessLogic.GetCredential(credentialId, externalCredentialId.Value, kindId, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); var nextProcessStep = callbackUrl == null ? null : Enumerable.Repeat(ProcessStepTypeId.TRIGGER_CALLBACK, 1); return ( hasEncryptionInformation @@ -89,7 +89,7 @@ public CredentialCreationProcessHandler(IIssuerRepositories issuerRepositories, public async Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> CreateCredentialForHolder(Guid credentialId, CancellationToken cancellationToken) { - var (holderWalletData, credential, encryptionInformation, callbackUrl) = await _issuerRepositories.GetInstance().GetCredentialData(credentialId).ConfigureAwait(false); + var (holderWalletData, credential, encryptionInformation, callbackUrl) = await _issuerRepositories.GetInstance().GetCredentialData(credentialId).ConfigureAwait(ConfigureAwaitOptions.None); if (credential is null) { throw new ConflictException("Credential must be set here"); @@ -105,7 +105,7 @@ public CredentialCreationProcessHandler(IIssuerRepositories issuerRepositories, throw new ConflictException("Wallet secret must be set"); } - await _walletBusinessLogic.CreateCredentialForHolder(credentialId, holderWalletData.WalletUrl, holderWalletData.ClientId, new EncryptionInformation(encryptionInformation.Secret, encryptionInformation.InitializationVector, encryptionInformation.EncryptionMode.Value), credential, cancellationToken).ConfigureAwait(false); + await _walletBusinessLogic.CreateCredentialForHolder(credentialId, holderWalletData.WalletUrl, holderWalletData.ClientId, new EncryptionInformation(encryptionInformation.Secret, encryptionInformation.InitializationVector, encryptionInformation.EncryptionMode.Value), credential, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); return ( callbackUrl is null ? null : Enumerable.Repeat(ProcessStepTypeId.TRIGGER_CALLBACK, 1), ProcessStepStatusId.DONE, @@ -115,14 +115,14 @@ public CredentialCreationProcessHandler(IIssuerRepositories issuerRepositories, public async Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> TriggerCallback(Guid credentialId, CancellationToken cancellationToken) { - var (bpn, callbackUrl) = await _issuerRepositories.GetInstance().GetCallbackUrl(credentialId).ConfigureAwait(false); + var (bpn, callbackUrl) = await _issuerRepositories.GetInstance().GetCallbackUrl(credentialId).ConfigureAwait(ConfigureAwaitOptions.None); if (callbackUrl is null) { throw new ConflictException("CallbackUrl must be set"); } var issuerResponseData = new IssuerResponseData(bpn, IssuerResponseStatus.SUCCESSFUL, "Successfully created Credential"); - await _callbackService.TriggerCallback(callbackUrl, issuerResponseData, cancellationToken).ConfigureAwait(false); + await _callbackService.TriggerCallback(callbackUrl, issuerResponseData, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); return ( null, ProcessStepStatusId.DONE, diff --git a/src/processes/CredentialProcess.Library/CredentialProcess.Library.csproj b/src/processes/CredentialProcess.Library/CredentialProcess.Library.csproj index bb58a792..f996d012 100644 --- a/src/processes/CredentialProcess.Library/CredentialProcess.Library.csproj +++ b/src/processes/CredentialProcess.Library/CredentialProcess.Library.csproj @@ -22,7 +22,7 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library - net7.0 + net8.0 enable enable diff --git a/src/processes/CredentialProcess.Library/Expiry/CredentialExpiryProcessHandler.cs b/src/processes/CredentialProcess.Library/Expiry/CredentialExpiryProcessHandler.cs index c1fc6ed2..1660e571 100644 --- a/src/processes/CredentialProcess.Library/Expiry/CredentialExpiryProcessHandler.cs +++ b/src/processes/CredentialProcess.Library/Expiry/CredentialExpiryProcessHandler.cs @@ -48,7 +48,7 @@ public CredentialExpiryProcessHandler(IIssuerRepositories repositories, IWalletS { var credentialRepository = _repositories.GetInstance(); var data = await credentialRepository.GetRevocationDataById(credentialId, string.Empty) - .ConfigureAwait(false); + .ConfigureAwait(ConfigureAwaitOptions.None); if (!data.Exists) { throw new NotFoundException($"Credential {credentialId} does not exist"); @@ -60,7 +60,7 @@ public CredentialExpiryProcessHandler(IIssuerRepositories repositories, IWalletS } // call walletService - await _walletService.RevokeCredentialForIssuer(data.ExternalCredentialId.Value, cancellationToken).ConfigureAwait(false); + await _walletService.RevokeCredentialForIssuer(data.ExternalCredentialId.Value, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); _repositories.GetInstance().AttachAndModifyDocuments( data.Documents.Select(d => new ValueTuple?, Action>( @@ -82,7 +82,7 @@ public CredentialExpiryProcessHandler(IIssuerRepositories repositories, IWalletS public async Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> TriggerNotification(Guid credentialId, CancellationToken cancellationToken) { - var (typeId, requesterId) = await _repositories.GetInstance().GetCredentialNotificationData(credentialId).ConfigureAwait(false); + var (typeId, requesterId) = await _repositories.GetInstance().GetCredentialNotificationData(credentialId).ConfigureAwait(ConfigureAwaitOptions.None); if (Guid.TryParse(requesterId, out var companyUserId)) { var content = JsonSerializer.Serialize(new { Type = typeId, CredentialId = credentialId }, Options); @@ -98,7 +98,7 @@ public CredentialExpiryProcessHandler(IIssuerRepositories repositories, IWalletS public async Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> TriggerMail(Guid credentialId, CancellationToken cancellationToken) { - var (typeId, requesterId) = await _repositories.GetInstance().GetCredentialNotificationData(credentialId).ConfigureAwait(false); + var (typeId, requesterId) = await _repositories.GetInstance().GetCredentialNotificationData(credentialId).ConfigureAwait(ConfigureAwaitOptions.None); var typeValue = typeId.GetEnumValue() ?? throw new UnexpectedConditionException($"VerifiedCredentialType {typeId} does not exists"); if (Guid.TryParse(requesterId, out var companyUserId)) diff --git a/src/processes/CredentialProcess.Worker/Creation/CredentialCreationProcessTypeExecutor.cs b/src/processes/CredentialProcess.Worker/Creation/CredentialCreationProcessTypeExecutor.cs index 745ef098..69357b87 100644 --- a/src/processes/CredentialProcess.Worker/Creation/CredentialCreationProcessTypeExecutor.cs +++ b/src/processes/CredentialProcess.Worker/Creation/CredentialCreationProcessTypeExecutor.cs @@ -56,7 +56,7 @@ public CredentialCreationProcessTypeExecutor( public async ValueTask InitializeProcess(Guid processId, IEnumerable processStepTypeIds) { - var (exists, credentialId) = await _issuerRepositories.GetInstance().GetDataForProcessId(processId).ConfigureAwait(false); + var (exists, credentialId) = await _issuerRepositories.GetInstance().GetDataForProcessId(processId).ConfigureAwait(ConfigureAwaitOptions.None); if (!exists) { throw new NotFoundException($"process {processId} does not exist or is not associated with an credential"); @@ -83,15 +83,15 @@ public CredentialCreationProcessTypeExecutor( (nextStepTypeIds, stepStatusId, modified, processMessage) = processStepTypeId switch { ProcessStepTypeId.CREATE_CREDENTIAL => await _credentialCreationProcessHandler.CreateCredential(_credentialId, cancellationToken) - .ConfigureAwait(false), + .ConfigureAwait(ConfigureAwaitOptions.None), ProcessStepTypeId.SIGN_CREDENTIAL => await _credentialCreationProcessHandler.SignCredential(_credentialId, cancellationToken) - .ConfigureAwait(false), + .ConfigureAwait(ConfigureAwaitOptions.None), ProcessStepTypeId.SAVE_CREDENTIAL_DOCUMENT => await _credentialCreationProcessHandler.SaveCredentialDocument(_credentialId, cancellationToken) - .ConfigureAwait(false), + .ConfigureAwait(ConfigureAwaitOptions.None), ProcessStepTypeId.CREATE_CREDENTIAL_FOR_HOLDER => await _credentialCreationProcessHandler.CreateCredentialForHolder(_credentialId, cancellationToken) - .ConfigureAwait(false), + .ConfigureAwait(ConfigureAwaitOptions.None), ProcessStepTypeId.TRIGGER_CALLBACK => await _credentialCreationProcessHandler.TriggerCallback(_credentialId, cancellationToken) - .ConfigureAwait(false), + .ConfigureAwait(ConfigureAwaitOptions.None), _ => (null, ProcessStepStatusId.TODO, false, null) }; } diff --git a/src/processes/CredentialProcess.Worker/CredentialProcess.Worker.csproj b/src/processes/CredentialProcess.Worker/CredentialProcess.Worker.csproj index a45ba693..ffbd40a1 100644 --- a/src/processes/CredentialProcess.Worker/CredentialProcess.Worker.csproj +++ b/src/processes/CredentialProcess.Worker/CredentialProcess.Worker.csproj @@ -22,7 +22,7 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Worker Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Worker - net7.0 + net8.0 enable enable diff --git a/src/processes/CredentialProcess.Worker/Expiry/CredentialExpiryProcessTypeExecutor.cs b/src/processes/CredentialProcess.Worker/Expiry/CredentialExpiryProcessTypeExecutor.cs index d73586cc..e8b010c8 100644 --- a/src/processes/CredentialProcess.Worker/Expiry/CredentialExpiryProcessTypeExecutor.cs +++ b/src/processes/CredentialProcess.Worker/Expiry/CredentialExpiryProcessTypeExecutor.cs @@ -54,7 +54,7 @@ public CredentialExpiryProcessTypeExecutor( public async ValueTask InitializeProcess(Guid processId, IEnumerable processStepTypeIds) { - var (exists, credentialId) = await _issuerRepositories.GetInstance().GetDataForProcessId(processId).ConfigureAwait(false); + var (exists, credentialId) = await _issuerRepositories.GetInstance().GetDataForProcessId(processId).ConfigureAwait(ConfigureAwaitOptions.None); if (!exists) { throw new NotFoundException($"process {processId} does not exist or is not associated with an credential"); @@ -81,11 +81,11 @@ public CredentialExpiryProcessTypeExecutor( (nextStepTypeIds, stepStatusId, modified, processMessage) = processStepTypeId switch { ProcessStepTypeId.REVOKE_CREDENTIAL => await _credentialExpiryProcessHandler.RevokeCredential(_credentialId, cancellationToken) - .ConfigureAwait(false), + .ConfigureAwait(ConfigureAwaitOptions.None), ProcessStepTypeId.TRIGGER_NOTIFICATION => await _credentialExpiryProcessHandler.TriggerNotification(_credentialId, cancellationToken) - .ConfigureAwait(false), + .ConfigureAwait(ConfigureAwaitOptions.None), ProcessStepTypeId.TRIGGER_MAIL => await _credentialExpiryProcessHandler.TriggerMail(_credentialId, cancellationToken) - .ConfigureAwait(false), + .ConfigureAwait(ConfigureAwaitOptions.None), _ => (null, ProcessStepStatusId.TODO, false, null) }; } diff --git a/src/processes/Processes.Library/Processes.Library.csproj b/src/processes/Processes.Library/Processes.Library.csproj index bbb4fd76..edcf898d 100644 --- a/src/processes/Processes.Library/Processes.Library.csproj +++ b/src/processes/Processes.Library/Processes.Library.csproj @@ -22,7 +22,7 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Processes.Library Org.Eclipse.TractusX.SsiCredentialIssuer.Processes.Library - net7.0 + net8.0 enable enable 76a1cf69-39e1-43a7-b6a7-fef83be5359f diff --git a/src/processes/Processes.Worker.Library/ProcessExecutionService.cs b/src/processes/Processes.Worker.Library/ProcessExecutionService.cs index a5edd1f0..180790cf 100644 --- a/src/processes/Processes.Worker.Library/ProcessExecutionService.cs +++ b/src/processes/Processes.Worker.Library/ProcessExecutionService.cs @@ -90,7 +90,7 @@ public async Task ExecuteAsync(CancellationToken stoppingToken) { if (hasChanged) { - await executorRepositories.SaveAsync().ConfigureAwait(false); + await executorRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None); } executorRepositories.Clear(); @@ -98,7 +98,7 @@ public async Task ExecuteAsync(CancellationToken stoppingToken) if (process.ReleaseLock()) { - await executorRepositories.SaveAsync().ConfigureAwait(false); + await executorRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None); executorRepositories.Clear(); } diff --git a/src/processes/Processes.Worker.Library/Processes.Worker.Library.csproj b/src/processes/Processes.Worker.Library/Processes.Worker.Library.csproj index be16ad8b..6721951e 100644 --- a/src/processes/Processes.Worker.Library/Processes.Worker.Library.csproj +++ b/src/processes/Processes.Worker.Library/Processes.Worker.Library.csproj @@ -22,20 +22,20 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Processes.Worker.Library Org.Eclipse.TractusX.SsiCredentialIssuer.Processes.Worker.Library - net7.0 + net8.0 enable enable - - - - - - - - + + + + + + + + diff --git a/src/processes/Processes.Worker/Processes.Worker.csproj b/src/processes/Processes.Worker/Processes.Worker.csproj index f61969f3..64cc0e51 100644 --- a/src/processes/Processes.Worker/Processes.Worker.csproj +++ b/src/processes/Processes.Worker/Processes.Worker.csproj @@ -22,7 +22,7 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Processes.Worker Org.Eclipse.TractusX.SsiCredentialIssuer.Processes.Worker - net7.0 + net8.0 enable enable Exe @@ -41,9 +41,9 @@ - - - + + + diff --git a/src/processes/Processes.Worker/Program.cs b/src/processes/Processes.Worker/Program.cs index 5b8cb16f..3133a8de 100644 --- a/src/processes/Processes.Worker/Program.cs +++ b/src/processes/Processes.Worker/Program.cs @@ -61,7 +61,7 @@ Log.Information("Start processing"); var workerInstance = host.Services.GetRequiredService(); - await workerInstance.ExecuteAsync(tokenSource.Token).ConfigureAwait(false); + await workerInstance.ExecuteAsync(tokenSource.Token).ConfigureAwait(ConfigureAwaitOptions.None); Log.Information("Execution finished shutting down"); } catch (Exception ex) when (!ex.GetType().Name.Equals("StopTheHostException", StringComparison.Ordinal)) diff --git a/tests/Tests.Shared/Extensions/HttpExtensions.cs b/tests/Tests.Shared/Extensions/HttpExtensions.cs index 56a77d38..86c42035 100644 --- a/tests/Tests.Shared/Extensions/HttpExtensions.cs +++ b/tests/Tests.Shared/Extensions/HttpExtensions.cs @@ -27,12 +27,12 @@ public static class HttpExtensions { public static async Task GetResultFromContent(this HttpResponseMessage response) { - using var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); + using var responseStream = await response.Content.ReadAsStreamAsync(); var options = new JsonSerializerOptions { Converters = { new JsonStringEnumConverter(allowIntegerValues: false) } }; - return await JsonSerializer.DeserializeAsync(responseStream, options).ConfigureAwait(false) ?? throw new InvalidOperationException(); + return await JsonSerializer.DeserializeAsync(responseStream, options) ?? throw new InvalidOperationException(); } public static HttpContent ToJsonContent(this object data, JsonSerializerOptions options, string contentType) diff --git a/tests/Tests.Shared/Tests.Shared.csproj b/tests/Tests.Shared/Tests.Shared.csproj index 33d05345..5c6aa99a 100644 --- a/tests/Tests.Shared/Tests.Shared.csproj +++ b/tests/Tests.Shared/Tests.Shared.csproj @@ -21,7 +21,7 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Tests.Shared Org.Eclipse.TractusX.SsiCredentialIssuer.Tests.Shared - net7.0 + net8.0 enable enable diff --git a/tests/credentials/SsiCredentialIssuer.Expiry.App.Tests/ExpiryCheckServiceTests.cs b/tests/credentials/SsiCredentialIssuer.Expiry.App.Tests/ExpiryCheckServiceTests.cs index ef896cea..ad374f2d 100644 --- a/tests/credentials/SsiCredentialIssuer.Expiry.App.Tests/ExpiryCheckServiceTests.cs +++ b/tests/credentials/SsiCredentialIssuer.Expiry.App.Tests/ExpiryCheckServiceTests.cs @@ -103,7 +103,7 @@ public async Task ExecuteAsync_WithInactiveAndEligibleForDeletion_RemovesEntry() .Returns(data.ToAsyncEnumerable()); // Act - await _sut.ExecuteAsync(CancellationToken.None).ConfigureAwait(false); + await _sut.ExecuteAsync(CancellationToken.None); // Assert A.CallTo(() => _companySsiDetailsRepository.RemoveSsiDetail(credentialId)).MustHaveHappenedOnceExactly(); @@ -134,7 +134,7 @@ public async Task ExecuteAsync_WithPendingAndExpiryBeforeNow_DeclinesRequest() .Returns(data.ToAsyncEnumerable()); // Act - await _sut.ExecuteAsync(CancellationToken.None).ConfigureAwait(false); + await _sut.ExecuteAsync(CancellationToken.None); // Assert A.CallTo(() => _companySsiDetailsRepository.RemoveSsiDetail(ssiDetail.Id)).MustNotHaveHappened(); @@ -180,7 +180,7 @@ public async Task ExecuteAsync_WithActiveCloseToExpiry_NotifiesCreator(int days, }); // Act - await _sut.ExecuteAsync(CancellationToken.None).ConfigureAwait(false); + await _sut.ExecuteAsync(CancellationToken.None); // Assert A.CallTo(() => _companySsiDetailsRepository.RemoveSsiDetail(ssiDetail.Id)).MustNotHaveHappened(); diff --git a/tests/credentials/SsiCredentialIssuer.Expiry.App.Tests/SsiCredentialIssuer.Expiry.App.Tests.csproj b/tests/credentials/SsiCredentialIssuer.Expiry.App.Tests/SsiCredentialIssuer.Expiry.App.Tests.csproj index b8f099c2..f57a9160 100644 --- a/tests/credentials/SsiCredentialIssuer.Expiry.App.Tests/SsiCredentialIssuer.Expiry.App.Tests.csproj +++ b/tests/credentials/SsiCredentialIssuer.Expiry.App.Tests/SsiCredentialIssuer.Expiry.App.Tests.csproj @@ -22,19 +22,18 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Expiry.App.Tests Org.Eclipse.TractusX.SsiCredentialIssuer.Expiry.App.Tests - net7.0 + net8.0 enable enable false - - + + - @@ -42,10 +41,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - diff --git a/tests/database/SsiCredentialIssuer.DbAccess.Tests/CompanySsiDetailsRepositoryTests.cs b/tests/database/SsiCredentialIssuer.DbAccess.Tests/CompanySsiDetailsRepositoryTests.cs index 156cb5df..721afdf8 100644 --- a/tests/database/SsiCredentialIssuer.DbAccess.Tests/CompanySsiDetailsRepositoryTests.cs +++ b/tests/database/SsiCredentialIssuer.DbAccess.Tests/CompanySsiDetailsRepositoryTests.cs @@ -56,7 +56,7 @@ public async Task GetDetailsForCompany_WithValidData_ReturnsExpected() var sut = await CreateSut(); // Act - var result = await sut.GetUseCaseParticipationForCompany(ValidBpnl, DateTimeOffset.MinValue).ToListAsync().ConfigureAwait(false); + var result = await sut.GetUseCaseParticipationForCompany(ValidBpnl, DateTimeOffset.MinValue).ToListAsync(); // Assert result.Should().HaveCount(8); @@ -83,7 +83,7 @@ public async Task GetDetailsForCompany_WithExpiryFilter_ReturnsExpected() var sut = await CreateSut(); // Act - var result = await sut.GetUseCaseParticipationForCompany(ValidBpnl, dt).ToListAsync().ConfigureAwait(false); + var result = await sut.GetUseCaseParticipationForCompany(ValidBpnl, dt).ToListAsync(); // Assert result.Should().HaveCount(8); @@ -113,7 +113,7 @@ public async Task GetAllCredentialDetails_WithValidData_ReturnsExpected() var sut = await CreateSut(); // Act - var result = await sut.GetAllCredentialDetails(null, null).ToListAsync().ConfigureAwait(false); + var result = await sut.GetAllCredentialDetails(null, null).ToListAsync(); // Assert result.Should().NotBeNull(); @@ -138,7 +138,7 @@ public async Task GetAllCredentialDetails_WithWithStatusId_ReturnsExpected() var sut = await CreateSut(); // Act - var result = await sut.GetAllCredentialDetails(CompanySsiDetailStatusId.PENDING, null).ToListAsync().ConfigureAwait(false); + var result = await sut.GetAllCredentialDetails(CompanySsiDetailStatusId.PENDING, null).ToListAsync(); // Assert result.Should().NotBeNull().And.HaveCount(4); @@ -159,7 +159,7 @@ public async Task GetAllCredentialDetails_WithWithCredentialType_ReturnsExpected var sut = await CreateSut(); // Act - var result = await sut.GetAllCredentialDetails(null, VerifiedCredentialTypeId.PCF_FRAMEWORK).ToListAsync().ConfigureAwait(false); + var result = await sut.GetAllCredentialDetails(null, VerifiedCredentialTypeId.PCF_FRAMEWORK).ToListAsync(); // Assert result.Should().NotBeNull().And.ContainSingle().Which.Bpnl.Should().Be(ValidBpnl); @@ -177,7 +177,7 @@ public async Task GetSsiCertificates_WithValidData_ReturnsExpected() var sut = await CreateSut(); // Act - var result = await sut.GetSsiCertificates(ValidBpnl, new DateTimeOffset(2023, 01, 01, 01, 01, 01, TimeSpan.Zero)).ToListAsync().ConfigureAwait(false); + var result = await sut.GetSsiCertificates(ValidBpnl, new DateTimeOffset(2023, 01, 01, 01, 01, 01, TimeSpan.Zero)).ToListAsync(); // Assert result.Should().HaveCount(2) @@ -200,7 +200,7 @@ public async Task GetOwnCredentialDetails_WithValidData_ReturnsExpected() var sut = await CreateSut(); // Act - var result = await sut.GetOwnCredentialDetails(ValidBpnl).ToListAsync().ConfigureAwait(false); + var result = await sut.GetOwnCredentialDetails(ValidBpnl).ToListAsync(); // Assert result.Should().HaveCount(6) @@ -221,7 +221,7 @@ public async Task GetOwnCredentialDetails_WithBpnWithoutCredential_ReturnsExpect var sut = await CreateSut(); // Act - var result = await sut.GetOwnCredentialDetails("BPNL000000INVALID").ToListAsync().ConfigureAwait(false); + var result = await sut.GetOwnCredentialDetails("BPNL000000INVALID").ToListAsync(); // Assert result.Should().BeEmpty(); @@ -258,7 +258,7 @@ public async Task CheckCredentialDetailsExistsForCompany_WithExistingData_Return var sut = await CreateSut(); // Act - var result = await sut.CheckSsiDetailsExistsForCompany(ValidBpnl, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, VerifiedCredentialTypeKindId.FRAMEWORK, new Guid("1268a76a-ca19-4dd8-b932-01f24071d560")).ConfigureAwait(false); + var result = await sut.CheckSsiDetailsExistsForCompany(ValidBpnl, VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, VerifiedCredentialTypeKindId.FRAMEWORK, new Guid("1268a76a-ca19-4dd8-b932-01f24071d560")); // Assert result.Should().BeTrue(); @@ -271,7 +271,7 @@ public async Task CheckCredentialDetailsExistsForCompany_WithNotExistingData_Ret var sut = await CreateSut(); // Act - var result = await sut.CheckSsiDetailsExistsForCompany("BPNL000000001TEST", VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, VerifiedCredentialTypeKindId.FRAMEWORK, new Guid("1268a76a-ca19-4dd8-b932-01f24071d560")).ConfigureAwait(false); + var result = await sut.CheckSsiDetailsExistsForCompany("BPNL000000001TEST", VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, VerifiedCredentialTypeKindId.FRAMEWORK, new Guid("1268a76a-ca19-4dd8-b932-01f24071d560")); // Assert result.Should().BeFalse(); @@ -284,7 +284,7 @@ public async Task CheckCredentialDetailsExistsForCompany_WithWrongTypeKindId_Ret var sut = await CreateSut(); // Act - var result = await sut.CheckSsiDetailsExistsForCompany("BPNL000000001TEST", VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, VerifiedCredentialTypeKindId.MEMBERSHIP, new Guid("1268a76a-ca19-4dd8-b932-01f24071d560")).ConfigureAwait(false); + var result = await sut.CheckSsiDetailsExistsForCompany("BPNL000000001TEST", VerifiedCredentialTypeId.TRACEABILITY_FRAMEWORK, VerifiedCredentialTypeKindId.MEMBERSHIP, new Guid("1268a76a-ca19-4dd8-b932-01f24071d560")); // Assert result.Should().BeFalse(); @@ -297,7 +297,7 @@ public async Task CheckCredentialDetailsExistsForCompany_WithInactive_ReturnsFal var sut = await CreateSut(); // Act - var result = await sut.CheckSsiDetailsExistsForCompany(ValidBpnl, VerifiedCredentialTypeId.BEHAVIOR_TWIN_FRAMEWORK, VerifiedCredentialTypeKindId.FRAMEWORK, new Guid("1268a76a-ca19-4dd8-b932-01f24071d562")).ConfigureAwait(false); + var result = await sut.CheckSsiDetailsExistsForCompany(ValidBpnl, VerifiedCredentialTypeId.BEHAVIOR_TWIN_FRAMEWORK, VerifiedCredentialTypeKindId.FRAMEWORK, new Guid("1268a76a-ca19-4dd8-b932-01f24071d562")); // Assert result.Should().BeFalse(); @@ -319,7 +319,7 @@ public async Task CheckUseCaseCredentialAndExternalTypeDetails_WithTypeId_Return var sut = await CreateSut(); // Act - var result = await sut.CheckCredentialTypeIdExistsForExternalTypeDetailVersionId(detailId, typeId).ConfigureAwait(false); + var result = await sut.CheckCredentialTypeIdExistsForExternalTypeDetailVersionId(detailId, typeId); // Assert result.Expiry.Should().Be(expiry); @@ -340,7 +340,7 @@ public async Task CheckSsiCertificateType_WithTypeId_ReturnsTrue(VerifiedCredent var sut = await CreateSut(); // Act - var result = await sut.CheckSsiCertificateType(typeId).ConfigureAwait(false); + var result = await sut.CheckSsiCertificateType(typeId); // Assert result.Exists.Should().Be(expectedResult); @@ -357,7 +357,7 @@ public async Task GetSsiApprovalData_WithValidData_ReturnsExpected() var sut = await CreateSut(); // Act - var result = await sut.GetSsiApprovalData(new("9f5b9934-4014-4099-91e9-7b1aee696b03")).ConfigureAwait(false); + var result = await sut.GetSsiApprovalData(new("9f5b9934-4014-4099-91e9-7b1aee696b03")); // Assert result.exists.Should().BeTrue(); @@ -373,7 +373,7 @@ public async Task GetSsiApprovalData_WithNotExisting_ReturnsExpected() var sut = await CreateSut(); // Act - var result = await sut.GetSsiApprovalData(Guid.NewGuid()).ConfigureAwait(false); + var result = await sut.GetSsiApprovalData(Guid.NewGuid()); // Assert result.exists.Should().BeFalse(); @@ -390,7 +390,7 @@ public async Task GetSsiRejectionData_WithValidData_ReturnsExpected() var sut = await CreateSut(); // Act - var result = await sut.GetSsiRejectionData(new("9f5b9934-4014-4099-91e9-7b1aee696b03")).ConfigureAwait(false); + var result = await sut.GetSsiRejectionData(new("9f5b9934-4014-4099-91e9-7b1aee696b03")); // Assert result.Exists.Should().BeTrue(); @@ -405,7 +405,7 @@ public async Task GetSsiRejectionData_WithNotExisting_ReturnsExpected() var sut = await CreateSut(); // Act - var result = await sut.GetSsiRejectionData(Guid.NewGuid()).ConfigureAwait(false); + var result = await sut.GetSsiRejectionData(Guid.NewGuid()); // Assert result.Should().Be(default); @@ -471,7 +471,7 @@ public async Task GetCertificateTypes_ReturnsExpected() var sut = await CreateSut(); // Act - var result = await sut.GetCertificateTypes(ValidBpnl).ToListAsync().ConfigureAwait(false); + var result = await sut.GetCertificateTypes(ValidBpnl).ToListAsync(); // Assert result.Should().ContainSingle().Which.Should().Be(VerifiedCredentialTypeId.BUSINESS_PARTNER_NUMBER); @@ -484,7 +484,7 @@ public async Task GetCertificateTypes_WithoutCertificate_ReturnsExpected() var sut = await CreateSut(); // Act - var result = await sut.GetCertificateTypes("BPNL0000001TEST").ToListAsync().ConfigureAwait(false); + var result = await sut.GetCertificateTypes("BPNL0000001TEST").ToListAsync(); // Assert result.Should().HaveCount(2).And.Satisfy( @@ -506,7 +506,7 @@ public async Task GetExpiryData_ReturnsExpected() var sut = await CreateSut(); // Act - var result = await sut.GetExpiryData(now, inactiveVcsToDelete, expiredVcsToDelete).ToListAsync().ConfigureAwait(false); + var result = await sut.GetExpiryData(now, inactiveVcsToDelete, expiredVcsToDelete).ToListAsync(); // Assert result.Should().HaveCount(6); @@ -616,13 +616,13 @@ public async Task AttachAndModifyProcessData_WithNoChanges_ReturnsExpected() private async Task CreateSut() { - var context = await _dbTestDbFixture.GetDbContext().ConfigureAwait(false); + var context = await _dbTestDbFixture.GetDbContext(); return new CompanySsiDetailsRepository(context); } private async Task<(CompanySsiDetailsRepository sut, IssuerDbContext context)> CreateSutWithContext() { - var context = await _dbTestDbFixture.GetDbContext().ConfigureAwait(false); + var context = await _dbTestDbFixture.GetDbContext(); return (new CompanySsiDetailsRepository(context), context); } diff --git a/tests/database/SsiCredentialIssuer.DbAccess.Tests/CredentialRepositoryTests.cs b/tests/database/SsiCredentialIssuer.DbAccess.Tests/CredentialRepositoryTests.cs index a306588a..6d80e5a4 100644 --- a/tests/database/SsiCredentialIssuer.DbAccess.Tests/CredentialRepositoryTests.cs +++ b/tests/database/SsiCredentialIssuer.DbAccess.Tests/CredentialRepositoryTests.cs @@ -54,7 +54,7 @@ public CredentialRepositoryTests(TestDbFixture testDbFixture) public async Task GetDataForProcessId_ReturnsExpectedDocument() { // Arrange - var sut = await CreateSut().ConfigureAwait(false); + var sut = await CreateSut(); // Act var result = await sut.GetDataForProcessId(new Guid("dd371565-9489-4907-a2e4-b8cbfe7a8cd2")); @@ -72,7 +72,7 @@ public async Task GetDataForProcessId_ReturnsExpectedDocument() public async Task GetCredentialData_ReturnsExpectedDocument() { // Arrange - var sut = await CreateSut().ConfigureAwait(false); + var sut = await CreateSut(); // Act var result = await sut.GetCredentialData(new Guid("9f5b9934-4014-4099-91e9-7b1aee696b03")); @@ -91,7 +91,7 @@ public async Task GetCredentialData_ReturnsExpectedDocument() public async Task GetWalletCredentialId_ReturnsExpectedDocument() { // Arrange - var sut = await CreateSut().ConfigureAwait(false); + var sut = await CreateSut(); // Act var result = await sut.GetWalletCredentialId(new Guid("9f5b9934-4014-4099-91e9-7b1aee696b03")); @@ -108,7 +108,7 @@ public async Task GetWalletCredentialId_ReturnsExpectedDocument() public async Task GetCredentialStorageInformationById_ReturnsExpectedDocument() { // Arrange - var sut = await CreateSut().ConfigureAwait(false); + var sut = await CreateSut(); // Act var result = await sut.GetCredentialStorageInformationById(new Guid("9f5b9934-4014-4099-91e9-7b1aee696b03")); @@ -126,7 +126,7 @@ public async Task GetCredentialStorageInformationById_ReturnsExpectedDocument() public async Task GetExternalCredentialAndKindId_ReturnsExpectedDocument() { // Arrange - var sut = await CreateSut().ConfigureAwait(false); + var sut = await CreateSut(); // Act var result = await sut.GetExternalCredentialAndKindId(new Guid("9f5b9934-4014-4099-91e9-7b1aee696b03")); @@ -144,7 +144,7 @@ public async Task GetExternalCredentialAndKindId_ReturnsExpectedDocument() public async Task AttachAndModifyCredential_ReturnsExpectedResult() { // Arrange - var (sut, context) = await CreateSutWithContext().ConfigureAwait(false); + var (sut, context) = await CreateSutWithContext(); // Act sut.AttachAndModifyCredential(Guid.NewGuid(), x => x.CompanySsiDetailStatusId = CompanySsiDetailStatusId.ACTIVE, x => x.CompanySsiDetailStatusId = CompanySsiDetailStatusId.PENDING); @@ -165,14 +165,14 @@ public async Task AttachAndModifyCredential_ReturnsExpectedResult() private async Task CreateSut() { - var context = await _dbTestDbFixture.GetDbContext().ConfigureAwait(false); + var context = await _dbTestDbFixture.GetDbContext(); var sut = new CredentialRepository(context); return sut; } private async Task<(CredentialRepository Sut, IssuerDbContext Context)> CreateSutWithContext() { - var context = await _dbTestDbFixture.GetDbContext().ConfigureAwait(false); + var context = await _dbTestDbFixture.GetDbContext(); var sut = new CredentialRepository(context); return (sut, context); } diff --git a/tests/database/SsiCredentialIssuer.DbAccess.Tests/DocumentRepositoryTests.cs b/tests/database/SsiCredentialIssuer.DbAccess.Tests/DocumentRepositoryTests.cs index a33be766..06a43755 100644 --- a/tests/database/SsiCredentialIssuer.DbAccess.Tests/DocumentRepositoryTests.cs +++ b/tests/database/SsiCredentialIssuer.DbAccess.Tests/DocumentRepositoryTests.cs @@ -55,7 +55,7 @@ public DocumentRepositoryTests(TestDbFixture testDbFixture) public async Task CreateDocument_ReturnsExpectedDocument() { // Arrange - var (sut, context) = await CreateSut().ConfigureAwait(false); + var (sut, context) = await CreateSut(); var test = "This is just test content"; var content = Encoding.UTF8.GetBytes(test); @@ -85,7 +85,7 @@ public async Task CreateDocument_ReturnsExpectedDocument() public async Task AssignDocumentToCompanySsiDetails_ReturnsExpectedDocument() { // Arrange - var (sut, context) = await CreateSut().ConfigureAwait(false); + var (sut, context) = await CreateSut(); var companySsiDetailId = Guid.NewGuid(); var documentId = Guid.NewGuid(); @@ -110,7 +110,7 @@ public async Task AssignDocumentToCompanySsiDetails_ReturnsExpectedDocument() public async Task AttachAndModifyDocuments_ReturnsExpectedResult() { // Arrange - var (sut, context) = await CreateSut().ConfigureAwait(false); + var (sut, context) = await CreateSut(); var documentData = new (Guid DocumentId, Action?, Action)[] { (Guid.NewGuid(), null, document => document.DocumentStatusId = DocumentStatusId.INACTIVE), @@ -138,7 +138,7 @@ public async Task AttachAndModifyDocuments_ReturnsExpectedResult() private async Task<(DocumentRepository, IssuerDbContext)> CreateSut() { - var context = await _dbTestDbFixture.GetDbContext().ConfigureAwait(false); + var context = await _dbTestDbFixture.GetDbContext(); var sut = new DocumentRepository(context); return (sut, context); } diff --git a/tests/database/SsiCredentialIssuer.DbAccess.Tests/IssuerDbContextTests.cs b/tests/database/SsiCredentialIssuer.DbAccess.Tests/IssuerDbContextTests.cs index 502354e9..0acb8021 100644 --- a/tests/database/SsiCredentialIssuer.DbAccess.Tests/IssuerDbContextTests.cs +++ b/tests/database/SsiCredentialIssuer.DbAccess.Tests/IssuerDbContextTests.cs @@ -63,12 +63,12 @@ public async Task SaveCreatedAuditableEntity_SetsLastEditorId() var id = Guid.NewGuid(); var ca = new CompanySsiDetail(id, "BPNL00000001TEST", VerifiedCredentialTypeId.BUSINESS_PARTNER_NUMBER, CompanySsiDetailStatusId.ACTIVE, "BPNL0001ISSUER", "ac1cf001-7fbc-1f2f-817f-bce058020001", before); - var sut = await CreateContext().ConfigureAwait(false); - using var trans = await sut.Database.BeginTransactionAsync().ConfigureAwait(false); + var sut = await CreateContext(); + using var trans = await sut.Database.BeginTransactionAsync(); // Act sut.Add(ca); - await sut.SaveChangesAsync().ConfigureAwait(false); + await sut.SaveChangesAsync(); // Assert ca.LastEditorId.Should().NotBeNull().And.Be("ac1cf001-7fbc-1f2f-817f-bce058020001"); @@ -76,7 +76,7 @@ public async Task SaveCreatedAuditableEntity_SetsLastEditorId() var auditEntries = await sut.AuditCompanySsiDetail20240419.Where(x => x.Id == id).ToListAsync(); auditEntries.Should().ContainSingle().Which.Should().Match( x => x.CompanySsiDetailStatusId == CompanySsiDetailStatusId.ACTIVE && (x.DateCreated - before) < TimeSpan.FromSeconds(1) && x.AuditV2OperationId == AuditOperationId.INSERT && (x.AuditV2DateLastChanged - now) < TimeSpan.FromSeconds(1) && x.LastEditorId == "ac1cf001-7fbc-1f2f-817f-bce058020001"); - await trans.RollbackAsync().ConfigureAwait(false); + await trans.RollbackAsync(); } [Fact] @@ -91,14 +91,14 @@ public async Task SaveDeletedAuditableEntity_SetsLastEditorId() var id = Guid.NewGuid(); var ca = new CompanySsiDetail(id, "BPNL00000001TEST", VerifiedCredentialTypeId.BUSINESS_PARTNER_NUMBER, CompanySsiDetailStatusId.ACTIVE, "BPNL0001ISSUER", "ac1cf001-7fbc-1f2f-817f-bce058020001", before); - var sut = await CreateContext().ConfigureAwait(false); - using var trans = await sut.Database.BeginTransactionAsync().ConfigureAwait(false); + var sut = await CreateContext(); + using var trans = await sut.Database.BeginTransactionAsync(); // Act sut.Add(ca); - await sut.SaveChangesAsync().ConfigureAwait(false); + await sut.SaveChangesAsync(); sut.Remove(ca); - await sut.SaveChangesAsync().ConfigureAwait(false); + await sut.SaveChangesAsync(); // Assert ca.LastEditorId.Should().NotBeNull().And.Be("ac1cf001-7fbc-1f2f-817f-bce058020001"); @@ -107,11 +107,11 @@ public async Task SaveDeletedAuditableEntity_SetsLastEditorId() auditEntries.Should().HaveCount(2).And.Satisfy( x => x.CompanySsiDetailStatusId == CompanySsiDetailStatusId.ACTIVE && (x.DateCreated - before) < TimeSpan.FromSeconds(1) && x.AuditV2OperationId == AuditOperationId.INSERT && x.LastEditorId == "ac1cf001-7fbc-1f2f-817f-bce058020001", x => x.CompanySsiDetailStatusId == CompanySsiDetailStatusId.ACTIVE && (x.DateCreated - before) < TimeSpan.FromSeconds(1) && x.AuditV2OperationId == AuditOperationId.DELETE && (x.AuditV2DateLastChanged - later) < TimeSpan.FromSeconds(1) && x.LastEditorId == "ac1cf001-7fbc-1f2f-817f-bce058020001"); - await trans.RollbackAsync().ConfigureAwait(false); + await trans.RollbackAsync(); } #endregion private async Task CreateContext() => - await _dbTestDbFixture.GetDbContext(_dateTimeProvider).ConfigureAwait(false); + await _dbTestDbFixture.GetDbContext(_dateTimeProvider); } diff --git a/tests/database/SsiCredentialIssuer.DbAccess.Tests/IssuerRepositoriesTests.cs b/tests/database/SsiCredentialIssuer.DbAccess.Tests/IssuerRepositoriesTests.cs index f836deaf..a2e3a7da 100644 --- a/tests/database/SsiCredentialIssuer.DbAccess.Tests/IssuerRepositoriesTests.cs +++ b/tests/database/SsiCredentialIssuer.DbAccess.Tests/IssuerRepositoriesTests.cs @@ -53,7 +53,7 @@ public IssuerRepositoriesTests(TestDbFixture testDbFixture) public async Task GetInstance_CompanySsiDetails_CreatesSuccessfully() { // Arrange - var sut = await CreateSut().ConfigureAwait(false); + var sut = await CreateSut(); // Act var result = sut.GetInstance(); @@ -66,7 +66,7 @@ public async Task GetInstance_CompanySsiDetails_CreatesSuccessfully() public async Task GetInstance_Credential_CreatesSuccessfully() { // Arrange - var sut = await CreateSut().ConfigureAwait(false); + var sut = await CreateSut(); // Act var result = sut.GetInstance(); @@ -79,7 +79,7 @@ public async Task GetInstance_Credential_CreatesSuccessfully() public async Task GetInstance_DocumentRepo_CreatesSuccessfully() { // Arrange - var sut = await CreateSut().ConfigureAwait(false); + var sut = await CreateSut(); // Act var result = sut.GetInstance(); @@ -92,7 +92,7 @@ public async Task GetInstance_DocumentRepo_CreatesSuccessfully() public async Task GetInstance_ProcessStep_CreatesSuccessfully() { // Arrange - var sut = await CreateSut().ConfigureAwait(false); + var sut = await CreateSut(); // Act var result = sut.GetInstance(); @@ -109,7 +109,7 @@ public async Task GetInstance_ProcessStep_CreatesSuccessfully() public async Task Clear_CreateSuccessfully() { // Arrange - var (sut, dbContext) = await CreateSutWithContext().ConfigureAwait(false); + var (sut, dbContext) = await CreateSutWithContext(); var changeTracker = dbContext.ChangeTracker; dbContext.Processes.Add(new Process(Guid.NewGuid(), ProcessTypeId.CREATE_CREDENTIAL, Guid.NewGuid())); @@ -129,7 +129,7 @@ public async Task Clear_CreateSuccessfully() public async Task Attach_CreateSuccessfully() { // Arrange - var (sut, dbContext) = await CreateSutWithContext().ConfigureAwait(false); + var (sut, dbContext) = await CreateSutWithContext(); var changeTracker = dbContext.ChangeTracker; var now = DateTimeOffset.Now; @@ -153,14 +153,14 @@ public async Task Attach_CreateSuccessfully() private async Task<(IssuerRepositories sut, IssuerDbContext dbContext)> CreateSutWithContext() { - var context = await _dbTestDbFixture.GetDbContext().ConfigureAwait(false); + var context = await _dbTestDbFixture.GetDbContext(); var sut = new IssuerRepositories(context); return (sut, context); } private async Task CreateSut() { - var context = await _dbTestDbFixture.GetDbContext().ConfigureAwait(false); + var context = await _dbTestDbFixture.GetDbContext(); var sut = new IssuerRepositories(context); return sut; } diff --git a/tests/database/SsiCredentialIssuer.DbAccess.Tests/ProcessStepRepositoryTests.cs b/tests/database/SsiCredentialIssuer.DbAccess.Tests/ProcessStepRepositoryTests.cs index e7c6d62c..f8bf2b26 100644 --- a/tests/database/SsiCredentialIssuer.DbAccess.Tests/ProcessStepRepositoryTests.cs +++ b/tests/database/SsiCredentialIssuer.DbAccess.Tests/ProcessStepRepositoryTests.cs @@ -53,7 +53,7 @@ public ProcessStepRepositoryTests(TestDbFixture testDbFixture) public async Task CreateProcess_CreatesSuccessfully() { // Arrange - var (sut, dbContext) = await CreateSutWithContext().ConfigureAwait(false); + var (sut, dbContext) = await CreateSutWithContext(); var changeTracker = dbContext.ChangeTracker; // Act @@ -84,7 +84,7 @@ public async Task CreateProcessStepRange_CreateSuccessfully() // Arrange var processId = Guid.NewGuid(); var processStepTypeIds = _fixture.CreateMany(3).ToImmutableArray(); - var (sut, dbContext) = await CreateSutWithContext().ConfigureAwait(false); + var (sut, dbContext) = await CreateSutWithContext(); var changeTracker = dbContext.ChangeTracker; // Act @@ -116,7 +116,7 @@ public async Task CreateProcessStep_CreateSuccessfully() { // Arrange var processId = Guid.NewGuid(); - var (sut, dbContext) = await CreateSutWithContext().ConfigureAwait(false); + var (sut, dbContext) = await CreateSutWithContext(); var changeTracker = dbContext.ChangeTracker; // Act @@ -141,7 +141,7 @@ public async Task CreateProcessStep_CreateSuccessfully() public async Task AttachAndModifyProcessStep_WithExistingProcessStep_UpdatesStatus() { // Arrange - var (sut, dbContext) = await CreateSutWithContext().ConfigureAwait(false); + var (sut, dbContext) = await CreateSutWithContext(); // Act sut.AttachAndModifyProcessStep(new Guid("48f35f84-8d98-4fbd-ba80-8cbce5eeadb5"), @@ -176,7 +176,7 @@ public async Task AttachAndModifyProcessSteps_UpdatesStatus() // Arrange var stepData = _fixture.CreateMany<(Guid ProcessStepId, ProcessStep InitialStep, ProcessStep ModifiedStep)>(5).ToImmutableArray(); - var (sut, dbContext) = await CreateSutWithContext().ConfigureAwait(false); + var (sut, dbContext) = await CreateSutWithContext(); // Act sut.AttachAndModifyProcessSteps(stepData.Select(data => new ValueTuple?, Action>( @@ -214,7 +214,7 @@ public async Task AttachAndModifyProcessSteps_WithUnmodifiedData_SkipsUpdateStat // Arrange var stepData = _fixture.CreateMany<(Guid ProcessStepId, ProcessStep InitialStep)>(5).ToImmutableArray(); - var (sut, dbContext) = await CreateSutWithContext().ConfigureAwait(false); + var (sut, dbContext) = await CreateSutWithContext(); // Act sut.AttachAndModifyProcessSteps(stepData.Select(data => new ValueTuple?, Action>( @@ -250,7 +250,7 @@ public async Task AttachAndModifyProcessSteps_WithUnmodifiedData_UpdatesLastChan // Arrange var stepData = _fixture.CreateMany<(Guid ProcessStepId, ProcessStep InitialStep)>(5).ToImmutableArray(); - var (sut, dbContext) = await CreateSutWithContext().ConfigureAwait(false); + var (sut, dbContext) = await CreateSutWithContext(); // Act sut.AttachAndModifyProcessSteps(stepData.Select(data => new ValueTuple?, Action>( @@ -293,10 +293,10 @@ public async Task GetActiveProcess_LockExpired_ReturnsExpected() ProcessStepTypeId.CREATE_CREDENTIAL_FOR_HOLDER, }; - var sut = await CreateSut().ConfigureAwait(false); + var sut = await CreateSut(); // Act - var result = await sut.GetActiveProcesses(processTypeIds, processStepTypeIds, DateTimeOffset.Parse("2023-03-02 00:00:00.000000 +00:00")).ToListAsync().ConfigureAwait(false); + var result = await sut.GetActiveProcesses(processTypeIds, processStepTypeIds, DateTimeOffset.Parse("2023-03-02 00:00:00.000000 +00:00")).ToListAsync(); result.Should().HaveCount(1) .And.Satisfy( x => x.Id == new Guid("dd371565-9489-4907-a2e4-b8cbfe7a8cd2") && x.ProcessTypeId == ProcessTypeId.CREATE_CREDENTIAL && x.LockExpiryDate == DateTimeOffset.Parse("2023-03-01 00:00:00.000000 +00:00") @@ -315,10 +315,10 @@ public async Task GetActiveProcess_Locked_ReturnsExpected() ProcessStepTypeId.CREATE_CREDENTIAL_FOR_HOLDER, }; - var sut = await CreateSut().ConfigureAwait(false); + var sut = await CreateSut(); // Act - var result = await sut.GetActiveProcesses(processTypeIds, processStepTypeIds, DateTimeOffset.Parse("2023-02-28 00:00:00.000000 +00:00")).ToListAsync().ConfigureAwait(false); + var result = await sut.GetActiveProcesses(processTypeIds, processStepTypeIds, DateTimeOffset.Parse("2023-02-28 00:00:00.000000 +00:00")).ToListAsync(); result.Should().BeEmpty(); } @@ -331,10 +331,10 @@ public async Task GetProcessStepData_ReturnsExpected() { // Arrange var processId = new Guid("dd371565-9489-4907-a2e4-b8cbfe7a8cd2"); - var sut = await CreateSut().ConfigureAwait(false); + var sut = await CreateSut(); // Act - var result = await sut.GetProcessStepData(processId).ToListAsync().ConfigureAwait(false); + var result = await sut.GetProcessStepData(processId).ToListAsync(); result.Should().HaveCount(1) .And.Satisfy( x => x.ProcessStepId == new Guid("cd231cb8-55de-4ae4-b93f-d440512341fb") && x.ProcessStepTypeId == ProcessStepTypeId.SAVE_CREDENTIAL_DOCUMENT @@ -345,14 +345,14 @@ public async Task GetProcessStepData_ReturnsExpected() private async Task<(ProcessStepRepository sut, IssuerDbContext dbContext)> CreateSutWithContext() { - var context = await _dbTestDbFixture.GetDbContext().ConfigureAwait(false); + var context = await _dbTestDbFixture.GetDbContext(); var sut = new ProcessStepRepository(context); return (sut, context); } private async Task CreateSut() { - var context = await _dbTestDbFixture.GetDbContext().ConfigureAwait(false); + var context = await _dbTestDbFixture.GetDbContext(); var sut = new ProcessStepRepository(context); return sut; } diff --git a/tests/database/SsiCredentialIssuer.DbAccess.Tests/Setup/TestDbFixture.cs b/tests/database/SsiCredentialIssuer.DbAccess.Tests/Setup/TestDbFixture.cs index 9095640a..cbd762c9 100644 --- a/tests/database/SsiCredentialIssuer.DbAccess.Tests/Setup/TestDbFixture.cs +++ b/tests/database/SsiCredentialIssuer.DbAccess.Tests/Setup/TestDbFixture.cs @@ -62,13 +62,13 @@ public async Task GetDbContext(IDateTimeProvider? dateTimeProvi .MigrationsHistoryTable("__efmigrations_history_issuer") ); var context = new IssuerDbContext(optionsBuilder.Options, new AuditHandlerV2(new FakeIdentityIdService(), dateTimeProvider ?? new UtcDateTimeProvider())); - await context.Database.EnsureCreatedAsync().ConfigureAwait(false); + await context.Database.EnsureCreatedAsync(); foreach (var seedAction in seedActions) { seedAction.Invoke(context); } - await context.SaveChangesAsync().ConfigureAwait(false); + await context.SaveChangesAsync(); return context; } @@ -78,7 +78,7 @@ public async Task GetDbContext(IDateTimeProvider? dateTimeProvi public async Task InitializeAsync() { await _container.StartAsync() - .ConfigureAwait(false); + ; var optionsBuilder = new DbContextOptionsBuilder(); @@ -109,6 +109,6 @@ await _container.StartAsync() public async Task DisposeAsync() { await _container.DisposeAsync() - .ConfigureAwait(false); + ; } } diff --git a/tests/database/SsiCredentialIssuer.DbAccess.Tests/SsiCredentialIssuer.DbAccess.Tests.csproj b/tests/database/SsiCredentialIssuer.DbAccess.Tests/SsiCredentialIssuer.DbAccess.Tests.csproj index 9a600cc4..d6fb2580 100644 --- a/tests/database/SsiCredentialIssuer.DbAccess.Tests/SsiCredentialIssuer.DbAccess.Tests.csproj +++ b/tests/database/SsiCredentialIssuer.DbAccess.Tests/SsiCredentialIssuer.DbAccess.Tests.csproj @@ -21,21 +21,20 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.DbAccess.Tests Org.Eclipse.TractusX.SsiCredentialIssuer.DbAccess.Tests - net7.0 + net8.0 enable enable false - - + + - - + @@ -43,10 +42,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - diff --git a/tests/externalservices/Callback.Service.Tests/Callback.Service.Tests.csproj b/tests/externalservices/Callback.Service.Tests/Callback.Service.Tests.csproj index 793659a7..d29387e0 100644 --- a/tests/externalservices/Callback.Service.Tests/Callback.Service.Tests.csproj +++ b/tests/externalservices/Callback.Service.Tests/Callback.Service.Tests.csproj @@ -21,7 +21,7 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Callback.Service.Tests Org.Eclipse.TractusX.SsiCredentialIssuer.Callback.Service.Tests - net7.0 + net8.0 enable enable false @@ -32,9 +32,8 @@ - - - + + @@ -46,10 +45,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - diff --git a/tests/externalservices/Callback.Service.Tests/CallbackServiceTests.cs b/tests/externalservices/Callback.Service.Tests/CallbackServiceTests.cs index a4f2f5de..2630a15e 100644 --- a/tests/externalservices/Callback.Service.Tests/CallbackServiceTests.cs +++ b/tests/externalservices/Callback.Service.Tests/CallbackServiceTests.cs @@ -78,7 +78,7 @@ public async Task TriggerCallback_WithValid_DoesNotThrowException() var sut = _fixture.Create(); // Act - await sut.TriggerCallback("/callback", data, CancellationToken.None).ConfigureAwait(false); + await sut.TriggerCallback("/callback", data, CancellationToken.None); // Assert request.Should().NotBeNull(); @@ -101,7 +101,7 @@ public async Task TriggerCallback_WithConflict_ThrowsServiceExceptionWithErrorCo httpClient.BaseAddress = new Uri("https://base.address.com"); A.CallTo(() => _tokenService.GetAuthorizedClient(_options.Value, A._)).Returns(httpClient); var sut = new CallbackService(_tokenService, _options); - async Task Act() => await sut.TriggerCallback("https://example.org/callback", _fixture.Create(), CancellationToken.None).ConfigureAwait(false); + async Task Act() => await sut.TriggerCallback("https://example.org/callback", _fixture.Create(), CancellationToken.None); // Act var ex = await Assert.ThrowsAsync(Act); diff --git a/tests/externalservices/Portal.Service.Tests/Portal.Service.Tests.csproj b/tests/externalservices/Portal.Service.Tests/Portal.Service.Tests.csproj index aea8d179..604a2a6c 100644 --- a/tests/externalservices/Portal.Service.Tests/Portal.Service.Tests.csproj +++ b/tests/externalservices/Portal.Service.Tests/Portal.Service.Tests.csproj @@ -21,7 +21,7 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Portal.Service.Tests Org.Eclipse.TractusX.SsiCredentialIssuer.Portal.Service.Tests - net7.0 + net8.0 enable enable false @@ -32,9 +32,8 @@ - - - + + @@ -46,10 +45,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - diff --git a/tests/externalservices/Portal.Service.Tests/PortalServiceTests.cs b/tests/externalservices/Portal.Service.Tests/PortalServiceTests.cs index 9e5ff4a4..6a1623eb 100644 --- a/tests/externalservices/Portal.Service.Tests/PortalServiceTests.cs +++ b/tests/externalservices/Portal.Service.Tests/PortalServiceTests.cs @@ -80,7 +80,7 @@ public async Task AddNotification_WithValid_DoesNotThrowException() var sut = new PortalService(_tokenService, _options); // Act - await sut.AddNotification("Test", requester, NotificationTypeId.CREDENTIAL_APPROVAL, CancellationToken.None).ConfigureAwait(false); + await sut.AddNotification("Test", requester, NotificationTypeId.CREDENTIAL_APPROVAL, CancellationToken.None); // Assert httpMessageHandlerMock.RequestMessage.Should().Match(x => @@ -110,7 +110,7 @@ public async Task AddNotification_WithConflict_ThrowsServiceExceptionWithErrorCo var sut = new PortalService(_tokenService, _options); // Act - async Task Act() => await sut.AddNotification("Test", requester, NotificationTypeId.CREDENTIAL_APPROVAL, CancellationToken.None).ConfigureAwait(false); + async Task Act() => await sut.AddNotification("Test", requester, NotificationTypeId.CREDENTIAL_APPROVAL, CancellationToken.None); // Assert var ex = await Assert.ThrowsAsync(Act); @@ -136,7 +136,7 @@ public async Task TriggerMail_WithValid_DoesNotThrowException() var sut = new PortalService(_tokenService, _options); // Act - await sut.TriggerMail("Test", requesterId, Enumerable.Empty(), CancellationToken.None).ConfigureAwait(false); + await sut.TriggerMail("Test", requesterId, Enumerable.Empty(), CancellationToken.None); // Assert httpMessageHandlerMock.RequestMessage.Should().Match(x => @@ -165,7 +165,7 @@ public async Task TriggerMail_WithConflict_ThrowsServiceExceptionWithErrorConten var sut = new PortalService(_tokenService, _options); // Act - async Task Act() => await sut.TriggerMail("Test", requesterId, Enumerable.Empty(), CancellationToken.None).ConfigureAwait(false); + async Task Act() => await sut.TriggerMail("Test", requesterId, Enumerable.Empty(), CancellationToken.None); // Assert var ex = await Assert.ThrowsAsync(Act); diff --git a/tests/externalservices/Wallet.Service.Tests/BusinessLogic/WalletBusinessLogicTests.cs b/tests/externalservices/Wallet.Service.Tests/BusinessLogic/WalletBusinessLogicTests.cs index f6a03d27..b29766be 100644 --- a/tests/externalservices/Wallet.Service.Tests/BusinessLogic/WalletBusinessLogicTests.cs +++ b/tests/externalservices/Wallet.Service.Tests/BusinessLogic/WalletBusinessLogicTests.cs @@ -85,7 +85,7 @@ public async Task CreateCredential_CallsExpected() .Returns(externalId); // Act - await _sut.CreateCredential(id, schema, CancellationToken.None).ConfigureAwait(false); + await _sut.CreateCredential(id, schema, CancellationToken.None); // Assert A.CallTo(() => _companySsiDetailRepository.AttachAndModifyCompanySsiDetails(id, A>._, A>._)) @@ -116,7 +116,7 @@ public async Task SignCredential_CallsExpected() .Returns("cred"); // Act - await _sut.SignCredential(id, credentialId, CancellationToken.None).ConfigureAwait(false); + await _sut.SignCredential(id, credentialId, CancellationToken.None); // Assert A.CallTo(() => _companySsiDetailRepository.AttachAndModifyCompanySsiDetails(id, A>._, A>._)) @@ -145,7 +145,7 @@ public async Task CreateCredentialForHolder_CallsExpected() }); // Act - await _sut.CreateCredentialForHolder(id, "https://example.org/wallet", "test1", new EncryptionInformation(secret, vector, 0), "thisisatestsecret", CancellationToken.None).ConfigureAwait(false); + await _sut.CreateCredentialForHolder(id, "https://example.org/wallet", "test1", new EncryptionInformation(secret, vector, 0), "thisisatestsecret", CancellationToken.None); // Assert A.CallTo(() => _companySsiDetailRepository.AttachAndModifyProcessData(id, A>._, A>._)) @@ -199,7 +199,7 @@ public async Task GetCredential_CallsExpected() .Returns(jsonDocument); // Act - await _sut.GetCredential(id, credentialId, VerifiedCredentialTypeKindId.BPN, CancellationToken.None).ConfigureAwait(false); + await _sut.GetCredential(id, credentialId, VerifiedCredentialTypeKindId.BPN, CancellationToken.None); // Assert A.CallTo(() => _documentRepository.CreateDocument(A._, A._, A._, MediaTypeId.JSON, DocumentTypeId.VERIFIED_CREDENTIAL, A>._)) @@ -232,10 +232,10 @@ public async Task GetCredential_WithSchemaNotMatching_CallsExpected() var jsonDocument = JsonDocument.Parse(data); A.CallTo(() => _walletService.GetCredential(credentialId, A._)) .Returns(jsonDocument); - async Task Act() => await _sut.GetCredential(id, credentialId, VerifiedCredentialTypeKindId.BPN, CancellationToken.None).ConfigureAwait(false); + async Task Act() => await _sut.GetCredential(id, credentialId, VerifiedCredentialTypeKindId.BPN, CancellationToken.None); // Act - var ex = await Assert.ThrowsAsync(Act).ConfigureAwait(false); + var ex = await Assert.ThrowsAsync(Act); // Assert ex.Message.Should().Be("Invalid schema for type BPN"); diff --git a/tests/externalservices/Wallet.Service.Tests/Services/BasicAuthTokenServiceTests.cs b/tests/externalservices/Wallet.Service.Tests/Services/BasicAuthTokenServiceTests.cs index 8a72afdd..8082d00e 100644 --- a/tests/externalservices/Wallet.Service.Tests/Services/BasicAuthTokenServiceTests.cs +++ b/tests/externalservices/Wallet.Service.Tests/Services/BasicAuthTokenServiceTests.cs @@ -67,7 +67,7 @@ public async Task GetAuthorizedClient_Success() var sut = new BasicAuthTokenService(_httpClientFactory); - var result = await sut.GetBasicAuthorizedClient(settings, _cancellationToken).ConfigureAwait(false); + var result = await sut.GetBasicAuthorizedClient(settings, _cancellationToken); result.Should().NotBeNull(); result.BaseAddress.Should().Be(_validBaseAddress); @@ -83,7 +83,7 @@ public async Task GetAuthorizedClient_HttpClientThrows_Throws() Task Act() => sut.GetBasicAuthorizedClient(settings, _cancellationToken); - var error = await Assert.ThrowsAsync(Act).ConfigureAwait(false); + var error = await Assert.ThrowsAsync(Act); error.Should().NotBeNull(); error.InnerException.Should().Be(_testException); diff --git a/tests/externalservices/Wallet.Service.Tests/Services/WalletServiceTests.cs b/tests/externalservices/Wallet.Service.Tests/Services/WalletServiceTests.cs index 3ddb3767..08f65963 100644 --- a/tests/externalservices/Wallet.Service.Tests/Services/WalletServiceTests.cs +++ b/tests/externalservices/Wallet.Service.Tests/Services/WalletServiceTests.cs @@ -5,6 +5,7 @@ using Json.More; using Microsoft.Extensions.Options; using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; +using Org.Eclipse.TractusX.Portal.Backend.Framework.Token; using Org.Eclipse.TractusX.SsiCredentialIssuer.Tests.Shared; using Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.DependencyInjection; using Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Models; @@ -60,7 +61,7 @@ public async Task CreateCredential_WithValid_DoesNotThrowException() .Returns(httpClient); // Act - var result = await _sut.CreateCredential(payload, CancellationToken.None).ConfigureAwait(false); + var result = await _sut.CreateCredential(payload, CancellationToken.None); // Assert httpMessageHandlerMock.RequestMessage.Should().Match(x => @@ -90,7 +91,7 @@ public async Task CreateCredential_WithConflict_ThrowsServiceExceptionWithErrorC A.CallTo(() => _basicAuthTokenService.GetBasicAuthorizedClient(_options.Value, A._)).Returns(httpClient); // Act - async Task Act() => await _sut.CreateCredential(payload, CancellationToken.None).ConfigureAwait(false); + async Task Act() => await _sut.CreateCredential(payload, CancellationToken.None); // Assert var ex = await Assert.ThrowsAsync(Act); @@ -118,7 +119,7 @@ public async Task SignCredential_WithValid_DoesNotThrowException() .Returns(httpClient); // Act - var result = await _sut.SignCredential(credentialId, CancellationToken.None).ConfigureAwait(false); + var result = await _sut.SignCredential(credentialId, CancellationToken.None); // Assert httpMessageHandlerMock.RequestMessage.Should().Match(x => @@ -149,7 +150,7 @@ public async Task SignCredential_WithConflict_ThrowsServiceExceptionWithErrorCon A.CallTo(() => _basicAuthTokenService.GetBasicAuthorizedClient(_options.Value, A._)).Returns(httpClient); // Act - async Task Act() => await _sut.SignCredential(credentialId, CancellationToken.None).ConfigureAwait(false); + async Task Act() => await _sut.SignCredential(credentialId, CancellationToken.None); // Assert var ex = await Assert.ThrowsAsync(Act); @@ -181,7 +182,7 @@ public async Task GetCredential_WithValid_DoesNotThrowException() .Returns(httpClient); // Act - var result = await _sut.GetCredential(credentialId, CancellationToken.None).ConfigureAwait(false); + var result = await _sut.GetCredential(credentialId, CancellationToken.None); // Assert result.RootElement.ToJsonString().Should().Be("{\"root\":\"123\"}"); @@ -206,7 +207,7 @@ public async Task GetCredential_WithConflict_ThrowsServiceExceptionWithErrorCont A.CallTo(() => _basicAuthTokenService.GetBasicAuthorizedClient(_options.Value, A._)).Returns(httpClient); // Act - async Task Act() => await _sut.GetCredential(credentialId, CancellationToken.None).ConfigureAwait(false); + async Task Act() => await _sut.GetCredential(credentialId, CancellationToken.None); // Assert var ex = await Assert.ThrowsAsync(Act); @@ -233,7 +234,7 @@ public async Task CreateCredentialForHolder_WithValid_DoesNotThrowException() .Returns(httpClient); // Act - var result = await _sut.CreateCredentialForHolder("https://example.org", "test", "testSec", "testCred", CancellationToken.None).ConfigureAwait(false); + var result = await _sut.CreateCredentialForHolder("https://example.org", "test", "testSec", "testCred", CancellationToken.None); // Assert httpMessageHandlerMock.RequestMessage.Should().Match(x => @@ -262,7 +263,7 @@ public async Task CreateCredentialForHolder_WithConflict_ThrowsServiceExceptionW A.CallTo(() => _basicAuthTokenService.GetBasicAuthorizedClient(A._, A._)).Returns(httpClient); // Act - async Task Act() => await _sut.CreateCredentialForHolder("https://example.org", "test", "testSec", "testCred", CancellationToken.None).ConfigureAwait(false); + async Task Act() => await _sut.CreateCredentialForHolder("https://example.org", "test", "testSec", "testCred", CancellationToken.None); // Assert var ex = await Assert.ThrowsAsync(Act); @@ -289,7 +290,7 @@ public async Task RevokeCredentialForIssuer_WithValid_DoesNotThrowException() .Returns(httpClient); // Act - await _sut.RevokeCredentialForIssuer(Guid.NewGuid(), CancellationToken.None).ConfigureAwait(false); + await _sut.RevokeCredentialForIssuer(Guid.NewGuid(), CancellationToken.None); // Assert httpMessageHandlerMock.RequestMessage.Should().Match(x => @@ -316,7 +317,7 @@ public async Task RevokeCredentialForIssuer_WithConflict_ThrowsServiceExceptionW A.CallTo(() => _basicAuthTokenService.GetBasicAuthorizedClient(A._, A._)).Returns(httpClient); // Act - async Task Act() => await _sut.RevokeCredentialForIssuer(Guid.NewGuid(), CancellationToken.None).ConfigureAwait(false); + async Task Act() => await _sut.RevokeCredentialForIssuer(Guid.NewGuid(), CancellationToken.None); // Assert var ex = await Assert.ThrowsAsync(Act); diff --git a/tests/externalservices/Wallet.Service.Tests/Wallet.Service.Tests.csproj b/tests/externalservices/Wallet.Service.Tests/Wallet.Service.Tests.csproj index 3a7bd735..7bfb851d 100644 --- a/tests/externalservices/Wallet.Service.Tests/Wallet.Service.Tests.csproj +++ b/tests/externalservices/Wallet.Service.Tests/Wallet.Service.Tests.csproj @@ -21,7 +21,7 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Tests Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Tests - net7.0 + net8.0 enable enable false @@ -32,25 +32,20 @@ - - - + + - + runtime; build; native; contentfiles; analyzers; buildtransitive all - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - diff --git a/tests/issuer/SsiCredentialIssuer.Service.Tests/Authentication/KeycloakClaimsTransformationTests.cs b/tests/issuer/SsiCredentialIssuer.Service.Tests/Authentication/KeycloakClaimsTransformationTests.cs index 45a7a059..2e77c475 100644 --- a/tests/issuer/SsiCredentialIssuer.Service.Tests/Authentication/KeycloakClaimsTransformationTests.cs +++ b/tests/issuer/SsiCredentialIssuer.Service.Tests/Authentication/KeycloakClaimsTransformationTests.cs @@ -55,7 +55,7 @@ public async Task TransformAsync_WithoutRoles_ReturnsExpected() var principal = new ClaimsPrincipal(identity); // Act - var result = await _sut.TransformAsync(principal).ConfigureAwait(false); + var result = await _sut.TransformAsync(principal); // Assert result.Claims.Should().ContainSingle() @@ -71,7 +71,7 @@ public async Task TransformAsync_WithRoles_ReturnsExpected() var principal = new ClaimsPrincipal(identity); // Act - var result = await _sut.TransformAsync(principal).ConfigureAwait(false); + var result = await _sut.TransformAsync(principal); // Assert result.Claims.Should().HaveCount(2).And.Satisfy( @@ -88,7 +88,7 @@ public async Task TransformAsync_WithIntRole_ReturnsExpected() var principal = new ClaimsPrincipal(identity); // Act - var result = await _sut.TransformAsync(principal).ConfigureAwait(false); + var result = await _sut.TransformAsync(principal); // Assert result.Claims.Should().ContainSingle() diff --git a/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/IssuerBusinessLogicTests.cs b/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/IssuerBusinessLogicTests.cs index bf29dd44..4ea1bf29 100644 --- a/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/IssuerBusinessLogicTests.cs +++ b/tests/issuer/SsiCredentialIssuer.Service.Tests/BusinessLogic/IssuerBusinessLogicTests.cs @@ -152,7 +152,7 @@ public async Task GetCredentialsForBpn_ReturnsExpected() Setup_GetCredentialsForBpn(); // Act - var result = await _sut.GetCredentialsForBpn().ToListAsync().ConfigureAwait(false); + var result = await _sut.GetCredentialsForBpn().ToListAsync(); // Assert result.Should().HaveCount(5); diff --git a/tests/issuer/SsiCredentialIssuer.Service.Tests/Controllers/IssuerControllerTests.cs b/tests/issuer/SsiCredentialIssuer.Service.Tests/Controllers/IssuerControllerTests.cs index 14dbf20a..6ddd8436 100644 --- a/tests/issuer/SsiCredentialIssuer.Service.Tests/Controllers/IssuerControllerTests.cs +++ b/tests/issuer/SsiCredentialIssuer.Service.Tests/Controllers/IssuerControllerTests.cs @@ -49,7 +49,7 @@ public IssuerControllerTests(IntegrationTestFactory factory) public async Task GetCertificateTypes() { // Act - var types = await _client.GetFromJsonAsync>($"{BaseUrl}/certificateTypes", JsonOptions).ConfigureAwait(false); + var types = await _client.GetFromJsonAsync>($"{BaseUrl}/certificateTypes", JsonOptions); // Assert types.Should().NotBeNull().And.HaveCount(2).And.Satisfy( @@ -66,7 +66,7 @@ public async Task GetCertificateTypes() public async Task CheckSwagger_ReturnsExpected() { // Act - var response = await _client.GetAsync($"{BaseUrl}/swagger/v1/swagger.json").ConfigureAwait(false); + var response = await _client.GetAsync($"{BaseUrl}/swagger/v1/swagger.json"); // Assert response.Should().NotBeNull(); diff --git a/tests/issuer/SsiCredentialIssuer.Service.Tests/Identity/MandatoryIdentityClaimHandlerTests.cs b/tests/issuer/SsiCredentialIssuer.Service.Tests/Identity/MandatoryIdentityClaimHandlerTests.cs index e2f973d4..15d695e6 100644 --- a/tests/issuer/SsiCredentialIssuer.Service.Tests/Identity/MandatoryIdentityClaimHandlerTests.cs +++ b/tests/issuer/SsiCredentialIssuer.Service.Tests/Identity/MandatoryIdentityClaimHandlerTests.cs @@ -57,7 +57,7 @@ public async Task HandleValidRequirement_WithoutUsername_ReturnsExpected() var sut = new MandatoryIdentityClaimHandler(_claimsIdentityDataBuilder, _logger); // Act - await sut.HandleAsync(context).ConfigureAwait(false); + await sut.HandleAsync(context); // Assert context.HasSucceeded.Should().Be(false); @@ -86,7 +86,7 @@ public async Task HandleValidRequirement_WithAllSet_ReturnsExpected() var sut = new MandatoryIdentityClaimHandler(_claimsIdentityDataBuilder, _logger); // Act - await sut.HandleAsync(context).ConfigureAwait(false); + await sut.HandleAsync(context); // Assert context.HasSucceeded.Should().Be(true); diff --git a/tests/issuer/SsiCredentialIssuer.Service.Tests/SsiCredentialIssuer.Service.Tests.csproj b/tests/issuer/SsiCredentialIssuer.Service.Tests/SsiCredentialIssuer.Service.Tests.csproj index 66667769..0e325a16 100644 --- a/tests/issuer/SsiCredentialIssuer.Service.Tests/SsiCredentialIssuer.Service.Tests.csproj +++ b/tests/issuer/SsiCredentialIssuer.Service.Tests/SsiCredentialIssuer.Service.Tests.csproj @@ -21,7 +21,7 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Tests Org.Eclipse.TractusX.SsiCredentialIssuer.Service.Tests - net7.0 + net8.0 enable enable false @@ -32,9 +32,8 @@ - - - + + @@ -46,10 +45,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - diff --git a/tests/processes/CredentialProcess.Library.Tests/CredentialProcess.Library.Tests.csproj b/tests/processes/CredentialProcess.Library.Tests/CredentialProcess.Library.Tests.csproj index 8ac25f57..e4e0c98a 100644 --- a/tests/processes/CredentialProcess.Library.Tests/CredentialProcess.Library.Tests.csproj +++ b/tests/processes/CredentialProcess.Library.Tests/CredentialProcess.Library.Tests.csproj @@ -19,7 +19,7 @@ - net7.0 + net8.0 enable enable false @@ -27,7 +27,8 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.Tests - + + @@ -36,10 +37,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - diff --git a/tests/processes/CredentialProcess.Worker.Tests/CredentialProcess.Worker.Tests.csproj b/tests/processes/CredentialProcess.Worker.Tests/CredentialProcess.Worker.Tests.csproj index 09e4f541..e6bc5f59 100644 --- a/tests/processes/CredentialProcess.Worker.Tests/CredentialProcess.Worker.Tests.csproj +++ b/tests/processes/CredentialProcess.Worker.Tests/CredentialProcess.Worker.Tests.csproj @@ -19,7 +19,7 @@ - net7.0 + net8.0 enable enable false @@ -27,7 +27,8 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Worker.Tests - + + @@ -36,10 +37,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - diff --git a/tests/processes/Processes.Library.Tests/Processes.Library.Tests.csproj b/tests/processes/Processes.Library.Tests/Processes.Library.Tests.csproj index a5652e21..e4619040 100644 --- a/tests/processes/Processes.Library.Tests/Processes.Library.Tests.csproj +++ b/tests/processes/Processes.Library.Tests/Processes.Library.Tests.csproj @@ -19,7 +19,7 @@ - net7.0 + net8.0 enable enable false @@ -27,7 +27,8 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Processes.Library.Tests - + + @@ -36,10 +37,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - diff --git a/tests/processes/Processes.Worker.Library.Tests/ProcessExecutorTests.cs b/tests/processes/Processes.Worker.Library.Tests/ProcessExecutorTests.cs index a9806209..37b82674 100644 --- a/tests/processes/Processes.Worker.Library.Tests/ProcessExecutorTests.cs +++ b/tests/processes/Processes.Worker.Library.Tests/ProcessExecutorTests.cs @@ -80,10 +80,10 @@ public void GetRegisteredProcessTypeIds_ReturnsExpected() public async Task ExecuteProcess_WithInvalidProcessTypeId_Throws() { // Arrange - var Act = async () => await _sut.ExecuteProcess(Guid.NewGuid(), (ProcessTypeId)default, CancellationToken.None).ToListAsync().ConfigureAwait(false); + var Act = async () => await _sut.ExecuteProcess(Guid.NewGuid(), (ProcessTypeId)default, CancellationToken.None).ToListAsync(); // Act - var result = await Assert.ThrowsAsync(Act).ConfigureAwait(false); + var result = await Assert.ThrowsAsync(Act); // Assert result.Message.Should().Be($"processType {(ProcessTypeId)default} is not a registered executable processType."); @@ -170,7 +170,7 @@ public async Task ExecuteProcess_WithInitialSteps_ReturnsExpected(ProcessStepSta }); // Act - var result = await _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ToListAsync().ConfigureAwait(false); + var result = await _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ToListAsync(); // Assert result.Should().HaveSameCount(executionResults).And.ContainInOrder(executionResults); @@ -269,7 +269,7 @@ public async Task ExecuteProcess_NoScheduleOrSkippedSteps_ReturnsExpected(Proces }); // Act - var result = await _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ToListAsync().ConfigureAwait(false); + var result = await _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ToListAsync(); // Assert result.Should().HaveSameCount(executionResults).And.ContainInOrder(executionResults); @@ -313,7 +313,7 @@ public async Task ExecuteProcess_NoExecutableSteps_ReturnsExpected() .Returns(new IProcessTypeExecutor.InitializationResult(false, null)); // Act - var result = await _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ToListAsync().ConfigureAwait(false); + var result = await _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ToListAsync(); // Assert result.Should().HaveCount(1).And.Contain(IProcessExecutor.ProcessExecutionResult.Unmodified); @@ -381,7 +381,7 @@ public async Task ExecuteProcess_NoScheduleOrSkippedSteps_SingleStepTypeWithDupl }); // Act - var result = await _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ToListAsync().ConfigureAwait(false); + var result = await _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ToListAsync(); // Assert result.Should().HaveSameCount(executionResults).And.ContainInOrder(executionResults); @@ -497,7 +497,7 @@ public async Task ExecuteProcess_WithScheduledSteps_ReturnsExpected(ProcessStepS }); // Act - var result = await _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ToListAsync().ConfigureAwait(false); + var result = await _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ToListAsync(); // Assert result. @@ -605,7 +605,7 @@ public async Task ExecuteProcess_WithDuplicateScheduledSteps_ReturnsExpected(Pro }); // Act - var result = await _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ToListAsync().ConfigureAwait(false); + var result = await _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ToListAsync(); result.Should().HaveSameCount(executionResults).And.ContainInOrder(executionResults); @@ -694,7 +694,7 @@ public async Task ExecuteProcess_WithSkippedSteps_ReturnsExpected(ProcessStepSta }); // Act - var result = await _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ToListAsync().ConfigureAwait(false); + var result = await _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ToListAsync(); // Assert result.Should().HaveSameCount(executionResults).And.ContainInOrder(executionResults); @@ -784,7 +784,7 @@ public async Task ExecuteProcess_ProcessThrowsTestException_ReturnsExpected(bool }); // Act - var result = await _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ToListAsync().ConfigureAwait(false); + var result = await _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ToListAsync(); // Assert result.Should().HaveSameCount(executionResults).And.ContainInOrder(executionResults); @@ -840,14 +840,14 @@ public async Task ExecuteProcess_ProcessThrowsSystemException_Throws(bool isLock var Act = async () => { - await foreach (var stepResult in _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None).ConfigureAwait(false)) + await foreach (var stepResult in _sut.ExecuteProcess(processId, ProcessTypeId.CREATE_CREDENTIAL, CancellationToken.None)) { stepResults.Add(stepResult); } }; // Act - var result = await Assert.ThrowsAsync(Act).ConfigureAwait(false); + var result = await Assert.ThrowsAsync(Act); // Assert stepResults.Should().HaveSameCount(executionResults).And.ContainInOrder(executionResults); diff --git a/tests/processes/Processes.Worker.Library.Tests/Processes.Worker.Library.Tests.csproj b/tests/processes/Processes.Worker.Library.Tests/Processes.Worker.Library.Tests.csproj index c5e5b725..247d4f0d 100644 --- a/tests/processes/Processes.Worker.Library.Tests/Processes.Worker.Library.Tests.csproj +++ b/tests/processes/Processes.Worker.Library.Tests/Processes.Worker.Library.Tests.csproj @@ -19,7 +19,7 @@ - net7.0 + net8.0 enable enable false @@ -27,7 +27,8 @@ Org.Eclipse.TractusX.SsiCredentialIssuer.Processes.Worker.Library.Tests - + + @@ -36,10 +37,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - From 6a8705009e16555b20c99e9619ad037911b1247f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:04:41 +0200 Subject: [PATCH 05/13] chore(deps): bump github/codeql-action from 3.24.9 to 3.25.3 (#86) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.24.9 to 3.25.3. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/1b1aada464948af03b950897e5eb522f92603cc2...d39d31e687223d841ef683f52467bd88e9b21c14) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: Phil Schneider Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/kics.yml | 2 +- .github/workflows/trivy-dev.yml | 10 +++++----- .github/workflows/trivy.yml | 10 +++++----- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 156c13af..f63bdd96 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -73,7 +73,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@1b1aada464948af03b950897e5eb522f92603cc2 # v2.227 + uses: github/codeql-action/init@d39d31e687223d841ef683f52467bd88e9b21c14 # v2.227 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -87,7 +87,7 @@ jobs: # Automates dependency installation for Python, Ruby, and JavaScript, optimizing the CodeQL analysis setup. # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@1b1aada464948af03b950897e5eb522f92603cc2 # v2.227 + uses: github/codeql-action/autobuild@d39d31e687223d841ef683f52467bd88e9b21c14 # v2.227 # ℹī¸ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -100,6 +100,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1b1aada464948af03b950897e5eb522f92603cc2 # v2.227 + uses: github/codeql-action/analyze@d39d31e687223d841ef683f52467bd88e9b21c14 # v2.227 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 6e710097..fe5ffb61 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -69,7 +69,7 @@ jobs: # Upload findings to GitHub Advanced Security Dashboard - name: Upload SARIF file for GitHub Advanced Security Dashboard if: always() - uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: sarif_file: kicsResults/results.sarif diff --git a/.github/workflows/trivy-dev.yml b/.github/workflows/trivy-dev.yml index da715a5b..58f50ed1 100644 --- a/.github/workflows/trivy-dev.yml +++ b/.github/workflows/trivy-dev.yml @@ -63,7 +63,7 @@ jobs: timeout: "3600s" - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 if: always() with: sarif_file: "trivy-results1.sarif" @@ -96,7 +96,7 @@ jobs: - name: Upload Trivy scan results to GitHub Security tab if: always() - uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: sarif_file: "trivy-results3.sarif" @@ -129,7 +129,7 @@ jobs: - name: Upload Trivy scan results to GitHub Security tab if: always() - uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: sarif_file: "trivy-results9.sarif" @@ -162,7 +162,7 @@ jobs: - name: Upload Trivy scan results to GitHub Security tab if: always() - uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: sarif_file: "trivy-results9.sarif" @@ -195,7 +195,7 @@ jobs: - name: Upload Trivy scan results to GitHub Security tab if: always() - uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: sarif_file: "trivy-results9.sarif" \ No newline at end of file diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index 1688ba06..cb1ecde1 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -64,7 +64,7 @@ jobs: timeout: "3600s" - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 if: always() with: sarif_file: "trivy-results1.sarif" @@ -97,7 +97,7 @@ jobs: - name: Upload Trivy scan results to GitHub Security tab if: always() - uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: sarif_file: "trivy-results3.sarif" @@ -129,7 +129,7 @@ jobs: - name: Upload Trivy scan results to GitHub Security tab if: always() - uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: sarif_file: "trivy-results9.sarif" @@ -161,7 +161,7 @@ jobs: - name: Upload Trivy scan results to GitHub Security tab if: always() - uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: sarif_file: "trivy-results9.sarif" @@ -193,7 +193,7 @@ jobs: - name: Upload Trivy scan results to GitHub Security tab if: always() - uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: sarif_file: "trivy-results9.sarif" \ No newline at end of file From 2a6b30809ba2c985e13442b42f940e6263005b20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:05:03 +0200 Subject: [PATCH 06/13] chore(deps): bump amannn/action-semantic-pull-request (#85) Bumps [amannn/action-semantic-pull-request](https://github.com/amannn/action-semantic-pull-request) from 5.4.0 to 5.5.2. - [Release notes](https://github.com/amannn/action-semantic-pull-request/releases) - [Changelog](https://github.com/amannn/action-semantic-pull-request/blob/main/CHANGELOG.md) - [Commits](https://github.com/amannn/action-semantic-pull-request/compare/e9fabac35e210fea40ca5b14c0da95a099eff26f...cfb60706e18bc85e8aec535e3c577abe8f70378e) --- updated-dependencies: - dependency-name: amannn/action-semantic-pull-request dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/lint-pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint-pull-request.yml b/.github/workflows/lint-pull-request.yml index 9d5e2c49..0100ec1c 100644 --- a/.github/workflows/lint-pull-request.yml +++ b/.github/workflows/lint-pull-request.yml @@ -31,7 +31,7 @@ jobs: name: Validate PR title runs-on: ubuntu-latest steps: - - uses: amannn/action-semantic-pull-request@e9fabac35e210fea40ca5b14c0da95a099eff26f # v5.4.0 + - uses: amannn/action-semantic-pull-request@cfb60706e18bc85e8aec535e3c577abe8f70378e # v5.5.2 id: lint_pr_title env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 0a49f57a3e9e091191723faf2693a34ace1a0cf8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:09:30 +0200 Subject: [PATCH 07/13] chore(deps): bump azure/setup-helm from 3.5 to 4 (#65) Bumps [azure/setup-helm](https://github.com/azure/setup-helm) from 3.5 to 4. - [Release notes](https://github.com/azure/setup-helm/releases) - [Changelog](https://github.com/Azure/setup-helm/blob/main/CHANGELOG.md) - [Commits](https://github.com/azure/setup-helm/compare/v3.5...b7246b12e77f7134dc2d460a3d5bad15bbe29390) --- updated-dependencies: - dependency-name: azure/setup-helm dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/owasp-zap.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/owasp-zap.yml b/.github/workflows/owasp-zap.yml index 10940774..a7a5988a 100644 --- a/.github/workflows/owasp-zap.yml +++ b/.github/workflows/owasp-zap.yml @@ -56,7 +56,7 @@ jobs: version: v0.20.0 - name: Set up Helm - uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3.5 + uses: azure/setup-helm@b7246b12e77f7134dc2d460a3d5bad15bbe29390 # v4.1.0 with: version: v3.5.0 From 3bd1ed4a0a8c16b4386f05c2fdd1e9f6d5d5ed9d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:10:08 +0200 Subject: [PATCH 08/13] chore(deps): bump docker/setup-buildx-action from 3.2.0 to 3.3.0 (#67) Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/2b51285047da1547ffb1b2203d8be4c0af6b1f20...d70bba72b1f3fd22344832f00baa16ece964efeb) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/credential-expiry-app-docker.yml | 2 +- .github/workflows/migrations-docker.yml | 2 +- .github/workflows/processes-worker-docker.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/release_candidate.yml | 2 +- .github/workflows/service-docker.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/credential-expiry-app-docker.yml b/.github/workflows/credential-expiry-app-docker.yml index ee62b8b5..db78b27c 100644 --- a/.github/workflows/credential-expiry-app-docker.yml +++ b/.github/workflows/credential-expiry-app-docker.yml @@ -55,7 +55,7 @@ jobs: password: ${{ secrets.DOCKER_HUB_TOKEN }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0 + uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Set up QEMU uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 diff --git a/.github/workflows/migrations-docker.yml b/.github/workflows/migrations-docker.yml index 27ae0371..1ee07010 100644 --- a/.github/workflows/migrations-docker.yml +++ b/.github/workflows/migrations-docker.yml @@ -56,7 +56,7 @@ jobs: password: ${{ secrets.DOCKER_HUB_TOKEN }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0 + uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Set up QEMU uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 diff --git a/.github/workflows/processes-worker-docker.yml b/.github/workflows/processes-worker-docker.yml index d782edf0..13bb638b 100644 --- a/.github/workflows/processes-worker-docker.yml +++ b/.github/workflows/processes-worker-docker.yml @@ -55,7 +55,7 @@ jobs: password: ${{ secrets.DOCKER_HUB_TOKEN }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0 + uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Set up QEMU uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7a7bc170..9733d56b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -117,7 +117,7 @@ jobs: password: ${{ secrets.DOCKER_HUB_TOKEN }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0 + uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Set up QEMU uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 diff --git a/.github/workflows/release_candidate.yml b/.github/workflows/release_candidate.yml index aec65337..d37b1f8c 100644 --- a/.github/workflows/release_candidate.yml +++ b/.github/workflows/release_candidate.yml @@ -59,7 +59,7 @@ jobs: password: ${{ secrets.DOCKER_HUB_TOKEN }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0 + uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Set up QEMU uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 diff --git a/.github/workflows/service-docker.yml b/.github/workflows/service-docker.yml index 76f01b1e..409190e1 100644 --- a/.github/workflows/service-docker.yml +++ b/.github/workflows/service-docker.yml @@ -55,7 +55,7 @@ jobs: password: ${{ secrets.DOCKER_HUB_TOKEN }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0 + uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Set up QEMU uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 From eb9fb0049d4eca35291bdecec3d8bed57fb87ca1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:11:17 +0200 Subject: [PATCH 09/13] chore(deps): bump actions/upload-artifact from 4.3.1 to 4.3.3 (#75) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.1 to 4.3.3. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/5d5d22a31266ced268874388b861e4b58bb5c2f3...65462800fd760344b1a7b4382951275a0abb4808) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dependencies.yml | 2 +- .github/workflows/owasp-zap.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml index 2f242add..e79e53ba 100644 --- a/.github/workflows/dependencies.yml +++ b/.github/workflows/dependencies.yml @@ -84,7 +84,7 @@ jobs: if: steps.dependencies-changed.outputs.changed == 'true' - name: Upload DEPENDENCIES file - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: path: DEPENDENCIES if: steps.dependencies-changed.outputs.changed == 'true' diff --git a/.github/workflows/owasp-zap.yml b/.github/workflows/owasp-zap.yml index a7a5988a..622fd001 100644 --- a/.github/workflows/owasp-zap.yml +++ b/.github/workflows/owasp-zap.yml @@ -144,7 +144,7 @@ jobs: - name: Upload HTML report if: success() || failure() - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: ZAP scan report path: ./report_html.html From 2cd1326b94a80418566a934d5a28b0c8a804656e Mon Sep 17 00:00:00 2001 From: Evelyn Gurschler Date: Tue, 30 Apr 2024 14:32:34 +0200 Subject: [PATCH 10/13] chore(consortia): change to centralidp-rc for rc env --- consortia/environments/values-rc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/consortia/environments/values-rc.yaml b/consortia/environments/values-rc.yaml index 27176150..e8e66e94 100644 --- a/consortia/environments/values-rc.yaml +++ b/consortia/environments/values-rc.yaml @@ -88,7 +88,7 @@ credentialExpiry: default: "Debug" centralidp: - address: "https://centralidp.dev.demo.catena-x.net" + address: "https://centralidp-rc.dev.demo.catena-x.net" jwtBearerOptions: tokenValidationParameters: validAudience: "Cl24-CX-SSI-CredentialIssuer" From 1d3132c4ddb34db4f4c71613f6360906c4fb8664 Mon Sep 17 00:00:00 2001 From: Evelyn Gurschler Date: Tue, 30 Apr 2024 16:22:58 +0200 Subject: [PATCH 11/13] chore: release 1.0.0-rc.3 Release-As: 1.0.0-rc.3 From 5a93df6ba50c1fe60f8f5f6a0f9983bd4cc3e982 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 30 Apr 2024 16:27:27 +0200 Subject: [PATCH 12/13] chore(changelog/v1.0.0-rc.3): release 1.0.0-rc.3 (#89) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- CHANGELOG.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d360e4b8..7394d46d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## [1.0.0-rc.3](https://github.com/eclipse-tractusx/ssi-credential-issuer/compare/v1.0.0-rc.1...v1.0.0-rc.3) (2024-04-30) + + +### Features + +* **revocation:** add endpoints to revoke credentials ([#43](https://github.com/eclipse-tractusx/ssi-credential-issuer/issues/43)) ([dc9c70d](https://github.com/eclipse-tractusx/ssi-credential-issuer/commit/dc9c70da4c0bcba979c71b5c636526c13041c774)) +* **ssi:** adjust framework creation endpoint ([#70](https://github.com/eclipse-tractusx/ssi-credential-issuer/issues/70)) ([2d06fe6](https://github.com/eclipse-tractusx/ssi-credential-issuer/commit/2d06fe65365b644a209900a464c6823cb0db372e)) + + +### Bug Fixes + +* adjust bpn schema ([#84](https://github.com/eclipse-tractusx/ssi-credential-issuer/issues/84)) ([e32ec3a](https://github.com/eclipse-tractusx/ssi-credential-issuer/commit/e32ec3a47e94133294a8e7035f81e5d8fbe305e3)) +* **callback:** set the correct base address for the callback ([#83](https://github.com/eclipse-tractusx/ssi-credential-issuer/issues/83)) ([9f79c54](https://github.com/eclipse-tractusx/ssi-credential-issuer/commit/9f79c541873c951eb6335aba6b5b1adda0ee25e9)), closes [#71](https://github.com/eclipse-tractusx/ssi-credential-issuer/issues/71) +* **ssi:** adjust schemas ([#72](https://github.com/eclipse-tractusx/ssi-credential-issuer/issues/72)) ([ba63179](https://github.com/eclipse-tractusx/ssi-credential-issuer/commit/ba63179300aa835bcb0f0d5c874c927ea48c89c9)) + + +### Miscellaneous Chores + +* release 1.0.0-rc.3 ([1d3132c](https://github.com/eclipse-tractusx/ssi-credential-issuer/commit/1d3132c4ddb34db4f4c71613f6360906c4fb8664)) + ## [1.0.0-rc.1](https://github.com/eclipse-tractusx/ssi-credential-issuer/compare/v1.0.0-rc.1...v1.0.0-rc.1) (2024-04-15) From f430009880fadf73fbafed057724eae955d34aff Mon Sep 17 00:00:00 2001 From: Evelyn Gurschler Date: Tue, 30 Apr 2024 16:32:33 +0200 Subject: [PATCH 13/13] build(1.0.0-rc.3): bump version and update docs --- charts/ssi-credential-issuer/Chart.yaml | 4 ++-- charts/ssi-credential-issuer/README.md | 2 +- consortia/argocd-app-templates/appsetup-int.yaml | 2 +- consortia/argocd-app-templates/appsetup-stable.yaml | 2 +- src/Directory.Build.props | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/charts/ssi-credential-issuer/Chart.yaml b/charts/ssi-credential-issuer/Chart.yaml index 1cd37b2d..c56664c4 100644 --- a/charts/ssi-credential-issuer/Chart.yaml +++ b/charts/ssi-credential-issuer/Chart.yaml @@ -20,8 +20,8 @@ apiVersion: v2 name: ssi-credential-issuer type: application -version: 1.0.0-rc.2 -appVersion: 1.0.0-rc.2 +version: 1.0.0-rc.3 +appVersion: 1.0.0-rc.3 description: Helm chart for SSI Credential Issuer home: https://github.com/eclipse-tractusx/ssi-credential-issuer dependencies: diff --git a/charts/ssi-credential-issuer/README.md b/charts/ssi-credential-issuer/README.md index 4ff2e5f2..7f7ab734 100644 --- a/charts/ssi-credential-issuer/README.md +++ b/charts/ssi-credential-issuer/README.md @@ -27,7 +27,7 @@ To use the helm chart as a dependency: dependencies: - name: ssi-credential-issuer repository: https://eclipse-tractusx.github.io/charts/dev - version: 1.0.0-rc.2 + version: 1.0.0-rc.3 ``` ## Requirements diff --git a/consortia/argocd-app-templates/appsetup-int.yaml b/consortia/argocd-app-templates/appsetup-int.yaml index f1695f2b..b1549b76 100644 --- a/consortia/argocd-app-templates/appsetup-int.yaml +++ b/consortia/argocd-app-templates/appsetup-int.yaml @@ -28,7 +28,7 @@ spec: source: path: charts/ssi-credential-issuer repoURL: 'https://github.com/eclipse-tractusx/ssi-credential-issuer.git' - targetRevision: ssi-credential-issuer-1.0.0-rc.2 + targetRevision: ssi-credential-issuer-1.0.0-rc.3 plugin: env: - name: AVP_SECRET diff --git a/consortia/argocd-app-templates/appsetup-stable.yaml b/consortia/argocd-app-templates/appsetup-stable.yaml index 33e28fc4..86d656ca 100644 --- a/consortia/argocd-app-templates/appsetup-stable.yaml +++ b/consortia/argocd-app-templates/appsetup-stable.yaml @@ -29,7 +29,7 @@ spec: source: path: '' repoURL: 'https://eclipse-tractusx.github.io/charts/dev' - targetRevision: ssi-credential-issuer-1.0.0-rc.2 + targetRevision: ssi-credential-issuer-1.0.0-rc.3 plugin: env: - name: HELM_VALUES diff --git a/src/Directory.Build.props b/src/Directory.Build.props index ff5d3169..4f32e8a4 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -20,6 +20,6 @@ 1.0.0 - rc.2 + rc.3