Skip to content

Commit

Permalink
test: fix e2e tests for the new credential schema logic
Browse files Browse the repository at this point in the history
Signed-off-by: Yurii Shynbuiev <yurii.shynbuiev@iohk.io>
  • Loading branch information
yshyn-iohk committed Nov 28, 2024
1 parent eb77bf7 commit e2aa717
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,16 @@ trait CredentialSchemaReferenceParsingLogic {
.getOrElse(handleDeprecatedSchemaId(deprecatedSchemaIdProperty).flatMap(makeUriStringOrErrorResponse))
}

def ensureCredentialSchemaRefIsNotUsedInSDJWT(
deprecatedSchemaIdProperty: Option[String | List[String]]
): IO[ErrorResponse, Unit] = {
deprecatedSchemaIdProperty.fold(ZIO.unit) { _ =>
ZIO.fail(ErrorResponse.badRequest(detail = Some("Credential schema reference is not supported yet in SD-JWT.")))
}
}

private def handleDeprecatedSchemaId(
deprecatedSchemaIdProperty: Option[String | List[String]]
): IO[ErrorResponse, String] = {
deprecatedSchemaIdProperty match {
case Some(schemaId: String) =>
ZIO.succeed(schemaId)
case Some(_: List[String]) =>
ZIO.fail(ErrorResponse.badRequest(detail = Some("Multiple schemas are not allowed.")))
ZIO.fail(ErrorResponse.badRequest(detail = Some("Multiple credential schemas are not allowed.")))
case None =>
ZIO.fail(ErrorResponse.badRequest(detail = Some("schemaId property is required.")))
ZIO.fail(ErrorResponse.badRequest(detail = Some("Credential schema property missed.")))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,37 @@ enum class CredentialSchema {
"name" to "Name",
"age" to 18,
)
}, ;
},

ID_SCHEMA {
override val credentialSchemaType: String =
"https://w3c-ccg.github.io/vc-json-schemas/schema/2.0/schema.json"
override val schemaType: String = "https://json-schema.org/draft/2020-12/schema"
override val schema: JsonSchema = JsonSchema(
id = "https://example.com/student-schema-1.0",
schema = schemaType,
description = "ID schema",
type = "object",
properties = mutableMapOf(
"firstName" to JsonSchemaProperty(type = "string"),
"lastName" to JsonSchemaProperty(type = "string"),
),
required = listOf("firstName", "lastName"),
)
override val credentialSchema: CredentialSchemaInput = CredentialSchemaInput(
author = "did:prism:agent",
name = UUID.randomUUID().toString(),
description = "ID credentials schema",
type = credentialSchemaType,
schema = schema,
tags = listOf("id", "personal"),
version = "1.0.0",
)
override val claims: Map<String, Any> = linkedMapOf(
"firstName" to "John",
"lastName" to "Doe",
)
};

abstract val credentialSchema: CredentialSchemaInput
abstract val schema: JsonSchema
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package steps.connectionless

import com.google.gson.JsonObject
import common.CredentialSchema
import interactions.Post
import interactions.body
import io.cucumber.java.en.*
Expand All @@ -14,19 +15,30 @@ import org.hyperledger.identus.client.models.*

class ConnectionLessSteps {

@When("{actor} creates a {string} credential offer invitation with {string} form DID")
fun inviterGeneratesACredentialOfferInvitation(issuer: Actor, credentialFormat: String, didForm: String) {
val claims = linkedMapOf(
"firstName" to "Automation",
"lastName" to "Execution",
"email" to "email@example.com",
)
@When("{actor} creates a {string} credential offer invitation with {string} form DID and {} schema")
fun inviterGeneratesACredentialOfferInvitation(
issuer: Actor,
credentialFormat: String,
didForm: String,
schema: CredentialSchema
) {
val claims = schema.claims
val schemaGuid = issuer.recall<String>(schema.name)

val schemaId: String? = if (schemaGuid != null) {
val baseUrl = issuer.recall<String>("baseUrl")
"$baseUrl/schema-registry/schemas/$schemaGuid"
} else {
null
}

val did: String = if (didForm == "short") {
issuer.recall("shortFormDid")
} else {
issuer.recall("longFormDid")
}
val credentialOfferRequest = CreateIssueCredentialRecordRequest(
schemaId = schemaId?.let { listOf(it) },
claims = claims,
issuingDID = did,
issuingKid = "assertion-1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,26 @@ class JwtCredentialSteps {

@When("{actor} offers a jwt credential to {actor} with {string} form DID")
fun issuerOffersAJwtCredential(issuer: Actor, holder: Actor, format: String) {
val claims = linkedMapOf(
"firstName" to "FirstName",
"lastName" to "LastName",
)
sendCredentialOffer(issuer, holder, format, null, claims, "assertion-1")
val claims = CredentialSchema.STUDENT_SCHEMA.claims

val schemaGuid = issuer.recall<String>(CredentialSchema.STUDENT_SCHEMA.name)

sendCredentialOffer(issuer, holder, format, schemaGuid, claims, "assertion-1")
saveCredentialOffer(issuer, holder)
}

@When("{actor} offers a jwt credential to {actor} with {string} form DID using issuingKid {string}")
fun issuerOffersAJwtCredentialWithIssuingKeyId(issuer: Actor, holder: Actor, format: String, issuingKid: String?) {
val claims = linkedMapOf(
"firstName" to "FirstName",
"lastName" to "LastName",
)
sendCredentialOffer(issuer, holder, format, null, claims, issuingKid)
@When("{actor} offers a jwt credential to {actor} with {string} form DID using issuingKid {string} and {} schema")
fun issuerOffersAJwtCredentialWithIssuingKeyId(
issuer: Actor,
holder: Actor,
format: String,
issuingKid: String?,
schema: CredentialSchema
) {
val claims = schema.claims
val schemaGuid = issuer.recall<String>(schema.name)

sendCredentialOffer(issuer, holder, format, schemaGuid, claims, issuingKid)
saveCredentialOffer(issuer, holder)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package steps.credentials

import com.google.gson.Gson
import com.nimbusds.jose.util.Base64URL
import common.CredentialSchema
import interactions.Post
import interactions.body
import io.cucumber.java.en.Then
Expand All @@ -17,18 +18,22 @@ import org.hyperledger.identus.client.models.*

class SdJwtCredentialSteps {

private val claims = linkedMapOf(
"firstName" to "Automation",
"lastName" to "Execution",
)

@When("{actor} offers a sd-jwt credential to {actor}")
fun issuerOffersSdJwtCredentialToHolder(issuer: Actor, holder: Actor) {
val connectionId = issuer.recall<Connection>("connection-with-${holder.name}").connectionId
val did = issuer.recall<String>("shortFormDid")
val schemaGuid = issuer.recall<String>(CredentialSchema.ID_SCHEMA.name)

val schemaId: String? = if (schemaGuid != null) {
val baseUrl = issuer.recall<String>("baseUrl")
"$baseUrl/schema-registry/schemas/$schemaGuid"
} else {
null
}

val credentialOfferRequest = CreateIssueCredentialRecordRequest(
claims = claims,
schemaId = schemaId?.let { listOf(it) },
claims = CredentialSchema.ID_SCHEMA.claims,
issuingDID = did,
connectionId = connectionId,
validityPeriod = 3600.0,
Expand Down Expand Up @@ -62,24 +67,24 @@ class SdJwtCredentialSteps {
)
}

@When("{actor} tries to offer a sd-jwt credential to {actor}")
fun issuerTriesToOfferSdJwtCredentialToHolder(issuer: Actor, holder: Actor) {
val connectionId = issuer.recall<Connection>("connection-with-${holder.name}").connectionId
val did = issuer.recall<String>("shortFormDid")

val credentialOfferRequest = CreateIssueCredentialRecordRequest(
claims = claims,
issuingDID = did,
connectionId = connectionId,
validityPeriod = 3600.0,
credentialFormat = "SDJWT",
automaticIssuance = false,
)

issuer.attemptsTo(
Post.to("/issue-credentials/credential-offers").body(credentialOfferRequest),
)
}
// @When("{actor} tries to offer a sd-jwt credential to {actor}")
// fun issuerTriesToOfferSdJwtCredentialToHolder(issuer: Actor, holder: Actor) {
// val connectionId = issuer.recall<Connection>("connection-with-${holder.name}").connectionId
// val did = issuer.recall<String>("shortFormDid")
//
// val credentialOfferRequest = CreateIssueCredentialRecordRequest(
// claims = claims,
// issuingDID = did,
// connectionId = connectionId,
// validityPeriod = 3600.0,
// credentialFormat = "SDJWT",
// automaticIssuance = false,
// )
//
// issuer.attemptsTo(
// Post.to("/issue-credentials/credential-offers").body(credentialOfferRequest),
// )
// }

@Then("{actor} checks the sd-jwt credential contents")
fun holderChecksTheSdJwtCredentialContents(holder: Actor) {
Expand Down Expand Up @@ -112,6 +117,7 @@ class SdJwtCredentialSteps {
) {
val issuedCredential = holder.recall<IssueCredentialRecord>("issuedCredential")
val jwtCredential = JwtCredential.parseBase64(issuedCredential.credential!!)
val actualClaims = CredentialSchema.ID_SCHEMA.claims.mapValues { it.value.toString() }

val payload = jwtCredential.payload!!.toJSONObject()

Expand All @@ -128,8 +134,8 @@ class SdJwtCredentialSteps {
Ensure.that(payload.containsKey("iss")).isTrue(),
Ensure.that(payload.containsKey("iat")).isTrue(),
Ensure.that(payload.containsKey("exp")).isTrue(),
Ensure.that(disclosedClaims["firstName"]!!.value).isEqualTo(claims["firstName"]!!),
Ensure.that(disclosedClaims["lastName"]!!.value).isEqualTo(claims["lastName"]!!),
Ensure.that(disclosedClaims["firstName"]!!.value).isEqualTo(actualClaims["firstName"]!!),
Ensure.that(disclosedClaims["lastName"]!!.value).isEqualTo(actualClaims["lastName"]!!),
)

additionalChecks(payload, disclosedClaims)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Feature: Issue JWT credential
Given Issuer and Holder have an existing connection
And Issuer has a published DID for JWT
And Holder has an unpublished DID for JWT
And Issuer has published STUDENT_SCHEMA schema
When Issuer offers a jwt credential to Holder with "short" form DID
And Holder receives the credential offer
And Holder accepts jwt credential offer
Expand All @@ -15,8 +16,9 @@ Feature: Issue JWT credential
Scenario: Issuing jwt credential with published PRISM DID using Ed25519
Given Issuer and Holder have an existing connection
And Issuer has a published DID for JWT
And Issuer has published STUDENT_SCHEMA schema
And Holder has an unpublished DID for JWT
When Issuer offers a jwt credential to Holder with "short" form DID using issuingKid "assertion-2"
When Issuer offers a jwt credential to Holder with "short" form DID using issuingKid "assertion-2" and STUDENT_SCHEMA schema
And Holder receives the credential offer
And Holder accepts jwt credential offer with keyId "auth-2"
And Issuer issues the credential
Expand Down Expand Up @@ -45,6 +47,7 @@ Feature: Issue JWT credential
Given Issuer and Holder have an existing connection
And Issuer has an unpublished DID for JWT
And Holder has an unpublished DID for JWT
And Issuer has published STUDENT_SCHEMA schema
And Issuer offers a jwt credential to Holder with "long" form DID
And Holder receives the credential offer
And Holder accepts jwt credential offer
Expand All @@ -53,8 +56,9 @@ Feature: Issue JWT credential

Scenario: Connectionless issuance of JWT credential using OOB invitation
Given Issuer has a published DID for JWT
And Issuer has published STUDENT_SCHEMA schema
And Holder has an unpublished DID for JWT
When Issuer creates a "JWT" credential offer invitation with "short" form DID
When Issuer creates a "JWT" credential offer invitation with "short" form DID and STUDENT_SCHEMA schema
And Holder accepts the credential offer invitation from Issuer
And Holder accepts jwt credential offer
And Issuer issues the credential
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Feature: Issue SD-JWT credential
Scenario: Issuing sd-jwt credential
Given Issuer and Holder have an existing connection
And Issuer has a published DID for SD_JWT
And Issuer has published ID_SCHEMA schema
And Holder has an unpublished DID for SD_JWT
When Issuer offers a sd-jwt credential to Holder
And Holder receives the credential offer
Expand All @@ -15,6 +16,7 @@ Feature: Issue SD-JWT credential
Scenario: Issuing sd-jwt credential with holder binding
Given Issuer and Holder have an existing connection
And Issuer has a published DID for SD_JWT
And Issuer has published ID_SCHEMA schema
And Holder has an unpublished DID for SD_JWT
When Issuer offers a sd-jwt credential to Holder
And Holder receives the credential offer
Expand All @@ -25,8 +27,9 @@ Feature: Issue SD-JWT credential

Scenario: Connectionless issuance of sd-jwt credential with holder binding
And Issuer has a published DID for SD_JWT
And Issuer has published ID_SCHEMA schema
And Holder has an unpublished DID for SD_JWT
When Issuer creates a "SDJWT" credential offer invitation with "short" form DID
When Issuer creates a "SDJWT" credential offer invitation with "short" form DID and ID_SCHEMA schema
And Holder accepts the credential offer invitation from Issuer
And Holder accepts credential offer for sd-jwt with 'auth-1' key binding
And Issuer issues the credential
Expand Down

0 comments on commit e2aa717

Please sign in to comment.