diff --git a/src/credentials/SsiCredentialIssuer.Reissuance.App/Program.cs b/src/credentials/SsiCredentialIssuer.Reissuance.App/Program.cs
index b4588a2c..d0e1edd1 100644
--- a/src/credentials/SsiCredentialIssuer.Reissuance.App/Program.cs
+++ b/src/credentials/SsiCredentialIssuer.Reissuance.App/Program.cs
@@ -30,7 +30,7 @@
using Org.Eclipse.TractusX.SsiCredentialIssuer.Portal.Service.DependencyInjection;
LoggingExtensions.EnsureInitialized();
-Log.Information("Building worker");
+Log.Information("Building Reissuance App");
try
{
var host = Host
@@ -47,7 +47,7 @@
})
.AddLogging()
.Build();
- Log.Information("Building worker completed");
+ Log.Information("Building Reissuance App completed");
using var tokenSource = new CancellationTokenSource();
Console.CancelKeyPress += (s, e) =>
diff --git a/src/database/SsiCredentialIssuer.DbAccess/Repositories/IReissuanceRepository.cs b/src/database/SsiCredentialIssuer.DbAccess/Repositories/IReissuanceRepository.cs
index b2e469e9..1388a216 100644
--- a/src/database/SsiCredentialIssuer.DbAccess/Repositories/IReissuanceRepository.cs
+++ b/src/database/SsiCredentialIssuer.DbAccess/Repositories/IReissuanceRepository.cs
@@ -28,4 +28,6 @@ public interface IReissuanceRepository
Guid GetCompanySsiDetailId(Guid companySsiDetaillId);
bool IsReissuedCredential(Guid companySsiDetaillId);
+
+ bool IsCredentialRevokedByReissuance(Guid companySsiDetaillId);
}
diff --git a/src/database/SsiCredentialIssuer.DbAccess/Repositories/ReissuanceRepository.cs b/src/database/SsiCredentialIssuer.DbAccess/Repositories/ReissuanceRepository.cs
index 47427283..a4c9cc30 100644
--- a/src/database/SsiCredentialIssuer.DbAccess/Repositories/ReissuanceRepository.cs
+++ b/src/database/SsiCredentialIssuer.DbAccess/Repositories/ReissuanceRepository.cs
@@ -52,4 +52,11 @@ public bool IsReissuedCredential(Guid companySsiDetaillId)
.Where(ssi => ssi.ReissuedCredentialId == companySsiDetaillId)
.Select(ssi => true).SingleOrDefault();
}
+
+ public bool IsCredentialRevokedByReissuance(Guid companySsiDetaillId)
+ {
+ return _dbContext.Reissuances
+ .Where(ssi => ssi.Id == companySsiDetaillId)
+ .Select(ssi => true).SingleOrDefault();
+ }
}
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 b4e48a92..cfa667b2 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
@@ -23,6 +23,10 @@
"verified_credential_external_type_id": 6,
"verified_credential_type_id": 6
},
+ {
+ "verified_credential_external_type_id": 7,
+ "verified_credential_type_id": 7
+ },
{
"verified_credential_external_type_id": 8,
"verified_credential_type_id": 8
@@ -35,6 +39,10 @@
"verified_credential_external_type_id": 10,
"verified_credential_type_id": 10
},
+ {
+ "verified_credential_external_type_id": 11,
+ "verified_credential_type_id": 11
+ },
{
"verified_credential_external_type_id": 12,
"verified_credential_type_id": 12
diff --git a/src/externalservices/Portal.Service/Models/NotificationTypeId.cs b/src/externalservices/Portal.Service/Models/NotificationTypeId.cs
index e6d3409d..e334f8ca 100644
--- a/src/externalservices/Portal.Service/Models/NotificationTypeId.cs
+++ b/src/externalservices/Portal.Service/Models/NotificationTypeId.cs
@@ -152,5 +152,10 @@ public enum NotificationTypeId
///
/// Notification when a credential got rejected
///
- CREDENTIAL_EXPIRY = 26
+ CREDENTIAL_EXPIRY = 26,
+
+ ///
+ /// Notification when a credential got Reissued
+ ///
+ CREDENTIAL_RENEWAL = 27
}
diff --git a/src/processes/CredentialProcess.Library/Expiry/CredentialExpiryProcessHandler.cs b/src/processes/CredentialProcess.Library/Expiry/CredentialExpiryProcessHandler.cs
index 1660e571..3f0be8ed 100644
--- a/src/processes/CredentialProcess.Library/Expiry/CredentialExpiryProcessHandler.cs
+++ b/src/processes/CredentialProcess.Library/Expiry/CredentialExpiryProcessHandler.cs
@@ -83,10 +83,12 @@ 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(ConfigureAwaitOptions.None);
+ var notificationTypeId = await GetNotificationTypeId(credentialId);
+
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);
+ await _portalService.AddNotification(content, companyUserId, notificationTypeId, cancellationToken);
}
return (
@@ -96,18 +98,30 @@ public CredentialExpiryProcessHandler(IIssuerRepositories repositories, IWalletS
null);
}
+ private Task GetNotificationTypeId(Guid credentialId)
+ {
+ var isRevokedByReissuance = _repositories.GetInstance().IsCredentialRevokedByReissuance(credentialId);
+ return Task.FromResult(isRevokedByReissuance ? NotificationTypeId.CREDENTIAL_RENEWAL : NotificationTypeId.CREDENTIAL_REJECTED);
+ }
+
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(ConfigureAwaitOptions.None);
-
var typeValue = typeId.GetEnumValue() ?? throw new UnexpectedConditionException($"VerifiedCredentialType {typeId} does not exists");
+ var isRevokedByReissuance = _repositories.GetInstance().IsCredentialRevokedByReissuance(credentialId);
+
if (Guid.TryParse(requesterId, out var companyUserId))
{
- var mailParameters = new MailParameter[]
+ if (isRevokedByReissuance)
+ {
+ var mailParameters = CreateEmailParameters(typeValue, "The credential about to expiry is revoked and new credential was reissued");
+ await _portalService.TriggerMail("CredentialRenewal", companyUserId, mailParameters, cancellationToken);
+ }
+ else
{
- new("requestName", typeValue), new("reason", "The credential is already expired")
- };
- await _portalService.TriggerMail("CredentialRejected", companyUserId, mailParameters, cancellationToken);
+ var mailParameters = CreateEmailParameters(typeValue, "The credential is already expired");
+ await _portalService.TriggerMail("CredentialRejected", companyUserId, mailParameters, cancellationToken);
+ }
}
return (
@@ -116,4 +130,12 @@ public CredentialExpiryProcessHandler(IIssuerRepositories repositories, IWalletS
false,
null);
}
+
+ private static MailParameter[] CreateEmailParameters(string typeValue, string reason)
+ {
+ return
+ [
+ new("requestName", typeValue), new("reason", reason)
+ ];
+ }
}
diff --git a/src/processes/CredentialProcess.Worker/DependencyInjection/CredentialProcessCollectionExtensions.cs b/src/processes/CredentialProcess.Worker/DependencyInjection/CredentialProcessCollectionExtensions.cs
index f8c254a1..b6732f70 100644
--- a/src/processes/CredentialProcess.Worker/DependencyInjection/CredentialProcessCollectionExtensions.cs
+++ b/src/processes/CredentialProcess.Worker/DependencyInjection/CredentialProcessCollectionExtensions.cs
@@ -18,7 +18,6 @@
********************************************************************************/
using Microsoft.Extensions.DependencyInjection;
-using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library;
using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Library.DependencyInjection;
using Org.Eclipse.TractusX.SsiCredentialIssuer.CredentialProcess.Worker.Expiry;
using Org.Eclipse.TractusX.SsiCredentialIssuer.Processes.Worker.Library;
diff --git a/tests/processes/CredentialProcess.Library.Tests/CredentialCreationProcessHandlerTests.cs b/tests/processes/CredentialProcess.Library.Tests/CredentialCreationProcessHandlerTests.cs
index 57862757..c3da8b46 100644
--- a/tests/processes/CredentialProcess.Library.Tests/CredentialCreationProcessHandlerTests.cs
+++ b/tests/processes/CredentialProcess.Library.Tests/CredentialCreationProcessHandlerTests.cs
@@ -125,7 +125,7 @@ public async Task SignCredential_WithValidData_ReturnsExpected()
result.modified.Should().BeFalse();
result.processMessage.Should().BeNull();
result.stepStatusId.Should().Be(ProcessStepStatusId.DONE);
- result.nextStepTypeIds.Should().ContainSingle().Which.Should().Be(ProcessStepTypeId.SAVE_CREDENTIAL_DOCUMENT);
+ result.nextStepTypeIds.Should().ContainSingle().Which.Should().Be(ProcessStepTypeId.REVOKE_REISSUED_CREDENTIAL);
}
#endregion
diff --git a/tests/processes/CredentialProcess.Library.Tests/CredentialExpiryProcessHandlerTests.cs b/tests/processes/CredentialProcess.Library.Tests/CredentialExpiryProcessHandlerTests.cs
index 56f95cb7..1155ee66 100644
--- a/tests/processes/CredentialProcess.Library.Tests/CredentialExpiryProcessHandlerTests.cs
+++ b/tests/processes/CredentialProcess.Library.Tests/CredentialExpiryProcessHandlerTests.cs
@@ -42,6 +42,7 @@ public class CredentialExpiryProcessHandlerTests
private readonly IWalletService _walletService;
private readonly IIssuerRepositories _issuerRepositories;
private readonly ICredentialRepository _credentialRepository;
+ private readonly IReissuanceRepository _reissuanceRepository;
private readonly IPortalService _portalService;
private readonly CredentialExpiryProcessHandler _sut;
@@ -58,9 +59,11 @@ public CredentialExpiryProcessHandlerTests()
_issuerRepositories = A.Fake();
_credentialRepository = A.Fake();
_documentRepository = A.Fake();
+ _reissuanceRepository = A.Fake();
A.CallTo(() => _issuerRepositories.GetInstance()).Returns(_credentialRepository);
A.CallTo(() => _issuerRepositories.GetInstance()).Returns(_documentRepository);
+ A.CallTo(() => _issuerRepositories.GetInstance()).Returns(_reissuanceRepository);
_walletService = A.Fake();
_portalService = A.Fake();
@@ -162,7 +165,7 @@ public async Task RevokeCredential_WithEmptyExternalCredentialId_ThrowsConflictE
#region TriggerNotification
[Fact]
- public async Task TriggerNotification_WithValid_CallsExpected()
+ public async Task TriggerNotification_CredentialRejected_WithValid_CallsExpected()
{
// Arrange
var requesterId = Guid.NewGuid();
@@ -181,12 +184,32 @@ public async Task TriggerNotification_WithValid_CallsExpected()
result.nextStepTypeIds.Should().ContainSingle().Which.Should().Be(ProcessStepTypeId.TRIGGER_MAIL);
}
+ [Fact]
+ public async Task TriggerNotification_CredentialRenewal_WithValid_CallsExpected()
+ {
+ // Arrange
+ var requesterId = Guid.NewGuid();
+ A.CallTo(() => _reissuanceRepository.IsCredentialRevokedByReissuance(_credentialId)).Returns(true);
+ A.CallTo(() => _credentialRepository.GetCredentialNotificationData(_credentialId))
+ .Returns((VerifiedCredentialExternalTypeId.BUSINESS_PARTNER_NUMBER, requesterId.ToString()));
+
+ // Act
+ var result = await _sut.TriggerNotification(_credentialId, CancellationToken.None);
+
+ // Assert
+ A.CallTo(() => _portalService.AddNotification(A._, requesterId, NotificationTypeId.CREDENTIAL_RENEWAL, 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()
+ public async Task TriggerMail_CredentialRejected_WithValid_CallsExpected()
{
// Arrange
var requesterId = Guid.NewGuid();
@@ -205,5 +228,25 @@ public async Task TriggerMail_WithValid_CallsExpected()
result.nextStepTypeIds.Should().BeNull();
}
+ [Fact]
+ public async Task TriggerMail_CredentialRenewal_WithValid_CallsExpected()
+ {
+ // Arrange
+ var requesterId = Guid.NewGuid();
+ A.CallTo(() => _reissuanceRepository.IsCredentialRevokedByReissuance(_credentialId)).Returns(true);
+ A.CallTo(() => _credentialRepository.GetCredentialNotificationData(_credentialId))
+ .Returns((VerifiedCredentialExternalTypeId.MEMBERSHIP_CREDENTIAL, requesterId.ToString()));
+
+ // Act
+ var result = await _sut.TriggerMail(_credentialId, CancellationToken.None);
+
+ // Assert
+ A.CallTo(() => _portalService.TriggerMail("CredentialRenewal", requesterId, A>._, A._))
+ .MustHaveHappenedOnceExactly();
+ result.modified.Should().BeFalse();
+ result.processMessage.Should().BeNull();
+ result.stepStatusId.Should().Be(ProcessStepStatusId.DONE);
+ result.nextStepTypeIds.Should().BeNull();
+ }
#endregion
}