From 9ac6e52ec447710ae7917d8176dcb0ebdc6b2e0d Mon Sep 17 00:00:00 2001 From: Bassam Date: Thu, 13 Jun 2024 21:41:33 -0400 Subject: [PATCH] fix: present error handling Part 2 (#1177) Signed-off-by: Bassam Riman --- .../server/jobs/PresentBackgroundJobs.scala | 2 +- .../controller/PresentProofController.scala | 48 ----- .../PresentProofControllerImpl.scala | 20 +- .../CredentialSchemaMultiTenancySpec.scala | 7 +- .../CredentialDefinitionServiceError.scala | 3 +- .../error}/CredentialSchemaServiceError.scala | 2 +- .../core/model/error/PresentationError.scala | 171 ++++++++++++++++-- .../service/CredentialDefinitionService.scala | 1 + .../CredentialDefinitionServiceImpl.scala | 8 +- .../service/CredentialSchemaService.scala | 1 + .../service/CredentialSchemaServiceImpl.scala | 8 +- .../core/service/CredentialServiceImpl.scala | 1 - .../service/MockPresentationService.scala | 6 +- .../core/service/PresentationService.scala | 6 +- .../service/PresentationServiceImpl.scala | 61 ++++--- .../service/PresentationServiceNotifier.scala | 10 +- 16 files changed, 219 insertions(+), 136 deletions(-) rename pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/{service => model/error}/CredentialDefinitionServiceError.scala (89%) rename pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/{service => model/error}/CredentialSchemaServiceError.scala (95%) 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 ed6f7ac767..20674bec8b 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 @@ -485,7 +485,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { presentation <- for { presentation <- presentationService - .createSDJwtPresentation(id, requestPresentation, prover) + .createSDJwtPresentation(id, requestPresentation) .provideSomeLayer(ZLayer.succeed(walletAccessContext)) } yield presentation _ <- presentationService diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofController.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofController.scala index dcab472a4e..027dc6ce7b 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofController.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofController.scala @@ -2,7 +2,6 @@ package org.hyperledger.identus.presentproof.controller import org.hyperledger.identus.api.http.{ErrorResponse, RequestContext} import org.hyperledger.identus.api.http.model.PaginationInput -import org.hyperledger.identus.pollux.core.model.error.PresentationError import org.hyperledger.identus.presentproof.controller.http.* import org.hyperledger.identus.shared.models.WalletAccessContext import zio.ZIO @@ -35,53 +34,6 @@ trait PresentProofController { } object PresentProofController { - def toHttpError(error: PresentationError): ErrorResponse = - error match - case PresentationError.RecordIdNotFound(recordId) => - ErrorResponse.notFound(detail = Some(s"Record Id not found: $recordId")) - case PresentationError.ThreadIdNotFound(thid) => - ErrorResponse.notFound(detail = Some(s"Thread Id not found: $thid")) - case PresentationError.InvalidFlowStateError(msg) => - ErrorResponse.badRequest(title = "InvalidFlowState", detail = Some(msg)) - case PresentationError.MissingAnoncredPresentationRequest(msg) => - ErrorResponse.badRequest(title = "Missing Anoncred Presentation Request", detail = Some(msg)) - case PresentationError.AnoncredPresentationCreationError(cause) => - ErrorResponse.badRequest(title = "Error Creating Anoncred Presentation", detail = Some(cause.toString)) - case PresentationError.AnoncredPresentationVerificationError(cause) => - ErrorResponse.badRequest(title = "Error Verifying Prensetation", detail = Some(cause.toString)) - case PresentationError.InvalidAnoncredPresentationRequest(msg) => - ErrorResponse.badRequest(title = "Invalid Anoncred Presentation Request", detail = Some(msg)) - case PresentationError.InvalidAnoncredPresentation(msg) => - ErrorResponse.badRequest(title = "Invalid Anoncred Presentation", detail = Some(msg)) - case PresentationError.NotMatchingPresentationCredentialFormat(cause) => - ErrorResponse.badRequest( - title = "Presentation and Credential Format Not Matching", - detail = Some(cause.toString) - ) - case PresentationError.UnexpectedError(msg) => - ErrorResponse.internalServerError(detail = Some(msg)) - case PresentationError.IssuedCredentialNotFoundError(_) => - ErrorResponse.internalServerError(detail = Some("Issued credential not found")) - case PresentationError.PresentationDecodingError(_) => - ErrorResponse.internalServerError(detail = Some("Presentation decoding error")) - case PresentationError.HolderBindingError(msg) => - ErrorResponse.internalServerError(detail = Some(s"Holder binding error: $msg")) - case PresentationError.MissingCredential => - ErrorResponse.badRequest( - title = "MissingCredential", - detail = Some("The Credential is missing from attachments") - ) - case PresentationError.MissingCredentialFormat => - ErrorResponse.badRequest( - title = "MissingCredentialFormat", - detail = Some("The Credential format is missing from the credential in attachment") - ) - case PresentationError.UnsupportedCredentialFormat(format) => - ErrorResponse.badRequest( - title = "UnsupportedCredentialFormat", - detail = Some(s"The Credential format '$format' is not Unsupported") - ) - def toDidCommID(str: String): ZIO[Any, ErrorResponse, org.hyperledger.identus.pollux.core.model.DidCommID] = ZIO .fromTry(Try(org.hyperledger.identus.pollux.core.model.DidCommID(str))) diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofControllerImpl.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofControllerImpl.scala index f9ec59216c..6d4ee6b041 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofControllerImpl.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofControllerImpl.scala @@ -19,6 +19,7 @@ import zio.json.* import zio.json.ast.Json import java.util.UUID +import scala.language.implicitConversions class PresentProofControllerImpl( presentationService: PresentationService, @@ -95,11 +96,7 @@ class PresentProofControllerImpl( } } } yield PresentationStatus.fromDomain(record) - - result.mapError { - case e: ConnectionServiceError => e.asInstanceOf[ErrorResponse] // use implicit conversion - case e: PresentationError => PresentProofController.toHttpError(e) - } + result } override def getPresentations(paginationInput: PaginationInput, thid: Option[String])(implicit @@ -113,7 +110,7 @@ class PresentProofControllerImpl( records.map(PresentationStatus.fromDomain) ) - result.mapError(PresentProofController.toHttpError) + result } override def getPresentation( @@ -126,11 +123,7 @@ class PresentProofControllerImpl( .fromOption(maybeRecord) .mapError(_ => ErrorResponse.notFound(detail = Some(s"Presentation record not found: $id"))) } yield PresentationStatus.fromDomain(record) - - result.mapError { - case e: ErrorResponse => e - case e: PresentationError => PresentProofController.toHttpError(e) - } + result } override def updatePresentation(id: UUID, requestPresentationAction: RequestPresentationAction)(implicit @@ -173,10 +166,7 @@ class PresentProofControllerImpl( } } yield PresentationStatus.fromDomain(record) - result.mapError { - case e: ErrorResponse => e - case e: PresentationError => PresentProofController.toHttpError(e) - } + result } } diff --git a/cloud-agent/service/server/src/test/scala/org/hyperledger/identus/pollux/schema/CredentialSchemaMultiTenancySpec.scala b/cloud-agent/service/server/src/test/scala/org/hyperledger/identus/pollux/schema/CredentialSchemaMultiTenancySpec.scala index b3ee1bf8a5..8737c4a1a5 100644 --- a/cloud-agent/service/server/src/test/scala/org/hyperledger/identus/pollux/schema/CredentialSchemaMultiTenancySpec.scala +++ b/cloud-agent/service/server/src/test/scala/org/hyperledger/identus/pollux/schema/CredentialSchemaMultiTenancySpec.scala @@ -3,13 +3,10 @@ package org.hyperledger.identus.pollux.schema import com.dimafeng.testcontainers.PostgreSQLContainer import org.hyperledger.identus.agent.walletapi.model.Entity import org.hyperledger.identus.container.util.MigrationAspects.* +import org.hyperledger.identus.pollux.core.model.error.CredentialSchemaGuidNotFoundError import org.hyperledger.identus.pollux.core.model.schema.`type`.CredentialJsonSchemaType import org.hyperledger.identus.pollux.core.model.schema.CredentialSchema -import org.hyperledger.identus.pollux.core.service.{ - CredentialSchemaGuidNotFoundError, - CredentialSchemaService, - CredentialSchemaServiceImpl -} +import org.hyperledger.identus.pollux.core.service.{CredentialSchemaService, CredentialSchemaServiceImpl} import org.hyperledger.identus.pollux.sql.repository.JdbcCredentialSchemaRepository import zio.* import zio.json.* diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialDefinitionServiceError.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/CredentialDefinitionServiceError.scala similarity index 89% rename from pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialDefinitionServiceError.scala rename to pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/CredentialDefinitionServiceError.scala index 92ce5fefe6..34d2c20aac 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialDefinitionServiceError.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/CredentialDefinitionServiceError.scala @@ -1,6 +1,5 @@ -package org.hyperledger.identus.pollux.core.service +package org.hyperledger.identus.pollux.core.model.error -import org.hyperledger.identus.pollux.core.model.error.CredentialSchemaError import org.hyperledger.identus.pollux.core.model.schema.CredentialSchema import org.hyperledger.identus.pollux.core.model.schema.CredentialSchema.* import org.hyperledger.identus.shared.models.{Failure, StatusCode} diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialSchemaServiceError.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/CredentialSchemaServiceError.scala similarity index 95% rename from pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialSchemaServiceError.scala rename to pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/CredentialSchemaServiceError.scala index 2e27dfe9db..dc5eeb3e27 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialSchemaServiceError.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/CredentialSchemaServiceError.scala @@ -1,4 +1,4 @@ -package org.hyperledger.identus.pollux.core.service +package org.hyperledger.identus.pollux.core.model.error import org.hyperledger.identus.pollux.core.model.error.CredentialSchemaError import org.hyperledger.identus.pollux.core.model.schema.CredentialSchema diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/PresentationError.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/PresentationError.scala index 775b447550..6bbb93b01a 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/PresentationError.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/PresentationError.scala @@ -1,24 +1,161 @@ package org.hyperledger.identus.pollux.core.model.error +import org.hyperledger.identus.pollux.core.model.schema.validator.JsonSchemaError import org.hyperledger.identus.pollux.core.model.DidCommID +import org.hyperledger.identus.pollux.core.service.URIDereferencerError +import org.hyperledger.identus.shared.models.{Failure, StatusCode} -sealed trait PresentationError +sealed trait PresentationError( + val statusCode: StatusCode, + val userFacingMessage: String +) extends Failure { + override val namespace = "Presentation" +} object PresentationError { - final case class RecordIdNotFound(recordId: DidCommID) extends PresentationError - final case class ThreadIdNotFound(thid: DidCommID) extends PresentationError - final case class InvalidFlowStateError(msg: String) extends PresentationError - final case class UnexpectedError(msg: String) extends PresentationError - final case class IssuedCredentialNotFoundError(cause: String) extends PresentationError - final case class NotMatchingPresentationCredentialFormat(cause: Throwable) extends PresentationError - final case class PresentationDecodingError(cause: String) extends PresentationError - final case class HolderBindingError(msg: String) extends PresentationError - object MissingCredential extends PresentationError - object MissingCredentialFormat extends PresentationError - final case class UnsupportedCredentialFormat(vcFormat: String) extends PresentationError - final case class InvalidAnoncredPresentationRequest(error: String) extends PresentationError - final case class InvalidAnoncredPresentation(error: String) extends PresentationError - final case class MissingAnoncredPresentationRequest(error: String) extends PresentationError - final case class AnoncredPresentationCreationError(cause: Throwable) extends PresentationError - final case class AnoncredPresentationVerificationError(cause: Throwable) extends PresentationError + + // TODO: Remove once PresentationJob is cleaned + final case class UnexpectedError(error: String) + extends PresentationError( + StatusCode.InternalServerError, + error + ) + + final case class RecordIdNotFound(recordId: DidCommID) + extends PresentationError( + StatusCode.NotFound, + s"Record Id not found: $recordId" + ) + + final case class ThreadIdNotFound(thid: DidCommID) + extends PresentationError( + StatusCode.NotFound, + s"Thread Id not found: $thid" + ) + + final case class NoThreadIdFoundInRecord(presentationId: String) + extends PresentationError( + StatusCode.InternalServerError, + s"Presentation record has missing ThreadId for record: $presentationId" + ) + + final case class InvalidFlowStateError(msg: String) + extends PresentationError( + StatusCode.BadRequest, + msg + ) + + final case class RequestPresentationHasMultipleAttachment(presentationId: String) + extends PresentationError( + StatusCode.BadRequest, + s"Request Presentation with multi attachments: $presentationId" + ) + + final case class IssuedCredentialNotFoundError(cause: String) + extends PresentationError( + StatusCode.InternalServerError, + "Issued credential not found" + ) + + final case class InvalidSchemaURIError(schemaUri: String, error: Throwable) + extends PresentationError( + StatusCode.BadRequest, + s"Invalid Schema Uri: $schemaUri, Error: ${error.getMessage}" + ) + + final case class InvalidCredentialDefinitionURIError(credentialDefinitionUri: String, error: Throwable) + extends PresentationError( + StatusCode.BadRequest, + s"Invalid Credential Definition Uri: $credentialDefinitionUri, Error: ${error.getMessage}" + ) + + final case class SchemaURIDereferencingError(error: URIDereferencerError) + extends PresentationError( + error.statusCode, + error.userFacingMessage + ) + + final case class CredentialDefinitionURIDereferencingError(error: URIDereferencerError) + extends PresentationError( + error.statusCode, + error.userFacingMessage + ) + + final case class PresentationDecodingError(cause: String) + extends PresentationError( + StatusCode.InternalServerError, + s"Presentation decoding error: $cause" + ) + + final case class HolderBindingError(msg: String) + extends PresentationError( + StatusCode.InternalServerError, + s"Holder binding error: $msg" + ) + + object MissingCredential + extends PresentationError( + StatusCode.BadRequest, + s"The Credential is missing from attachments" + ) + + object MissingCredentialFormat + extends PresentationError( + StatusCode.BadRequest, + s"The Credential format is missing from the credential in attachment" + ) + + final case class UnsupportedCredentialFormat(vcFormat: String) + extends PresentationError( + StatusCode.BadRequest, + s"The Credential format '$vcFormat' is not Unsupported" + ) + + final case class InvalidAnoncredPresentationRequest(error: String) + extends PresentationError( + StatusCode.InternalServerError, + error + ) + + final case class InvalidAnoncredPresentation(error: String) + extends PresentationError( + StatusCode.InternalServerError, + error + ) + + final case class MissingAnoncredPresentationRequest(error: String) + extends PresentationError( + StatusCode.InternalServerError, + error + ) + + final case class NotMatchingPresentationCredentialFormat(cause: Throwable) + extends PresentationError( + StatusCode.BadRequest, + s"Presentation and Credential Format Not Matching: ${cause.toString}" + ) + + final case class AnoncredPresentationCreationError(cause: Throwable) + extends PresentationError( + StatusCode.InternalServerError, + cause.toString + ) + + final case class AnoncredCredentialProofParsingError(cause: String) + extends PresentationError( + StatusCode.BadRequest, + cause + ) + + final case class AnoncredPresentationParsingError(cause: JsonSchemaError) + extends PresentationError( + StatusCode.BadRequest, + cause.error + ) + + final case class AnoncredPresentationVerificationError(cause: Throwable) + extends PresentationError( + StatusCode.BadRequest, + cause.toString + ) } diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialDefinitionService.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialDefinitionService.scala index da0e77416e..1aecbbe7a4 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialDefinitionService.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialDefinitionService.scala @@ -1,5 +1,6 @@ package org.hyperledger.identus.pollux.core.service +import org.hyperledger.identus.pollux.core.model.error.CredentialDefinitionServiceError import org.hyperledger.identus.pollux.core.model.schema.CredentialDefinition import org.hyperledger.identus.pollux.core.model.schema.CredentialDefinition.* import org.hyperledger.identus.shared.models.WalletAccessContext diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialDefinitionServiceImpl.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialDefinitionServiceImpl.scala index 5bb4924432..9dcca15cee 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialDefinitionServiceImpl.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialDefinitionServiceImpl.scala @@ -3,7 +3,13 @@ package org.hyperledger.identus.pollux.core.service import org.hyperledger.identus.agent.walletapi.storage import org.hyperledger.identus.agent.walletapi.storage.GenericSecretStorage import org.hyperledger.identus.pollux.anoncreds.{AnoncredLib, AnoncredSchemaDef} -import org.hyperledger.identus.pollux.core.model.error.CredentialSchemaError +import org.hyperledger.identus.pollux.core.model.error.{ + CredentialDefinitionCreationError, + CredentialDefinitionGuidNotFoundError, + CredentialDefinitionServiceError, + CredentialDefinitionValidationError, + CredentialSchemaError +} import org.hyperledger.identus.pollux.core.model.error.CredentialSchemaError.{ CredentialSchemaParsingError, CredentialSchemaValidationError, diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialSchemaService.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialSchemaService.scala index f7de9c5663..1fdb69d04e 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialSchemaService.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialSchemaService.scala @@ -1,5 +1,6 @@ package org.hyperledger.identus.pollux.core.service +import org.hyperledger.identus.pollux.core.model.error.CredentialSchemaServiceError import org.hyperledger.identus.pollux.core.model.schema.CredentialSchema import org.hyperledger.identus.pollux.core.model.schema.CredentialSchema.* import org.hyperledger.identus.shared.models.WalletAccessContext diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialSchemaServiceImpl.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialSchemaServiceImpl.scala index cf03a3f876..ec96d7d678 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialSchemaServiceImpl.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialSchemaServiceImpl.scala @@ -1,6 +1,12 @@ package org.hyperledger.identus.pollux.core.service -import org.hyperledger.identus.pollux.core.model.error.CredentialSchemaError +import org.hyperledger.identus.pollux.core.model.error.{ + CredentialSchemaError, + CredentialSchemaGuidNotFoundError, + CredentialSchemaServiceError, + CredentialSchemaUpdateError, + CredentialSchemaValidationError +} import org.hyperledger.identus.pollux.core.model.schema.CredentialSchema import org.hyperledger.identus.pollux.core.model.schema.CredentialSchema.FilteredEntries import org.hyperledger.identus.pollux.core.repository.CredentialSchemaRepository diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceImpl.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceImpl.scala index 3ac0291ff8..295b8be99c 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceImpl.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceImpl.scala @@ -396,7 +396,6 @@ private class CredentialServiceImpl( guid: UUID ): UIO[CredentialDefinition] = credentialDefinitionService .getByGUID(guid) - .mapError(e => CredentialDefinitionServiceError(e.toString)) .orDieAsUnmanagedFailure private[this] def getCredentialDefinitionPrivatePart( diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/MockPresentationService.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/MockPresentationService.scala index db99586e7b..35060c4607 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/MockPresentationService.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/MockPresentationService.scala @@ -209,14 +209,12 @@ object MockPresentationService extends Mock[PresentationService] { ): IO[PresentationError, PresentationPayload] = ??? override def createPresentationFromRecord( - record: DidCommID, - issuer: Issuer, + record: DidCommID ): IO[PresentationError, PresentationCompact] = ??? def createSDJwtPresentation( recordId: DidCommID, - requestPresentation: RequestPresentation, - prover: Issuer, + requestPresentation: RequestPresentation ): ZIO[WalletAccessContext, PresentationError, Presentation] = ??? override def createAnoncredPresentationPayloadFromRecord( 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 ec2d34d16a..b7aab2f253 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 @@ -58,14 +58,12 @@ trait PresentationService { ): ZIO[WalletAccessContext, PresentationError, PresentationPayload] def createPresentationFromRecord( - record: DidCommID, - issuer: Issuer, + record: DidCommID ): ZIO[WalletAccessContext, PresentationError, PresentationCompact] def createSDJwtPresentation( recordId: DidCommID, - requestPresentation: RequestPresentation, - prover: Issuer, + requestPresentation: RequestPresentation ): ZIO[WalletAccessContext, PresentationError, Presentation] def createAnoncredPresentationPayloadFromRecord( 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 a70e78f516..921f1ea511 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 @@ -24,7 +24,6 @@ import zio.* import zio.json.* import java.net.URI -import java.rmi.UnexpectedException import java.time.Instant import java.util.{Base64 as JBase64, UUID} import java.util as ju @@ -95,8 +94,7 @@ private class PresentationServiceImpl( } override def createPresentationFromRecord( - recordId: DidCommID, - prover: Issuer + recordId: DidCommID ): ZIO[WalletAccessContext, PresentationError, PresentationCompact] = { for { @@ -136,11 +134,10 @@ private class PresentationServiceImpl( override def createSDJwtPresentation( recordId: DidCommID, - requestPresentation: RequestPresentation, - prover: Issuer, + requestPresentation: RequestPresentation ): ZIO[WalletAccessContext, PresentationError, Presentation] = { for { - presentationPayload <- createPresentationFromRecord(recordId, prover) + presentationPayload <- createPresentationFromRecord(recordId) presentation <- ZIO.succeed( Presentation( body = Presentation.Body( @@ -412,7 +409,7 @@ private class PresentationServiceImpl( .mapError(error => InvalidAnoncredPresentationRequest(error.error)) case _ => ZIO.fail(InvalidAnoncredPresentationRequest("Expecting Base64-encoded data")) case Some(unsupportedFormat) => ZIO.fail(PresentationError.UnsupportedCredentialFormat(unsupportedFormat)) - case _ => ZIO.fail(PresentationError.UnexpectedError("Presentation with multi attachments")) + case _ => ZIO.fail(PresentationError.RequestPresentationHasMultipleAttachment(request.id)) } record <- ZIO.succeed( PresentationRecord( @@ -661,14 +658,14 @@ private class PresentationServiceImpl( } yield presentation } - private def resolveSchema(schemaUri: String): IO[UnexpectedError, (String, AnoncredSchemaDef)] = { + private def resolveSchema(schemaUri: String): IO[PresentationError, (String, AnoncredSchemaDef)] = { for { - uri <- ZIO.attempt(new URI(schemaUri)).mapError(e => UnexpectedError(e.getMessage)) - content <- uriDereferencer.dereference(uri).mapError(e => UnexpectedError(e.userFacingMessage)) + uri <- ZIO.attempt(new URI(schemaUri)).mapError(e => InvalidSchemaURIError(schemaUri, e)) + content <- uriDereferencer.dereference(uri).mapError(e => SchemaURIDereferencingError(e)) anoncredSchema <- AnoncredSchemaSerDesV1.schemaSerDes .deserialize(content) - .mapError(error => UnexpectedError(s"AnonCreds Schema parsing error: $error")) + .mapError(error => AnoncredPresentationParsingError(error)) anoncredLibSchema = AnoncredSchemaDef( schemaUri, @@ -681,14 +678,16 @@ private class PresentationServiceImpl( private def resolveCredentialDefinition( credentialDefinitionUri: String - ): IO[UnexpectedError, (String, AnoncredCredentialDefinition)] = { + ): IO[PresentationError, (String, AnoncredCredentialDefinition)] = { for { - uri <- ZIO.attempt(new URI(credentialDefinitionUri)).mapError(e => UnexpectedError(e.getMessage)) - content <- uriDereferencer.dereference(uri).mapError(e => UnexpectedError(e.userFacingMessage)) + uri <- ZIO + .attempt(new URI(credentialDefinitionUri)) + .mapError(e => InvalidCredentialDefinitionURIError(credentialDefinitionUri, e)) + content <- uriDereferencer.dereference(uri).mapError(e => CredentialDefinitionURIDereferencingError(e)) _ <- PublicCredentialDefinitionSerDesV1.schemaSerDes .validate(content) - .mapError(error => UnexpectedError(s"AnonCreds Schema parsing error: $error")) + .mapError(error => AnoncredPresentationParsingError(error)) anoncredCredentialDefinition = AnoncredCredentialDefinition(content) } yield (credentialDefinitionUri, anoncredCredentialDefinition) } @@ -763,11 +762,7 @@ private class PresentationServiceImpl( .fromEither( AnoncredCredentialProofsV1.schemaSerDes.serialize(credentialsToUse) ) - .mapError(error => - PresentationError.UnexpectedError( - s"Unable to serialize credentialsToUse. credentialsToUse:$credentialsToUse, error:$error" - ) - ) + .mapError(error => PresentationError.AnoncredCredentialProofParsingError(error)) count <- presentationRepository .updateAnoncredPresentationWithCredentialsToUse( recordId, @@ -850,7 +845,12 @@ private class PresentationServiceImpl( presentation: Presentation ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = { for { - record <- getRecordFromThreadId(presentation.thid) + thid <- + ZIO + .fromOption(presentation.thid) + .map(DidCommID(_)) + .mapError(_ => NoThreadIdFoundInRecord(presentation.id)) + record <- getRecordFromThreadId(thid) _ <- presentationRepository .updateWithPresentation(record.id, presentation, ProtocolState.PresentationReceived) @@ CustomMetricsAspect .startRecordingTime( @@ -880,7 +880,12 @@ private class PresentationServiceImpl( proposePresentation: ProposePresentation ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = { for { - record <- getRecordFromThreadId(proposePresentation.thid) + thid <- + ZIO + .fromOption(proposePresentation.thid) + .map(DidCommID(_)) + .mapError(_ => NoThreadIdFoundInRecord(proposePresentation.id)) + record <- getRecordFromThreadId(thid) _ <- presentationRepository .updateWithProposePresentation(record.id, proposePresentation, ProtocolState.ProposalReceived) record <- getRecord(record.id) @@ -993,7 +998,7 @@ private class PresentationServiceImpl( deserializedPresentation <- AnoncredPresentationV1.schemaSerDes .deserialize(serializedPresentation.data) - .mapError(error => PresentationError.UnexpectedError(error.error)) + .mapError(error => AnoncredPresentationParsingError(error)) schemaIds = deserializedPresentation.identifiers.map(_.schema_id) schemaMap <- ZIO @@ -1047,18 +1052,14 @@ private class PresentationServiceImpl( } yield result private def getRecordFromThreadId( - thid: Option[String] + thid: DidCommID ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = { for { - thidID <- ZIO - .fromOption(thid) - .map(DidCommID(_)) - .mapError(_ => UnexpectedError("No `thid` found in Presentation request")) maybeRecord <- presentationRepository - .findPresentationRecordByThreadId(thidID) + .findPresentationRecordByThreadId(thid) record <- ZIO .fromOption(maybeRecord) - .mapError(_ => ThreadIdNotFound(thidID)) + .mapError(_ => ThreadIdNotFound(thid)) } yield record } 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 57cac47c11..e551ddb08c 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 @@ -203,17 +203,15 @@ class PresentationServiceNotifier( svc.createJwtPresentationPayloadFromRecord(record, issuer, issuanceDate) override def createPresentationFromRecord( - record: DidCommID, - issuer: Issuer + record: DidCommID ): ZIO[WalletAccessContext, PresentationError, PresentationCompact] = - svc.createPresentationFromRecord(record, issuer) + svc.createPresentationFromRecord(record) override def createSDJwtPresentation( record: DidCommID, - requestPresentation: RequestPresentation, - issuer: Issuer + requestPresentation: RequestPresentation ): ZIO[WalletAccessContext, PresentationError, Presentation] = - svc.createSDJwtPresentation(record, requestPresentation, issuer) + svc.createSDJwtPresentation(record, requestPresentation) override def createAnoncredPresentationPayloadFromRecord( record: DidCommID,