Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
Signed-off-by: FabioPinheiro <[email protected]>
  • Loading branch information
FabioPinheiro committed Jun 24, 2024
1 parent bd79a9e commit 90395eb
Show file tree
Hide file tree
Showing 30 changed files with 159 additions and 130 deletions.
6 changes: 3 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 ()
}
Expand All @@ -634,4 +635,5 @@ object IssueBackgroundJobs extends BackgroundJobsHelper {

}

}
val FIXME = 1 + 1 // FIXME scalafmt !!!!!!!!!!!!!!!!!!!11
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -534,7 +545,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper {
requestPresentation: RequestPresentation
): ZIO[
PresentationService & DIDNonSecretStorage,
PresentationError | DIDSecretStorageError | BackgroundJobError,
ERROR_AUX1,
Unit
] = {
maybeCredentialsToUseJson match {
Expand Down Expand Up @@ -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
] = {

Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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 =
Expand All @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -180,15 +181,17 @@ 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)
.mapError(_ => badRequestUnsupportedCredentialType("No credential definition provided"))
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(
Expand All @@ -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
}
}

Expand All @@ -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
}
Expand All @@ -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}"))
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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.*
Expand Down Expand Up @@ -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
}
}
Loading

0 comments on commit 90395eb

Please sign in to comment.