From 0729ed792d5bf2414a2ae3677c6b1fa62de6fae4 Mon Sep 17 00:00:00 2001 From: Bassam Riman Date: Thu, 12 Sep 2024 12:01:53 -0400 Subject: [PATCH] ATL-7765: VCVerification API support ARRAY or OBJECT as Credential Schema Signed-off-by: Bassam Riman --- .../VcVerificationServiceImpl.scala | 5 +- .../resources/vc-schema-driver-license.json | 6 +- .../test/resources/vc-schema-personal.json | 4 +- .../VcVerificationServiceImplSpec.scala | 80 +++++++++++++++++++ 4 files changed, 88 insertions(+), 7 deletions(-) diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/verification/VcVerificationServiceImpl.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/verification/VcVerificationServiceImpl.scala index 18b5370bb5..7ad3c9588d 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/verification/VcVerificationServiceImpl.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/verification/VcVerificationServiceImpl.scala @@ -2,7 +2,8 @@ package org.hyperledger.identus.pollux.core.service.verification import org.hyperledger.identus.pollux.core.model.schema.CredentialSchema import org.hyperledger.identus.pollux.core.service.URIDereferencer -import org.hyperledger.identus.pollux.vc.jwt.{DidResolver, JWT, JWTVerification, JwtCredential} +import org.hyperledger.identus.pollux.vc.jwt.{CredentialPayload, DidResolver, JWT, JWTVerification, JwtCredential} +import org.hyperledger.identus.pollux.vc.jwt.CredentialPayload.Implicits import zio.* import java.time.OffsetDateTime @@ -104,7 +105,7 @@ class VcVerificationServiceImpl(didResolver: DidResolver, uriDereferencer: URIDe CredentialSchema .validateJWTCredentialSubject( credentialSchema.id, - decodedJwt.credentialSubject.noSpaces, + CredentialPayload.Implicits.jwtVcEncoder(decodedJwt.vc).noSpaces, uriDereferencer ) .mapError(error => diff --git a/pollux/core/src/test/resources/vc-schema-driver-license.json b/pollux/core/src/test/resources/vc-schema-driver-license.json index e5a9f20cb7..f2ff164f61 100644 --- a/pollux/core/src/test/resources/vc-schema-driver-license.json +++ b/pollux/core/src/test/resources/vc-schema-driver-license.json @@ -11,16 +11,16 @@ "format": "date-time" }, "drivingLicenseID": { - "type": "string" + "type": "integer" }, "drivingClass": { "type": "integer" } }, "required": ["dateOfIssuance", "drivingLicenseID", "drivingClass"], - "additionalProperties": false + "additionalProperties": true } }, "required": ["credentialSubject"], - "additionalProperties": false + "additionalProperties": true } diff --git a/pollux/core/src/test/resources/vc-schema-personal.json b/pollux/core/src/test/resources/vc-schema-personal.json index 3f2d0e9b15..cb0cb16a4c 100644 --- a/pollux/core/src/test/resources/vc-schema-personal.json +++ b/pollux/core/src/test/resources/vc-schema-personal.json @@ -18,9 +18,9 @@ } }, "required": ["email", "userName", "age"], - "additionalProperties": false + "additionalProperties": true } }, "required": ["credentialSubject"], - "additionalProperties": false + "additionalProperties": true } diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/verification/VcVerificationServiceImplSpec.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/verification/VcVerificationServiceImplSpec.scala index 3d9f41da04..62be6e2e87 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/verification/VcVerificationServiceImplSpec.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/verification/VcVerificationServiceImplSpec.scala @@ -515,6 +515,86 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS someVcVerificationServiceLayer ++ ZLayer.succeed(WalletAccessContext(WalletId.random)) ), + test("verify subject given multiple schema") { + for { + svc <- ZIO.service[VcVerificationService] + verifier = "did:prism:verifier" + jwtCredentialPayload = W3cCredentialPayload( + `@context` = + Set("https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1"), + maybeId = Some("http://example.edu/credentials/3732"), + `type` = Set("VerifiableCredential", "UniversityDegreeCredential"), + issuer = Left(issuer.did.toString), + issuanceDate = Instant.parse("2010-01-01T00:00:00Z"), + maybeExpirationDate = Some(Instant.parse("2010-01-12T00:00:00Z")), + maybeValidFrom = Some(Instant.parse("2010-01-12T00:00:00Z")), + maybeValidUntil = Some(Instant.parse("2010-01-12T00:00:00Z")), + maybeCredentialSchema = Some( + Right( + List( + CredentialSchema( + id = "resource:///vc-schema-personal.json", + `type` = "JsonSchemaValidator2018" + ), + CredentialSchema( + id = "resource:///vc-schema-driver-license.json", + `type` = "JsonSchemaValidator2018" + ) + ) + ) + ), + credentialSubject = Json.obj( + "userName" -> Json.fromString("Alice"), + "age" -> Json.fromInt(42), + "email" -> Json.fromString("alice@wonderland.com"), + "dateOfIssuance" -> Json.fromString("2000-01-01T10:00:00Z"), + "drivingLicenseID" -> Json.fromInt(12345), + "drivingClass" -> Json.fromInt(5) + ), + maybeCredentialStatus = Some( + CredentialStatus( + id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", + `type` = "StatusList2021Entry", + statusPurpose = StatusPurpose.Revocation, + statusListIndex = 0, + statusListCredential = "https://example.com/credentials/status/3" + ) + ), + maybeRefreshService = Some( + RefreshService( + id = "https://example.edu/refresh/3732", + `type` = "ManualRefreshService2018" + ) + ), + maybeEvidence = Option.empty, + maybeTermsOfUse = Option.empty, + aud = Set(verifier) + ).toJwtCredentialPayload + signedJwtCredential = issuer.signer.encode(jwtCredentialPayload.asJson) + result <- + svc.verify( + List( + VcVerificationRequest(signedJwtCredential.value, VcVerification.SubjectVerification) + ) + ) + } yield { + assertTrue( + result.contains( + VcVerificationResult( + signedJwtCredential.value, + VcVerification.SubjectVerification, + true + ) + ) + ) + } + }.provideSomeLayer( + MockDIDService.empty ++ + MockManagedDIDService.empty ++ + ResourceURIDereferencerImpl.layer >+> + someVcVerificationServiceLayer ++ + ZLayer.succeed(WalletAccessContext(WalletId.random)) + ), test("verify nbf given valid") { for { svc <- ZIO.service[VcVerificationService]