From 5e005560c62d4f50fdad4b0b7cede355cced9753 Mon Sep 17 00:00:00 2001 From: Shailesh Patil Date: Tue, 7 Jan 2025 16:16:14 +0000 Subject: [PATCH] fix: Add disclose claims to presentation record credential type SDJWT (#1487) Signed-off-by: mineme0110 --- .../server/jobs/PresentBackgroundJobs.scala | 39 +++++++++++++++---- .../controller/http/PresentationStatus.scala | 17 ++++++++ .../http/PresentationStatusPage.scala | 5 +++ .../core/model/PresentationRecord.scala | 4 ++ .../repository/PresentationRepository.scala | 5 +++ .../core/service/PresentationService.scala | 5 +++ .../service/PresentationServiceImpl.scala | 18 +++++++++ .../service/PresentationServiceNotifier.scala | 7 ++++ .../PresentationRepositoryInMemory.scala | 29 ++++++++++++++ .../PresentationRepositorySpecSuite.scala | 1 + .../service/MockPresentationService.scala | 5 +++ .../PresentationServiceNotifierSpec.scala | 1 + .../pollux/sdjwt/ValidClaimsSpec.scala | 2 +- ...30__add_sdjwt_disclosed_claims_columns.sql | 3 ++ .../JdbcPresentationRepository.scala | 29 ++++++++++++++ 15 files changed, 161 insertions(+), 9 deletions(-) create mode 100644 pollux/sql-doobie/src/main/resources/sql/pollux/V30__add_sdjwt_disclosed_claims_columns.sql diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala index c1177b2da2..c79d84121b 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala @@ -124,18 +124,19 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => ZIO.unit - case PresentationRecord(_, _, _, _, _, _, _, InvitationExpired, _, _, _, _, _, _, _, _, _, _, _, _, _, _) => + case PresentationRecord(_, _, _, _, _, _, _, InvitationExpired, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) => ZIO.unit - case PresentationRecord(id, _, _, _, _, _, _, ProposalPending, _, _, _, _, _, _, _, _, _, _, _, _, _, _) => + case PresentationRecord(id, _, _, _, _, _, _, ProposalPending, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) => ZIO.fail(NotImplemented) - case PresentationRecord(id, _, _, _, _, _, _, ProposalSent, _, _, _, _, _, _, _, _, _, _, _, _, _, _) => + case PresentationRecord(id, _, _, _, _, _, _, ProposalSent, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) => ZIO.fail(NotImplemented) - case PresentationRecord(id, _, _, _, _, _, _, ProposalReceived, _, _, _, _, _, _, _, _, _, _, _, _, _, _) => + case PresentationRecord(id, _, _, _, _, _, _, ProposalReceived, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) => ZIO.fail(NotImplemented) - case PresentationRecord(id, _, _, _, _, _, _, ProposalRejected, _, _, _, _, _, _, _, _, _, _, _, _, _, _) => + case PresentationRecord(id, _, _, _, _, _, _, ProposalRejected, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) => ZIO.fail(NotImplemented) case PresentationRecord( id, @@ -159,6 +160,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => // Verifier ZIO.fail(InvalidState("PresentationRecord 'RequestPending' with no Record")) @@ -184,6 +186,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => // Verifier Verifier.handleRequestPending(id, requestPresentation) @@ -209,6 +212,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => // Verifier ZIO.logDebug("PresentationRecord: RequestSent") *> ZIO.unit @@ -234,6 +238,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => // Prover ZIO.logDebug("PresentationRecord: RequestReceived") *> ZIO.unit @@ -259,6 +264,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => // Prover ZIO.logDebug("PresentationRecord: RequestRejected") *> ZIO.unit @@ -284,10 +290,11 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => ZIO.fail(NotImplemented) - case PresentationRecord(id, _, _, _, _, _, _, ProblemReportSent, _, _, _, _, _, _, _, _, _, _, _, _, _, _) => + case PresentationRecord(id, _, _, _, _, _, _, ProblemReportSent, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) => ZIO.fail(NotImplemented) case PresentationRecord( id, @@ -311,6 +318,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => ZIO.fail(NotImplemented) @@ -336,6 +344,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => // Prover ZIO.fail(InvalidState("PresentationRecord 'RequestPending' with no Record")) @@ -362,6 +371,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => // Prover Prover.PresentationPending.handle( @@ -394,6 +404,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => // Prover ZIO.fail(InvalidState("PresentationRecord in 'PresentationGenerated' with no Presentation")) @@ -420,12 +431,13 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => // Prover ZIO.logDebug("PresentationRecord: PresentationGenerated") *> ZIO.unit Prover.handlePresentationGenerated(id, presentation) - case PresentationRecord(id, _, _, _, _, _, _, PresentationSent, _, _, _, _, _, _, _, _, _, _, _, _, _, _) => + case PresentationRecord(id, _, _, _, _, _, _, PresentationSent, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) => ZIO.logDebug("PresentationRecord: PresentationSent") *> ZIO.unit case PresentationRecord( id, @@ -449,6 +461,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => // Verifier ZIO.fail(InvalidState("PresentationRecord in 'PresentationReceived' with no Presentation")) @@ -474,6 +487,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => ZIO.fail(InvalidState("PresentationRecord in 'PresentationReceived' with no Presentation Request")) @@ -499,6 +513,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => // Verifier ZIO.logDebug("PresentationRecord: PresentationReceived") *> ZIO.unit @@ -526,6 +541,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => ZIO.logDebug("PresentationRecord: PresentationVerificationFailed") *> ZIO.unit @@ -551,6 +567,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => ZIO.logDebug("PresentationRecord: PresentationVerifiedAccepted") *> ZIO.unit @@ -576,6 +593,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => ZIO.logDebug("PresentationRecord: PresentationVerified") *> ZIO.unit @@ -601,6 +619,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, _, _, + _, _ ) => ZIO.logDebug("PresentationRecord: PresentationRejected") *> ZIO.unit @@ -1224,12 +1243,16 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { verifiedClaims.mapError(error => PresentationReceivedError(error.toString)) case any => ZIO.fail(PresentationReceivedError("Only Base64 Supported")) } + service <- ZIO.service[PresentationService] _ <- credentialsClaimsValidationResult match case valid: SDJWT.Valid => ZIO.logInfo(s"CredentialsClaimsValidationResult: $valid") + val jsonObj = valid.asInstanceOf[SDJWT.ValidClaims].claims + service + .updateWithSDJWTDisclosedClaims(id, jsonObj) + .provideSomeLayer(ZLayer.succeed(walletAccessContext)) case invalid: SDJWT.Invalid => ZIO.logError(s"CredentialsClaimsValidationResult: $invalid") - service <- ZIO.service[PresentationService] presReceivedToProcessedAspect = CustomMetricsAspect.endRecordingTime( s"${id}_present_proof_flow_verifier_presentation_received_to_verification_success_or_failure_ms_gauge", "present_proof_flow_verifier_presentation_received_to_verification_success_or_failure_ms_gauge" diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/PresentationStatus.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/PresentationStatus.scala index 18e7f0ccfc..301b6c8321 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/PresentationStatus.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/PresentationStatus.scala @@ -7,7 +7,9 @@ import org.hyperledger.identus.pollux.core.model.PresentationRecord import org.hyperledger.identus.presentproof.controller.http.PresentationStatus.annotations import org.hyperledger.identus.shared.models.{FailureInfo, StatusCode} import sttp.tapir.{Schema, Validator} +import sttp.tapir.json.zio.schemaForZioJsonValue import sttp.tapir.Schema.annotations.{description, encodedExample, validate} +import zio.json.* import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} import zio.json.EncoderOps @@ -35,6 +37,9 @@ final case class PresentationStatus( @description(annotations.requestData.description) @encodedExample(annotations.requestData.example) requestData: Seq[String], + @description(annotations.disclosedClaims.description) + @encodedExample(annotations.disclosedClaims.example) + disclosedClaims: Option[zio.json.ast.Json], @description(annotations.connectionId.description) @encodedExample(annotations.connectionId.example) connectionId: Option[String] = None, @@ -68,6 +73,7 @@ object PresentationStatus { status = domain.protocolState.toString, proofs = Seq.empty, data = data, + disclosedClaims = domain.sdJwtDisclosedClaims, requestData = requestData, connectionId = domain.connectionId, invitation = domain.invitation.map(invitation => OOBPresentationInvitation.fromDomain(invitation)), @@ -159,6 +165,17 @@ object PresentationStatus { description = "The list of proofs presented by the prover to the verifier.", example = Seq.empty ) + + object disclosedClaims + extends Annotation[zio.json.ast.Json]( + description = """ + |The set of claims disclosed from the issued credential, this field is applicable to credential type SDJWT only. + |""".stripMargin, + example = zio.json.ast.Json.Obj( + "firstname" -> zio.json.ast.Json.Str("Alice"), + "lastname" -> zio.json.ast.Json.Str("Wonderland"), + ) + ) object requestData extends Annotation[Seq[String]]( description = "The list of request presented by the verifier to the prover.", diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/PresentationStatusPage.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/PresentationStatusPage.scala index d9cf2d1986..1105f09f31 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/PresentationStatusPage.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/PresentationStatusPage.scala @@ -71,6 +71,7 @@ object PresentationStatusPage { status = "RequestSent", proofs = Seq.empty, data = Seq.empty, + disclosedClaims = None, requestData = Seq.empty, connectionId = Some("e0d81be9-47ca-4e0b-b8a7-325e8c3abc2f"), invitation = None, @@ -82,6 +83,7 @@ object PresentationStatusPage { role = "Prover", status = "RequestReceived", proofs = Seq.empty, + disclosedClaims = None, requestData = Seq.empty, data = Seq.empty, metaRetries = 5 @@ -92,6 +94,7 @@ object PresentationStatusPage { role = "Prover", status = "PresentationPending", proofs = Seq.empty, + disclosedClaims = None, requestData = Seq.empty, data = Seq.empty, metaRetries = 5 @@ -102,6 +105,7 @@ object PresentationStatusPage { role = "Verifier", status = "PresentationVerified", proofs = Seq.empty, + disclosedClaims = None, requestData = Seq.empty, data = Seq( "{\"claimsToDisclose\":{\"emailAddress\":{},\"givenName\":{}},\"presentation\":\"{\\\"protected\\\":\\\"eyJhbGciOiJFZERTQSJ9\\\",\\\"payload\\\":\\\"eyJfc2QiOlsiMGl4d0tIV0dzbzFvZThFR0hQd2tGYW9EZE1TRFQ3SmgyNkZGSm1ZbGRnRSIsIjQ4VlFXZS1tcjBibHMyOWpicHFKeDNxX2dYY0k5N3dHcEpsZnRoNXQwMGciLCI0Wk9xanFNZVNUVHRKQTNJRExsc3ZXN0dTNzRIemNxY3N2NVFoZk1valE4IiwiUjhGRE0ydXB1V09mNmVJMVA5ckNPdG12c3puVWFFYXpncVNuN0JfeTE0MCIsIlU5MmpfUHlpcHN2TERNQTlDaVRWbnl3bUFzYTM4S2lDWm5TeVhyUE5mNG8iLCJldFB1Mmc5ajdRd01rZ3g5VnpEX1RnNTNUV3UydVpadk1KeHRnNEJ1WGJBIiwidGV3RG1LWklNcS10bUNrMkpqZU0wajNYbU1aUUFLN01heENVNlF4dm9OMCJdLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6ImRpZDpwcmlzbToxMmEzOWI1YWEwZTcxODI3ZmMxYzYwMjg1ZDVlZWJjMTk0Yjg2NzFhYTJmY2QxZDM2NDBkMGYwMTBlMzliZmVlIiwiaWF0IjoxNzE3NDEwMzgzLCJleHAiOjE3MjAwMDIzODN9\\\",\\\"signature\\\":\\\"953FfSRU_0Y2q0ERrFPzbXJ_hkF0YQe5efwESaZwtXDCn8aanD3MUstp3lzqGZkhvcWRdtCCpIxzhy0zgKwLBg\\\",\\\"disclosures\\\":[\\\"WyI0SHF6MDZCeG5fRlJMb2hWX2lWNXp3IiwgImdpdmVuTmFtZSIsICJBbGljZSJd\\\",\\\"WyJLUnNYYU01c3NXZTl4UEhqQnNjT213IiwgImVtYWlsQWRkcmVzcyIsICJhbGljZUB3b25kZXJsYW5kLmNvbSJd\\\"],\\\"kb_jwt\\\":null}\"}" @@ -115,6 +119,7 @@ object PresentationStatusPage { role = "Verifier", status = "InvitationGenerated", proofs = Seq.empty, + disclosedClaims = None, data = Seq.empty, requestData = Seq.empty, connectionId = None, diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/PresentationRecord.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/PresentationRecord.scala index 6a737dcdc0..f5add2e30e 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/PresentationRecord.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/PresentationRecord.scala @@ -10,6 +10,7 @@ import java.time.Instant type AnoncredCredentialProofs = zio.json.ast.Json type SdJwtCredentialToDisclose = zio.json.ast.Json +type SdJwtDisclosedClaims = zio.json.ast.Json final case class PresentationRecord( id: DidCommID, @@ -30,6 +31,7 @@ final case class PresentationRecord( anoncredCredentialsToUse: Option[AnoncredCredentialProofs], sdJwtClaimsToUseJsonSchemaId: Option[String], sdJwtClaimsToDisclose: Option[SdJwtCredentialToDisclose], + sdJwtDisclosedClaims: Option[SdJwtDisclosedClaims], metaRetries: Int, metaNextRetry: Option[Instant], metaLastFailure: Option[Failure], @@ -64,6 +66,7 @@ object PresentationRecord { anoncredCredentialsToUse: Option[AnoncredCredentialProofs], sdJwtClaimsToUseJsonSchemaId: Option[String], sdJwtClaimsToDisclose: Option[SdJwtCredentialToDisclose], + sdJwtDisclosedClaims: Option[SdJwtDisclosedClaims], metaRetries: Int, metaNextRetry: Option[Instant], metaLastFailure: Option[Failure] @@ -88,6 +91,7 @@ object PresentationRecord { anoncredCredentialsToUse, sdJwtClaimsToUseJsonSchemaId, sdJwtClaimsToDisclose, + sdJwtDisclosedClaims, metaRetries, metaNextRetry, metaLastFailure, diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepository.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepository.scala index 55b7443a0e..0760d0cace 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepository.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepository.scala @@ -47,6 +47,11 @@ trait PresentationRepository { protocolState: ProtocolState ): URIO[WalletAccessContext, Unit] + def updateWithSDJWTDisclosedClaims( + recordId: DidCommID, + sdJwtDisclosedClaims: SdJwtDisclosedClaims, + ): URIO[WalletAccessContext, Unit] + def updateWithPresentation( recordId: DidCommID, presentation: Presentation, diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationService.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationService.scala index 20426ec477..d3abf28e3d 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationService.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationService.scala @@ -171,6 +171,11 @@ trait PresentationService { recordId: DidCommID ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] + def updateWithSDJWTDisclosedClaims( + recordId: DidCommID, + claimsDisclosed: SdJwtDisclosedClaims + ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] + def verifyAnoncredPresentation( presentation: Presentation, requestPresentation: RequestPresentation, diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceImpl.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceImpl.scala index 43a9dce134..443995ad80 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceImpl.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceImpl.scala @@ -453,6 +453,7 @@ private class PresentationServiceImpl( anoncredCredentialsToUse = None, sdJwtClaimsToUseJsonSchemaId = None, sdJwtClaimsToDisclose = None, + sdJwtDisclosedClaims = None, metaRetries = maxRetries, metaNextRetry = Some(Instant.now()), metaLastFailure = None @@ -532,6 +533,7 @@ private class PresentationServiceImpl( anoncredCredentialsToUse = None, sdJwtClaimsToUseJsonSchemaId = None, sdJwtClaimsToDisclose = None, + sdJwtDisclosedClaims = None, metaRetries = maxRetries, metaNextRetry = Some(Instant.now()), metaLastFailure = None, @@ -865,6 +867,22 @@ private class PresentationServiceImpl( } yield record } + def updateWithSDJWTDisclosedClaims( + recordId: DidCommID, + claimsDisclosed: SdJwtDisclosedClaims + ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = { + for { + record <- getRecordWithState(recordId, ProtocolState.PresentationReceived) + _ <- + presentationRepository + .updateWithSDJWTDisclosedClaims( + recordId, + claimsDisclosed + ) + record <- getRecord(recordId) + } yield record + } + override def acceptAnoncredRequestPresentation( recordId: DidCommID, credentialsToUse: AnoncredCredentialProofsV1 diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceNotifier.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceNotifier.scala index 350c161100..abf7d95aaf 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceNotifier.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceNotifier.scala @@ -14,6 +14,7 @@ import org.hyperledger.identus.pollux.vc.jwt.{Issuer, PresentationPayload, W3cCr import org.hyperledger.identus.shared.models.* import zio.* import zio.json.* +import zio.json.ast.Json import zio.URIO import java.time.Instant @@ -328,6 +329,12 @@ class PresentationServiceNotifier( invitation: String ): ZIO[WalletAccessContext, PresentationError, RequestPresentation] = svc.getRequestPresentationFromInvitation(pairwiseProverDID, invitation) + + override def updateWithSDJWTDisclosedClaims( + recordId: DidCommID, + claimsDisclosed: Json + ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = + svc.updateWithSDJWTDisclosedClaims(recordId, claimsDisclosed) } object PresentationServiceNotifier { diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepositoryInMemory.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepositoryInMemory.scala index b058da5cae..2fc7dccc2a 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepositoryInMemory.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepositoryInMemory.scala @@ -311,6 +311,35 @@ class PresentationRepositoryInMemory( result.ensureOneAffectedRowOrDie } + override def updateWithSDJWTDisclosedClaims( + recordId: DidCommID, + sdJwtDisclosedClaims: SdJwtDisclosedClaims, + ): URIO[WalletAccessContext, Unit] = { + val result = + for { + storeRef <- walletStoreRef + maybeRecord <- findPresentationRecord(recordId) + count <- maybeRecord + .map(record => + for { + _ <- storeRef.update(r => + r.updated( + recordId, + record.copy( + updatedAt = Some(Instant.now), + sdJwtDisclosedClaims = Some(sdJwtDisclosedClaims), + metaRetries = maxRetries, + metaLastFailure = None, + ) + ) + ) + } yield 1 + ) + .getOrElse(ZIO.succeed(0)) + } yield count + result.ensureOneAffectedRowOrDie + } + override def updateWithProposePresentation( recordId: DidCommID, request: ProposePresentation, diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepositorySpecSuite.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepositorySpecSuite.scala index 3491c070db..82aca576aa 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepositorySpecSuite.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepositorySpecSuite.scala @@ -36,6 +36,7 @@ object PresentationRepositorySpecSuite { anoncredCredentialsToUse = None, sdJwtClaimsToUseJsonSchemaId = None, sdJwtClaimsToDisclose = None, + sdJwtDisclosedClaims = None, metaRetries = maxRetries, metaNextRetry = Some(Instant.now()), metaLastFailure = None diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/MockPresentationService.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/MockPresentationService.scala index dad75bfcee..11196fd540 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/MockPresentationService.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/MockPresentationService.scala @@ -332,6 +332,11 @@ object MockPresentationService extends Mock[PresentationService] { override def findPresentationRecord(recordId: DidCommID): URIO[WalletAccessContext, Option[PresentationRecord]] = ??? + def updateWithSDJWTDisclosedClaims( + recordId: DidCommID, + claimsDisclosed: ast.Json + ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = ??? + override def findPresentationRecordByThreadId( thid: DidCommID ): IO[PresentationError, Option[PresentationRecord]] = diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceNotifierSpec.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceNotifierSpec.scala index 8f4197a57a..033b6c4b05 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceNotifierSpec.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceNotifierSpec.scala @@ -39,6 +39,7 @@ object PresentationServiceNotifierSpec extends ZIOSpecDefault with PresentationS None, None, None, + None, 5, None, None, diff --git a/pollux/sd-jwt/src/test/scala/org/hyperledger/identus/pollux/sdjwt/ValidClaimsSpec.scala b/pollux/sd-jwt/src/test/scala/org/hyperledger/identus/pollux/sdjwt/ValidClaimsSpec.scala index 140f255e1e..4a3c4b4c97 100644 --- a/pollux/sd-jwt/src/test/scala/org/hyperledger/identus/pollux/sdjwt/ValidClaimsSpec.scala +++ b/pollux/sd-jwt/src/test/scala/org/hyperledger/identus/pollux/sdjwt/ValidClaimsSpec.scala @@ -71,7 +71,7 @@ object ValidClaimsSpec extends ZIOSpecDefault { """.stripMargin.fromJson[ast.Json.Obj] } yield SDJWT.ValidClaims(claims).verifyDiscoseClaims(expected) assert(ret)(isRight(equalTo(SDJWT.ClaimsDoNotMatch))) - }, + } ) } diff --git a/pollux/sql-doobie/src/main/resources/sql/pollux/V30__add_sdjwt_disclosed_claims_columns.sql b/pollux/sql-doobie/src/main/resources/sql/pollux/V30__add_sdjwt_disclosed_claims_columns.sql new file mode 100644 index 0000000000..23b62e17bb --- /dev/null +++ b/pollux/sql-doobie/src/main/resources/sql/pollux/V30__add_sdjwt_disclosed_claims_columns.sql @@ -0,0 +1,3 @@ +-- presentation_records +ALTER TABLE public.presentation_records + ADD COLUMN "sd_jwt_disclosed_claims" JSON; \ No newline at end of file diff --git a/pollux/sql-doobie/src/main/scala/org/hyperledger/identus/pollux/sql/repository/JdbcPresentationRepository.scala b/pollux/sql-doobie/src/main/scala/org/hyperledger/identus/pollux/sql/repository/JdbcPresentationRepository.scala index db5d2c9002..2eceb47f4d 100644 --- a/pollux/sql-doobie/src/main/scala/org/hyperledger/identus/pollux/sql/repository/JdbcPresentationRepository.scala +++ b/pollux/sql-doobie/src/main/scala/org/hyperledger/identus/pollux/sql/repository/JdbcPresentationRepository.scala @@ -166,6 +166,7 @@ class JdbcPresentationRepository( | anoncred_credentials_to_use, | sd_jwt_claims_to_use_json_schema_id, | sd_jwt_claims_to_disclose, + | sd_jwt_disclosed_claims, | meta_retries, | meta_next_retry, | meta_last_failure, @@ -187,6 +188,7 @@ class JdbcPresentationRepository( | ${record.anoncredCredentialsToUse}, | ${record.sdJwtClaimsToUseJsonSchemaId}, | ${record.sdJwtClaimsToDisclose}, + | ${record.sdJwtDisclosedClaims}, | ${record.metaRetries}, | ${record.metaNextRetry}, | ${record.metaLastFailure}, @@ -226,6 +228,7 @@ class JdbcPresentationRepository( | anoncred_credentials_to_use, | sd_jwt_claims_to_use_json_schema_id, | sd_jwt_claims_to_disclose, + | sd_jwt_disclosed_claims, | meta_retries, | meta_next_retry, | meta_last_failure, @@ -278,6 +281,7 @@ class JdbcPresentationRepository( | anoncred_credentials_to_use, | sd_jwt_claims_to_use_json_schema_id, | sd_jwt_claims_to_disclose, + | sd_jwt_disclosed_claims, | meta_retries, | meta_next_retry, | meta_last_failure, @@ -327,6 +331,7 @@ class JdbcPresentationRepository( | anoncred_credentials_to_use, | sd_jwt_claims_to_use_json_schema_id, | sd_jwt_claims_to_disclose, + | sd_jwt_disclosed_claims, | meta_retries, | meta_next_retry, | meta_last_failure, @@ -365,6 +370,7 @@ class JdbcPresentationRepository( | anoncred_credentials_to_use, | sd_jwt_claims_to_use_json_schema_id, | sd_jwt_claims_to_disclose, + | sd_jwt_disclosed_claims, | meta_retries, | meta_next_retry, | meta_last_failure, @@ -401,6 +407,7 @@ class JdbcPresentationRepository( | anoncred_credentials_to_use, | sd_jwt_claims_to_use_json_schema_id, | sd_jwt_claims_to_disclose, + | sd_jwt_disclosed_claims, | meta_retries, | meta_next_retry, | meta_last_failure, @@ -511,6 +518,28 @@ class JdbcPresentationRepository( .ensureOneAffectedRowOrDie } + override def updateWithSDJWTDisclosedClaims( + recordId: DidCommID, + sdJwtDisclosedClaims: SdJwtDisclosedClaims + ): URIO[WalletAccessContext, Unit] = { + val cxnIO = sql""" + | UPDATE public.presentation_records + | SET + | sd_jwt_disclosed_claims = $sdJwtDisclosedClaims, + | updated_at = ${Instant.now}, + | meta_retries = $maxRetries, + | meta_next_retry = ${Instant.now}, + | meta_last_failure = null + | WHERE + | id = $recordId + """.stripMargin.update + + cxnIO.run + .transactWallet(xa) + .orDie + .ensureOneAffectedRowOrDie + } + override def updateAfterFail( recordId: DidCommID, failReason: Option[Failure]