From 380651edfd4f33564a466fecd521d2f24fa0f502 Mon Sep 17 00:00:00 2001 From: Alfred Tuffreau Date: Wed, 26 Jan 2022 15:00:40 +0100 Subject: [PATCH 1/3] Added support to generate EBSI presentation and store the generated presentations --- build.gradle.kts | 4 +-- src/main/kotlin/id/walt/cli/VcCommand.kt | 2 +- .../kotlin/id/walt/custodian/Custodian.kt | 34 ++++++++++++++----- .../kotlin/id/walt/rest/core/VcController.kt | 3 +- .../rest/custodian/CustodianController.kt | 4 +-- .../services/vc/JsonLdCredentialService.kt | 11 ++++-- .../walt/services/vc/JwtCredentialService.kt | 10 ++++-- .../vc/WaltIdJsonLdCredentialService.kt | 12 +++++-- .../services/vc/WaltIdJwtCredentialService.kt | 22 +++++++++--- .../vcstore/FileSystemVcStoreService.kt | 7 +++- .../kotlin/id/walt/auditor/AuditorTest.kt | 4 +-- .../kotlin/id/walt/cli/VcVerifyCommandTest.kt | 4 +-- .../id/walt/custodian/CustodianPresentTest.kt | 10 +++--- src/test/kotlin/id/walt/essif/EssifIntTest.kt | 2 +- .../vc/WaltIdJsonLdCredentialServiceTest.kt | 6 ++-- templates/vc-template-europass.json | 20 +++++------ 16 files changed, 105 insertions(+), 50 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 60961b53..5205e3a7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "id.walt" -version = "1.4-SNAPSHOT" +version = "1.4.1-SNAPSHOT" repositories { mavenCentral() @@ -44,7 +44,7 @@ dependencies { implementation("com.google.guava:guava:31.0.1-jre") // VC - implementation("id.walt:waltid-ssikit-vclib:1.9.0") + implementation("id.walt:waltid-ssikit-vclib:1.11.2-SNAPSHOT") // JSON implementation("org.json:json:20210307") diff --git a/src/main/kotlin/id/walt/cli/VcCommand.kt b/src/main/kotlin/id/walt/cli/VcCommand.kt index 3cd57f17..e852e597 100644 --- a/src/main/kotlin/id/walt/cli/VcCommand.kt +++ b/src/main/kotlin/id/walt/cli/VcCommand.kt @@ -152,7 +152,7 @@ class PresentVcCommand : CliktCommand( val vcStrList = vcSources.values.toList() // Creating the Verifiable Presentation - val vp = Custodian.getService().createPresentation(vcStrList, holderDid, verifierDid, domain, challenge) + val vp = Custodian.getService().createPresentation(vcStrList, holderDid, verifierDid, domain, challenge, null) log.debug { "Presentation created:\n$vp" } diff --git a/src/main/kotlin/id/walt/custodian/Custodian.kt b/src/main/kotlin/id/walt/custodian/Custodian.kt index 80f38503..3a8e1175 100644 --- a/src/main/kotlin/id/walt/custodian/Custodian.kt +++ b/src/main/kotlin/id/walt/custodian/Custodian.kt @@ -9,6 +9,8 @@ import id.walt.services.key.KeyService import id.walt.services.vc.JsonLdCredentialService import id.walt.services.vc.JwtCredentialService import id.walt.vclib.model.VerifiableCredential +import id.walt.vclib.model.VerifiableCredential.Companion.fromString +import java.time.Instant abstract class Custodian : WaltIdService() { override val implementation get() = serviceImplementation() @@ -26,8 +28,13 @@ abstract class Custodian : WaltIdService() { open fun deleteCredential(alias: String): Boolean = implementation.deleteCredential(alias) open fun createPresentation( - vcs: List, holderDid: String, verifierDid: String? = null, domain: String? = null, challenge: String? = null - ): String = implementation.createPresentation(vcs, holderDid, verifierDid, domain, challenge) + vcs: List, + holderDid: String, + verifierDid: String? = null, + domain: String? = null, + challenge: String? = null + , expirationDate: Instant? + ): String = implementation.createPresentation(vcs, holderDid, verifierDid, domain, challenge, expirationDate) companion object : ServiceProvider { override fun getService() = object : Custodian() {} @@ -40,7 +47,9 @@ open class WaltIdCustodian : Custodian() { private val jwtCredentialService = JwtCredentialService.getService() private val jsonLdCredentialService = JsonLdCredentialService.getService() - override fun generateKey(keyAlgorithm: KeyAlgorithm): Key = ContextManager.keyStore.load(keyService.generate(keyAlgorithm).id) + override fun generateKey(keyAlgorithm: KeyAlgorithm): Key = + ContextManager.keyStore.load(keyService.generate(keyAlgorithm).id) + override fun getKey(alias: String): Key = ContextManager.keyStore.load(alias) override fun listKeys(): List = ContextManager.keyStore.listKeys() override fun storeKey(key: Key) = ContextManager.keyStore.store(key) @@ -49,15 +58,22 @@ open class WaltIdCustodian : Custodian() { override fun getCredential(id: String) = ContextManager.vcStore.getCredential(id, VC_GROUP) override fun listCredentials(): List = ContextManager.vcStore.listCredentials(VC_GROUP) override fun listCredentialIds(): List = ContextManager.vcStore.listCredentialIds(VC_GROUP) - override fun storeCredential(alias: String, vc: VerifiableCredential) = ContextManager.vcStore.storeCredential(alias, vc, VC_GROUP) + override fun storeCredential(alias: String, vc: VerifiableCredential) = + ContextManager.vcStore.storeCredential(alias, vc, VC_GROUP) + override fun deleteCredential(alias: String) = ContextManager.vcStore.deleteCredential(alias, VC_GROUP) override fun createPresentation( - vcs: List, holderDid: String, verifierDid: String?, domain: String?, challenge: String? - ): String = when { - vcs.stream().allMatch { VerifiableCredential.isJWT(it) } -> jwtCredentialService.present(vcs, holderDid, verifierDid, challenge) - vcs.stream().noneMatch { VerifiableCredential.isJWT(it) } -> jsonLdCredentialService.present(vcs, holderDid, domain, challenge) + vcs: List, + holderDid: String, + verifierDid: String?, + domain: String?, + challenge: String?, + expirationDate: Instant? + ) = when { + vcs.stream().allMatch { VerifiableCredential.isJWT(it) } -> jwtCredentialService.present(vcs, holderDid, verifierDid, challenge, expirationDate) + vcs.stream().noneMatch { VerifiableCredential.isJWT(it) } -> jsonLdCredentialService.present(vcs, holderDid, domain, challenge, expirationDate) else -> throw IllegalStateException("All verifiable credentials must be of the same proof type.") - } + }.also { fromString(it).also { vp -> storeCredential(vp.id!!, vp) } } } diff --git a/src/main/kotlin/id/walt/rest/core/VcController.kt b/src/main/kotlin/id/walt/rest/core/VcController.kt index f814172f..57cc0f06 100644 --- a/src/main/kotlin/id/walt/rest/core/VcController.kt +++ b/src/main/kotlin/id/walt/rest/core/VcController.kt @@ -77,7 +77,8 @@ object VcController { listOf(presentVcReq.vc), presentVcReq.holderDid, presentVcReq.domain, - presentVcReq.challenge + presentVcReq.challenge, + null ) ) } diff --git a/src/main/kotlin/id/walt/rest/custodian/CustodianController.kt b/src/main/kotlin/id/walt/rest/custodian/CustodianController.kt index e44813ef..4176990a 100644 --- a/src/main/kotlin/id/walt/rest/custodian/CustodianController.kt +++ b/src/main/kotlin/id/walt/rest/custodian/CustodianController.kt @@ -185,7 +185,7 @@ object CustodianController { fun presentCredentials(ctx: Context) { val req = ctx.bodyAsClass() - ctx.result(custodian.createPresentation(req.vcs, req.holderDid, req.verifierDid, req.domain, req.challenge)) + ctx.result(custodian.createPresentation(req.vcs, req.holderDid, req.verifierDid, req.domain, req.challenge, null)) } fun presentCredentialIdsDocs() = document() @@ -202,7 +202,7 @@ object CustodianController { val ids = req.vcIds.map { custodian.getCredential(it)!!.encode() } - ctx.result(custodian.createPresentation(ids, req.holderDid, req.verifierDid, req.domain, req.challenge)) + ctx.result(custodian.createPresentation(ids, req.holderDid, req.verifierDid, req.domain, req.challenge, null)) } } diff --git a/src/main/kotlin/id/walt/services/vc/JsonLdCredentialService.kt b/src/main/kotlin/id/walt/services/vc/JsonLdCredentialService.kt index fa3a1885..1543d488 100644 --- a/src/main/kotlin/id/walt/services/vc/JsonLdCredentialService.kt +++ b/src/main/kotlin/id/walt/services/vc/JsonLdCredentialService.kt @@ -7,6 +7,7 @@ import id.walt.signatory.ProofConfig import id.walt.vclib.model.VerifiableCredential import info.weboftrust.ldsignatures.LdProof import kotlinx.serialization.Serializable +import java.time.Instant enum class VerificationType { VERIFIABLE_CREDENTIAL, @@ -26,8 +27,14 @@ abstract class JsonLdCredentialService : WaltIdService() { open fun verifyVc(vcJson: String): Boolean = implementation.verifyVc(vcJson) open fun verifyVp(vpJson: String): Boolean = implementation.verifyVp(vpJson) - open fun present(vcs: List, holderDid: String, domain: String?, challenge: String?): String = - implementation.present(vcs, holderDid, domain, challenge) + open fun present( + vcs: List, + holderDid: String, + domain: String?, + challenge: String?, + expirationDate: Instant? + ): String = + implementation.present(vcs, holderDid, domain, challenge, expirationDate) open fun listVCs(): List = implementation.listVCs() diff --git a/src/main/kotlin/id/walt/services/vc/JwtCredentialService.kt b/src/main/kotlin/id/walt/services/vc/JwtCredentialService.kt index 45c1492c..1c3ef069 100644 --- a/src/main/kotlin/id/walt/services/vc/JwtCredentialService.kt +++ b/src/main/kotlin/id/walt/services/vc/JwtCredentialService.kt @@ -6,6 +6,7 @@ import id.walt.services.WaltIdService import id.walt.signatory.ProofConfig import id.walt.vclib.model.VerifiableCredential import info.weboftrust.ldsignatures.LdProof +import java.time.Instant abstract class JwtCredentialService : WaltIdService() { @@ -18,8 +19,13 @@ abstract class JwtCredentialService : WaltIdService() { open fun verifyVc(vc: String): Boolean = implementation.verifyVc(vc) open fun verifyVp(vp: String): Boolean = implementation.verifyVp(vp) - open fun present(vcs: List, holderDid: String, verifierDid: String? = null, challenge: String? = null): String = - implementation.present(vcs, holderDid, verifierDid, challenge) + open fun present( + vcs: List, + holderDid: String, + verifierDid: String? = null, + challenge: String? = null, + expirationDate: Instant? = null + ): String = implementation.present(vcs, holderDid, verifierDid, challenge, expirationDate) open fun listVCs(): List = implementation.listVCs() diff --git a/src/main/kotlin/id/walt/services/vc/WaltIdJsonLdCredentialService.kt b/src/main/kotlin/id/walt/services/vc/WaltIdJsonLdCredentialService.kt index 8ab618f0..d97c8271 100644 --- a/src/main/kotlin/id/walt/services/vc/WaltIdJsonLdCredentialService.kt +++ b/src/main/kotlin/id/walt/services/vc/WaltIdJsonLdCredentialService.kt @@ -25,6 +25,7 @@ import java.net.URI import java.net.URL import java.nio.file.Files import java.nio.file.Path +import java.time.Instant import java.util.* private val log = KotlinLogging.logger {} @@ -270,7 +271,13 @@ open class WaltIdJsonLdCredentialService : JsonLdCredentialService() { // return verifier.verify(jsonLdObject) // } - override fun present(vcs: List, holderDid: String, domain: String?, challenge: String?): String { + override fun present( + vcs: List, + holderDid: String, + domain: String?, + challenge: String?, + expirationDate: Instant? + ): String { log.debug { "Creating a presentation for VCs:\n$vcs" } val id = "urn:uuid:${UUID.randomUUID()}" @@ -281,7 +288,8 @@ open class WaltIdJsonLdCredentialService : JsonLdCredentialService() { proofType = ProofType.LD_PROOF, domain = domain, nonce = challenge, - credentialId = id + credentialId = id, + expirationDate = expirationDate ) val vpReqStr = VerifiablePresentation(id = id, holder = holderDid, verifiableCredential = vcs.map { it.toCredential() }).encode() diff --git a/src/main/kotlin/id/walt/services/vc/WaltIdJwtCredentialService.kt b/src/main/kotlin/id/walt/services/vc/WaltIdJwtCredentialService.kt index 6292cfd4..5e2104ca 100644 --- a/src/main/kotlin/id/walt/services/vc/WaltIdJwtCredentialService.kt +++ b/src/main/kotlin/id/walt/services/vc/WaltIdJwtCredentialService.kt @@ -14,7 +14,10 @@ import net.pwall.json.schema.JSONSchema import java.net.URL import java.nio.file.Files import java.nio.file.Path +import java.text.SimpleDateFormat import java.time.Instant +import java.time.ZoneOffset +import java.time.format.DateTimeFormatter import java.util.* private val log = KotlinLogging.logger {} @@ -29,12 +32,14 @@ open class WaltIdJwtCredentialService : JwtCredentialService() { override fun sign(jsonCred: String, config: ProofConfig): String { log.debug { "Signing JWT object with config: $config" } + val crd = jsonCred.toCredential() val issuerDid = config.issuerDid val issueDate = config.issueDate ?: Instant.now() val validDate = config.validDate ?: Instant.now() val jwtClaimsSet = JWTClaimsSet.Builder() .jwtID(config.credentialId) .issuer(issuerDid) + .subject(config.subjectDid) .issueTime(Date.from(issueDate)) .notBeforeTime(Date.from(validDate)) @@ -44,11 +49,10 @@ open class WaltIdJwtCredentialService : JwtCredentialService() { config.verifierDid?.let { jwtClaimsSet.audience(config.verifierDid) } config.nonce?.let { jwtClaimsSet.claim("nonce", config.nonce) } - when (val crd = jsonCred.toCredential()) { + when (crd) { is VerifiablePresentation -> jwtClaimsSet .claim(JWT_VP_CLAIM, crd.toMap()) else -> jwtClaimsSet - .subject(config.subjectDid) .claim(JWT_VC_CLAIM, crd.toMap()) } @@ -80,18 +84,26 @@ open class WaltIdJwtCredentialService : JwtCredentialService() { override fun verifyVp(vp: String): Boolean = verifyVc(vp) - override fun present(vcs: List, holderDid: String, verifierDid: String?, challenge: String?): String { + override fun present( + vcs: List, + holderDid: String, + verifierDid: String?, + challenge: String?, + expirationDate: Instant? + ): String { log.debug { "Creating a presentation for VCs:\n$vcs" } val id = "urn:uuid:${UUID.randomUUID()}" val config = ProofConfig( issuerDid = holderDid, + subjectDid = holderDid, verifierDid = verifierDid, proofType = ProofType.JWT, nonce = challenge, - credentialId = id + credentialId = id, + expirationDate = expirationDate ) - val vpReqStr = VerifiablePresentation(verifiableCredential = vcs.map { it.toCredential() }).encode() + val vpReqStr = VerifiablePresentation(holder = holderDid, verifiableCredential = vcs.map { it.toCredential() }).encode() log.trace { "VP request: $vpReqStr" } log.trace { "Proof config: $$config" } diff --git a/src/main/kotlin/id/walt/services/vcstore/FileSystemVcStoreService.kt b/src/main/kotlin/id/walt/services/vcstore/FileSystemVcStoreService.kt index c2638884..1527a46c 100644 --- a/src/main/kotlin/id/walt/services/vcstore/FileSystemVcStoreService.kt +++ b/src/main/kotlin/id/walt/services/vcstore/FileSystemVcStoreService.kt @@ -4,6 +4,8 @@ package id.walt.services.vcstore import id.walt.vclib.model.VerifiableCredential import id.walt.vclib.model.toCredential import java.io.File +import java.net.URLEncoder +import java.nio.charset.StandardCharsets open class FileSystemVcStoreService : VcStoreService() { @@ -25,7 +27,10 @@ open class FileSystemVcStoreService : VcStoreService() { override fun listCredentialIds(group: String): List = getGroupDir(group).listFiles()!!.map { it.nameWithoutExtension } - override fun storeCredential(alias: String, vc: VerifiableCredential, group: String) = getFileById(alias, group).writeText(vc.encode()) + override fun storeCredential(alias: String, vc: VerifiableCredential, group: String) = + getFileById( + URLEncoder.encode(alias, StandardCharsets.UTF_8), group + ).writeText(vc.encode()) override fun deleteCredential(alias: String, group: String) = getFileById(alias, group).delete() } diff --git a/src/test/kotlin/id/walt/auditor/AuditorTest.kt b/src/test/kotlin/id/walt/auditor/AuditorTest.kt index c757bfa1..c1bd7270 100644 --- a/src/test/kotlin/id/walt/auditor/AuditorTest.kt +++ b/src/test/kotlin/id/walt/auditor/AuditorTest.kt @@ -46,7 +46,7 @@ class AuditorCommandTest : StringSpec() { ) vpStr = - custodian.createPresentation(listOf(vcStr), did, did, "https://api.preprod.ebsi.eu", "d04442d3-661f-411e-a80f-42f19f594c9d") + custodian.createPresentation(listOf(vcStr), did, did, "https://api.preprod.ebsi.eu", "d04442d3-661f-411e-a80f-42f19f594c9d", null) vcJwt = signatory.issue( "VerifiableDiploma", ProofConfig( @@ -58,7 +58,7 @@ class AuditorCommandTest : StringSpec() { DummySignatoryDataProvider() ) - vpJwt = custodian.createPresentation(listOf(vcJwt), did, did, null, "abcd") + vpJwt = custodian.createPresentation(listOf(vcJwt), did, did, null, "abcd", null) } init { diff --git a/src/test/kotlin/id/walt/cli/VcVerifyCommandTest.kt b/src/test/kotlin/id/walt/cli/VcVerifyCommandTest.kt index 1fb7e0ec..4c5e003a 100644 --- a/src/test/kotlin/id/walt/cli/VcVerifyCommandTest.kt +++ b/src/test/kotlin/id/walt/cli/VcVerifyCommandTest.kt @@ -37,7 +37,7 @@ class VcVerifyCommandTest : StringSpec({ val vcStr = Signatory.getService().issue( "VerifiableDiploma", ProofConfig(issuerDid = did, subjectDid = did, issuerVerificationMethod = "Ed25519Signature2018") ) - val vpStr = JsonLdCredentialService.getService().present(listOf(vcStr), did, "https://api.preprod.ebsi.eu", "d04442d3-661f-411e-a80f-42f19f594c9d") + val vpStr = JsonLdCredentialService.getService().present(listOf(vcStr), did, "https://api.preprod.ebsi.eu", "d04442d3-661f-411e-a80f-42f19f594c9d", null) val vpFile = File.createTempFile("vpr", ".json") try { vpFile.writeText(vpStr) @@ -52,7 +52,7 @@ class VcVerifyCommandTest : StringSpec({ val vcJwt = Signatory.getService().issue( "VerifiableDiploma", ProofConfig(issuerDid = did, subjectDid = did, issuerVerificationMethod = "Ed25519Signature2018", proofType = ProofType.JWT) ) - val vpJwt = Custodian.getService().createPresentation(listOf(vcJwt), did, did, null ,"abcd") + val vpJwt = Custodian.getService().createPresentation(listOf(vcJwt), did, did, null ,"abcd", null) val vpFile = File.createTempFile("vpr", ".jwt") try { vpFile.writeText(vpJwt) diff --git a/src/test/kotlin/id/walt/custodian/CustodianPresentTest.kt b/src/test/kotlin/id/walt/custodian/CustodianPresentTest.kt index fd7c828a..2a3447bd 100644 --- a/src/test/kotlin/id/walt/custodian/CustodianPresentTest.kt +++ b/src/test/kotlin/id/walt/custodian/CustodianPresentTest.kt @@ -49,7 +49,7 @@ class CustodianPresentTest : StringSpec() { init { "Json ld presentation" { - val presStr = Custodian.getService().createPresentation(listOf(vcJsonLd), did, did, null, null) + val presStr = Custodian.getService().createPresentation(listOf(vcJsonLd), did, did, null, null, null) println("Created VP: $presStr") val pres = presStr.toCredential() @@ -58,7 +58,7 @@ class CustodianPresentTest : StringSpec() { } "Jwt presentation" { - val presStr = Custodian.getService().createPresentation(listOf(vcJwt), did, did, null, "abcd") + val presStr = Custodian.getService().createPresentation(listOf(vcJwt), did, did, null, "abcd", null) println("Created VP: $presStr") checkVerifiablePresentation(presStr) @@ -67,7 +67,7 @@ class CustodianPresentTest : StringSpec() { "Jwt presentation without audience or nonce" { val presStr = Custodian .getService() - .createPresentation(listOf(vcJwt), did, null, null, "abcd") + .createPresentation(listOf(vcJwt), did, null, null, "abcd", null) println("Created VP: $presStr") checkVerifiablePresentation(presStr) @@ -76,7 +76,7 @@ class CustodianPresentTest : StringSpec() { "Jwt presentation without nonce" { val presStr = Custodian .getService() - .createPresentation(listOf(vcJwt), did, did, null) + .createPresentation(listOf(vcJwt), did, did, null, null, null) println("Created VP: $presStr") checkVerifiablePresentation(presStr) @@ -86,7 +86,7 @@ class CustodianPresentTest : StringSpec() { assertThrows { Custodian .getService() - .createPresentation(listOf(vcJsonLd, vcJwt), did, did, null, "abcd") + .createPresentation(listOf(vcJsonLd, vcJwt), did, did, null, "abcd", null) } } } diff --git a/src/test/kotlin/id/walt/essif/EssifIntTest.kt b/src/test/kotlin/id/walt/essif/EssifIntTest.kt index 55c08165..685ed879 100644 --- a/src/test/kotlin/id/walt/essif/EssifIntTest.kt +++ b/src/test/kotlin/id/walt/essif/EssifIntTest.kt @@ -172,7 +172,7 @@ class EssifIntTest() : StringSpec({ val vcStrList = src.stream().map { vc -> vc.readText() }.collect(Collectors.toList()) // Creating the Verifiable Presentation - val vp = Custodian.getService().createPresentation(vcStrList, holderDid, null, null, null) + val vp = Custodian.getService().createPresentation(vcStrList, holderDid, null, null, null, null) println("Verifiable presentation generated for holder DID: \"$holderDid\"") println("Verifiable presentation document (below, JSON):\n\n$vp") diff --git a/src/test/kotlin/id/walt/services/vc/WaltIdJsonLdCredentialServiceTest.kt b/src/test/kotlin/id/walt/services/vc/WaltIdJsonLdCredentialServiceTest.kt index 28ca5aba..2a0c221e 100644 --- a/src/test/kotlin/id/walt/services/vc/WaltIdJsonLdCredentialServiceTest.kt +++ b/src/test/kotlin/id/walt/services/vc/WaltIdJsonLdCredentialServiceTest.kt @@ -53,7 +53,7 @@ class WaltIdJsonLdCredentialServiceTest : AnnotationSpec() { vcVerified.verificationType shouldBe VerificationType.VERIFIABLE_CREDENTIAL val holderDid = vc.subject!! - val vpStr = credentialService.present(listOf(vcStr), holderDid, "domain.com", "nonce") + val vpStr = credentialService.present(listOf(vcStr), holderDid, "domain.com", "nonce", null) println("Presentation generated: $vpStr") val vp = vpStr.toCredential() as VerifiablePresentation @@ -111,7 +111,7 @@ class WaltIdJsonLdCredentialServiceTest : AnnotationSpec() { fun presentVa() { val vaStr = File("$VC_PATH/vc-ebsi-verifiable-authorisation.json").readText() - val vp = credentialService.present(listOf(vaStr), vaStr.toCredential().subject!!, null, null) + val vp = credentialService.present(listOf(vaStr), vaStr.toCredential().subject!!, null, null, null) println(vp) } @@ -133,7 +133,7 @@ class WaltIdJsonLdCredentialServiceTest : AnnotationSpec() { val vcSigned = vc.toCredential() println(vcSigned.toString()) - val vp = credentialService.present(listOf(vc), vcSigned.subject!!, domain, challenge) + val vp = credentialService.present(listOf(vc), vcSigned.subject!!, domain, challenge, null) println("Presentation generated: $vp") val vpVerified = credentialService.verifyVp(vp) diff --git a/templates/vc-template-europass.json b/templates/vc-template-europass.json index 4cae0a69..f5cb64b7 100644 --- a/templates/vc-template-europass.json +++ b/templates/vc-template-europass.json @@ -44,11 +44,11 @@ "specifiedBy": [ { "eCTSCreditPoints": 5, - "eqfLevel": "http://data.europa.eu/snb/eqf/4", + "eqflLevel": "http://data.europa.eu/snb/eqf/4", "id": "urn:epass:qualification:1", "isPartialQualification": true, "maximumDuration": "P6M", - "nqfLevel": "http://data.europa.eu/snb/qdr/c_49672c5a", + "nqflLevel": "http://data.europa.eu/snb/qdr/c_49672c5a", "title": "Applied mathematics", "volumeOfLearning": "PT60H" } @@ -116,17 +116,17 @@ ] }, "id": "urn:epass:learningAchievement:1", - "specifiedBy": { + "specifiedBy": [{ "eCTSCreditPoints": 120, "entryRequirementsNote": "The minimum educational requirement for enrolment into graduate university programmes is the completion of an undergraduate university programme. The university can allow students who have completed a professional programme to also enrol graduate university programmes, but they are allowed to set special requirements in these cases.\nThe minimum educational requirement for enrolment into specialist graduate professional programmes is the completion of an undergraduate university programme or a professional programme (first cycle).", - "eqfLevel": "http://data.europa.eu/snb/eqf/5", + "eqflLevel": "http://data.europa.eu/snb/eqf/5", "id": "urn:epass:qualification:20", "isPartialQualification": false, "maximumDuration": "P21M", - "nqfLevel": "http://data.europa.eu/snb/qdr/c_dcc9aca1", + "nqflLevel": "http://data.europa.eu/snb/qdr/c_dcc9aca1", "title": "Master of Science in Civil Engineering", "volumeOfLearning": "PT1440H" - }, + }], "title": "Master of Science in Civil Engineering", "wasAwardedBy": { "awardingBody": [ @@ -135,7 +135,7 @@ "awardingDate": "2019-09-20T00:00:00+02:00", "id": "urn:epass:awardingProcess:1" }, - "wasDerivedFrom": { + "wasDerivedFrom": [{ "assessedBy": [ "did:ebsi:zsSgDXeYPhZ3AuKhTFneDf1" ], @@ -151,8 +151,8 @@ "title": "Overall Diploma Assessment" }, "title": "Overall Diploma Assessment" - }, - "wasInfluencedBy": { + }], + "wasInfluencedBy": [{ "directedBy": [ "did:ebsi:zsSgDXeYPhZ3AuKhTFneDf1" ], @@ -181,7 +181,7 @@ "startedAtTime": "2017-09-04T00:00:00+02:00", "title": "Master of Science in Civil Engineering", "workload": "PT60H" - } + }] } ], "id": "did:epass:person:1", From 0b767eb4566ed637c7e0f23dd2357a5e7a5af61b Mon Sep 17 00:00:00 2001 From: Alfred Tuffreau Date: Wed, 26 Jan 2022 15:02:18 +0100 Subject: [PATCH 2/3] removed unused imports --- .../kotlin/id/walt/services/vc/WaltIdJwtCredentialService.kt | 3 --- .../id/walt/services/vc/WaltIdJsonLdCredentialServiceTest.kt | 2 -- 2 files changed, 5 deletions(-) diff --git a/src/main/kotlin/id/walt/services/vc/WaltIdJwtCredentialService.kt b/src/main/kotlin/id/walt/services/vc/WaltIdJwtCredentialService.kt index 5e2104ca..b96c102c 100644 --- a/src/main/kotlin/id/walt/services/vc/WaltIdJwtCredentialService.kt +++ b/src/main/kotlin/id/walt/services/vc/WaltIdJwtCredentialService.kt @@ -14,10 +14,7 @@ import net.pwall.json.schema.JSONSchema import java.net.URL import java.nio.file.Files import java.nio.file.Path -import java.text.SimpleDateFormat import java.time.Instant -import java.time.ZoneOffset -import java.time.format.DateTimeFormatter import java.util.* private val log = KotlinLogging.logger {} diff --git a/src/test/kotlin/id/walt/services/vc/WaltIdJsonLdCredentialServiceTest.kt b/src/test/kotlin/id/walt/services/vc/WaltIdJsonLdCredentialServiceTest.kt index 2a0c221e..279e1214 100644 --- a/src/test/kotlin/id/walt/services/vc/WaltIdJsonLdCredentialServiceTest.kt +++ b/src/test/kotlin/id/walt/services/vc/WaltIdJsonLdCredentialServiceTest.kt @@ -13,8 +13,6 @@ import id.walt.test.RESOURCES_PATH import id.walt.test.getTemplate import id.walt.test.readCredOffer import id.walt.vclib.credentials.* -import id.walt.vclib.model.CredentialSchema -import id.walt.vclib.model.CredentialStatus import id.walt.vclib.model.toCredential import io.kotest.core.spec.style.AnnotationSpec import io.kotest.matchers.shouldBe From a12b2c72690a67adcf84efca83ff886a254ecb26 Mon Sep 17 00:00:00 2001 From: Alfred Tuffreau Date: Wed, 26 Jan 2022 15:36:05 +0100 Subject: [PATCH 3/3] Revert test 'SNAPSHOT' versions --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 33ce8429..5cd12309 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "id.walt" -version = "1.4.1-SNAPSHOT" +version = "1.4-SNAPSHOT" repositories { mavenCentral() @@ -44,7 +44,7 @@ dependencies { implementation("com.google.guava:guava:31.0.1-jre") // VC - implementation("id.walt:waltid-ssikit-vclib:1.11.2-SNAPSHOT") + implementation("id.walt:waltid-ssikit-vclib:1.11.1") // JSON implementation("org.json:json:20210307")