From 90395eb3dbf2e48cabe79151bbc557455e7859d9 Mon Sep 17 00:00:00 2001 From: FabioPinheiro Date: Fri, 21 Jun 2024 17:23:53 +0100 Subject: [PATCH] wip Signed-off-by: FabioPinheiro --- build.sbt | 6 +- .../server/jobs/ConnectBackgroundJobs.scala | 23 ++---- .../server/jobs/IssueBackgroundJobs.scala | 8 +- .../server/jobs/PresentBackgroundJobs.scala | 29 +++++--- .../controller/DIDCommControllerError.scala | 74 ++++++++----------- .../controller/DIDCommControllerImpl.scala | 2 +- .../CredentialIssuerController.scala | 21 ++++-- .../domain/Openid4VCIProofJwtOps.scala | 32 ++++---- .../service/OIDCCredentialIssuerService.scala | 24 +++--- .../core/service/ConnectionServiceImpl.scala | 2 +- ...V8__clear_content_of_meta_last_failure.sql | 2 + .../repository/JdbcConnectionRepository.scala | 6 +- .../core/model/IssueCredentialRecord.scala | 2 +- .../core/model/PresentationRecord.scala | 2 +- .../repository/CredentialRepository.scala | 2 +- .../CredentialRepositoryInMemory.scala | 4 +- .../repository/PresentationRepository.scala | 2 +- .../PresentationRepositoryInMemory.scala | 4 +- .../core/service/CredentialService.scala | 2 +- .../core/service/CredentialServiceImpl.scala | 2 +- .../service/CredentialServiceNotifier.scala | 2 +- .../core/service/MockCredentialService.scala | 5 +- .../service/MockPresentationService.scala | 2 +- .../core/service/PresentationService.scala | 2 +- .../service/PresentationServiceImpl.scala | 2 +- .../service/PresentationServiceNotifier.scala | 2 +- ...23__clear_content_of_meta_last_failure.sql | 3 + .../repository/JdbcCredentialRepository.scala | 9 ++- .../JdbcPresentationRepository.scala | 7 +- .../identus/shared/models/Failure.scala | 6 +- 30 files changed, 159 insertions(+), 130 deletions(-) create mode 100644 connect/sql-doobie/src/main/resources/sql/connect/V8__clear_content_of_meta_last_failure.sql create mode 100644 pollux/sql-doobie/src/main/resources/sql/pollux/V23__clear_content_of_meta_last_failure.sql diff --git a/build.sbt b/build.sbt index 19d35cc23a..68e166f3a5 100644 --- a/build.sbt +++ b/build.sbt @@ -846,12 +846,12 @@ lazy val cloudAgentServer = project "-Yno-deep-subtypes", "-Yno-decode-stacktraces", "-Yno-patmat-opt", - "-Yshow-print-errors", - "-Ydetailed-stats", + // "-Yshow-print-errors", + // "-Ydetailed-stats", // "-Xshow-phases", // "-Xprint:all", // "-Ydebug", - "-Ylog:all", + // "-Ylog:all", ), fork := true, libraryDependencies ++= D_CloudAgent.serverDependencies, diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/ConnectBackgroundJobs.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/ConnectBackgroundJobs.scala index c4bffda598..5ed92b4441 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/ConnectBackgroundJobs.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/ConnectBackgroundJobs.scala @@ -12,7 +12,7 @@ import org.hyperledger.identus.connect.core.model.ConnectionRecord import org.hyperledger.identus.connect.core.model.ConnectionRecord.* import org.hyperledger.identus.connect.core.service.ConnectionService import org.hyperledger.identus.mercury.* -import org.hyperledger.identus.mercury.error.SendMessageError +import org.hyperledger.identus.mercury.model.error.SendMessageError import org.hyperledger.identus.resolvers.DIDResolver import org.hyperledger.identus.shared.models.WalletAccessContext import org.hyperledger.identus.shared.utils.aspects.CustomMetricsAspect @@ -123,12 +123,12 @@ object ConnectBackgroundJobs extends BackgroundJobsHelper { // inviteeProcessFlow // TODO decrease metaRetries if it has a error inviteeProcessFlow - // @@ InviteeProcessConnectionRecordPendingSuccess.trackSuccess - // @@ InviteeProcessConnectionRecordPendingFailed.trackError - // @@ InviteeProcessConnectionRecordPendingTotal - // @@ Metric - // .gauge("connection_flow_invitee_process_connection_record_ms_gauge") - // .trackDurationWith(_.toMetricsSeconds) + @@ InviteeProcessConnectionRecordPendingSuccess.trackSuccess + @@ InviteeProcessConnectionRecordPendingFailed.trackError + @@ InviteeProcessConnectionRecordPendingTotal + @@ Metric + .gauge("connection_flow_invitee_process_connection_record_ms_gauge") + .trackDurationWith(_.toMetricsSeconds) case ConnectionRecord( id, @@ -185,16 +185,9 @@ object ConnectBackgroundJobs extends BackgroundJobsHelper { s"Connect - Error processing record: ${record.id}", Cause.fail(walletNotFound) ) - case ((walletAccessContext, e)) => + case ((walletAccessContext, errorResponse)) => for { connectService <- ZIO.service[ConnectionService] - errorResponse: org.hyperledger.identus.shared.models.Failure = e match - case ex @ KeyNotFoundError(didId, keyId) => ex - case ex @ ErrorResponseReceivedFromPeerAgent(response) => ex - case ex @ SendMessageError(cause, mData) => ex - case ex @ RecordIdNotFound(recordId) => ex - case ex @ InvalidStateForOperation(state) => ex - // e: KeyNotFoundError | SendMessageError | (RecordIdNotFound | InvalidStateForOperation | ErrorResponseReceivedFromPeerAgent) _ <- connectService .reportProcessingFailure(record.id, Some(errorResponse)) .provideSomeLayer(ZLayer.succeed(walletAccessContext)) diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/IssueBackgroundJobs.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/IssueBackgroundJobs.scala index 0780309a28..d752e81d78 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/IssueBackgroundJobs.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/IssueBackgroundJobs.scala @@ -618,11 +618,12 @@ object IssueBackgroundJobs extends BackgroundJobsHelper { case walletNotFound: WalletNotFoundError => ZIO.unit case CredentialServiceError.RecordNotFound(_, _) => ZIO.unit case CredentialServiceError.UnsupportedDidFormat(_) => ZIO.unit - case ((walletAccessContext, e)) => + case failure: org.hyperledger.identus.shared.models.Failure => ??? //FIXME + case ((walletAccessContext, failure)) => for { credentialService <- ZIO.service[CredentialService] _ <- credentialService - .reportProcessingFailure(record.id, Some(e.toString)) + .reportProcessingFailure(record.id, Some(failure)) .provideSomeLayer(ZLayer.succeed(walletAccessContext)) } yield () } @@ -634,4 +635,5 @@ object IssueBackgroundJobs extends BackgroundJobsHelper { } -} + val FIXME = 1 + 1 // FIXME scalafmt !!!!!!!!!!!!!!!!!!!11 +} 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 8f6daf2b31..25e18796cc 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 @@ -44,8 +44,18 @@ import zio.prelude.ZValidation.* import java.time.{Clock, Instant, ZoneId} object PresentBackgroundJobs extends BackgroundJobsHelper { - type ERROR = DIDSecretStorageError | PresentationError | CredentialServiceError | BackgroundJobError | - CastorDIDResolutionError | GetManagedDIDError | TransportError + + private type ERROR_AUX1 = org.hyperledger.identus.shared.models.Failure + // PresentationError | DIDSecretStorageError | BackgroundJobError | org.hyperledger.identus.shared.models.Failure + private type ERROR_AUX2 = org.hyperledger.identus.shared.models.Failure + // PresentationError | DIDSecretStorageError | TransportError | org.hyperledger.identus.shared.models.Failure + private type ERROR_AUX3 = org.hyperledger.identus.shared.models.Failure + // PresentationError | DIDSecretStorageError | BackgroundJobError | TransportError | + // org.hyperledger.identus.shared.models.Failure + + private type ERROR = // org.hyperledger.identus.shared.models.Failure + DIDSecretStorageError | PresentationError | /*CredentialServiceError | BackgroundJobError |*/ + CastorDIDResolutionError | GetManagedDIDError | TransportError | org.hyperledger.identus.shared.models.Failure private type RESOURCES = COMMON_RESOURCES & CredentialService & JwtDidResolver & DIDService & AppConfig & MESSAGING_RESOURCES @@ -83,7 +93,8 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { aux(record) .tapError({ (error: PresentationError | DIDSecretStorageError | BackgroundJobError | CredentialServiceError | - CastorDIDResolutionError | GetManagedDIDError | TransportError) => + CastorDIDResolutionError | GetManagedDIDError | TransportError | + org.hyperledger.identus.shared.models.Failure) => ZIO.logErrorCause( s"Present Proof - Error processing record: ${record.id}", Cause.fail(error) @@ -534,7 +545,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { requestPresentation: RequestPresentation ): ZIO[ PresentationService & DIDNonSecretStorage, - PresentationError | DIDSecretStorageError | BackgroundJobError, + ERROR_AUX1, Unit ] = { maybeCredentialsToUseJson match { @@ -646,7 +657,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { def handlePresentationGenerated(id: DidCommID, presentation: Presentation): ZIO[ JwtDidResolver & COMMON_RESOURCES & MESSAGING_RESOURCES, - PresentationError | DIDSecretStorageError | BackgroundJobError | TransportError, + ERROR_AUX3, Unit ] = { @@ -713,7 +724,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { def handleRequestPending(id: DidCommID, record: RequestPresentation): ZIO[ JwtDidResolver & COMMON_RESOURCES & MESSAGING_RESOURCES, - PresentationError | DIDSecretStorageError | BackgroundJobError | TransportError, + ERROR_AUX3, Unit ] = { val VerifierSendPresentationRequestMsgSuccess = counterMetric( @@ -801,7 +812,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { credentialFormat: CredentialFormat ): ZIO[ AppConfig & JwtDidResolver & COMMON_RESOURCES & MESSAGING_RESOURCES, - PresentationError | DIDSecretStorageError | TransportError, + ERROR_AUX2, Unit ] = { val result = @@ -815,7 +826,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { private def handleJWT(id: DidCommID, requestPresentation: RequestPresentation, presentation: Presentation): ZIO[ AppConfig & JwtDidResolver & COMMON_RESOURCES & MESSAGING_RESOURCES, - PresentationError | DIDSecretStorageError | TransportError, + ERROR_AUX2, Unit ] = { val clock = java.time.Clock.system(ZoneId.systemDefault) @@ -929,7 +940,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { private def handleSDJWT(id: DidCommID, presentation: Presentation): ZIO[ JwtDidResolver & COMMON_RESOURCES & MESSAGING_RESOURCES, - PresentationError | DIDSecretStorageError | TransportError, + ERROR_AUX2, Unit ] = { for { diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/didcomm/controller/DIDCommControllerError.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/didcomm/controller/DIDCommControllerError.scala index 88e2f5b659..2c46434de9 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/didcomm/controller/DIDCommControllerError.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/didcomm/controller/DIDCommControllerError.scala @@ -3,49 +3,39 @@ package org.hyperledger.identus.didcomm.controller import org.hyperledger.identus.mercury.model.DidId import org.hyperledger.identus.shared.models.{Failure, StatusCode} -sealed trait DIDCommControllerError( - val statusCode: StatusCode, - val userFacingMessage: String -) extends Failure { - override val namespace = "DIDCommControllerError" +sealed trait DIDCommControllerError extends Failure { + override def namespace = "DIDCommControllerError" } object DIDCommControllerError { - final case class InvalidContentType(maybeContentType: Option[String]) - extends DIDCommControllerError( - StatusCode.BadRequest, - maybeContentType match - case Some(value) => s"The 'content-type' request header value is invalid: $value" - case None => s"The 'content-type' request header is undefined" - ) - - final case class RecipientNotFoundError() - extends DIDCommControllerError( - StatusCode.UnprocessableContent, - "Recipient not found in the DIDComm Message" - ) - - final case class UnexpectedError(override val statusCode: StatusCode) - extends DIDCommControllerError( - statusCode, - "An unexpected error occurred while processing your request" - ) - - final case class RequestBodyParsingError(cause: String) - extends DIDCommControllerError( - StatusCode.BadRequest, - s"Unable to parse the request body as a valid DIDComm message: $cause" - ) - - final case class PeerDIDNotFoundError(did: DidId) - extends DIDCommControllerError( - StatusCode.UnprocessableContent, - s"The Peer DID was not found in this agent: ${did.value}" - ) - - final case class PeerDIDKeyNotFoundError(did: DidId, keyId: String) - extends DIDCommControllerError( - StatusCode.UnprocessableContent, - s"The Peer DID does not contain the required key: DID=$did, keyId=$keyId" - ) + final case class InvalidContentType(maybeContentType: Option[String]) extends DIDCommControllerError { + override def statusCode: StatusCode = StatusCode.BadRequest + override def userFacingMessage: String = maybeContentType match + case Some(value) => s"The 'content-type' request header value is invalid: $value" + case None => s"The 'content-type' request header is undefined" + } + + object RecipientNotFoundError extends DIDCommControllerError { + override def statusCode: StatusCode = StatusCode.UnprocessableContent + override def userFacingMessage: String = "Recipient not found in the DIDComm Message" + } + + final case class UnexpectedError(statusCode: StatusCode) extends DIDCommControllerError { + override def userFacingMessage: String = "An unexpected error occurred while processing your request" + } + + final case class RequestBodyParsingError(cause: String) extends DIDCommControllerError { + override def statusCode: StatusCode = StatusCode.BadRequest + override def userFacingMessage: String = s"Unable to parse the request body as a valid DIDComm message: $cause" + } + + final case class PeerDIDNotFoundError(did: DidId) extends DIDCommControllerError { + override def statusCode: StatusCode = StatusCode.UnprocessableContent + override def userFacingMessage: String = s"The Peer DID was not found in this agent: ${did.value}" + } + + final case class PeerDIDKeyNotFoundError(did: DidId, keyId: String) extends DIDCommControllerError { + override def statusCode: StatusCode = StatusCode.UnprocessableContent + override def userFacingMessage: String = s"The Peer DID does not contain the required key: DID=$did, keyId=$keyId" + } } diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/didcomm/controller/DIDCommControllerImpl.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/didcomm/controller/DIDCommControllerImpl.scala index 44d7e1e8e5..b910ace0f4 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/didcomm/controller/DIDCommControllerImpl.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/didcomm/controller/DIDCommControllerImpl.scala @@ -71,7 +71,7 @@ class DIDCommControllerImpl( for { recipientDid <- ZIO .fromOption(msg.recipients.headOption.map(_.header.kid.split("#")(0))) - .mapError(_ => RecipientNotFoundError()) + .mapError(_ => RecipientNotFoundError) _ <- ZIO.logInfo(s"Extracted recipient Did => $recipientDid") didId = DidId(recipientDid) maybePeerDIDRecord <- didNonSecretStorage.getPeerDIDRecord(didId).orDie diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/oid4vci/controller/CredentialIssuerController.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/oid4vci/controller/CredentialIssuerController.scala index 158bdda0d7..29d81e4321 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/oid4vci/controller/CredentialIssuerController.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/oid4vci/controller/CredentialIssuerController.scala @@ -166,8 +166,9 @@ case class CredentialIssuerControllerImpl( ZIO.unit, ZIO.fail(OIDCCredentialIssuerService.Errors.InvalidProof("Invalid proof")) ) - .mapError { case InvalidProof(message) => - badRequestInvalidProof(jwt, message) + .mapError { + case InvalidProof(message) => badRequestInvalidProof(jwt, message) + case DIDResolutionError(message) => badRequestInvalidProof(jwt, message) } nonce <- getNonceFromJwt(JWT(jwt)) .mapError(throwable => badRequestInvalidProof(jwt, throwable.getMessage)) @@ -180,7 +181,9 @@ case class CredentialIssuerControllerImpl( sessionWithSubjectDid <- credentialIssuerService .updateIssuanceSession(session.withSubjectDid(subjectDid)) .mapError(ue => - serverError(Some(s"Unexpected error while updating issuance session with subject DID: ${ue.message}")) + serverError( + Some(s"Unexpected error while updating issuance session with subject DID: ${ue.userFacingMessage}") + ) ) credentialDefinition <- ZIO .fromOption(maybeCredentialDefinition) @@ -188,7 +191,7 @@ case class CredentialIssuerControllerImpl( validatedCredentialDefinition <- credentialIssuerService .validateCredentialDefinition(credentialDefinition) .mapError(ue => - serverError(Some(s"Unexpected error while validating credential definition: ${ue.message}")) + serverError(Some(s"Unexpected error while validating credential definition: ${ue.userFacingMessage}")) ) credential <- credentialIssuerService .issueJwtCredential( @@ -198,9 +201,11 @@ case class CredentialIssuerControllerImpl( maybeCredentialIdentifier, validatedCredentialDefinition ) - .mapError(ue => serverError(Some(s"Unexpected error while issuing credential: ${ue.message}"))) + .mapError(ue => serverError(Some(s"Unexpected error while issuing credential: ${ue.userFacingMessage}"))) } yield ImmediateCredentialResponse(credential.value) case None => ZIO.fail(badRequestInvalidProof(jwt = "empty", details = "No proof provided")) + // case Some(CwtProof(_, _)) => ??? // TODO + // case Some(LdpProof(_, _)) => ??? // TODO } } @@ -223,7 +228,9 @@ case class CredentialIssuerControllerImpl( ) .map(offer => CredentialOfferResponse(offer.offerUri)) .mapError(ue => - internalServerError(detail = Some(s"Unexpected error while creating credential offer: ${ue.message}")) + internalServerError(detail = + Some(s"Unexpected error while creating credential offer: ${ue.userFacingMessage}") + ) ) } yield resp } @@ -236,7 +243,7 @@ case class CredentialIssuerControllerImpl( .getIssuanceSessionByIssuerState(request.issuerState) .map(session => NonceResponse(session.nonce)) .mapError(ue => - internalServerError(detail = Some(s"Unexpected error while creating credential offer: ${ue.message}")) + internalServerError(detail = Some(s"Unexpected error while creating credential offer: ${ue.userFacingMessage}")) ) } diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/oid4vci/domain/Openid4VCIProofJwtOps.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/oid4vci/domain/Openid4VCIProofJwtOps.scala index 19d8d7e584..5834ebad98 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/oid4vci/domain/Openid4VCIProofJwtOps.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/oid4vci/domain/Openid4VCIProofJwtOps.scala @@ -1,11 +1,11 @@ package org.hyperledger.identus.oid4vci.domain import com.nimbusds.jose.{JOSEObjectType, JWSAlgorithm, JWSHeader, JWSObject, JWSSigner, Payload} -import org.hyperledger.identus.castor.core.model.did.{DID, DIDUrl, LongFormPrismDID} +import org.hyperledger.identus.castor.core.model.did.DIDUrl import org.hyperledger.identus.pollux.vc.jwt.JWT import org.hyperledger.identus.pollux.vc.jwt.JwtSignerImplicits.* import org.hyperledger.identus.shared.crypto.Secp256k1PrivateKey -import zio.{Task, ZIO} +import zio.* import java.util.UUID import scala.jdk.CollectionConverters.* @@ -46,36 +46,42 @@ trait Openid4VCIProofJwtOps { JWT(makeJwtProof(header, payload, privateKey.asJwtSigner)) } - def getKeyIdFromJwt(jwt: JWT): Task[String] = { + def getKeyIdFromJwt(jwt: JWT): IO[RuntimeException, String] = { // FIXME RuntimeException for { - jwsObject <- ZIO.fromTry(Try(JWSObject.parse(jwt.value))) + jwsObject <- ZIO.fromTry(Try(JWSObject.parse(jwt.value))).orDie // FIXME keyID = jwsObject.getHeader.getKeyID - _ <- ZIO.fail(new Exception("Key ID not found in JWT header")) when (keyID == null || keyID.isEmpty) + _ <- ZIO.fail( + new RuntimeException("Key ID not found in JWT header") + ) when (keyID == null || keyID.isEmpty) } yield keyID } - def getAlgorithmFromJwt(jwt: JWT): Task[String] = { + def getAlgorithmFromJwt(jwt: JWT): IO[RuntimeException, String] = { for { - jwsObject <- ZIO.fromTry(Try(JWSObject.parse(jwt.value))) + jwsObject <- ZIO.fromTry(Try(JWSObject.parse(jwt.value))).orDie // FIXME algorithm <- ZIO .fromOption(Option(jwsObject.getHeader.getAlgorithm)) - .mapError(_ => new Exception("Algorithm not found in JWT header")) + .mapError(_ => new RuntimeException("Algorithm not found in JWT header")) } yield algorithm.getName } - def getNonceFromJwt(jwt: JWT): Task[String] = { + def getNonceFromJwt(jwt: JWT): IO[RuntimeException, String] = { // FIXME RuntimeException for { - jwsObject <- ZIO.fromTry(Try(JWSObject.parse(jwt.value))) + jwsObject <- ZIO.fromTry(Try(JWSObject.parse(jwt.value))).orDie // FIXME payload = jwsObject.getPayload.toJSONObject nonce = payload.get("nonce").asInstanceOf[String] - _ <- ZIO.fail(new Exception("Nonce not found in JWT payload")) when (nonce == null || nonce.isEmpty) + _ <- ZIO.fail( + new RuntimeException("Nonce not found in JWT payload") + ) when (nonce == null || nonce.isEmpty) } yield nonce } - def parseDIDUrlFromKeyId(jwt: JWT): Task[DIDUrl] = { + def parseDIDUrlFromKeyId(jwt: JWT): IO[RuntimeException, DIDUrl] = { // FIXME RuntimeException for { keyId <- getKeyIdFromJwt(jwt) - didUrl <- ZIO.fromEither(DIDUrl.fromString(keyId)).mapError(e => new Exception(e)) + didUrl <- ZIO + .fromEither(DIDUrl.fromString(keyId)) + .mapError(e => new RuntimeException(e)) } yield didUrl } } diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/oid4vci/service/OIDCCredentialIssuerService.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/oid4vci/service/OIDCCredentialIssuerService.scala index 4e17335a65..2341446980 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/oid4vci/service/OIDCCredentialIssuerService.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/oid4vci/service/OIDCCredentialIssuerService.scala @@ -24,7 +24,7 @@ import org.hyperledger.identus.pollux.vc.jwt.{ W3cCredentialPayload, * } -import org.hyperledger.identus.shared.models.{WalletAccessContext, WalletId} +import org.hyperledger.identus.shared.models.* import zio.* import java.net.{URI, URL} @@ -40,7 +40,7 @@ trait OIDCCredentialIssuerService { import OIDCCredentialIssuerService.Error import OIDCCredentialIssuerService.Errors.* - def verifyJwtProof(jwt: JWT): IO[InvalidProof, Boolean] + def verifyJwtProof(jwt: JWT): IO[InvalidProof | DIDResolutionError, Boolean] def validateCredentialDefinition( credentialDefinition: CredentialDefinition @@ -70,30 +70,31 @@ trait OIDCCredentialIssuerService { } object OIDCCredentialIssuerService { - trait Error { - def message: String + sealed trait Error extends Failure { + override val namespace = "OIDCCredentialIssuerService" + override val statusCode = StatusCode.FixmeStatusCode } // TODO: use shared Failure trait object Errors { - case class InvalidProof(message: String) extends Error + case class InvalidProof(userFacingMessage: String) extends Error - case class DIDResolutionError(message: String) extends Error + case class DIDResolutionError(userFacingMessage: String) extends Error case class CredentialConfigurationNotFound(issuerId: UUID, credentialConfigurationId: String) extends Error { - override def message: String = + override def userFacingMessage: String = s"Credential configuration with id $credentialConfigurationId not found for issuer $issuerId" } case class CredentialSchemaError(cause: org.hyperledger.identus.pollux.core.model.error.CredentialSchemaError) extends Error { - override def message: String = cause.userFacingMessage + override def userFacingMessage: String = cause.userFacingMessage } - case class ServiceError(message: String) extends Error + case class ServiceError(userFacingMessage: String) extends Error case class UnexpectedError(cause: Throwable) extends Error { - override def message: String = cause.getMessage + override def userFacingMessage: String = cause.getMessage // TODO } } } @@ -129,14 +130,13 @@ case class OIDCCredentialIssuerServiceImpl( } yield verificationMethod } - override def verifyJwtProof(jwt: JWT): IO[InvalidProof, Boolean] = { + override def verifyJwtProof(jwt: JWT): IO[InvalidProof | DIDResolutionError, Boolean] = { for { algorithm <- getAlgorithmFromJwt(jwt) .mapError(e => InvalidProof(e.getMessage)) didUrl <- parseDIDUrlFromKeyId(jwt) .mapError(e => InvalidProof(e.getMessage)) verificationMethod <- resolveVerificationMethodByKeyId(didUrl) - .mapError(dre => InvalidProof(dre.message)) publicKey <- JWTVerification.extractPublicKey(verificationMethod).toZIO.mapError(InvalidProof.apply) _ <- JWTVerification.validateEncodedJwt(jwt, publicKey).toZIO.mapError(InvalidProof.apply) _ <- ZIO.succeed(println(s"JWT proof is verified: ${jwt.value}")) // TODO: remove before the release diff --git a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceImpl.scala b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceImpl.scala index 6f01e332a3..c0e97294e7 100644 --- a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceImpl.scala +++ b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceImpl.scala @@ -295,7 +295,7 @@ private class ConnectionServiceImpl( } yield record } - def reportProcessingFailure( + override def reportProcessingFailure( recordId: UUID, failReason: Option[org.hyperledger.identus.shared.models.Failure] ): URIO[WalletAccessContext, Unit] = diff --git a/connect/sql-doobie/src/main/resources/sql/connect/V8__clear_content_of_meta_last_failure.sql b/connect/sql-doobie/src/main/resources/sql/connect/V8__clear_content_of_meta_last_failure.sql new file mode 100644 index 0000000000..bf1eddfb59 --- /dev/null +++ b/connect/sql-doobie/src/main/resources/sql/connect/V8__clear_content_of_meta_last_failure.sql @@ -0,0 +1,2 @@ +-- Clear content of meta_last_failure +UPDATE public.connection_records SET meta_last_failure=NULL; \ No newline at end of file diff --git a/connect/sql-doobie/src/main/scala/org/hyperledger/identus/connect/sql/repository/JdbcConnectionRepository.scala b/connect/sql-doobie/src/main/scala/org/hyperledger/identus/connect/sql/repository/JdbcConnectionRepository.scala index 361bcb2e40..1ebc70df6f 100644 --- a/connect/sql-doobie/src/main/scala/org/hyperledger/identus/connect/sql/repository/JdbcConnectionRepository.scala +++ b/connect/sql-doobie/src/main/scala/org/hyperledger/identus/connect/sql/repository/JdbcConnectionRepository.scala @@ -45,8 +45,10 @@ class JdbcConnectionRepository(xa: Transactor[ContextAwareTask], xb: Transactor[ given connectionResponseGet: Get[ConnectionResponse] = Get[String].map(decode[ConnectionResponse](_).getOrElse(???)) given connectionResponsePut: Put[ConnectionResponse] = Put[String].contramap(_.asJson.toString) - given failureGet: Get[org.hyperledger.identus.shared.models.Failure] = ??? - given failurePut: Put[org.hyperledger.identus.shared.models.Failure] = ??? + given failureGet: Get[org.hyperledger.identus.shared.models.Failure] = + ??? // FIXME !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + given failurePut: Put[org.hyperledger.identus.shared.models.Failure] = + ??? // FIXME !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! override def create(record: ConnectionRecord): URIO[WalletAccessContext, Unit] = { val cxnIO = sql""" diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/IssueCredentialRecord.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/IssueCredentialRecord.scala index 030fa2865a..cf4944f0a2 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/IssueCredentialRecord.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/IssueCredentialRecord.scala @@ -40,7 +40,7 @@ final case class IssueCredentialRecord( issuingDID: Option[CanonicalPrismDID], metaRetries: Int, metaNextRetry: Option[Instant], - metaLastFailure: Option[String], + metaLastFailure: Option[org.hyperledger.identus.shared.models.Failure], ) { def offerCredentialFormatAndData: Option[(IssueCredentialOfferFormat, OfferCredential)] = offerCredentialData.map { data => 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 92ba7a493c..8407c3cf49 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 @@ -30,7 +30,7 @@ final case class PresentationRecord( sdJwtClaimsToDisclose: Option[SdJwtCredentialToDisclose], metaRetries: Int, metaNextRetry: Option[Instant], - metaLastFailure: Option[String], + metaLastFailure: Option[org.hyperledger.identus.shared.models.Failure], ) { def withTruncatedTimestamp(unit: ChronoUnit = ChronoUnit.MICROS): PresentationRecord = copy( diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/repository/CredentialRepository.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/repository/CredentialRepository.scala index 68c4199864..e432e01988 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/repository/CredentialRepository.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/repository/CredentialRepository.scala @@ -99,7 +99,7 @@ trait CredentialRepository { def updateAfterFail( recordId: DidCommID, - failReason: Option[String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): URIO[WalletAccessContext, Unit] } diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/repository/CredentialRepositoryInMemory.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/repository/CredentialRepositoryInMemory.scala index e395cc3b2b..e401de9903 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/repository/CredentialRepositoryInMemory.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/repository/CredentialRepositoryInMemory.scala @@ -328,9 +328,9 @@ class CredentialRepositoryInMemory( } yield () } - def updateAfterFail( + override def updateAfterFail( recordId: DidCommID, - failReason: Option[String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): URIO[WalletAccessContext, Unit] = for { storeRef <- walletStoreRef maybeRecord <- findById(recordId) 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 2e80f3af54..30b292e33e 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 @@ -73,6 +73,6 @@ trait PresentationRepository { def updateAfterFail( recordId: DidCommID, - failReason: Option[String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): URIO[WalletAccessContext, Unit] } diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepositoryInMemory.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepositoryInMemory.scala index f934e1ddbb..b7b09115b7 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepositoryInMemory.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepositoryInMemory.scala @@ -340,9 +340,9 @@ class PresentationRepositoryInMemory( result.ensureOneAffectedRowOrDie } - def updateAfterFail( + override def updateAfterFail( recordId: DidCommID, - failReason: Option[String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): URIO[WalletAccessContext, Unit] = { val result = for { diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialService.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialService.scala index a349955d24..a6033245a7 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialService.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialService.scala @@ -150,7 +150,7 @@ trait CredentialService { def reportProcessingFailure( recordId: DidCommID, - failReason: Option[String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): URIO[WalletAccessContext, Unit] def getJwtIssuer( 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 23db13c265..23e7680803 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 @@ -858,7 +858,7 @@ class CredentialServiceImpl( override def reportProcessingFailure( recordId: DidCommID, - failReason: Option[String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): URIO[WalletAccessContext, Unit] = credentialRepository.updateAfterFail(recordId, failReason) diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceNotifier.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceNotifier.scala index d933059297..eebcb3ad17 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceNotifier.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceNotifier.scala @@ -188,7 +188,7 @@ class CredentialServiceNotifier( override def reportProcessingFailure( recordId: DidCommID, - failReason: Option[_root_.java.lang.String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): URIO[WalletAccessContext, Unit] = svc.reportProcessingFailure(recordId, failReason) diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/MockCredentialService.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/MockCredentialService.scala index ebaee00e70..9eef6317f5 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/MockCredentialService.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/MockCredentialService.scala @@ -100,7 +100,8 @@ object MockCredentialService extends Mock[CredentialService] { object MarkCredentialPublicationPending extends Effect[DidCommID, CredentialServiceError, IssueCredentialRecord] object MarkCredentialPublicationQueued extends Effect[DidCommID, CredentialServiceError, IssueCredentialRecord] object MarkCredentialPublished extends Effect[DidCommID, CredentialServiceError, IssueCredentialRecord] - object ReportProcessingFailure extends Effect[(DidCommID, Option[String]), Nothing, Unit] + object ReportProcessingFailure + extends Effect[(DidCommID, Option[org.hyperledger.identus.shared.models.Failure]), Nothing, Unit] override val compose: URLayer[mock.Proxy, CredentialService] = ZLayer { for { @@ -245,7 +246,7 @@ object MockCredentialService extends Mock[CredentialService] { override def reportProcessingFailure( recordId: DidCommID, - failReason: Option[String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): URIO[WalletAccessContext, Unit] = proxy(ReportProcessingFailure, recordId, failReason) 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 b1dbadc82e..055fd86499 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 @@ -261,7 +261,7 @@ object MockPresentationService extends Mock[PresentationService] { override def reportProcessingFailure( recordId: DidCommID, - failReason: Option[String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): IO[PresentationError, Unit] = ??? } 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 f7b0fe9b09..85e90a28f6 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 @@ -168,7 +168,7 @@ trait PresentationService { def reportProcessingFailure( recordId: DidCommID, - failReason: Option[String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): ZIO[WalletAccessContext, PresentationError, Unit] } 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 d153000be6..0dbec71693 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 @@ -1100,7 +1100,7 @@ private class PresentationServiceImpl( def reportProcessingFailure( recordId: DidCommID, - failReason: Option[String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): ZIO[WalletAccessContext, PresentationError, Unit] = for { _ <- getRecord(recordId) 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 41fd7636cc..334319e896 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 @@ -280,7 +280,7 @@ class PresentationServiceNotifier( override def reportProcessingFailure( recordId: DidCommID, - failReason: Option[_root_.java.lang.String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): ZIO[WalletAccessContext, PresentationError, Unit] = svc.reportProcessingFailure(recordId, failReason) } diff --git a/pollux/sql-doobie/src/main/resources/sql/pollux/V23__clear_content_of_meta_last_failure.sql b/pollux/sql-doobie/src/main/resources/sql/pollux/V23__clear_content_of_meta_last_failure.sql new file mode 100644 index 0000000000..403c9d44fe --- /dev/null +++ b/pollux/sql-doobie/src/main/resources/sql/pollux/V23__clear_content_of_meta_last_failure.sql @@ -0,0 +1,3 @@ +-- Clear content of meta_last_failure +UPDATE public.issue_credential_records SET meta_last_failure=NULL; +UPDATE public.presentation_records SET meta_last_failure=NULL; \ No newline at end of file diff --git a/pollux/sql-doobie/src/main/scala/org/hyperledger/identus/pollux/sql/repository/JdbcCredentialRepository.scala b/pollux/sql-doobie/src/main/scala/org/hyperledger/identus/pollux/sql/repository/JdbcCredentialRepository.scala index ab502e8907..979c0cbdc2 100644 --- a/pollux/sql-doobie/src/main/scala/org/hyperledger/identus/pollux/sql/repository/JdbcCredentialRepository.scala +++ b/pollux/sql-doobie/src/main/scala/org/hyperledger/identus/pollux/sql/repository/JdbcCredentialRepository.scala @@ -24,6 +24,7 @@ import zio.json.* import java.time.Instant import java.util.UUID + class JdbcCredentialRepository(xa: Transactor[ContextAwareTask], xb: Transactor[Task], maxRetries: Int) extends CredentialRepository { @@ -56,6 +57,12 @@ class JdbcCredentialRepository(xa: Transactor[ContextAwareTask], xb: Transactor[ given keyIdGet: Get[KeyId] = Get[String].map(KeyId(_)) given keyIdPut: Put[KeyId] = Put[String].contramap(_.value) + + given failureGet: Get[org.hyperledger.identus.shared.models.Failure] = ??? // FIXME !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Get[String].map(e => ???) + given failurePut: Put[org.hyperledger.identus.shared.models.Failure] = ??? // FIXME !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Put[String].contramap(e => ???) + override def create(record: IssueCredentialRecord): URIO[WalletAccessContext, Unit] = { val cxnIO = sql""" | INSERT INTO public.issue_credential_records( @@ -547,7 +554,7 @@ class JdbcCredentialRepository(xa: Transactor[ContextAwareTask], xb: Transactor[ def updateAfterFail( recordId: DidCommID, - failReason: Option[String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): URIO[WalletAccessContext, Unit] = { val cxnIO = sql""" | UPDATE public.issue_credential_records 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 6123d81785..f53bf9e42a 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 @@ -161,6 +161,11 @@ class JdbcPresentationRepository( Get[String].map(decode[ProposePresentation](_).getOrElse(???)) given proposePresentationPut: Put[ProposePresentation] = Put[String].contramap(_.asJson.toString) + given failureGet: Get[org.hyperledger.identus.shared.models.Failure] = ??? // FIXME !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Get[String].map(e => ???) + given failurePut: Put[org.hyperledger.identus.shared.models.Failure] = ??? // FIXME !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Put[String].contramap(e => ???) + override def createPresentationRecord(record: PresentationRecord): URIO[WalletAccessContext, Unit] = { val cxnIO = sql""" | INSERT INTO public.presentation_records( @@ -488,7 +493,7 @@ class JdbcPresentationRepository( def updateAfterFail( recordId: DidCommID, - failReason: Option[String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): URIO[WalletAccessContext, Unit] = { val cxnIO = sql""" | UPDATE public.presentation_records diff --git a/shared/core/src/main/scala/org/hyperledger/identus/shared/models/Failure.scala b/shared/core/src/main/scala/org/hyperledger/identus/shared/models/Failure.scala index a23dd52afd..77879dfcb8 100644 --- a/shared/core/src/main/scala/org/hyperledger/identus/shared/models/Failure.scala +++ b/shared/core/src/main/scala/org/hyperledger/identus/shared/models/Failure.scala @@ -3,9 +3,9 @@ package org.hyperledger.identus.shared.models import zio.{URIO, ZIO} trait Failure { - val namespace: String - val statusCode: StatusCode - val userFacingMessage: String + def namespace: String + def statusCode: StatusCode + def userFacingMessage: String def toUnmanagedFailureException = UnmanagedFailureException(this) }