diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/schema/CredentialSchema.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/schema/CredentialSchema.scala index 6c05b941cb..8c12ad125a 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/schema/CredentialSchema.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/schema/CredentialSchema.scala @@ -8,7 +8,7 @@ import io.iohk.atala.pollux.core.model.schema.`type`.{ CredentialJsonSchemaType, CredentialSchemaType } -import io.iohk.atala.pollux.core.model.schema.validator.JsonSchemaValidatorImpl +import io.iohk.atala.pollux.core.model.schema.validator.{JsonSchemaValidator, JsonSchemaValidatorImpl} import io.iohk.atala.pollux.core.service.URIDereferencer import zio.* import zio.json.* @@ -116,11 +116,10 @@ object CredentialSchema { given JsonEncoder[CredentialSchema] = DeriveJsonEncoder.gen[CredentialSchema] given JsonDecoder[CredentialSchema] = DeriveJsonDecoder.gen[CredentialSchema] - def validateJWTClaims( + def validSchemaValidator( schemaId: String, - claims: String, uriDereferencer: URIDereferencer - ): IO[CredentialSchemaError, Unit] = { + ): IO[CredentialSchemaError, JsonSchemaValidator] = { for { uri <- ZIO.attempt(new URI(schemaId)).mapError(t => URISyntaxError(t.getMessage)) content <- uriDereferencer.dereference(uri).mapError(err => UnexpectedError(err.toString)) @@ -137,7 +136,17 @@ object CredentialSchema { .mapError(error => CredentialSchemaParsingError(s"Failed to parse schema content as Json or OEA: $error")) .flatMap(cs => JsonSchemaValidatorImpl.from(cs.schema).mapError(SchemaError.apply)) ) - _ <- schemaValidator.validate(claims).mapError(SchemaError.apply) + } yield schemaValidator + } + + def validateJWTCredentialSubject( + schemaId: String, + credentialSubject: String, + uriDereferencer: URIDereferencer + ): IO[CredentialSchemaError, Unit] = { + for { + schemaValidator <- validSchemaValidator(schemaId, uriDereferencer) + _ <- schemaValidator.validate(credentialSubject).mapError(SchemaError.apply) } yield () } diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialServiceImpl.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialServiceImpl.scala index 06b2af96df..9b4e5fe06e 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialServiceImpl.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialServiceImpl.scala @@ -139,7 +139,7 @@ private class CredentialServiceImpl( _ <- maybeSchemaId match case Some(schemaId) => CredentialSchema - .validateJWTClaims(schemaId, claims.noSpaces, uriDereferencer) + .validateJWTCredentialSubject(schemaId, claims.noSpaces, uriDereferencer) .mapError(e => CredentialSchemaError(e)) case None => ZIO.unit diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/verification/VcVerificationService.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/verification/VcVerificationService.scala index f88b1e5142..980e276965 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/verification/VcVerificationService.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/verification/VcVerificationService.scala @@ -6,17 +6,18 @@ trait VcVerificationService { def verify(request: List[VcVerificationRequest]): IO[VcVerificationServiceError, List[VcVerificationResult]] } +sealed trait VcVerificationParameter + +case class AudienceParameter(aud: String) extends VcVerificationParameter + final case class VcVerificationRequest( credential: String, - verifications: List[VcVerification] + verification: VcVerification, + parameter: Option[VcVerificationParameter] ) final case class VcVerificationResult( credential: String, - checks: List[VcVerification], - successfulChecks: List[VcVerification], - failedChecks: List[VcVerification], - failedAsWarningChecks: List[VcVerification] + verification: VcVerification, + success: Boolean ) - -final case class VcVerificationOutcome(verification: VcVerification, success: Boolean) diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/verification/VcVerificationServiceImpl.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/verification/VcVerificationServiceImpl.scala index 0614701c22..30df433ba6 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/verification/VcVerificationServiceImpl.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/verification/VcVerificationServiceImpl.scala @@ -3,6 +3,7 @@ package io.iohk.atala.pollux.core.service.verification import io.iohk.atala.pollux.core.model.schema.CredentialSchema import io.iohk.atala.pollux.core.service.URIDereferencer import io.iohk.atala.pollux.vc.jwt.{DidResolver, JWT, JWTVerification, JwtCredential} +import sttp.tapir.Schema import zio.{IO, *} class VcVerificationServiceImpl(didResolver: DidResolver, uriDereferencer: URIDereferencer) @@ -10,51 +11,38 @@ class VcVerificationServiceImpl(didResolver: DidResolver, uriDereferencer: URIDe override def verify( vcVerificationRequests: List[VcVerificationRequest] ): IO[VcVerificationServiceError, List[VcVerificationResult]] = { - vcVerificationRequests.map(vcVerificationRequest => - val verificationOutcomesZIO = ZIO.collectAll( - vcVerificationRequest.verifications - .map(verification => verify(vcVerificationRequest.credential, verification)) + ZIO.collectAll( + vcVerificationRequests.map(vcVerificationRequest => + verify(vcVerificationRequest.credential, vcVerificationRequest.verification, vcVerificationRequest.parameter) ) - - verificationOutcomesZIO.map(verificationOutcomes => { - val successfulChecks = verificationOutcomes.filter(_.success).map(_.verification) - - val failedVerifications = verificationOutcomes.filterNot(_.success).map(_.verification) - - val failedAsErrorChecks = - failedVerifications.filter(verification => verification.failureType == VcVerificationFailureType.ERROR) - - val failedAsWarningChecks = - failedVerifications.filter(verification => verification.failureType == VcVerificationFailureType.WARN) - - VcVerificationResult( - credential = vcVerificationRequest.credential, - checks = vcVerificationRequest.verifications, - successfulChecks = successfulChecks, - failedChecks = failedAsErrorChecks, - failedAsWarningChecks = failedAsWarningChecks - ) - }) ) - ZIO.succeed(List.empty) } private def verify( credential: String, - verification: VcVerification - ): IO[VcVerificationServiceError, VcVerificationOutcome] = { - verification match { - case VcVerification.SchemaCheck => verifySchema(credential) - case VcVerification.SignatureVerification => verifySignature(credential) - case VcVerification.ExpirationCheck => verifyExpiration(credential) - case VcVerification.NotBeforeCheck => verifyNotBefore(credential) - case VcVerification.AlgorithmVerification => verifyAlgorithm(credential) - case VcVerification.IssuerIdentification => verifyIssuerIdentification(credential) - case _ => ZIO.fail(VcVerificationServiceError.UnexpectedError(s"Unsupported Verification $verification")) + verification: VcVerification, + maybeParameter: Option[VcVerificationParameter] + ): IO[VcVerificationServiceError, VcVerificationResult] = { + (verification, maybeParameter) match { + case (VcVerification.SchemaCheck, None) => verifySchema(credential) + case (VcVerification.SignatureVerification, None) => verifySignature(credential) + case (VcVerification.ExpirationCheck, None) => verifyExpiration(credential) + case (VcVerification.NotBeforeCheck, None) => verifyNotBefore(credential) + case (VcVerification.AlgorithmVerification, None) => verifyAlgorithm(credential) + case (VcVerification.IssuerIdentification, None) => verifyIssuerIdentification(credential) + case (VcVerification.SubjectVerification, None) => verifySubjectVerification(credential) + case (VcVerification.SemanticCheckOfClaims, None) => verifySemanticCheckOfClaims(credential) + case (VcVerification.AudienceCheck, Some(AudienceParameter(aud))) => verifyAudienceCheck(credential, aud) + case _ => + ZIO.fail( + VcVerificationServiceError.UnexpectedError( + s"Unsupported Verification:$verification and Parameters:$maybeParameter" + ) + ) } } - private def verifySchema(credential: String): IO[VcVerificationServiceError, VcVerificationOutcome] = { + private def verifySchema(credential: String): IO[VcVerificationServiceError, VcVerificationResult] = { val result = for { decodedJwt <- @@ -65,40 +53,81 @@ class VcVerificationServiceImpl(didResolver: DidResolver, uriDereferencer: URIDe ZIO .fromOption(decodedJwt.maybeCredentialSchema) .mapError(error => VcVerificationServiceError.UnexpectedError(s"Missing Credential Schema: $error")) - } yield CredentialSchema - .validateJWTClaims( - credentialSchema.id, - decodedJwt.credentialSubject.noSpaces, - uriDereferencer - ) + result <- CredentialSchema + .validSchemaValidator( + credentialSchema.id, + uriDereferencer + ) + .mapError(error => VcVerificationServiceError.UnexpectedError(s"Schema Validator Failed: $error")) + } yield result - result.map(validation => - validation - .as( - VcVerificationOutcome( + result + .as( + VcVerificationResult( + credential = credential, + verification = VcVerification.SchemaCheck, + success = true + ) + ) + .catchAll(_ => + ZIO.succeed( + VcVerificationResult( + credential = credential, verification = VcVerification.SchemaCheck, - success = true + success = false ) ) - .catchAll(_ => - ZIO.succeed( - VcVerificationOutcome( - verification = VcVerification.SchemaCheck, - success = false - ) + ) + } + + private def verifySubjectVerification(credential: String): IO[VcVerificationServiceError, VcVerificationResult] = { + val result = + for { + decodedJwt <- + JwtCredential + .decodeJwt(JWT(credential)) + .mapError(error => VcVerificationServiceError.UnexpectedError(s"Unable decode JWT: $error")) + credentialSchema <- + ZIO + .fromOption(decodedJwt.maybeCredentialSchema) + .mapError(error => VcVerificationServiceError.UnexpectedError(s"Missing Credential Schema: $error")) + result <- CredentialSchema + .validateJWTCredentialSubject( + credentialSchema.id, + decodedJwt.credentialSubject.noSpaces, + uriDereferencer ) - ) - ) + .mapError(error => + VcVerificationServiceError.UnexpectedError(s"JWT Credential Subject Validation Failed: $error") + ) + } yield result - ZIO.succeed(VcVerificationOutcome(verification = VcVerification.SchemaCheck, success = true)) + result + .as( + VcVerificationResult( + credential = credential, + verification = VcVerification.SubjectVerification, + success = true + ) + ) + .catchAll(_ => + ZIO.succeed( + VcVerificationResult( + credential = credential, + verification = VcVerification.SubjectVerification, + success = false + ) + ) + ) } - private def verifySignature(credential: String): IO[VcVerificationServiceError, VcVerificationOutcome] = { + private def verifySignature(credential: String): IO[VcVerificationServiceError, VcVerificationResult] = { JwtCredential .validateEncodedJWT(JWT(credential))(didResolver) .mapError(error => VcVerificationServiceError.UnexpectedError(error)) .map(validation => - VcVerificationOutcome( + VcVerificationResult( + credential = credential, verification = VcVerification.SignatureVerification, success = validation .map(_ => true) @@ -107,9 +136,10 @@ class VcVerificationServiceImpl(didResolver: DidResolver, uriDereferencer: URIDe ) } - private def verifyExpiration(credential: String): IO[VcVerificationServiceError, VcVerificationOutcome] = { + private def verifyExpiration(credential: String): IO[VcVerificationServiceError, VcVerificationResult] = { ZIO.succeed( - VcVerificationOutcome( + VcVerificationResult( + credential = credential, verification = VcVerification.ExpirationCheck, success = JwtCredential .validateExpiration(JWT(credential)) @@ -119,9 +149,10 @@ class VcVerificationServiceImpl(didResolver: DidResolver, uriDereferencer: URIDe ) } - private def verifyNotBefore(credential: String): IO[VcVerificationServiceError, VcVerificationOutcome] = { + private def verifyNotBefore(credential: String): IO[VcVerificationServiceError, VcVerificationResult] = { ZIO.succeed( - VcVerificationOutcome( + VcVerificationResult( + credential = credential, verification = VcVerification.NotBeforeCheck, success = JwtCredential .validateNotBefore(JWT(credential)) @@ -131,9 +162,10 @@ class VcVerificationServiceImpl(didResolver: DidResolver, uriDereferencer: URIDe ) } - private def verifyAlgorithm(credential: String): IO[VcVerificationServiceError, VcVerificationOutcome] = { + private def verifyAlgorithm(credential: String): IO[VcVerificationServiceError, VcVerificationResult] = { ZIO.succeed( - VcVerificationOutcome( + VcVerificationResult( + credential = credential, verification = VcVerification.AlgorithmVerification, success = JWTVerification .validateAlgorithm(JWT(credential)) @@ -143,12 +175,13 @@ class VcVerificationServiceImpl(didResolver: DidResolver, uriDereferencer: URIDe ) } - private def verifyIssuerIdentification(credential: String): IO[VcVerificationServiceError, VcVerificationOutcome] = { + private def verifyIssuerIdentification(credential: String): IO[VcVerificationServiceError, VcVerificationResult] = { JwtCredential .validateIssuerJWT(JWT(credential))(didResolver) .mapError(error => VcVerificationServiceError.UnexpectedError(error)) .map(validation => - VcVerificationOutcome( + VcVerificationResult( + credential = credential, verification = VcVerification.IssuerIdentification, success = validation .map(_ => true) @@ -156,6 +189,47 @@ class VcVerificationServiceImpl(didResolver: DidResolver, uriDereferencer: URIDe ) ) } + + private def verifySemanticCheckOfClaims(credential: String): IO[VcVerificationServiceError, VcVerificationResult] = { + val result = + for { + decodedJwt <- + JwtCredential + .decodeJwt(JWT(credential)) + .mapError(error => VcVerificationServiceError.UnexpectedError(s"Unable decode JWT: $error")) + } yield decodedJwt + + result + .as( + VcVerificationResult( + credential = credential, + verification = VcVerification.SubjectVerification, + success = true + ) + ) + .catchAll(_ => + ZIO.succeed( + VcVerificationResult( + credential = credential, + verification = VcVerification.SubjectVerification, + success = false + ) + ) + ) + } + + private def verifyAudienceCheck( + credential: String, + aud: String + ): IO[VcVerificationServiceError, VcVerificationResult] = { + ZIO.succeed( + VcVerificationResult( + credential = credential, + verification = VcVerification.SubjectVerification, + success = true + ) + ) + } } object VcVerificationServiceImpl { diff --git a/pollux/lib/vc-jwt/src/main/scala/io/iohk/atala/pollux/vc/jwt/JWTVerification.scala b/pollux/lib/vc-jwt/src/main/scala/io/iohk/atala/pollux/vc/jwt/JWTVerification.scala index 7b774dbefe..4b2a21d43c 100644 --- a/pollux/lib/vc-jwt/src/main/scala/io/iohk/atala/pollux/vc/jwt/JWTVerification.scala +++ b/pollux/lib/vc-jwt/src/main/scala/io/iohk/atala/pollux/vc/jwt/JWTVerification.scala @@ -37,7 +37,7 @@ object JWTVerification { .fromOptionWith("An algorithm must be specified in the header")(JwtCirce.parseHeader(header).algorithm) result <- Validation - .fromPredicateWith("No PublicKey to validate against found")( + .fromPredicateWith("Algorithm Not Supported")( SUPPORT_PUBLIC_KEY_TYPES.getOrElse(algorithm.name, Set.empty) )(_.nonEmpty) .flatMap(_ => Validation.unit) diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/PrismAgentApp.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/PrismAgentApp.scala index b697f42a20..a8950f0c1b 100644 --- a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/PrismAgentApp.scala +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/PrismAgentApp.scala @@ -3,13 +3,7 @@ package io.iohk.atala.agent.server import io.iohk.atala.agent.notification.WebhookPublisher import io.iohk.atala.agent.server.config.AppConfig import io.iohk.atala.agent.server.http.{ZHttp4sBlazeServer, ZHttpEndpoints} -import io.iohk.atala.agent.server.jobs.{ - ConnectBackgroundJobs, - DIDStateSyncBackgroundJobs, - IssueBackgroundJobs, - PresentBackgroundJobs, - StatusListJobs -} +import io.iohk.atala.agent.server.jobs.* import io.iohk.atala.agent.walletapi.model.{Entity, Wallet, WalletSeed} import io.iohk.atala.agent.walletapi.service.{EntityService, ManagedDIDService, WalletManagementService} import io.iohk.atala.agent.walletapi.storage.DIDNonSecretStorage @@ -31,8 +25,7 @@ import io.iohk.atala.pollux.credentialschema.{SchemaRegistryServerEndpoints, Ver import io.iohk.atala.pollux.vc.jwt.DidResolver as JwtDidResolver import io.iohk.atala.presentproof.controller.PresentProofServerEndpoints import io.iohk.atala.resolvers.DIDResolver -import io.iohk.atala.shared.models.WalletAdministrationContext -import io.iohk.atala.shared.models.{HexString, WalletAccessContext, WalletId} +import io.iohk.atala.shared.models.{HexString, WalletAccessContext, WalletAdministrationContext, WalletId} import io.iohk.atala.shared.utils.DurationOps.toMetricsSeconds import io.iohk.atala.system.controller.SystemServerEndpoints import io.iohk.atala.verification.controller.VcVerificationServerEndpoints diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/VcVerificationControllerImpl.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/VcVerificationControllerImpl.scala index b26be647e7..e83c3fc3ad 100644 --- a/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/VcVerificationControllerImpl.scala +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/VcVerificationControllerImpl.scala @@ -1,7 +1,7 @@ package io.iohk.atala.verification.controller import io.iohk.atala.api.http.{ErrorResponse, RequestContext} -import io.iohk.atala.pollux.core.service.verification.{VcVerification, VcVerificationRequest, VcVerificationService} +import io.iohk.atala.pollux.core.service.verification.VcVerificationService import io.iohk.atala.verification.controller import zio.* @@ -10,33 +10,20 @@ class VcVerificationControllerImpl(vcVerificationService: VcVerificationService) override def verify( requests: List[controller.http.VcVerificationRequest] )(implicit rc: RequestContext): IO[ErrorResponse, List[controller.http.VcVerificationResponse]] = { - val serviceRequests = - requests.map(request => { - val verifications = - if (request.verifications.isEmpty) - VcVerification.values.toList - else - request.verifications - - VcVerificationRequest( - credential = request.credential, - verifications = verifications + val result = + ZIO.collectAll(requests.map(request => { + val serviceRequests = controller.http.VcVerificationRequest.toService(request) + for { + results <- + vcVerificationService + .verify(serviceRequests) + .mapError(error => VcVerificationController.toHttpError(error)) + } yield controller.http.VcVerificationResponse( + request.credential, + results.map(result => controller.http.VcVerificationResult.toService(result)) ) - }) - for { - results <- - vcVerificationService - .verify(serviceRequests) - .mapError(error => VcVerificationController.toHttpError(error)) - } yield results.map(result => - controller.http.VcVerificationResponse( - result.credential, - result.checks, - result.successfulChecks, - result.failedChecks, - result.failedAsWarningChecks - ) - ) + })) + ZIO.succeed(List.empty) } } diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/ParameterizableVcVerification.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/ParameterizableVcVerification.scala new file mode 100644 index 0000000000..8994cedf77 --- /dev/null +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/ParameterizableVcVerification.scala @@ -0,0 +1,18 @@ +package io.iohk.atala.verification.controller.http + +import sttp.tapir.Schema +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} + +final case class ParameterizableVcVerification( + verification: VcVerification, + parameter: Option[VcVerificationParameter] +) +object ParameterizableVcVerification { + given encoder: JsonEncoder[ParameterizableVcVerification] = + DeriveJsonEncoder.gen[ParameterizableVcVerification] + + given decoder: JsonDecoder[ParameterizableVcVerification] = + DeriveJsonDecoder.gen[ParameterizableVcVerification] + + given schema: Schema[ParameterizableVcVerification] = Schema.derived +} diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerification.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerification.scala new file mode 100644 index 0000000000..0458e03583 --- /dev/null +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerification.scala @@ -0,0 +1,65 @@ +package io.iohk.atala.verification.controller.http + +import io.iohk.atala.pollux.core.service +import io.iohk.atala.pollux.core.service.verification.VcVerification as ServiceVcVerification +import sttp.tapir.Schema +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} + +enum VcVerification { + case SignatureVerification + case IssuerIdentification + case ExpirationCheck + case NotBeforeCheck + case AudienceCheck + case SubjectVerification + case IntegrityOfClaims + case ComplianceWithStandards + case RevocationCheck + case AlgorithmVerification + case SchemaCheck + case SemanticCheckOfClaims +} + +object VcVerification { + given encoder: JsonEncoder[VcVerification] = + DeriveJsonEncoder.gen[VcVerification] + + given decoder: JsonDecoder[VcVerification] = + DeriveJsonDecoder.gen[VcVerification] + + given schema: Schema[VcVerification] = Schema.derivedEnumeration.defaultStringBased + + def convert(verification: VcVerification): ServiceVcVerification = { + verification match { + case SignatureVerification => ServiceVcVerification.SignatureVerification + case IssuerIdentification => ServiceVcVerification.IssuerIdentification + case ExpirationCheck => ServiceVcVerification.ExpirationCheck + case NotBeforeCheck => ServiceVcVerification.NotBeforeCheck + case AudienceCheck => ServiceVcVerification.AudienceCheck + case SubjectVerification => ServiceVcVerification.SubjectVerification + case IntegrityOfClaims => ServiceVcVerification.IntegrityOfClaims + case ComplianceWithStandards => ServiceVcVerification.ComplianceWithStandards + case RevocationCheck => ServiceVcVerification.RevocationCheck + case AlgorithmVerification => ServiceVcVerification.AlgorithmVerification + case SchemaCheck => ServiceVcVerification.SchemaCheck + case SemanticCheckOfClaims => ServiceVcVerification.SemanticCheckOfClaims + } + } + + def toService(verification: ServiceVcVerification): VcVerification = { + verification match { + case ServiceVcVerification.SignatureVerification => SignatureVerification + case ServiceVcVerification.IssuerIdentification => IssuerIdentification + case ServiceVcVerification.ExpirationCheck => ExpirationCheck + case ServiceVcVerification.NotBeforeCheck => NotBeforeCheck + case ServiceVcVerification.AudienceCheck => AudienceCheck + case ServiceVcVerification.SubjectVerification => SubjectVerification + case ServiceVcVerification.IntegrityOfClaims => IntegrityOfClaims + case ServiceVcVerification.ComplianceWithStandards => ComplianceWithStandards + case ServiceVcVerification.RevocationCheck => RevocationCheck + case ServiceVcVerification.AlgorithmVerification => AlgorithmVerification + case ServiceVcVerification.SchemaCheck => SchemaCheck + case ServiceVcVerification.SemanticCheckOfClaims => SemanticCheckOfClaims + } + } +} diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerificationParameter.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerificationParameter.scala new file mode 100644 index 0000000000..43e7c93f6f --- /dev/null +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerificationParameter.scala @@ -0,0 +1,36 @@ +package io.iohk.atala.verification.controller.http + +import io.iohk.atala.pollux.core.service.verification.{ + AudienceParameter as ServiceAudienceParameter, + VcVerificationParameter as ServiceVcVerificationParameter +} +import sttp.tapir.Schema +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} + +sealed trait VcVerificationParameter + +object VcVerificationParameter { + given encoder: JsonEncoder[VcVerificationParameter] = + DeriveJsonEncoder.gen[VcVerificationParameter] + + given decoder: JsonDecoder[VcVerificationParameter] = + DeriveJsonDecoder.gen[VcVerificationParameter] + + given schema: Schema[VcVerificationParameter] = Schema.derived + + def convert(parameter: VcVerificationParameter): ServiceVcVerificationParameter = { + parameter match + case AudienceParameter(aud) => ServiceAudienceParameter(aud) + } +} + +case class AudienceParameter(aud: String) extends VcVerificationParameter +object AudienceParameter { + given encoder: JsonEncoder[AudienceParameter] = + DeriveJsonEncoder.gen[AudienceParameter] + + given decoder: JsonDecoder[AudienceParameter] = + DeriveJsonDecoder.gen[AudienceParameter] + + given schema: Schema[AudienceParameter] = Schema.derived +} diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerificationRequest.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerificationRequest.scala index dbe0b37654..af1e04eb13 100644 --- a/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerificationRequest.scala +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerificationRequest.scala @@ -1,7 +1,7 @@ package io.iohk.atala.verification.controller.http import io.iohk.atala.api.http.Annotation -import io.iohk.atala.pollux.core.service.verification.VcVerification +import io.iohk.atala.pollux.core.service.verification.VcVerificationRequest as ServiceVcVerificationRequest import sttp.tapir.Schema import sttp.tapir.Schema.annotations.{description, encodedExample} import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} @@ -12,7 +12,7 @@ final case class VcVerificationRequest( credential: String, @description(VcVerificationRequest.annotations.vcVerification.description) @encodedExample(VcVerificationRequest.annotations.vcVerification.example) - verifications: List[VcVerification] + verifications: List[ParameterizableVcVerification] ) object VcVerificationRequest { @@ -52,4 +52,14 @@ object VcVerificationRequest { DeriveJsonDecoder.gen[VcVerificationRequest] given credentialVerificationRequestSchema: Schema[VcVerificationRequest] = Schema.derived + + def toService(request: VcVerificationRequest): List[ServiceVcVerificationRequest] = { + request.verifications.map(verification => + ServiceVcVerificationRequest( + credential = request.credential, + verification = VcVerification.convert(verification.verification), + parameter = verification.parameter.map(param => VcVerificationParameter.convert(param)) + ) + ) + } } diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerificationResponse.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerificationResponse.scala index 32ccc3c464..70e4ee35bc 100644 --- a/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerificationResponse.scala +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerificationResponse.scala @@ -1,7 +1,6 @@ package io.iohk.atala.verification.controller.http import io.iohk.atala.api.http.Annotation -import io.iohk.atala.pollux.core.service.verification.VcVerification import sttp.tapir.Schema import sttp.tapir.Schema.annotations.{description, encodedExample} import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} @@ -12,16 +11,7 @@ final case class VcVerificationResponse( credential: String, @description(VcVerificationResponse.annotations.checks.description) @encodedExample(VcVerificationResponse.annotations.checks.example) - checks: List[VcVerification], - @description(VcVerificationResponse.annotations.successfulChecks.description) - @encodedExample(VcVerificationResponse.annotations.successfulChecks.example) - successfulChecks: List[VcVerification], - @description(VcVerificationResponse.annotations.failedChecks.description) - @encodedExample(VcVerificationResponse.annotations.failedChecks.example) - failedChecks: List[VcVerification], - @description(VcVerificationResponse.annotations.failedAsWarningChecks.description) - @encodedExample(VcVerificationResponse.annotations.failedAsWarningChecks.example) - failedAsWarningChecks: List[VcVerification] + result: List[VcVerificationResult], ) object VcVerificationResponse { diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerificationResult.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerificationResult.scala new file mode 100644 index 0000000000..99158682da --- /dev/null +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/verification/controller/http/VcVerificationResult.scala @@ -0,0 +1,26 @@ +package io.iohk.atala.verification.controller.http + +import io.iohk.atala.pollux.core.service.verification.VcVerificationResult as ServiceVcVerificationResult +import sttp.tapir.Schema +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} + +final case class VcVerificationResult( + verification: VcVerification, + success: Boolean +) +object VcVerificationResult { + given encoder: JsonEncoder[VcVerificationResult] = + DeriveJsonEncoder.gen[VcVerificationResult] + + given decoder: JsonDecoder[VcVerificationResult] = + DeriveJsonDecoder.gen[VcVerificationResult] + + given schema: Schema[VcVerificationResult] = Schema.derived + + def toService(result: ServiceVcVerificationResult): VcVerificationResult = { + VcVerificationResult( + verification = VcVerification.toService(result.verification), + success = result.success + ) + } +}