From 16c73e9e5011992b1d17b4b5f36e23f1570b0ad7 Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Mon, 14 Oct 2024 15:07:09 +0200 Subject: [PATCH] feat: check holder equals issuer * check if the holder equals the issuer, if so skip the import credential for holder step Refs: #250 --- .../Repositories/CredentialRepository.cs | 10 ++---- .../Repositories/ICredentialRepository.cs | 3 +- .../BusinessLogic/IWalletBusinessLogic.cs | 2 ++ .../CredentialCreationProcessHandler.cs | 11 ++++++- .../CredentialRepositoryTests.cs | 17 ---------- .../CredentialCreationProcessHandlerTests.cs | 33 +++++++++++++++++-- 6 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/database/SsiCredentialIssuer.DbAccess/Repositories/CredentialRepository.cs b/src/database/SsiCredentialIssuer.DbAccess/Repositories/CredentialRepository.cs index 370d0f4..b2d55c3 100644 --- a/src/database/SsiCredentialIssuer.DbAccess/Repositories/CredentialRepository.cs +++ b/src/database/SsiCredentialIssuer.DbAccess/Repositories/CredentialRepository.cs @@ -28,15 +28,11 @@ namespace Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Repositories; public class CredentialRepository(IssuerDbContext dbContext) : ICredentialRepository { - public Task GetWalletCredentialId(Guid credentialId) => - dbContext.CompanySsiDetails.Where(x => x.Id == credentialId) - .Select(x => x.ExternalCredentialId) - .SingleOrDefaultAsync(); - - public Task<(HolderWalletData HolderWalletData, string? Credential, EncryptionTransformationData EncryptionInformation, string? CallbackUrl)> GetCredentialData(Guid credentialId) => + public Task<(bool IsIssuerCompany, HolderWalletData HolderWalletData, string? Credential, EncryptionTransformationData EncryptionInformation, string? CallbackUrl)> GetCredentialData(Guid credentialId) => dbContext.CompanySsiDetails .Where(x => x.Id == credentialId) - .Select(x => new ValueTuple( + .Select(x => new ValueTuple( + x.Bpnl == x.IssuerBpn, new HolderWalletData(x.CompanySsiProcessData!.HolderWalletUrl, x.CompanySsiProcessData.ClientId), x.Credential, new EncryptionTransformationData(x.CompanySsiProcessData!.ClientSecret, x.CompanySsiProcessData.InitializationVector, x.CompanySsiProcessData.EncryptionMode), diff --git a/src/database/SsiCredentialIssuer.DbAccess/Repositories/ICredentialRepository.cs b/src/database/SsiCredentialIssuer.DbAccess/Repositories/ICredentialRepository.cs index 0f66e48..b1d42c4 100644 --- a/src/database/SsiCredentialIssuer.DbAccess/Repositories/ICredentialRepository.cs +++ b/src/database/SsiCredentialIssuer.DbAccess/Repositories/ICredentialRepository.cs @@ -26,8 +26,7 @@ namespace Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Repositories; public interface ICredentialRepository { - Task GetWalletCredentialId(Guid credentialId); - Task<(HolderWalletData HolderWalletData, string? Credential, EncryptionTransformationData EncryptionInformation, string? CallbackUrl)> GetCredentialData(Guid credentialId); + Task<(bool IsIssuerCompany, HolderWalletData HolderWalletData, string? Credential, EncryptionTransformationData EncryptionInformation, string? CallbackUrl)> GetCredentialData(Guid credentialId); Task<(bool Exists, Guid CredentialId)> GetDataForProcessId(Guid processId); Task<(VerifiedCredentialTypeKindId CredentialTypeKindId, JsonDocument Schema)> GetCredentialStorageInformationById(Guid credentialId); Task<(Guid? ExternalCredentialId, VerifiedCredentialTypeKindId KindId, bool HasEncryptionInformation, string? CallbackUrl)> GetExternalCredentialAndKindId(Guid credentialId); diff --git a/src/externalservices/Wallet.Service/BusinessLogic/IWalletBusinessLogic.cs b/src/externalservices/Wallet.Service/BusinessLogic/IWalletBusinessLogic.cs index 8922d15..46dfbd8 100644 --- a/src/externalservices/Wallet.Service/BusinessLogic/IWalletBusinessLogic.cs +++ b/src/externalservices/Wallet.Service/BusinessLogic/IWalletBusinessLogic.cs @@ -26,6 +26,8 @@ namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.BusinessLogic; public interface IWalletBusinessLogic { Task CreateSignedCredential(Guid companySsiDetailId, JsonDocument schema, CancellationToken cancellationToken); + Task CreateCredentialForHolder(Guid companySsiDetailId, string holderWalletUrl, string clientId, EncryptionInformation encryptionInformation, string credential, CancellationToken cancellationToken); + Task GetCredential(Guid credentialId, Guid externalCredentialId, VerifiedCredentialTypeKindId kindId, CancellationToken cancellationToken); } diff --git a/src/processes/CredentialProcess.Library/Creation/CredentialCreationProcessHandler.cs b/src/processes/CredentialProcess.Library/Creation/CredentialCreationProcessHandler.cs index 49c684a..f5b1a25 100644 --- a/src/processes/CredentialProcess.Library/Creation/CredentialCreationProcessHandler.cs +++ b/src/processes/CredentialProcess.Library/Creation/CredentialCreationProcessHandler.cs @@ -66,7 +66,16 @@ public class CredentialCreationProcessHandler( 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(ConfigureAwaitOptions.None); + var (isIssuerCompany, holderWalletData, credential, encryptionInformation, callbackUrl) = await issuerRepositories.GetInstance().GetCredentialData(credentialId).ConfigureAwait(ConfigureAwaitOptions.None); + if (isIssuerCompany) + { + return ( + callbackUrl is null ? null : Enumerable.Repeat(ProcessStepTypeId.TRIGGER_CALLBACK, 1), + ProcessStepStatusId.SKIPPED, + false, + "ProcessStep was skipped because the holder is the issuer"); + } + if (credential is null) { throw new ConflictException("Credential must be set here"); diff --git a/tests/database/SsiCredentialIssuer.DbAccess.Tests/CredentialRepositoryTests.cs b/tests/database/SsiCredentialIssuer.DbAccess.Tests/CredentialRepositoryTests.cs index a87e85a..3bd1f86 100644 --- a/tests/database/SsiCredentialIssuer.DbAccess.Tests/CredentialRepositoryTests.cs +++ b/tests/database/SsiCredentialIssuer.DbAccess.Tests/CredentialRepositoryTests.cs @@ -85,23 +85,6 @@ public async Task GetCredentialData_ReturnsExpectedDocument() #endregion - #region GetWalletCredentialId - - [Fact] - public async Task GetWalletCredentialId_ReturnsExpectedDocument() - { - // Arrange - var sut = await CreateSut(); - - // Act - var result = await sut.GetWalletCredentialId(new Guid("9f5b9934-4014-4099-91e9-7b1aee696b03")); - - // Assert - result.Should().Be(new Guid("bd474c60-e7ce-450f-bdf4-73604546fc5e")); - } - - #endregion - #region GetCredentialStorageInformationById [Fact] diff --git a/tests/processes/CredentialProcess.Library.Tests/CredentialCreationProcessHandlerTests.cs b/tests/processes/CredentialProcess.Library.Tests/CredentialCreationProcessHandlerTests.cs index c0473be..5399745 100644 --- a/tests/processes/CredentialProcess.Library.Tests/CredentialCreationProcessHandlerTests.cs +++ b/tests/processes/CredentialProcess.Library.Tests/CredentialCreationProcessHandlerTests.cs @@ -136,7 +136,7 @@ public async Task CreateCredentialForHolder_WithCredentialNotSet_SkipsStep() { // Arrange A.CallTo(() => _credentialRepository.GetCredentialData(_credentialId)) - .Returns(default((HolderWalletData, string?, EncryptionTransformationData, string?))); + .Returns(default((bool, HolderWalletData, string?, EncryptionTransformationData, string?))); Task Act() => _sut.CreateCredentialForHolder(_credentialId, CancellationToken.None); // Act @@ -151,7 +151,7 @@ public async Task CreateCredentialForHolder_WithClientIdNull_SkipsStep() { // Arrange A.CallTo(() => _credentialRepository.GetCredentialData(_credentialId)) - .Returns((new HolderWalletData(null, null), "test", _fixture.Create(), "https://example.org")); + .Returns((false, new HolderWalletData(null, null), "test", _fixture.Create(), "https://example.org")); Task Act() => _sut.CreateCredentialForHolder(_credentialId, CancellationToken.None); // Act @@ -166,7 +166,7 @@ public async Task CreateCredentialForHolder_WithWalletUrlNull_SkipsStep() { // Arrange A.CallTo(() => _credentialRepository.GetCredentialData(_credentialId)) - .Returns((new HolderWalletData(null, "c1"), "test", _fixture.Create(), "https://example.org")); + .Returns((false, new HolderWalletData(null, "c1"), "test", _fixture.Create(), "https://example.org")); Task Act() => _sut.CreateCredentialForHolder(_credentialId, CancellationToken.None); // Act @@ -182,6 +182,7 @@ public async Task CreateCredentialForHolder_WithEncryptionNotSet_SkipsStep() // Arrange A.CallTo(() => _credentialRepository.GetCredentialData(_credentialId)) .Returns(( + false, new HolderWalletData("https://example.org", "c1"), "test", new EncryptionTransformationData("test"u8.ToArray(), "test"u8.ToArray(), 0), @@ -203,6 +204,7 @@ public async Task CreateCredentialForHolder_WithValidData_ReturnsExpected() // Arrange A.CallTo(() => _credentialRepository.GetCredentialData(_credentialId)) .Returns(( + false, new HolderWalletData("https://example.org", "c1"), "test", _fixture.Create(), @@ -221,6 +223,31 @@ public async Task CreateCredentialForHolder_WithValidData_ReturnsExpected() result.nextStepTypeIds.Should().ContainSingle().Which.Should().Be(ProcessStepTypeId.TRIGGER_CALLBACK); } + [Fact] + public async Task CreateCredentialForHolder_WithIssuerAsHolder_ReturnsExpected() + { + // Arrange + A.CallTo(() => _credentialRepository.GetCredentialData(_credentialId)) + .Returns(( + true, + new HolderWalletData("https://example.org", "c1"), + "test", + _fixture.Create(), + "https://example.org")); + + // Act + var result = await _sut.CreateCredentialForHolder(_credentialId, CancellationToken.None); + + // Assert + A.CallTo(() => _walletBusinessLogic.CreateCredentialForHolder(A._, A._, A._, A._, A._, A._)) + .MustNotHaveHappened(); + + result.modified.Should().BeFalse(); + result.processMessage.Should().Be("ProcessStep was skipped because the holder is the issuer"); + result.stepStatusId.Should().Be(ProcessStepStatusId.SKIPPED); + result.nextStepTypeIds.Should().ContainSingle().Which.Should().Be(ProcessStepTypeId.TRIGGER_CALLBACK); + } + #endregion #region TriggerCallback