diff --git a/.mega-linter.yml b/.mega-linter.yml
index 786cf36edd..6736cb65d1 100644
--- a/.mega-linter.yml
+++ b/.mega-linter.yml
@@ -28,6 +28,7 @@ DISABLE_LINTERS:
- PYTHON_MYPY
- PYTHON_PYRIGHT
- PYTHON_RUFF
+ - TYPESCRIPT_STANDARD
DISABLE_ERRORS_LINTERS:
- KOTLIN_KTLINT
@@ -65,5 +66,5 @@ YAML_PRETTIER_FILTER_REGEX_EXCLUDE: "infrastructure/charts/agent/*|cloud-agent/s
YAML_V8R_FILTER_REGEX_EXCLUDE: "infrastructure/charts/agent/*"
JAVASCRIPT_STANDARD_FILTER_REGEX_EXCLUDE:
"tests/performance-tests/agent-performance-tests-k6/src/k6chaijs.js\
- |tests/didcomm-tests/docker/initdb.js"
+ |tests/performance-tests/agent-performance-tests-k6/src/common/ProofsService.ts|tests/didcomm-tests/docker/initdb.js"
BASH_SHELLCHECK_FILTER_REGEX_EXCLUDE: "infrastructure/*"
diff --git a/cloud-agent/service/server/src/main/resources/logback.xml b/cloud-agent/service/server/src/main/resources/logback.xml
index 9121c1c22d..a91551a3d1 100644
--- a/cloud-agent/service/server/src/main/resources/logback.xml
+++ b/cloud-agent/service/server/src/main/resources/logback.xml
@@ -13,6 +13,9 @@
+
+
+
diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala
index 4bfb247176..a6f2bfae67 100644
--- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala
+++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala
@@ -20,7 +20,7 @@ import org.hyperledger.identus.mercury.model.*
import org.hyperledger.identus.mercury.protocol.invitation.v2.Invitation
import org.hyperledger.identus.mercury.protocol.presentproof.*
import org.hyperledger.identus.mercury.protocol.reportproblem.v2.{ProblemCode, ReportProblem}
-import org.hyperledger.identus.pollux.core.model.*
+import org.hyperledger.identus.pollux.core.model.{presentation, *}
import org.hyperledger.identus.pollux.core.model.error.{CredentialServiceError, PresentationError}
import org.hyperledger.identus.pollux.core.model.error.PresentationError.*
import org.hyperledger.identus.pollux.core.model.presentation.Options
@@ -28,6 +28,7 @@ import org.hyperledger.identus.pollux.core.service.{CredentialService, Presentat
import org.hyperledger.identus.pollux.core.service.serdes.AnoncredCredentialProofsV1
import org.hyperledger.identus.pollux.sdjwt.{HolderPrivateKey, IssuerPublicKey, PresentationCompact, SDJWT}
import org.hyperledger.identus.pollux.vc.jwt.{DidResolver as JwtDidResolver, Issuer as JwtIssuer, JWT, JwtPresentation}
+import org.hyperledger.identus.pollux.vc.jwt.CredentialSchemaAndTrustedIssuersConstraint
import org.hyperledger.identus.resolvers.DIDResolver
import org.hyperledger.identus.shared.http.*
import org.hyperledger.identus.shared.messaging
@@ -37,7 +38,7 @@ import org.hyperledger.identus.shared.utils.aspects.CustomMetricsAspect
import org.hyperledger.identus.shared.utils.DurationOps.toMetricsSeconds
import zio.*
import zio.metrics.*
-import zio.prelude.Validation
+import zio.prelude.{Validation, ZValidation}
import zio.prelude.ZValidation.{Failure as ZFailure, *}
import java.time.{Instant, ZoneId}
@@ -947,7 +948,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper {
object Verifier {
- def handleRequestPending(id: DidCommID, record: RequestPresentation): ZIO[
+ def handleRequestPending(id: DidCommID, requestPresentation: RequestPresentation): ZIO[
JwtDidResolver & COMMON_RESOURCES & MESSAGING_RESOURCES,
Failure,
Unit
@@ -978,17 +979,20 @@ object PresentBackgroundJobs extends BackgroundJobsHelper {
val verifierReqPendingToSentFlow = for {
_ <- ZIO.log(s"PresentationRecord: RequestPending (Send Message)")
- walletAccessContext <- buildWalletAccessContextLayer(
- record.from.getOrElse(throw new RuntimeException("from is None is not possible"))
- )
+ walletAccessContext <- ZIO
+ .fromOption(requestPresentation.from)
+ .mapError(_ => RequestPresentationMissingField(id.value, "sender"))
+ .flatMap(buildWalletAccessContextLayer)
+
result <- for {
didOps <- ZIO.service[DidOps]
- didCommAgent <- buildDIDCommAgent(
- record.from.getOrElse(throw new RuntimeException("from is None is not possible"))
- ).provideSomeLayer(ZLayer.succeed(walletAccessContext))
+ didCommAgent <- ZIO
+ .fromOption(requestPresentation.from)
+ .mapError(_ => RequestPresentationMissingField(id.value, "sender"))
+ .flatMap(buildDIDCommAgent(_).provideSomeLayer(ZLayer.succeed(walletAccessContext)))
resp <-
MessagingService
- .send(record.makeMessage)
+ .send(requestPresentation.makeMessage)
.provideSomeLayer(didCommAgent)
@@ Metric
.gauge("present_proof_flow_verifier_send_presentation_request_msg_ms_gauge")
@@ -1069,6 +1073,16 @@ object PresentBackgroundJobs extends BackgroundJobsHelper {
}
}
+ private def buildReportProblem(presentation: Presentation, error: String): ReportProblem = {
+ ReportProblem.build(
+ fromDID = presentation.to,
+ toDID = presentation.from,
+ pthid = presentation.thid.getOrElse(presentation.id),
+ code = ProblemCode("e.p.presentation-verification-failed"),
+ comment = Some(error)
+ )
+ }
+
private def handleJWT(
id: DidCommID,
requestPresentation: RequestPresentation,
@@ -1085,7 +1099,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper {
_ <- checkInvitationExpiry(id, invitation).provideSomeLayer(ZLayer.succeed(walletAccessContext))
result <- for {
didResolverService <- ZIO.service[JwtDidResolver]
- credentialsClaimsValidationResult <- presentation.attachments.head.data match {
+ claimsValidationResult <- presentation.attachments.head.data match {
case Base64(data) =>
val base64Decoded = new String(java.util.Base64.getUrlDecoder.decode(data))
val maybePresentationOptions: Either[PresentationError, Option[Options]] =
@@ -1103,17 +1117,33 @@ object PresentBackgroundJobs extends BackgroundJobsHelper {
)
)
.getOrElse(Right(None))
+ val schemaIdAndTrustedIssuers = requestPresentation.body.proof_types.map { proofType =>
+ CredentialSchemaAndTrustedIssuersConstraint(
+ proofType.schema,
+ proofType.trustIssuers.map(_.map(_.value))
+ )
+ }
val presentationClaimsValidationResult = for {
- _ <- ZIO.fromEither(maybePresentationOptions.map {
+ validationResult: Validation[String, Unit] <- ZIO.fromEither(maybePresentationOptions.map {
case Some(options) =>
- JwtPresentation.validatePresentation(
- JWT(base64Decoded),
- options.domain,
- options.challenge
- )
- case _ => Validation.unit
+ JwtPresentation
+ .validatePresentation(
+ JWT(base64Decoded),
+ Some(options.domain),
+ Some(options.challenge),
+ schemaIdAndTrustedIssuers
+ )
+ case _ =>
+ JwtPresentation
+ .validatePresentation(
+ JWT(base64Decoded),
+ None,
+ None,
+ schemaIdAndTrustedIssuers
+ )
})
+
verificationConfig <- ZIO.service[AppConfig].map(_.agent.verification)
_ <- ZIO.log(s"VerificationConfig: ${verificationConfig}")
@@ -1121,18 +1151,21 @@ object PresentBackgroundJobs extends BackgroundJobsHelper {
// A proof is typically attached to a verifiable presentation for authentication purposes
// and to a verifiable credential as a method of assertion.
uriResolver <- ZIO.service[UriResolver]
- result <- JwtPresentation
+ result: Validation[String, Unit] <- JwtPresentation
.verify(
JWT(base64Decoded),
verificationConfig.toPresentationVerificationOptions()
)(didResolverService, uriResolver)(clock)
.mapError(error => PresentationError.PresentationVerificationError(error.mkString))
- } yield result
+ } yield Seq(validationResult, result)
presentationClaimsValidationResult
case any => ZIO.fail(PresentationReceivedError("Only Base64 Supported"))
}
+ credentialsClaimsValidationResult = ZValidation
+ .validateAll(claimsValidationResult)
+ .map(_ => ())
_ <- credentialsClaimsValidationResult match
case l @ ZFailure(_, _) => ZIO.logError(s"CredentialsClaimsValidationResult: $l")
case l @ Success(_, _) => ZIO.logInfo(s"CredentialsClaimsValidationResult: $l")
@@ -1151,19 +1184,13 @@ object PresentBackgroundJobs extends BackgroundJobsHelper {
_ <- service
.markPresentationVerificationFailed(id)
.provideSomeLayer(ZLayer.succeed(walletAccessContext)) @@ presReceivedToProcessedAspect
- didCommAgent <- buildDIDCommAgent(presentation.from).provideSomeLayer(
+ didCommAgent <- buildDIDCommAgent(presentation.to).provideSomeLayer(
ZLayer.succeed(walletAccessContext)
)
- reportproblem = ReportProblem.build(
- fromDID = presentation.to,
- toDID = presentation.from,
- pthid = presentation.thid.getOrElse(presentation.id),
- code = ProblemCode("e.p.presentation-verification-failed"),
- comment = Some(error.mkString)
- )
+ reportProblem = buildReportProblem(presentation, error.mkString)
_ <-
MessagingService
- .send(reportproblem.toMessage)
+ .send(reportProblem.toMessage)
.provideSomeLayer(didCommAgent)
_ <- ZIO.log(s"CredentialsClaimsValidationResult: $error")
} yield ()
@@ -1219,19 +1246,13 @@ object PresentBackgroundJobs extends BackgroundJobsHelper {
_ <- service
.markPresentationVerificationFailed(id)
.provideSomeLayer(ZLayer.succeed(walletAccessContext)) @@ presReceivedToProcessedAspect
- didCommAgent <- buildDIDCommAgent(presentation.from).provideSomeLayer(
+ didCommAgent <- buildDIDCommAgent(presentation.to).provideSomeLayer(
ZLayer.succeed(walletAccessContext)
)
- reportproblem = ReportProblem.build(
- fromDID = presentation.to,
- toDID = presentation.from,
- pthid = presentation.thid.getOrElse(presentation.id),
- code = ProblemCode("e.p.presentation-verification-failed"),
- comment = Some(invalid.toString)
- )
+ reportProblem = buildReportProblem(presentation, invalid.toString)
resp <-
MessagingService
- .send(reportproblem.toMessage)
+ .send(reportProblem.toMessage)
.provideSomeLayer(didCommAgent)
_ <- ZIO.log(s"CredentialsClaimsValidationResult: ${invalid.toString}")
} yield ()
@@ -1263,19 +1284,13 @@ object PresentBackgroundJobs extends BackgroundJobsHelper {
.provideSomeLayer(ZLayer.succeed(walletAccessContext)) @@ presReceivedToProcessedAspect)
.flatMapError(e =>
for {
- didCommAgent <- buildDIDCommAgent(presentation.from).provideSomeLayer(
+ didCommAgent <- buildDIDCommAgent(presentation.to).provideSomeLayer(
ZLayer.succeed(walletAccessContext)
)
- reportproblem = ReportProblem.build(
- fromDID = presentation.to,
- toDID = presentation.from,
- pthid = presentation.thid.getOrElse(presentation.id),
- code = ProblemCode("e.p.presentation-verification-failed"),
- comment = Some(e.toString)
- )
+ reportProblem = buildReportProblem(presentation, e.toString)
_ <-
MessagingService
- .send(reportproblem.toMessage)
+ .send(reportProblem.toMessage)
.provideSomeLayer(didCommAgent)
_ <- ZIO.log(s"CredentialsClaimsValidationResult: ${e.toString}")
} yield ()
@@ -1286,12 +1301,4 @@ object PresentBackgroundJobs extends BackgroundJobsHelper {
}
}
}
-
-// val syncDIDPublicationStateFromDlt: ZIO[WalletAccessContext & ManagedDIDService, GetManagedDIDError, Unit] =
-// for {
-// managedDidService <- ZIO.service[ManagedDIDService]
-// _ <- managedDidService.syncManagedDIDState
-// _ <- managedDidService.syncUnconfirmedUpdateOperations
-// } yield ()
-
}
diff --git a/mercury/protocol-report-problem/src/main/scala/org/hyperledger/identus/mercury/protocol/reportproblem/v2/ReportProblem.scala b/mercury/protocol-report-problem/src/main/scala/org/hyperledger/identus/mercury/protocol/reportproblem/v2/ReportProblem.scala
index 4c6867e52a..22e64637ef 100644
--- a/mercury/protocol-report-problem/src/main/scala/org/hyperledger/identus/mercury/protocol/reportproblem/v2/ReportProblem.scala
+++ b/mercury/protocol-report-problem/src/main/scala/org/hyperledger/identus/mercury/protocol/reportproblem/v2/ReportProblem.scala
@@ -50,7 +50,7 @@ object ReportProblem {
given Encoder[ReportProblem] = deriveEncoder[ReportProblem]
given Decoder[ReportProblem] = deriveDecoder[ReportProblem]
- def readFromMessage(message: Message): ReportProblem =
+ def fromMessage(message: Message): ReportProblem =
val body = message.body.asJson.as[ReportProblem.Body].toOption.get // TODO get
ReportProblem(
id = message.id,
diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/PresentationError.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/PresentationError.scala
index 4f4a1d7eef..4ea28a3359 100644
--- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/PresentationError.scala
+++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/PresentationError.scala
@@ -198,6 +198,12 @@ object PresentationError {
msg
)
+ final case class PresentationValidationError(msg: String)
+ extends PresentationError(
+ StatusCode.BadRequest,
+ msg
+ )
+
final case class PresentationReceivedError(msg: String)
extends PresentationError(
StatusCode.InternalServerError,
diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceImpl.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceImpl.scala
index bdd741e155..8fdcc7cd57 100644
--- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceImpl.scala
+++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceImpl.scala
@@ -26,6 +26,7 @@ import org.hyperledger.identus.pollux.core.repository.{CredentialRepository, Cre
import org.hyperledger.identus.pollux.prex.{ClaimFormat, Jwt, PresentationDefinition}
import org.hyperledger.identus.pollux.sdjwt.*
import org.hyperledger.identus.pollux.vc.jwt.{Issuer as JwtIssuer, *}
+import org.hyperledger.identus.pollux.vc.jwt.PresentationPayload.Implicits.*
import org.hyperledger.identus.shared.crypto.{Ed25519KeyPair, Secp256k1KeyPair}
import org.hyperledger.identus.shared.http.UriResolver
import org.hyperledger.identus.shared.messaging.{Producer, WalletIdAndRecordId}
@@ -1505,7 +1506,7 @@ class CredentialServiceImpl(
ZIO.fail(CredentialRequestValidationFailed(s"JWT presentation verification failed: $error"))
jwtPresentation <- ZIO
- .fromTry(JwtPresentation.decodeJwt(jwt))
+ .fromTry(JwtPresentation.decodeJwt[JwtPresentationPayload](jwt))
.mapError(t => CredentialRequestValidationFailed(s"JWT presentation decoding failed: ${t.getMessage}"))
} yield jwtPresentation
}
diff --git a/pollux/prex/src/main/scala/org/hyperledger/identus/pollux/prex/PresentationSubmissionVerification.scala b/pollux/prex/src/main/scala/org/hyperledger/identus/pollux/prex/PresentationSubmissionVerification.scala
index fe167a1122..cf816034a5 100644
--- a/pollux/prex/src/main/scala/org/hyperledger/identus/pollux/prex/PresentationSubmissionVerification.scala
+++ b/pollux/prex/src/main/scala/org/hyperledger/identus/pollux/prex/PresentationSubmissionVerification.scala
@@ -13,7 +13,7 @@ import org.hyperledger.identus.pollux.prex.PresentationSubmissionError.{
JsonPathNotFound,
SubmissionNotSatisfyInputDescriptors
}
-import org.hyperledger.identus.pollux.vc.jwt.{JWT, JwtCredential, JwtPresentation}
+import org.hyperledger.identus.pollux.vc.jwt.{JWT, JwtCredential, JwtPresentation, JwtPresentationPayload}
import org.hyperledger.identus.pollux.vc.jwt.CredentialPayload.Implicits.*
import org.hyperledger.identus.pollux.vc.jwt.PresentationPayload.Implicits.*
import org.hyperledger.identus.shared.json.{JsonInterop, JsonPath, JsonPathError, JsonSchemaValidatorImpl}
@@ -220,7 +220,7 @@ object PresentationSubmissionVerification {
.map(JWT(_))
.mapError(_ => InvalidDataTypeForClaimFormat(format, path, "string"))
payload <- ZIO
- .fromTry(JwtPresentation.decodeJwt(jwt))
+ .fromTry(JwtPresentation.decodeJwt[JwtPresentationPayload](jwt))
.mapError(e => ClaimDecodeFailure(format, path, e.getMessage()))
_ <- formatVerification(jwt)
.mapError(errors => ClaimFormatVerificationFailure(format, path, errors.mkString))
diff --git a/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/CredentialSchemaAndTrustedIssuersConstraint.scala b/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/CredentialSchemaAndTrustedIssuersConstraint.scala
new file mode 100644
index 0000000000..0f8f0e68e0
--- /dev/null
+++ b/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/CredentialSchemaAndTrustedIssuersConstraint.scala
@@ -0,0 +1,6 @@
+package org.hyperledger.identus.pollux.vc.jwt
+
+case class CredentialSchemaAndTrustedIssuersConstraint(
+ schemaId: String,
+ trustedIssuers: Option[Seq[String]]
+)
diff --git a/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/VerifiablePresentationPayload.scala b/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/VerifiablePresentationPayload.scala
index 9cada23670..ffe96ca470 100644
--- a/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/VerifiablePresentationPayload.scala
+++ b/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/VerifiablePresentationPayload.scala
@@ -337,6 +337,12 @@ object JwtPresentation {
.flatMap(decode[JwtPresentationPayload](_).toTry)
}
+ def decodeJwt[A](jwt: JWT)(using decoder: io.circe.Decoder[A]): Try[A] = {
+ JwtCirce
+ .decodeRaw(jwt.value, options = JwtOptions(signature = false, expiration = false, notBefore = false))
+ .flatMap(decode[A](_).toTry)
+ }
+
def decodeJwt(jwt: JWT, publicKey: PublicKey): Try[JwtPresentationPayload] = {
JwtCirce
.decodeRaw(jwt.value, publicKey, JwtOptions(expiration = false, notBefore = false))
@@ -370,7 +376,7 @@ object JwtPresentation {
)(didResolver: DidResolver, uriResolver: UriResolver)(implicit
clock: Clock
): IO[List[String], Validation[String, Unit]] = {
- val validateJwtPresentation = Validation.fromTry(decodeJwt(jwt)).mapError(_.toString)
+ val validateJwtPresentation = Validation.fromTry(decodeJwt[JwtPresentationPayload](jwt)).mapError(_.toString)
val credentialValidationZIO =
ValidationUtils.foreach(
@@ -405,12 +411,94 @@ object JwtPresentation {
domain: String,
challenge: String
): Validation[String, Unit] = {
- val validateJwtPresentation = Validation.fromTry(decodeJwt(jwt)).mapError(_.toString)
+ val validateJwtPresentation = Validation.fromTry(decodeJwt[JwtPresentationPayload](jwt)).mapError(_.toString)
for {
decodeJwtPresentation <- validateJwtPresentation
- aud <- validateAudience(decodeJwtPresentation, domain)
+ aud <- validateAudience(decodeJwtPresentation, Some(domain))
result <- validateNonce(decodeJwtPresentation, Some(challenge))
} yield result
+ }
+
+ def validatePresentation(
+ jwt: JWT,
+ domain: Option[String],
+ challenge: Option[String],
+ schemaIdAndTrustedIssuers: Seq[CredentialSchemaAndTrustedIssuersConstraint]
+ ): Validation[String, Unit] = {
+ val validateJwtPresentation = Validation.fromTry(decodeJwt[JwtPresentationPayload](jwt)).mapError(_.toString)
+ for {
+ decodeJwtPresentation <- validateJwtPresentation
+ aud <- validateAudience(decodeJwtPresentation, domain)
+ nonce <- validateNonce(decodeJwtPresentation, challenge)
+ result <- validateSchemaIdAndTrustedIssuers(decodeJwtPresentation, schemaIdAndTrustedIssuers)
+ } yield {
+ result
+ }
+ }
+
+ def validateSchemaIdAndTrustedIssuers(
+ decodedJwtPresentation: JwtPresentationPayload,
+ schemaIdAndTrustedIssuers: Seq[CredentialSchemaAndTrustedIssuersConstraint]
+ ): Validation[String, Unit] = {
+ import org.hyperledger.identus.pollux.vc.jwt.CredentialPayload.Implicits.*
+
+ val vcList = decodedJwtPresentation.vp.verifiableCredential
+ val expectedSchemaIds = schemaIdAndTrustedIssuers.map(_.schemaId)
+ val trustedIssuers = schemaIdAndTrustedIssuers.flatMap(_.trustedIssuers).flatten
+ ZValidation
+ .validateAll(
+ vcList.map {
+ case (w3cVerifiableCredentialPayload: W3cVerifiableCredentialPayload) =>
+ val credentialSchemas = w3cVerifiableCredentialPayload.payload.maybeCredentialSchema
+ val issuer = w3cVerifiableCredentialPayload.payload.issuer
+ for {
+ s <- validateSchemaIds(credentialSchemas, expectedSchemaIds)
+ i <- validateIsTrustedIssuer(issuer, trustedIssuers)
+ } yield i
+
+ case (jwtVerifiableCredentialPayload: JwtVerifiableCredentialPayload) =>
+ for {
+ jwtCredentialPayload <- Validation
+ .fromTry(decodeJwt[JwtCredentialPayload](jwtVerifiableCredentialPayload.jwt))
+ .mapError(_.toString)
+ issuer = jwtCredentialPayload.issuer
+ credentialSchemas = jwtCredentialPayload.maybeCredentialSchema
+ s <- validateSchemaIds(credentialSchemas, expectedSchemaIds)
+ i <- validateIsTrustedIssuer(issuer, trustedIssuers)
+ } yield i
+ }
+ )
+ .map(_ => ())
+ }
+ def validateSchemaIds(
+ credentialSchemas: Option[CredentialSchema | List[CredentialSchema]],
+ expectedSchemaIds: Seq[String]
+ ): Validation[String, Unit] = {
+ if (expectedSchemaIds.nonEmpty) {
+ val isValidSchema = credentialSchemas match {
+ case Some(schema: CredentialSchema) => expectedSchemaIds.contains(schema.id)
+ case Some(schemaList: List[CredentialSchema]) => expectedSchemaIds.intersect(schemaList.map(_.id)).nonEmpty
+ case _ => false
+ }
+ if (!isValidSchema) {
+ Validation.fail(s"SchemaId expected =$expectedSchemaIds actual found =$credentialSchemas")
+ } else Validation.unit
+ } else Validation.unit
+
+ }
+
+ def validateIsTrustedIssuer(
+ credentialIssuer: String | CredentialIssuer,
+ trustedIssuers: Seq[String]
+ ): Validation[String, Unit] = {
+ if (trustedIssuers.nonEmpty) {
+ val isValidIssuer = credentialIssuer match
+ case issuer: String => trustedIssuers.contains(issuer)
+ case issuer: CredentialIssuer => trustedIssuers.contains(issuer.id)
+ if (!isValidIssuer) {
+ Validation.fail(s"TrustedIssuers = ${trustedIssuers.mkString(",")} actual issuer = $credentialIssuer")
+ } else Validation.unit
+ } else Validation.unit
}
@@ -424,19 +512,15 @@ object JwtPresentation {
}
def validateAudience(
decodedJwtPresentation: JwtPresentationPayload,
- domain: String
+ domain: Option[String]
): Validation[String, Unit] = {
- if (!decodedJwtPresentation.aud.contains(domain)) {
+ if (!domain.forall(domain => decodedJwtPresentation.aud.contains(domain))) {
Validation.fail(s"domain/Audience dont match doamin=$domain, exp=${decodedJwtPresentation.aud}")
} else Validation.unit
}
def verifyHolderBinding(jwt: JWT): Validation[String, Unit] = {
import org.hyperledger.identus.pollux.vc.jwt.CredentialPayload.Implicits.*
- val decodeJWT = (jwt: JWT) =>
- Validation
- .fromTry(JwtCirce.decodeRaw(jwt.value, options = JwtOptions(false, false, false)))
- .mapError(_.getMessage)
def validateCredentialSubjectId(
vcList: IndexedSeq[VerifiableCredentialPayload],
@@ -459,10 +543,9 @@ object JwtPresentation {
case (jwtVerifiableCredentialPayload: JwtVerifiableCredentialPayload) =>
for {
- jwtCredentialDecoded <- decodeJWT(jwtVerifiableCredentialPayload.jwt)
jwtCredentialPayload <- Validation
- .fromEither(decode[JwtCredentialPayload](jwtCredentialDecoded))
- .mapError(_.getMessage)
+ .fromTry(decodeJwt[JwtCredentialPayload](jwtVerifiableCredentialPayload.jwt))
+ .mapError(_.toString)
mayBeSubjectDid = jwtCredentialPayload.maybeSub
x <-
if (mayBeSubjectDid.contains(iss)) {
@@ -477,20 +560,15 @@ object JwtPresentation {
.map(_ => ())
}
for {
- decodedJWT <- decodeJWT(jwt)
- jwtPresentationPayload <- Validation.fromEither(decode[JwtPresentationPayload](decodedJWT)).mapError(_.getMessage)
+ jwtPresentationPayload <- Validation
+ .fromTry(decodeJwt[JwtPresentationPayload](jwt))
+ .mapError(_.toString)
result <- validateCredentialSubjectId(jwtPresentationPayload.vp.verifiableCredential, jwtPresentationPayload.iss)
} yield result
}
def verifyDates(jwt: JWT, leeway: TemporalAmount)(implicit clock: Clock): Validation[String, Unit] = {
val now = clock.instant()
-
- val decodeJWT =
- Validation
- .fromTry(JwtCirce.decodeRaw(jwt.value, options = JwtOptions(false, false, false)))
- .mapError(_.getMessage)
-
def validateNbfNotAfterExp(maybeNbf: Option[Instant], maybeExp: Option[Instant]): Validation[String, Unit] = {
val maybeResult =
for {
@@ -525,8 +603,9 @@ object JwtPresentation {
}
for {
- decodedJWT <- decodeJWT
- jwtCredentialPayload <- Validation.fromEither(decode[JwtPresentationPayload](decodedJWT)).mapError(_.getMessage)
+ jwtCredentialPayload <- Validation
+ .fromTry(decodeJwt[JwtPresentationPayload](jwt))
+ .mapError(_.toString)
maybeNbf = jwtCredentialPayload.maybeNbf
maybeExp = jwtCredentialPayload.maybeExp
result <- Validation.validateWith(
diff --git a/pollux/vc-jwt/src/test/scala/org/hyperledger/identus/pollux/vc/jwt/JwtPresentationTest.scala b/pollux/vc-jwt/src/test/scala/org/hyperledger/identus/pollux/vc/jwt/JwtPresentationTest.scala
new file mode 100644
index 0000000000..7122818572
--- /dev/null
+++ b/pollux/vc-jwt/src/test/scala/org/hyperledger/identus/pollux/vc/jwt/JwtPresentationTest.scala
@@ -0,0 +1,99 @@
+package org.hyperledger.identus.pollux.vc.jwt
+
+import zio.test.*
+import zio.test.ZIOSpecDefault
+
+object JwtPresentationTest extends ZIOSpecDefault {
+ val jwt = JWT(
+ "eyJraWQiOiJteS1hdXRoLWtleSIsInR5cCI6IkpXVCIsImFsZyI6IkVTMjU2SyJ9.eyJpc3MiOiJkaWQ6cHJpc206YjgwZjAxMTZhYWY2OTI5MGRkMzJiZDE0OTNmN2IxYWJhMDM5OTYyM2JkNDk5Mzk3NTRjNThhNGNmZTU4M2QwYzpDcGNDQ3BRQ0VqOEtDMjE1TFdGMWRHZ3RhMlY1RUFSS0xnb0pjMlZqY0RJMU5tc3hFaUVDQnViQkpoNDhRNjhqOTJZS3NjMVFqQ0prOHFvRXBMamRoejNRRVFzRWpWRVNTZ29XYlhrdGEyVjVMV0Z6YzJWeWRHbHZiazFsZEdodlpCQUNTaTRLQ1hObFkzQXlOVFpyTVJJaEFoTENSMkhTa3NOWUh2Y0dCUWZzQVZrdDNFa1pMSVpMVEhYcFc4ckJRRHI5RWpzS0IyMWhjM1JsY2pBUUFVb3VDZ2x6WldOd01qVTJhekVTSVFMRC10d3c1SklVbzA2dXQ5MDQwaTZ5dTdhQUhMcWdxajdUcHBZNlUtQzhrQnBJQ2c1aFoyVnVkQzFpWVhObExYVnliQklRVEdsdWEyVmtVbVZ6YjNWeVkyVldNUm9rYUhSMGNEb3ZMekU1TWk0eE5qZ3VNUzQ0TmpvNU1EQXdMMk5zYjNWa0xXRm5aVzUwIiwiYXVkIjoiaHR0cHM6XC9cL3ByaXNtLXZlcmlmaWVyLmNvbSIsInZwIjp7InR5cGUiOlsiVmVyaWZpYWJsZVByZXNlbnRhdGlvbiJdLCJAY29udGV4dCI6WyJodHRwczpcL1wvd3d3LnczLm9yZ1wvMjAxOFwvcHJlc2VudGF0aW9uc1wvdjEiXSwidmVyaWZpYWJsZUNyZWRlbnRpYWwiOlsiZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKRlpFUlRRU0o5LmV5SnBjM01pT2lKa2FXUTZjSEpwYzIwNk1HWmxaVFF4Wm1Sa05qZ3dOemMyTTJOall6VXpPV015T1RnME1XRTBNVGhqTnpaaE9EbGlNMlk0WTJRMlpHRTRPV1JsTW1FelpERmhNRFExTnpGbU5UcERjSE5EUTNCblEwVnJXVXRHVnpFMVRGZDBiR1ZUTVdoa1dGSnZXbGMxTUdGWFRtaGtSMngyWW1oQlJWTnBjMHRDTUZaclRXcFZNVTFVYTFOSlJIVjVSVlF4YUVOQmRVTjJhek5QYm05bmJETTRZMDFwU201NFgycHJURmxUVG5kWFRVbEJiblJzVEVWclkwdEdiVEUxVEZkMGJHVlRNV2hqTTA1c1kyNVNjR0l5TlU1YVdGSnZZakpSVVVGcmIzSkRaMlJHV2tSSk1VNVVSVFZGYVVOYVFWSkpibE5rVWtwRVN5MUZUSEp4VjI5a01YZE9UMGhvZFhSM1dsSkVTMG90YnpWQlpraHlZbkpTU1RkRFoyUjBXVmhPTUZwWVNYZEZRVVpMVEdkdlNtTXlWbXBqUkVreFRtMXplRVZwUlVSSE1XMXpkV056VlhOa1VVOHRibGx3Y2xGWU5HOUJXRnBJVnpKak9GQlNWM3BTWkZOMGF6WXdPRFZKWVZOQmIwOVpWMlJzWW01UmRGbHRSbnBhVXpFeFkyMTNVMFZGZUhCaWJYUnNXa1pLYkdNeU9URmpiVTVzVm1wRllVcEhhREJrU0VFMlRIazRlRTlVU1hWTlZGazBUR3BGZFU5RVdUWlBSRUYzVFVNNWFtSkhPVEZhUXpGb1dqSldkV1JCSWl3aWMzVmlJam9pWkdsa09uQnlhWE50T21JNE1HWXdNVEUyWVdGbU5qa3lPVEJrWkRNeVltUXhORGt6WmpkaU1XRmlZVEF6T1RrMk1qTmlaRFE1T1RNNU56VTBZelU0WVRSalptVTFPRE5rTUdNNlEzQmpRME53VVVORmFqaExRekl4TlV4WFJqRmtSMmQwWVRKV05VVkJVa3RNWjI5S1l6SldhbU5FU1RGT2JYTjRSV2xGUTBKMVlrSkthRFE0VVRZNGFqa3lXVXR6WXpGUmFrTkthemh4YjBWd1RHcGthSG96VVVWUmMwVnFWa1ZUVTJkdlYySllhM1JoTWxZMVRGZEdlbU15Vm5sa1IyeDJZbXN4YkdSSGFIWmFRa0ZEVTJrMFMwTllUbXhaTTBGNVRsUmFjazFTU1doQmFFeERVakpJVTJ0elRsbElkbU5IUWxGbWMwRldhM1F6Uld0YVRFbGFURlJJV0hCWE9ISkNVVVJ5T1VWcWMwdENNakZvWXpOU2JHTnFRVkZCVlc5MVEyZHNlbHBYVG5kTmFsVXlZWHBGVTBsUlRFUXRkSGQzTlVwSlZXOHdOblYwT1RBME1HazJlWFUzWVVGSVRIRm5jV28zVkhCd1dUWlZMVU00YTBKd1NVTm5OV2hhTWxaMVpFTXhhVmxZVG14TVdGWjVZa0pKVVZSSGJIVmhNbFpyVlcxV2VtSXpWbmxaTWxaWFRWSnZhMkZJVWpCalJHOTJUSHBGTlUxcE5IaE9hbWQxVFZNME5FNXFielZOUkVGM1RESk9jMkl6Vm10TVYwWnVXbGMxTUNJc0ltNWlaaUk2TVRjek1qQXhOVEl6TVN3aVpYaHdJam94TnpNeU1ERTRPRE14TENKMll5STZleUpqY21Wa1pXNTBhV0ZzVTJOb1pXMWhJanBiZXlKcFpDSTZJbWgwZEhBNlhDOWNMekU1TWk0eE5qZ3VNUzQ0TmpvNE1EQXdYQzlqYkc5MVpDMWhaMlZ1ZEZ3dmMyTm9aVzFoTFhKbFoybHpkSEo1WEM5elkyaGxiV0Z6WEM4Mk16TmhOamhtTnkwMFpUZGlMVE13TnpNdFlUbGhNQzA0WVdVNU5qUmtZVFU1TmpjaUxDSjBlWEJsSWpvaVEzSmxaR1Z1ZEdsaGJGTmphR1Z0WVRJd01qSWlmVjBzSW1OeVpXUmxiblJwWVd4VGRXSnFaV04wSWpwN0ltVnRZV2xzUVdSa2NtVnpjeUk2SW1Gc2FXTmxRSGR2Ym1SbGNteGhibVF1WTI5dElpd2laSEpwZG1sdVowTnNZWE56SWpvekxDSm1ZVzFwYkhsT1lXMWxJam9pVjI5dVpHVnliR0Z1WkNJc0ltZHBkbVZ1VG1GdFpTSTZJa0ZzYVdObElpd2laSEpwZG1sdVoweHBZMlZ1YzJWSlJDSTZJakV5TXpRMUlpd2lhV1FpT2lKa2FXUTZjSEpwYzIwNllqZ3daakF4TVRaaFlXWTJPVEk1TUdSa016SmlaREUwT1RObU4ySXhZV0poTURNNU9UWXlNMkprTkRrNU16azNOVFJqTlRoaE5HTm1aVFU0TTJRd1l6cERjR05EUTNCUlEwVnFPRXRETWpFMVRGZEdNV1JIWjNSaE1sWTFSVUZTUzB4bmIwcGpNbFpxWTBSSk1VNXRjM2hGYVVWRFFuVmlRa3BvTkRoUk5qaHFPVEpaUzNOak1WRnFRMHByT0hGdlJYQk1hbVJvZWpOUlJWRnpSV3BXUlZOVFoyOVhZbGhyZEdFeVZqVk1WMFo2WXpKV2VXUkhiSFppYXpGc1pFZG9kbHBDUVVOVGFUUkxRMWhPYkZrelFYbE9WRnB5VFZKSmFFRm9URU5TTWtoVGEzTk9XVWgyWTBkQ1VXWnpRVlpyZERORmExcE1TVnBNVkVoWWNGYzRja0pSUkhJNVJXcHpTMEl5TVdoak0xSnNZMnBCVVVGVmIzVkRaMng2V2xkT2QwMXFWVEpoZWtWVFNWRk1SQzEwZDNjMVNrbFZiekEyZFhRNU1EUXdhVFo1ZFRkaFFVaE1jV2R4YWpkVWNIQlpObFV0UXpoclFuQkpRMmMxYUZveVZuVmtRekZwV1ZoT2JFeFlWbmxpUWtsUlZFZHNkV0V5Vm10VmJWWjZZak5XZVZreVZsZE5VbTlyWVVoU01HTkViM1pNZWtVMVRXazBlRTVxWjNWTlV6UTBUbXB2TlUxRVFYZE1NazV6WWpOV2EweFhSbTVhVnpVd0lpd2laR0YwWlU5bVNYTnpkV0Z1WTJVaU9pSXlNREl3TFRFeExURXpWREl3T2pJd09qTTVLekF3T2pBd0luMHNJblI1Y0dVaU9sc2lWbVZ5YVdacFlXSnNaVU55WldSbGJuUnBZV3dpWFN3aVFHTnZiblJsZUhRaU9sc2lhSFIwY0hNNlhDOWNMM2QzZHk1M015NXZjbWRjTHpJd01UaGNMMk55WldSbGJuUnBZV3h6WEM5Mk1TSmRMQ0pwYzNOMVpYSWlPbnNpYVdRaU9pSmthV1E2Y0hKcGMyMDZNR1psWlRReFptUmtOamd3TnpjMk0yTmpZelV6T1dNeU9UZzBNV0UwTVRoak56WmhPRGxpTTJZNFkyUTJaR0U0T1dSbE1tRXpaREZoTURRMU56Rm1OVHBEY0hORFEzQm5RMFZyV1V0R1Z6RTFURmQwYkdWVE1XaGtXRkp2V2xjMU1HRlhUbWhrUjJ4MlltaEJSVk5wYzB0Q01GWnJUV3BWTVUxVWExTkpSSFY1UlZReGFFTkJkVU4yYXpOUGJtOW5iRE00WTAxcFNtNTRYMnByVEZsVFRuZFhUVWxCYm5Sc1RFVnJZMHRHYlRFMVRGZDBiR1ZUTVdoak0wNXNZMjVTY0dJeU5VNWFXRkp2WWpKUlVVRnJiM0pEWjJSR1drUkpNVTVVUlRWRmFVTmFRVkpKYmxOa1VrcEVTeTFGVEhKeFYyOWtNWGRPVDBob2RYUjNXbEpFUzBvdGJ6VkJaa2h5WW5KU1NUZERaMlIwV1ZoT01GcFlTWGRGUVVaTFRHZHZTbU15Vm1walJFa3hUbTF6ZUVWcFJVUkhNVzF6ZFdOelZYTmtVVTh0Ymxsd2NsRllORzlCV0ZwSVZ6SmpPRkJTVjNwU1pGTjBhell3T0RWSllWTkJiMDlaVjJSc1ltNVJkRmx0Um5wYVV6RXhZMjEzVTBWRmVIQmliWFJzV2taS2JHTXlPVEZqYlU1c1ZtcEZZVXBIYURCa1NFRTJUSGs0ZUU5VVNYVk5WRmswVEdwRmRVOUVXVFpQUkVGM1RVTTVhbUpIT1RGYVF6Rm9XakpXZFdSQklpd2lkSGx3WlNJNklsQnliMlpwYkdVaWZTd2lZM0psWkdWdWRHbGhiRk4wWVhSMWN5STZleUp6ZEdGMGRYTlFkWEp3YjNObElqb2lVbVYyYjJOaGRHbHZiaUlzSW5OMFlYUjFjMHhwYzNSSmJtUmxlQ0k2TVN3aWFXUWlPaUpvZEhSd09sd3ZYQzh4T1RJdU1UWTRMakV1T0RZNk9EQXdNRnd2WTJ4dmRXUXRZV2RsYm5SY0wyTnlaV1JsYm5ScFlXd3RjM1JoZEhWelhDODBaRGN4TmpZM01pMDFNekpqTFRRM056Y3RZVEJoTmkxbU56azJNR1F3TlRKbFpHVWpNU0lzSW5SNWNHVWlPaUpUZEdGMGRYTk1hWE4wTWpBeU1VVnVkSEo1SWl3aWMzUmhkSFZ6VEdsemRFTnlaV1JsYm5ScFlXd2lPaUpvZEhSd09sd3ZYQzh4T1RJdU1UWTRMakV1T0RZNk9EQXdNRnd2WTJ4dmRXUXRZV2RsYm5SY0wyTnlaV1JsYm5ScFlXd3RjM1JoZEhWelhDODBaRGN4TmpZM01pMDFNekpqTFRRM056Y3RZVEJoTmkxbU56azJNR1F3TlRKbFpHVWlmWDE5LmpiRE02NHQ1N3JoTXktNEt5ZnlsR3FCZGdzMUtJbXZpa0QzblFuVFRPbF9YcXV6UThTWGpZVEYyTWREbXJGRzAtSUk5NGo4ZmlUS0xYcWRpQ1NXNEN3Il19LCJub25jZSI6IjExYzkxNDkzLTAxYjMtNGM0ZC1hYzM2LWIzMzZiYWI1YmRkZiJ9.d5bzOLV-kQZvCceoFppqlPRG7aK3mo9sZVCj5_sPqIMvOqzAbxTOPyfI459GFKpeF8ApsNwJyx9jED_cRaqqiQ"
+ )
+ val domain = Some("https://prism-verifier.com")
+ val challenge = Some("11c91493-01b3-4c4d-ac36-b336bab5bddf")
+ val schemaIdAndTrustedIssuers = Seq(
+ CredentialSchemaAndTrustedIssuersConstraint(
+ schemaId = "http://192.168.1.86:8000/cloud-agent/schema-registry/schemas/633a68f7-4e7b-3073-a9a0-8ae964da5967",
+ trustedIssuers = Some(
+ Seq(
+ "did:prism:0fee41fdd6807763ccc539c29841a418c76a89b3f8cd6da89de2a3d1a04571f5:CpsCCpgCEkYKFW15LWtleS1hdXRoZW50aWNhdGlvbhAESisKB0VkMjU1MTkSIDuyET1hCAuCvk3Onogl38cMiJnx_jkLYSNwWMIAntlLEkcKFm15LWtleS1hc3NlcnRpb25NZXRob2QQAkorCgdFZDI1NTE5EiCZARInSdRJDK-ELrqWod1wNOHhutwZRDKJ-o5AfHrbrRI7CgdtYXN0ZXIwEAFKLgoJc2VjcDI1NmsxEiEDG1msucsUsdQO-nYprQX4oAXZHW2c8PRWzRdStk6085IaSAoOYWdlbnQtYmFzZS11cmwSEExpbmtlZFJlc291cmNlVjEaJGh0dHA6Ly8xOTIuMTY4LjEuODY6ODAwMC9jbG91ZC1hZ2VudA"
+ )
+ )
+ )
+ )
+ override def spec = suite("JWTVerificationSpec")(
+ test("validate true when issuer is trusted") {
+ val validation = JwtPresentation.validatePresentation(
+ jwt,
+ domain,
+ challenge,
+ schemaIdAndTrustedIssuers
+ )
+ assertTrue(validation.fold(_ => false, _ => true))
+ },
+ test("fail when issuer is not trusted") {
+ val trustedIssuer = "did:prism:issuer"
+ val schemaIdAndTrustedIssuers = Seq(
+ CredentialSchemaAndTrustedIssuersConstraint(
+ schemaId =
+ "http://192.168.1.86:8000/cloud-agent/schema-registry/schemas/633a68f7-4e7b-3073-a9a0-8ae964da5967",
+ trustedIssuers = Some(
+ Seq(
+ trustedIssuer
+ )
+ )
+ )
+ )
+ val validation = JwtPresentation.validatePresentation(
+ jwt,
+ domain,
+ challenge,
+ schemaIdAndTrustedIssuers
+ )
+ assertTrue(validation.fold(_ => true, _ => false))
+ assertTrue(validation.fold(chunk => chunk.mkString.contains(trustedIssuer), _ => false))
+ },
+ test("fail when schema ID doesn't match") {
+ val expectedSchemaId = "http://192.168.1.86:8000/cloud-agent/schema-registry/schemas/schemaId"
+ val schemaIdAndTrustedIssuers = Seq(
+ CredentialSchemaAndTrustedIssuersConstraint(
+ schemaId = expectedSchemaId,
+ trustedIssuers = Some(
+ Seq(
+ "did:prism:0fee41fdd6807763ccc539c29841a418c76a89b3f8cd6da89de2a3d1a04571f5:CpsCCpgCEkYKFW15LWtleS1hdXRoZW50aWNhdGlvbhAESisKB0VkMjU1MTkSIDuyET1hCAuCvk3Onogl38cMiJnx_jkLYSNwWMIAntlLEkcKFm15LWtleS1hc3NlcnRpb25NZXRob2QQAkorCgdFZDI1NTE5EiCZARInSdRJDK-ELrqWod1wNOHhutwZRDKJ-o5AfHrbrRI7CgdtYXN0ZXIwEAFKLgoJc2VjcDI1NmsxEiEDG1msucsUsdQO-nYprQX4oAXZHW2c8PRWzRdStk6085IaSAoOYWdlbnQtYmFzZS11cmwSEExpbmtlZFJlc291cmNlVjEaJGh0dHA6Ly8xOTIuMTY4LjEuODY6ODAwMC9jbG91ZC1hZ2VudA"
+ )
+ )
+ )
+ )
+ val validation = JwtPresentation.validatePresentation(
+ jwt,
+ domain,
+ challenge,
+ schemaIdAndTrustedIssuers
+ )
+ assertTrue(validation.fold(_ => true, _ => false))
+ assertTrue(validation.fold(chunk => chunk.mkString.contains(expectedSchemaId), _ => false))
+ },
+ test("fail when domain validation fails") {
+ val domain = Some("domain")
+ val validation = JwtPresentation.validatePresentation(
+ jwt,
+ domain,
+ challenge,
+ schemaIdAndTrustedIssuers
+ )
+ assertTrue(validation.fold(_ => true, _ => false))
+ assertTrue(validation.fold(chunk => chunk.mkString.contains("domain/Audience dont match"), _ => false))
+ },
+ test("fail when challenge validation fails") {
+ val challenge = Some("challenge")
+ val validation = JwtPresentation.validatePresentation(
+ jwt,
+ domain,
+ challenge,
+ schemaIdAndTrustedIssuers
+ )
+ assertTrue(validation.fold(_ => true, _ => false))
+ assertTrue(validation.fold(chunk => chunk.mkString.contains("Challenge/Nonce dont match"), _ => false))
+ }
+ )
+
+}
diff --git a/shared/core/src/main/scala/org/hyperledger/identus/shared/messaging/kafka/ZKafkaMessagingServiceImpl.scala b/shared/core/src/main/scala/org/hyperledger/identus/shared/messaging/kafka/ZKafkaMessagingServiceImpl.scala
index 9180fc4d62..14e5ab0491 100644
--- a/shared/core/src/main/scala/org/hyperledger/identus/shared/messaging/kafka/ZKafkaMessagingServiceImpl.scala
+++ b/shared/core/src/main/scala/org/hyperledger/identus/shared/messaging/kafka/ZKafkaMessagingServiceImpl.scala
@@ -9,6 +9,7 @@ import zio.kafka.consumer.{
ConsumerSettings as ZKConsumerSettings,
Subscription as ZKSubscription
}
+import zio.kafka.consumer.Consumer.{AutoOffsetStrategy, OffsetRetrieval}
import zio.kafka.producer.{Producer as ZKProducer, ProducerSettings as ZKProducerSettings}
import zio.kafka.serde.{Deserializer as ZKDeserializer, Serializer as ZKSerializer}
@@ -80,7 +81,7 @@ class ZKafkaConsumerImpl[K, V](
.withMaxPollInterval(maxPollInterval) // Should be max.poll.records x 'max processing time per record'
// 'pollTimeout' default is 50 millis. This is a ZIO Kafka property.
.withPollTimeout(pollTimeout)
- // .withOffsetRetrieval(OffsetRetrieval.Auto(AutoOffsetStrategy.Earliest))
+ .withOffsetRetrieval(OffsetRetrieval.Auto(AutoOffsetStrategy.Earliest))
.withRebalanceSafeCommits(rebalanceSafeCommits)
// .withMaxRebalanceDuration(30.seconds)
)
diff --git a/tests/integration-tests/src/test/kotlin/abilities/ListenToEvents.kt b/tests/integration-tests/src/test/kotlin/abilities/ListenToEvents.kt
index e2116d6793..3450e30dd5 100644
--- a/tests/integration-tests/src/test/kotlin/abilities/ListenToEvents.kt
+++ b/tests/integration-tests/src/test/kotlin/abilities/ListenToEvents.kt
@@ -3,26 +3,37 @@ package abilities
import com.google.gson.GsonBuilder
import common.TestConstants
import io.iohk.atala.automation.restassured.CustomGsonObjectMapperFactory
-import io.ktor.http.*
-import io.ktor.server.application.*
-import io.ktor.server.engine.*
-import io.ktor.server.netty.*
-import io.ktor.server.request.*
-import io.ktor.server.response.*
-import io.ktor.server.routing.*
-import models.*
+import io.ktor.http.HttpStatusCode
+import io.ktor.server.application.Application
+import io.ktor.server.application.call
+import io.ktor.server.engine.ApplicationEngine
+import io.ktor.server.engine.embeddedServer
+import io.ktor.server.netty.Netty
+import io.ktor.server.request.receiveText
+import io.ktor.server.response.respond
+import io.ktor.server.routing.get
+import io.ktor.server.routing.post
+import io.ktor.server.routing.routing
+import models.ConnectionEvent
+import models.CredentialEvent
+import models.DidEvent
+import models.Event
+import models.PresentationEvent
+import models.PresentationStatusAdapter
import net.serenitybdd.screenplay.Ability
import net.serenitybdd.screenplay.Actor
import net.serenitybdd.screenplay.HasTeardown
import net.serenitybdd.screenplay.Question
-import org.hyperledger.identus.client.models.*
+import org.hyperledger.identus.client.models.Connection
+import org.hyperledger.identus.client.models.IssueCredentialRecord
import java.net.URL
import java.time.OffsetDateTime
open class ListenToEvents(
private val url: URL,
webhookPort: Int?,
-) : Ability, HasTeardown {
+) : Ability,
+ HasTeardown {
private val server: ApplicationEngine
private val gson = GsonBuilder()
@@ -88,48 +99,36 @@ open class ListenToEvents(
}
companion object {
- fun at(url: URL, webhookPort: Int?): ListenToEvents {
- return ListenToEvents(url, webhookPort)
- }
+ fun at(url: URL, webhookPort: Int?): ListenToEvents = ListenToEvents(url, webhookPort)
- fun with(actor: Actor): ListenToEvents {
- return actor.abilityTo(ListenToEvents::class.java)
- }
+ fun with(actor: Actor): ListenToEvents = actor.abilityTo(ListenToEvents::class.java)
- fun presentationProofStatus(actor: Actor): Question {
- return Question.about("presentation status").answeredBy {
- val proofEvent = with(actor).presentationEvents.lastOrNull {
- it.data.thid == actor.recall("thid")
- }
- proofEvent?.data?.status
+ fun presentationProofStatus(actor: Actor): Question = Question.about("presentation status").answeredBy {
+ val proofEvent = with(actor).presentationEvents.lastOrNull {
+ it.data.thid == actor.recall("thid")
}
+ proofEvent?.data?.status
}
- fun connectionState(actor: Actor): Question {
- return Question.about("connection state").answeredBy {
- val lastEvent = with(actor).connectionEvents.lastOrNull {
- it.data.thid == actor.recall("connection").thid
- }
- lastEvent?.data?.state
+ fun connectionState(actor: Actor): Question = Question.about("connection state").answeredBy {
+ val lastEvent = with(actor).connectionEvents.lastOrNull {
+ it.data.thid == actor.recall("connection").thid
}
+ lastEvent?.data?.state
}
- fun credentialState(actor: Actor): Question {
- return Question.about("credential state").answeredBy {
- val credentialEvent = ListenToEvents.with(actor).credentialEvents.lastOrNull {
- it.data.thid == actor.recall("thid")
- }
- credentialEvent?.data?.protocolState
+ fun credentialState(actor: Actor): Question = Question.about("credential state").answeredBy {
+ val credentialEvent = ListenToEvents.with(actor).credentialEvents.lastOrNull {
+ it.data.thid == actor.recall("thid")
}
+ credentialEvent?.data?.protocolState
}
- fun didStatus(actor: Actor): Question {
- return Question.about("did status").answeredBy {
- val didEvent = ListenToEvents.with(actor).didEvents.lastOrNull {
- it.data.did == actor.recall("shortFormDid")
- }
- didEvent?.data?.status
+ fun didStatus(actor: Actor): Question = Question.about("did status").answeredBy {
+ val didEvent = ListenToEvents.with(actor).didEvents.lastOrNull {
+ it.data.did == actor.recall("shortFormDid")
}
+ didEvent?.data?.status
}
}
@@ -143,9 +142,7 @@ open class ListenToEvents(
.start(wait = false)
}
- override fun toString(): String {
- return "Listen HTTP port at $url"
- }
+ override fun toString(): String = "Listen HTTP port at $url"
override fun tearDown() {
server.stop()
diff --git a/tests/integration-tests/src/test/kotlin/common/CredentialSchema.kt b/tests/integration-tests/src/test/kotlin/common/CredentialSchema.kt
index 05a6bbf37c..b128ddce39 100644
--- a/tests/integration-tests/src/test/kotlin/common/CredentialSchema.kt
+++ b/tests/integration-tests/src/test/kotlin/common/CredentialSchema.kt
@@ -34,7 +34,37 @@ enum class CredentialSchema {
"name" to "Name",
"age" to 18,
)
- }, ;
+ },
+ EMPLOYEE_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/employee-schema-1.0",
+ schema = schemaType,
+ description = "Employee schema",
+ type = "object",
+ properties = mutableMapOf(
+ "name" to JsonSchemaProperty(type = "string"),
+ "age" to JsonSchemaProperty(type = "integer"),
+ ),
+ required = listOf("name", "age"),
+ )
+ override val credentialSchema: CredentialSchemaInput = CredentialSchemaInput(
+ author = "did:prism:agent",
+ name = UUID.randomUUID().toString(),
+ description = "Simple employee credentials schema",
+ type = credentialSchemaType,
+ schema = schema,
+ tags = listOf("employee", "employees"),
+ version = "1.0.0",
+ )
+ override val claims: Map = linkedMapOf(
+ "name" to "Name",
+ "age" to 18,
+ )
+ },
+ ;
abstract val credentialSchema: CredentialSchemaInput
abstract val schema: JsonSchema
diff --git a/tests/integration-tests/src/test/kotlin/common/DidDocumentTemplate.kt b/tests/integration-tests/src/test/kotlin/common/DidDocumentTemplate.kt
new file mode 100644
index 0000000000..a82f4cbced
--- /dev/null
+++ b/tests/integration-tests/src/test/kotlin/common/DidDocumentTemplate.kt
@@ -0,0 +1,9 @@
+package common
+
+import org.hyperledger.identus.client.models.ManagedDIDKeyTemplate
+import org.hyperledger.identus.client.models.Service
+
+data class DidDocumentTemplate(
+ val publicKeys: MutableList,
+ val services: MutableList,
+)
diff --git a/tests/integration-tests/src/test/kotlin/common/DidPurpose.kt b/tests/integration-tests/src/test/kotlin/common/DidPurpose.kt
deleted file mode 100644
index c4c30ca83c..0000000000
--- a/tests/integration-tests/src/test/kotlin/common/DidPurpose.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-package common
-
-import org.hyperledger.identus.client.models.*
-
-enum class DidPurpose {
- CUSTOM {
- override val publicKeys = mutableListOf()
- override val services = mutableListOf()
- },
- SD_JWT {
- override val publicKeys = mutableListOf(
- ManagedDIDKeyTemplate("auth-1", Purpose.AUTHENTICATION, Curve.ED25519),
- ManagedDIDKeyTemplate("assertion-1", Purpose.ASSERTION_METHOD, Curve.ED25519),
- )
- override val services = mutableListOf()
- },
- JWT {
- override val publicKeys = mutableListOf(
- ManagedDIDKeyTemplate("auth-1", Purpose.AUTHENTICATION, Curve.SECP256K1),
- ManagedDIDKeyTemplate("auth-2", Purpose.AUTHENTICATION, Curve.ED25519),
- ManagedDIDKeyTemplate("assertion-1", Purpose.ASSERTION_METHOD, Curve.SECP256K1),
- ManagedDIDKeyTemplate("assertion-2", Purpose.ASSERTION_METHOD, Curve.ED25519),
- )
- override val services = mutableListOf()
- },
- OIDC_JWT {
- override val publicKeys = mutableListOf(
- ManagedDIDKeyTemplate("auth-1", Purpose.AUTHENTICATION, Curve.SECP256K1),
- ManagedDIDKeyTemplate("auth-2", Purpose.AUTHENTICATION, Curve.ED25519),
- ManagedDIDKeyTemplate("assertion-1", Purpose.ASSERTION_METHOD, Curve.SECP256K1),
- )
- override val services = mutableListOf()
- },
- ANONCRED {
- override val publicKeys = mutableListOf()
- override val services = mutableListOf()
- }, ;
-
- abstract val publicKeys: MutableList
- abstract val services: MutableList
-}
diff --git a/tests/integration-tests/src/test/kotlin/common/DidType.kt b/tests/integration-tests/src/test/kotlin/common/DidType.kt
new file mode 100644
index 0000000000..38f2c2b792
--- /dev/null
+++ b/tests/integration-tests/src/test/kotlin/common/DidType.kt
@@ -0,0 +1,50 @@
+package common
+
+import org.hyperledger.identus.client.models.*
+
+enum class DidType {
+ CUSTOM {
+ override val documentTemplate get() = DidDocumentTemplate(
+ publicKeys = mutableListOf(),
+ services = mutableListOf(),
+ )
+ },
+ SD_JWT {
+ override val documentTemplate get() = DidDocumentTemplate(
+ publicKeys = mutableListOf(
+ ManagedDIDKeyTemplate("auth-1", Purpose.AUTHENTICATION, Curve.ED25519),
+ ManagedDIDKeyTemplate("assertion-1", Purpose.ASSERTION_METHOD, Curve.ED25519),
+ ),
+ services = mutableListOf(),
+ )
+ },
+ JWT {
+ override val documentTemplate get() = DidDocumentTemplate(
+ publicKeys = mutableListOf(
+ ManagedDIDKeyTemplate("auth-1", Purpose.AUTHENTICATION, Curve.SECP256K1),
+ ManagedDIDKeyTemplate("auth-2", Purpose.AUTHENTICATION, Curve.ED25519),
+ ManagedDIDKeyTemplate("assertion-1", Purpose.ASSERTION_METHOD, Curve.SECP256K1),
+ ManagedDIDKeyTemplate("assertion-2", Purpose.ASSERTION_METHOD, Curve.ED25519),
+ ),
+ services = mutableListOf(),
+ )
+ },
+ OIDC_JWT {
+ override val documentTemplate get() = DidDocumentTemplate(
+ publicKeys = mutableListOf(
+ ManagedDIDKeyTemplate("auth-1", Purpose.AUTHENTICATION, Curve.SECP256K1),
+ ManagedDIDKeyTemplate("auth-2", Purpose.AUTHENTICATION, Curve.ED25519),
+ ManagedDIDKeyTemplate("assertion-1", Purpose.ASSERTION_METHOD, Curve.SECP256K1),
+ ),
+ services = mutableListOf(),
+ )
+ },
+ ANONCRED {
+ override val documentTemplate get() = DidDocumentTemplate(
+ publicKeys = mutableListOf(),
+ services = mutableListOf(),
+ )
+ }, ;
+
+ abstract val documentTemplate: DidDocumentTemplate
+}
diff --git a/tests/integration-tests/src/test/kotlin/steps/common/CommonSteps.kt b/tests/integration-tests/src/test/kotlin/steps/common/CommonSteps.kt
index d5c8428b13..06aaab22bf 100644
--- a/tests/integration-tests/src/test/kotlin/steps/common/CommonSteps.kt
+++ b/tests/integration-tests/src/test/kotlin/steps/common/CommonSteps.kt
@@ -1,7 +1,7 @@
package steps.common
import common.CredentialSchema
-import common.DidPurpose
+import common.DidType
import interactions.Get
import io.cucumber.java.en.Given
import io.iohk.atala.automation.extensions.get
@@ -13,7 +13,7 @@ import org.hyperledger.identus.client.models.Connection
import org.hyperledger.identus.client.models.ConnectionsPage
import steps.connection.ConnectionSteps
import steps.credentials.*
-import steps.did.PublishDidSteps
+import steps.did.CreateDidSteps
import steps.schemas.CredentialSchemasSteps
class CommonSteps {
@@ -21,21 +21,21 @@ class CommonSteps {
fun holderHasIssuedJwtCredentialFromIssuer(holder: Actor, issuer: Actor) {
actorsHaveExistingConnection(issuer, holder)
- val publishDidSteps = PublishDidSteps()
- publishDidSteps.agentHasAnUnpublishedDID(holder, DidPurpose.JWT)
- publishDidSteps.agentHasAPublishedDID(issuer, DidPurpose.JWT)
+ val createDidSteps = CreateDidSteps()
+ createDidSteps.agentHasAnUnpublishedDID(holder, DidType.JWT)
+ createDidSteps.agentHasAPublishedDID(issuer, DidType.JWT)
val jwtCredentialSteps = JwtCredentialSteps()
val credentialSteps = CredentialSteps()
jwtCredentialSteps.issuerOffersAJwtCredential(issuer, holder, "short")
credentialSteps.holderReceivesCredentialOffer(holder)
- jwtCredentialSteps.holderAcceptsJwtCredentialOfferForJwt(holder)
+ jwtCredentialSteps.holderAcceptsJwtCredentialOfferForJwt(holder, "auth-1")
credentialSteps.issuerIssuesTheCredential(issuer)
credentialSteps.holderReceivesTheIssuedCredential(holder)
}
- @Given("{actor} has a jwt issued credential with {} schema from {actor}")
+ @Given("{actor} has a jwt issued credential with '{}' schema from {actor}")
fun holderHasIssuedJwtCredentialFromIssuerWithSchema(
holder: Actor,
schema: CredentialSchema,
@@ -43,9 +43,9 @@ class CommonSteps {
) {
actorsHaveExistingConnection(issuer, holder)
- val publishDidSteps = PublishDidSteps()
- publishDidSteps.agentHasAnUnpublishedDID(holder, DidPurpose.JWT)
- publishDidSteps.agentHasAPublishedDID(issuer, DidPurpose.JWT)
+ val createDidSteps = CreateDidSteps()
+ createDidSteps.agentHasAnUnpublishedDID(holder, DidType.JWT)
+ createDidSteps.agentHasAPublishedDID(issuer, DidType.JWT)
val schemaSteps = CredentialSchemasSteps()
schemaSteps.agentHasAPublishedSchema(issuer, schema)
@@ -54,7 +54,7 @@ class CommonSteps {
val credentialSteps = CredentialSteps()
jwtCredentialSteps.issuerOffersJwtCredentialToHolderUsingSchema(issuer, holder, "short", schema)
credentialSteps.holderReceivesCredentialOffer(holder)
- jwtCredentialSteps.holderAcceptsJwtCredentialOfferForJwt(holder)
+ jwtCredentialSteps.holderAcceptsJwtCredentialOfferForJwt(holder, "auth-1")
credentialSteps.issuerIssuesTheCredential(issuer)
credentialSteps.holderReceivesTheIssuedCredential(holder)
}
@@ -63,9 +63,9 @@ class CommonSteps {
fun holderHasIssuedSdJwtCredentialFromIssuer(holder: Actor, issuer: Actor) {
actorsHaveExistingConnection(issuer, holder)
- val publishDidSteps = PublishDidSteps()
- publishDidSteps.agentHasAnUnpublishedDID(holder, DidPurpose.SD_JWT)
- publishDidSteps.agentHasAPublishedDID(issuer, DidPurpose.SD_JWT)
+ val createDidSteps = CreateDidSteps()
+ createDidSteps.agentHasAnUnpublishedDID(holder, DidType.SD_JWT)
+ createDidSteps.agentHasAPublishedDID(issuer, DidType.SD_JWT)
val sdJwtCredentialSteps = SdJwtCredentialSteps()
val credentialSteps = CredentialSteps()
@@ -80,9 +80,9 @@ class CommonSteps {
fun holderHasIssuedSdJwtCredentialFromIssuerWithKeyBind(holder: Actor, issuer: Actor) {
actorsHaveExistingConnection(issuer, holder)
- val publishDidSteps = PublishDidSteps()
- publishDidSteps.agentHasAnUnpublishedDID(holder, DidPurpose.SD_JWT)
- publishDidSteps.agentHasAPublishedDID(issuer, DidPurpose.SD_JWT)
+ val createDidSteps = CreateDidSteps()
+ createDidSteps.agentHasAnUnpublishedDID(holder, DidType.SD_JWT)
+ createDidSteps.agentHasAPublishedDID(issuer, DidType.SD_JWT)
val sdJwtCredentialSteps = SdJwtCredentialSteps()
val credentialSteps = CredentialSteps()
@@ -97,8 +97,6 @@ class CommonSteps {
fun actorsHaveExistingConnection(inviter: Actor, invitee: Actor) {
inviter.attemptsTo(
Get.resource("/connections"),
- )
- inviter.attemptsTo(
Ensure.thatTheLastResponse().statusCode().isEqualTo(HttpStatus.SC_OK),
)
val inviterConnection = SerenityRest.lastResponse().get().contents!!.firstOrNull {
@@ -109,8 +107,6 @@ class CommonSteps {
if (inviterConnection != null) {
invitee.attemptsTo(
Get.resource("/connections"),
- )
- invitee.attemptsTo(
Ensure.thatTheLastResponse().statusCode().isEqualTo(HttpStatus.SC_OK),
)
inviteeConnection = SerenityRest.lastResponse().get().contents!!.firstOrNull {
diff --git a/tests/integration-tests/src/test/kotlin/steps/connection/ConnectionSteps.kt b/tests/integration-tests/src/test/kotlin/steps/connection/ConnectionSteps.kt
index 17df7e4bf3..1c3e2e0e94 100644
--- a/tests/integration-tests/src/test/kotlin/steps/connection/ConnectionSteps.kt
+++ b/tests/integration-tests/src/test/kotlin/steps/connection/ConnectionSteps.kt
@@ -15,9 +15,12 @@ import org.apache.http.HttpStatus.SC_CREATED
import org.apache.http.HttpStatus.SC_OK
import org.assertj.core.api.Assertions.assertThat
import org.hamcrest.CoreMatchers
-import org.hyperledger.identus.client.models.*
+import org.hyperledger.identus.client.models.AcceptConnectionInvitationRequest
+import org.hyperledger.identus.client.models.Connection
import org.hyperledger.identus.client.models.Connection.State.CONNECTION_RESPONSE_RECEIVED
import org.hyperledger.identus.client.models.Connection.State.CONNECTION_RESPONSE_SENT
+import org.hyperledger.identus.client.models.Connection.State.INVITATION_GENERATED
+import org.hyperledger.identus.client.models.CreateConnectionRequest
class ConnectionSteps {
@@ -29,12 +32,11 @@ class ConnectionSteps {
inviter.attemptsTo(
Post.to("/connections").body(CreateConnectionRequest(label = connectionLabel)),
+ Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_CREATED),
)
val connection = SerenityRest.lastResponse().get()
-
inviter.attemptsTo(
- Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_CREATED),
Ensure.that(connection.label!!).isEqualTo(connectionLabel),
Ensure.that(connection.state).isEqualTo(Connection.State.INVITATION_GENERATED),
Ensure.that(connection.role).isEqualTo(Connection.Role.INVITER),
@@ -48,20 +50,14 @@ class ConnectionSteps {
fun inviteeSendsAConnectionRequestToInviter(invitee: Actor, inviter: Actor) {
// Bob accepts connection using achieved out-of-band invitation
val inviterConnection = inviter.recall("connection")
+ val body = AcceptConnectionInvitationRequest(inviterConnection.invitation.invitationUrl.split("=")[1])
invitee.attemptsTo(
- Post.to("/connection-invitations")
- .with {
- it.body(
- AcceptConnectionInvitationRequest(
- inviterConnection.invitation.invitationUrl.split("=")[1],
- ),
- )
- },
+ Post.to("/connection-invitations").body(body),
+ Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_OK),
)
- val inviteeConnection = SerenityRest.lastResponse().get()
+ val inviteeConnection = SerenityRest.lastResponse().get()
invitee.attemptsTo(
- Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_OK),
Ensure.that(inviteeConnection.invitation.from).isEqualTo(inviterConnection.invitation.from),
Ensure.that(inviteeConnection.invitation.id).isEqualTo(inviterConnection.invitation.id),
Ensure.that(inviteeConnection.invitation.invitationUrl)
diff --git a/tests/integration-tests/src/test/kotlin/steps/connectionless/ConnectionLessSteps.kt b/tests/integration-tests/src/test/kotlin/steps/connectionless/ConnectionLessSteps.kt
index ec7a49a0df..04d6772c38 100644
--- a/tests/integration-tests/src/test/kotlin/steps/connectionless/ConnectionLessSteps.kt
+++ b/tests/integration-tests/src/test/kotlin/steps/connectionless/ConnectionLessSteps.kt
@@ -14,7 +14,7 @@ import org.hyperledger.identus.client.models.*
class ConnectionLessSteps {
- @When("{actor} creates a {string} credential offer invitation with {string} form DID")
+ @When("{actor} creates a '{}' credential offer invitation with '{}' form DID")
fun inviterGeneratesACredentialOfferInvitation(issuer: Actor, credentialFormat: String, didForm: String) {
val claims = linkedMapOf(
"firstName" to "Automation",
@@ -90,12 +90,7 @@ class ConnectionLessSteps {
challenge = "11c91493-01b3-4c4d-ac36-b336bab5bddf",
domain = "https://example-verifier.com",
),
- proofs = listOf(
- ProofRequestAux(
- schemaId = "https://schema.org/Person",
- trustIssuers = listOf("did:web:atalaprism.io/users/testUser"),
- ),
- ),
+ proofs = emptyList(),
)
verifier.attemptsTo(
diff --git a/tests/integration-tests/src/test/kotlin/steps/credentials/CredentialSteps.kt b/tests/integration-tests/src/test/kotlin/steps/credentials/CredentialSteps.kt
index 7c2251ec83..d3aac42ea4 100644
--- a/tests/integration-tests/src/test/kotlin/steps/credentials/CredentialSteps.kt
+++ b/tests/integration-tests/src/test/kotlin/steps/credentials/CredentialSteps.kt
@@ -48,9 +48,6 @@ class CredentialSteps {
issuer.attemptsTo(
Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_OK),
- )
-
- issuer.attemptsTo(
PollingWait.until(
ListenToEvents.credentialState(issuer),
equalTo(CREDENTIAL_SENT),
diff --git a/tests/integration-tests/src/test/kotlin/steps/credentials/JwtCredentialSteps.kt b/tests/integration-tests/src/test/kotlin/steps/credentials/JwtCredentialSteps.kt
index 5ca7c1d96b..551662d448 100644
--- a/tests/integration-tests/src/test/kotlin/steps/credentials/JwtCredentialSteps.kt
+++ b/tests/integration-tests/src/test/kotlin/steps/credentials/JwtCredentialSteps.kt
@@ -62,7 +62,7 @@ class JwtCredentialSteps {
holder.remember("thid", credentialRecord.thid)
}
- @When("{actor} offers a jwt credential to {actor} with {string} form DID")
+ @When("{actor} offers a jwt credential to {actor} with '{}' form DID")
fun issuerOffersAJwtCredential(issuer: Actor, holder: Actor, format: String) {
val claims = linkedMapOf(
"firstName" to "FirstName",
@@ -72,7 +72,7 @@ class JwtCredentialSteps {
saveCredentialOffer(issuer, holder)
}
- @When("{actor} offers a jwt credential to {actor} with {string} form DID using issuingKid {string}")
+ @When("{actor} offers a jwt credential to {actor} with '{}' form DID using issuingKid '{}'")
fun issuerOffersAJwtCredentialWithIssuingKeyId(issuer: Actor, holder: Actor, format: String, issuingKid: String?) {
val claims = linkedMapOf(
"firstName" to "FirstName",
@@ -82,7 +82,7 @@ class JwtCredentialSteps {
saveCredentialOffer(issuer, holder)
}
- @When("{actor} offers a jwt credential to {actor} with {} form using {} schema")
+ @When("{actor} offers a jwt credential to {actor} with '{}' form using '{}' schema")
fun issuerOffersJwtCredentialToHolderUsingSchema(
issuer: Actor,
holder: Actor,
@@ -95,7 +95,7 @@ class JwtCredentialSteps {
saveCredentialOffer(issuer, holder)
}
- @When("{actor} offers a jwt credential to {actor} with {} form DID with wrong claims structure using {} schema")
+ @When("{actor} offers a jwt credential to {actor} with '{}' form DID with wrong claims structure using '{}' schema")
fun issuerOffersJwtCredentialToHolderWithWrongClaimStructure(
issuer: Actor,
holder: Actor,
@@ -110,22 +110,13 @@ class JwtCredentialSteps {
sendCredentialOffer(issuer, holder, format, schemaGuid, claims, "assertion-1")
}
- @When("{actor} accepts jwt credential offer")
- fun holderAcceptsJwtCredentialOfferForJwt(holder: Actor) {
+ @When("{actor} accepts jwt credential offer using '{}' key id")
+ fun holderAcceptsJwtCredentialOfferForJwt(holder: Actor, keyId: String) {
val recordId = holder.recall("recordId")
+ val longFormDid = holder.recall("longFormDid")
+ val acceptRequest = AcceptCredentialOfferRequest(longFormDid, keyId)
holder.attemptsTo(
- Post.to("/issue-credentials/records/$recordId/accept-offer")
- .body(AcceptCredentialOfferRequest(holder.recall("longFormDid"), holder.recall("kidSecp256K1"))),
- Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_OK),
- )
- }
-
- @When("{actor} accepts jwt credential offer with keyId {string}")
- fun holderAcceptsJwtCredentialOfferForJwtWithKeyId(holder: Actor, keyId: String?) {
- val recordId = holder.recall("recordId")
- holder.attemptsTo(
- Post.to("/issue-credentials/records/$recordId/accept-offer")
- .body(AcceptCredentialOfferRequest(holder.recall("longFormDid"), keyId)),
+ Post.to("/issue-credentials/records/$recordId/accept-offer").body(acceptRequest),
Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_OK),
)
}
diff --git a/tests/integration-tests/src/test/kotlin/steps/did/PublishDidSteps.kt b/tests/integration-tests/src/test/kotlin/steps/did/CreateDidSteps.kt
similarity index 63%
rename from tests/integration-tests/src/test/kotlin/steps/did/PublishDidSteps.kt
rename to tests/integration-tests/src/test/kotlin/steps/did/CreateDidSteps.kt
index 8bff650f21..78ea918abf 100644
--- a/tests/integration-tests/src/test/kotlin/steps/did/PublishDidSteps.kt
+++ b/tests/integration-tests/src/test/kotlin/steps/did/CreateDidSteps.kt
@@ -1,11 +1,15 @@
package steps.did
import abilities.ListenToEvents
-import common.DidPurpose
+import common.DidDocumentTemplate
+import common.DidType
+import common.DidType.CUSTOM
import interactions.Get
import interactions.Post
import interactions.body
-import io.cucumber.java.en.*
+import io.cucumber.java.en.Given
+import io.cucumber.java.en.Then
+import io.cucumber.java.en.When
import io.iohk.atala.automation.extensions.get
import io.iohk.atala.automation.serenity.ensure.Ensure
import io.iohk.atala.automation.serenity.interactions.PollingWait
@@ -15,84 +19,64 @@ import org.apache.http.HttpStatus
import org.apache.http.HttpStatus.SC_CREATED
import org.apache.http.HttpStatus.SC_OK
import org.hamcrest.CoreMatchers.equalTo
-import org.hyperledger.identus.client.models.*
-
-class PublishDidSteps {
-
- @Given("{actor} has a published DID for {}")
- fun agentHasAPublishedDID(agent: Actor, didPurpose: DidPurpose) {
- if (agent.recallAll().containsKey("hasPublishedDid") && actualDidHasSamePurpose(agent, didPurpose)) {
+import org.hyperledger.identus.client.models.CreateManagedDidRequest
+import org.hyperledger.identus.client.models.CreateManagedDidRequestDocumentTemplate
+import org.hyperledger.identus.client.models.Curve
+import org.hyperledger.identus.client.models.DIDOperationResponse
+import org.hyperledger.identus.client.models.DIDResolutionResult
+import org.hyperledger.identus.client.models.ManagedDID
+import org.hyperledger.identus.client.models.ManagedDIDKeyTemplate
+import org.hyperledger.identus.client.models.Purpose
+
+class CreateDidSteps {
+
+ @Given("{actor} has a published DID for '{}'")
+ fun agentHasAPublishedDID(agent: Actor, didType: DidType) {
+ if (agent.recallAll().containsKey("hasPublishedDid") && actualDidHasSamePurpose(agent, didType)) {
return
}
- agentHasAnUnpublishedDID(agent, didPurpose)
+ agentHasAnUnpublishedDID(agent, didType)
hePublishesDidToLedger(agent)
}
- @Given("{actor} has an unpublished DID for {}")
- fun agentHasAnUnpublishedDID(agent: Actor, didPurpose: DidPurpose) {
+ @Given("{actor} has an unpublished DID for '{}'")
+ fun agentHasAnUnpublishedDID(agent: Actor, didType: DidType) {
if (agent.recallAll().containsKey("shortFormDid") || agent.recallAll().containsKey("longFormDid")) {
// is not published and has the same purpose
- if (!agent.recallAll().containsKey("hasPublishedDid") && actualDidHasSamePurpose(agent, didPurpose)) {
+ if (!agent.recallAll().containsKey("hasPublishedDid") && actualDidHasSamePurpose(agent, didType)) {
return
}
}
- agentCreatesUnpublishedDid(agent, didPurpose)
- }
-
- private fun actualDidHasSamePurpose(agent: Actor, didPurpose: DidPurpose): Boolean {
- val actualPurpose: DidPurpose = agent.recall("didPurpose") ?: return false
- return actualPurpose == didPurpose
+ agentCreatesUnpublishedDid(agent, didType)
}
- @Given("{actor} creates unpublished DID")
+ @Given("{actor} creates empty unpublished DID")
fun agentCreatesEmptyUnpublishedDid(actor: Actor) {
- agentCreatesUnpublishedDid(actor, DidPurpose.CUSTOM)
+ agentCreatesUnpublishedDid(actor, CUSTOM)
}
- @Given("{actor} creates unpublished DID for {}")
- fun agentCreatesUnpublishedDid(actor: Actor, didPurpose: DidPurpose) {
- val createDidRequest = CreateManagedDidRequest(
- CreateManagedDidRequestDocumentTemplate(didPurpose.publicKeys, services = didPurpose.services),
- )
- actor.attemptsTo(
- Post.to("/did-registrar/dids").body(createDidRequest),
- Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_CREATED),
- )
-
- val managedDid = SerenityRest.lastResponse().get()
-
- actor.attemptsTo(
- Ensure.that(managedDid.longFormDid!!).isNotEmpty(),
- Get.resource("/did-registrar/dids/${managedDid.longFormDid}"),
- Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_OK),
- )
-
- val did = SerenityRest.lastResponse().get()
-
- actor.remember("longFormDid", managedDid.longFormDid)
- actor.remember("kidSecp256K1", "auth-1")
- actor.remember("kidEd25519", "auth-2")
- actor.remember("shortFormDid", did.did)
- actor.remember("didPurpose", didPurpose)
- actor.forget("hasPublishedDid")
+ @Given("{actor} creates unpublished DID for '{}'")
+ fun agentCreatesUnpublishedDid(actor: Actor, didType: DidType) {
+ createDid(actor, didType, didType.documentTemplate)
}
@When("{actor} prepares a custom PRISM DID")
fun actorPreparesCustomDid(actor: Actor) {
- val customDid = DidPurpose.CUSTOM
+ val customDid = CUSTOM.documentTemplate
actor.remember("customDid", customDid)
}
@When("{actor} adds a '{curve}' key for '{purpose}' purpose with '{}' name to the custom PRISM DID")
fun actorAddsKeyToCustomDid(actor: Actor, curve: Curve, purpose: Purpose, name: String) {
- val customDid = actor.recall("customDid")
- customDid.publicKeys.add(ManagedDIDKeyTemplate(name, purpose, curve))
+ val documentTemplate = actor.recall("customDid")
+ documentTemplate.publicKeys.add(ManagedDIDKeyTemplate(name, purpose, curve))
+ actor.remember("customDid", documentTemplate)
}
@When("{actor} creates the custom PRISM DID")
fun actorCreatesTheCustomPrismDid(actor: Actor) {
- val customDid = actor.recall("customDid")
- agentCreatesUnpublishedDid(actor, customDid)
+ val documentTemplate = actor.recall("customDid")
+ createDid(actor, CUSTOM, documentTemplate)
}
@When("{actor} publishes DID to ledger")
@@ -131,4 +115,38 @@ class PublishDidSteps {
Ensure.that(didResolutionResult.didDocumentMetadata.deactivated!!).isFalse(),
)
}
+
+ private fun actualDidHasSamePurpose(agent: Actor, didType: DidType): Boolean {
+ val actualPurpose: DidType = agent.recall("didPurpose") ?: return false
+ return actualPurpose == didType
+ }
+
+ private fun createDid(actor: Actor, didType: DidType, documentTemplate: DidDocumentTemplate) {
+ val createDidRequest = CreateManagedDidRequest(
+ CreateManagedDidRequestDocumentTemplate(
+ publicKeys = documentTemplate.publicKeys,
+ services = documentTemplate.services,
+ ),
+ )
+
+ actor.attemptsTo(
+ Post.to("/did-registrar/dids").body(createDidRequest),
+ Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_CREATED),
+ )
+
+ val managedDid = SerenityRest.lastResponse().get()
+
+ actor.attemptsTo(
+ Ensure.that(managedDid.longFormDid!!).isNotEmpty(),
+ Get.resource("/did-registrar/dids/${managedDid.longFormDid}"),
+ Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_OK),
+ )
+
+ val did = SerenityRest.lastResponse().get()
+
+ actor.remember("longFormDid", managedDid.longFormDid)
+ actor.remember("shortFormDid", did.did)
+ actor.remember("didPurpose", didType)
+ actor.forget("hasPublishedDid")
+ }
}
diff --git a/tests/integration-tests/src/test/kotlin/steps/multitenancy/WalletsSteps.kt b/tests/integration-tests/src/test/kotlin/steps/multitenancy/WalletsSteps.kt
index c2eb65cebb..9fbf303e51 100644
--- a/tests/integration-tests/src/test/kotlin/steps/multitenancy/WalletsSteps.kt
+++ b/tests/integration-tests/src/test/kotlin/steps/multitenancy/WalletsSteps.kt
@@ -41,7 +41,7 @@ class WalletsSteps {
return SerenityRest.lastResponse().get()
}
- @When("{actor} creates new wallet with name {string}")
+ @When("{actor} creates new wallet with name '{}'")
fun iCreateNewWalletWithName(acme: Actor, name: String) {
val wallet = createNewWallet(acme, name)
acme.attemptsTo(
@@ -88,7 +88,7 @@ class WalletsSteps {
)
}
- @Then("{actor} should have a wallet with name {string}")
+ @Then("{actor} should have a wallet with name '{}'")
fun iShouldHaveAWalletWithName(acme: Actor, name: String) {
acme.attemptsTo(
Get.resource("/wallets/${acme.recall("walletId")}")
diff --git a/tests/integration-tests/src/test/kotlin/steps/oid4vci/IssueCredentialSteps.kt b/tests/integration-tests/src/test/kotlin/steps/oid4vci/IssueCredentialSteps.kt
index 6a2e906361..e639fda97a 100644
--- a/tests/integration-tests/src/test/kotlin/steps/oid4vci/IssueCredentialSteps.kt
+++ b/tests/integration-tests/src/test/kotlin/steps/oid4vci/IssueCredentialSteps.kt
@@ -28,7 +28,7 @@ import java.net.URI
import java.net.URL
class IssueCredentialSteps {
- @When("{actor} creates an offer using {string} configuration with {string} form DID")
+ @When("{actor} creates an offer using '{}' configuration with '{}' form DID")
fun issuerCreateCredentialOffer(issuer: Actor, configurationId: String, didForm: String) {
val credentialIssuer = issuer.recall("oid4vciCredentialIssuer")
val claims = linkedMapOf(
diff --git a/tests/integration-tests/src/test/kotlin/steps/oid4vci/ManageCredentialConfigSteps.kt b/tests/integration-tests/src/test/kotlin/steps/oid4vci/ManageCredentialConfigSteps.kt
index 8a53c311f9..7dbc0f41f6 100644
--- a/tests/integration-tests/src/test/kotlin/steps/oid4vci/ManageCredentialConfigSteps.kt
+++ b/tests/integration-tests/src/test/kotlin/steps/oid4vci/ManageCredentialConfigSteps.kt
@@ -22,7 +22,7 @@ import org.hyperledger.identus.client.models.IssuerMetadata
import java.util.UUID
class ManageCredentialConfigSteps {
- @Given("{actor} has {string} credential configuration created from {}")
+ @Given("{actor} has '{}' credential configuration created from '{}'")
fun issuerHasExistingCredentialConfig(issuer: Actor, configurationId: String, schema: CredentialSchema) {
ManageIssuerSteps().issuerHasExistingCredentialIssuer(issuer)
val credentialIssuer = issuer.recall("oid4vciCredentialIssuer")
@@ -34,7 +34,7 @@ class ManageCredentialConfigSteps {
}
}
- @When("{actor} uses {} to create a credential configuration {string}")
+ @When("{actor} uses '{}' to create a credential configuration '{}'")
fun issuerCreateCredentialConfiguration(issuer: Actor, schema: CredentialSchema, configurationId: String) {
val credentialIssuer = issuer.recall("oid4vciCredentialIssuer")
val schemaGuid = issuer.recall(schema.name)
@@ -52,7 +52,7 @@ class ManageCredentialConfigSteps {
)
}
- @When("{actor} deletes {string} credential configuration")
+ @When("{actor} deletes '{}' credential configuration")
fun issuerDeletesCredentialConfiguration(issuer: Actor, configurationId: String) {
val credentialIssuer = issuer.recall("oid4vciCredentialIssuer")
issuer.attemptsTo(
@@ -61,7 +61,7 @@ class ManageCredentialConfigSteps {
)
}
- @When("{actor} deletes a non existent {} credential configuration")
+ @When("{actor} deletes a non existent '{}' credential configuration")
fun issuerDeletesANonExistentCredentialConfiguration(issuer: Actor, configurationId: String) {
val credentialIssuer = issuer.recall("oid4vciCredentialIssuer")
issuer.attemptsTo(
@@ -75,7 +75,7 @@ class ManageCredentialConfigSteps {
issuer.remember("credentialConfiguration", credentialConfiguration)
}
- @When("{actor} uses {} issuer id for credential configuration")
+ @When("{actor} uses '{}' issuer id for credential configuration")
fun issuerUsesIssuerId(issuer: Actor, issuerId: String) {
if (issuerId == "existing") {
val credentialIssuer = issuer.recall("oid4vciCredentialIssuer")
@@ -129,7 +129,7 @@ class ManageCredentialConfigSteps {
)
}
- @Then("{actor} sees the {string} configuration on IssuerMetadata endpoint")
+ @Then("{actor} sees the '{}' configuration on IssuerMetadata endpoint")
fun issuerSeesCredentialConfiguration(issuer: Actor, configurationId: String) {
val credentialIssuer = issuer.recall("oid4vciCredentialIssuer")
issuer.attemptsTo(
@@ -143,7 +143,7 @@ class ManageCredentialConfigSteps {
)
}
- @Then("{actor} cannot see the {string} configuration on IssuerMetadata endpoint")
+ @Then("{actor} cannot see the '{}' configuration on IssuerMetadata endpoint")
fun issuerCannotSeeCredentialConfiguration(issuer: Actor, configurationId: String) {
val credentialIssuer = issuer.recall("oid4vciCredentialIssuer")
issuer.attemptsTo(
diff --git a/tests/integration-tests/src/test/kotlin/steps/proofs/JwtProofSteps.kt b/tests/integration-tests/src/test/kotlin/steps/proofs/JwtProofSteps.kt
index 78985e62b0..7e70708b41 100644
--- a/tests/integration-tests/src/test/kotlin/steps/proofs/JwtProofSteps.kt
+++ b/tests/integration-tests/src/test/kotlin/steps/proofs/JwtProofSteps.kt
@@ -1,5 +1,6 @@
package steps.proofs
+import common.CredentialSchema
import interactions.*
import io.cucumber.java.en.When
import io.iohk.atala.automation.extensions.get
@@ -15,6 +16,31 @@ class JwtProofSteps {
@When("{actor} sends a request for jwt proof presentation to {actor}")
fun verifierSendsARequestForJwtProofPresentationToHolder(verifier: Actor, holder: Actor) {
val verifierConnectionToHolder = verifier.recall("connection-with-${holder.name}").connectionId
+ val presentationRequest = RequestPresentationInput(
+ connectionId = verifierConnectionToHolder,
+ options = Options(
+ challenge = "11c91493-01b3-4c4d-ac36-b336bab5bddf",
+ domain = "https://example-verifier.com",
+ ),
+ proofs = emptyList(),
+ )
+ verifier.attemptsTo(
+ Post.to("/present-proof/presentations").body(presentationRequest),
+ Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_CREATED),
+ )
+ val presentationStatus = SerenityRest.lastResponse().get()
+ verifier.remember("thid", presentationStatus.thid)
+ holder.remember("thid", presentationStatus.thid)
+ }
+
+ @When("{actor} sends a request for jwt proof from trustedIssuer {actor} using {} schema presentation to {actor}")
+ fun verifierSendsARequestForJwtProofPresentationToHolderUsingSchemaFromTrustedIssuer(verifier: Actor, issuer: Actor, schema: CredentialSchema, holder: Actor) {
+ val verifierConnectionToHolder = verifier.recall("connection-with-${holder.name}").connectionId
+ val trustIssuer = issuer.recall("longFormDid")
+ val baseUrl = issuer.recall("baseUrl")
+ val schemaGuid = issuer.recall(schema.name)!!
+ val schemaId = "$baseUrl/schema-registry/schemas/$schemaGuid"
+
val presentationRequest = RequestPresentationInput(
connectionId = verifierConnectionToHolder,
options = Options(
@@ -23,8 +49,8 @@ class JwtProofSteps {
),
proofs = listOf(
ProofRequestAux(
- schemaId = "https://schema.org/Person",
- trustIssuers = listOf("did:web:atalaprism.io/users/testUser"),
+ schemaId = schemaId,
+ trustIssuers = listOf(trustIssuer),
),
),
)
diff --git a/tests/integration-tests/src/test/kotlin/steps/schemas/CredentialSchemasSteps.kt b/tests/integration-tests/src/test/kotlin/steps/schemas/CredentialSchemasSteps.kt
index ae14368831..37511cd35f 100644
--- a/tests/integration-tests/src/test/kotlin/steps/schemas/CredentialSchemasSteps.kt
+++ b/tests/integration-tests/src/test/kotlin/steps/schemas/CredentialSchemasSteps.kt
@@ -16,7 +16,7 @@ import java.util.UUID
class CredentialSchemasSteps {
- @Given("{actor} has published {} schema")
+ @Given("{actor} has published '{}' schema")
fun agentHasAPublishedSchema(agent: Actor, schema: CredentialSchema) {
if (agent.recallAll().containsKey(schema.name)) {
return
@@ -24,7 +24,7 @@ class CredentialSchemasSteps {
agentCreatesANewCredentialSchema(agent, schema)
}
- @When("{actor} creates a new credential {} schema")
+ @When("{actor} creates a new credential '{}' schema")
fun agentCreatesANewCredentialSchema(actor: Actor, schema: CredentialSchema) {
actor.attemptsTo(
Post.to("/schema-registry/schemas").body(
diff --git a/tests/integration-tests/src/test/kotlin/steps/verification/VcVerificationSteps.kt b/tests/integration-tests/src/test/kotlin/steps/verification/VcVerificationSteps.kt
index 32f285a197..174aed265d 100644
--- a/tests/integration-tests/src/test/kotlin/steps/verification/VcVerificationSteps.kt
+++ b/tests/integration-tests/src/test/kotlin/steps/verification/VcVerificationSteps.kt
@@ -47,7 +47,7 @@ class VcVerificationSteps {
holder.remember("issuerDid", "did:prism:issuer")
}
- @Given("{actor} has a {} problem in the Verifiable Credential")
+ @Given("{actor} has a '{}' problem in the Verifiable Credential")
fun holderHasProblemInTheVerifiableCredential(holder: Actor, problem: JwtCredentialProblem) {
val jwt = problem.jwt()
holder.remember("jwt", jwt)
@@ -64,7 +64,7 @@ class VcVerificationSteps {
holder.remember("checks", checks)
}
- @Then("{actor} should see that verification has failed with {} problem")
+ @Then("{actor} should see that verification has failed with '{}' problem")
fun holderShouldSeeThatVerificationHasFailedWithProblem(holder: Actor, problem: JwtCredentialProblem) {
}
diff --git a/tests/integration-tests/src/test/resources/features/connection/connection.feature b/tests/integration-tests/src/test/resources/features/connection/connection.feature
index 329f9115bd..0b742d2fb7 100644
--- a/tests/integration-tests/src/test/resources/features/connection/connection.feature
+++ b/tests/integration-tests/src/test/resources/features/connection/connection.feature
@@ -1,9 +1,9 @@
@connection @create
Feature: Agents connection
-Scenario: Establish a connection between two agents
- When Issuer generates a connection invitation to Holder
- And Holder sends a connection request to Issuer
- And Issuer receives the connection request and sends back the response
- And Holder receives the connection response
- Then Issuer and Holder have a connection
+ Scenario: Establish a connection between two agents
+ When Issuer generates a connection invitation to Holder
+ And Holder sends a connection request to Issuer
+ And Issuer receives the connection request and sends back the response
+ And Holder receives the connection response
+ Then Issuer and Holder have a connection
diff --git a/tests/integration-tests/src/test/resources/features/credential/anoncred/issuance.feature b/tests/integration-tests/src/test/resources/features/credential/anoncred/issuance.feature
index 712d6d7db6..3011d2cb2e 100644
--- a/tests/integration-tests/src/test/resources/features/credential/anoncred/issuance.feature
+++ b/tests/integration-tests/src/test/resources/features/credential/anoncred/issuance.feature
@@ -3,8 +3,8 @@ Feature: Issue Anoncred credential
Background:
Given Issuer and Holder have an existing connection
- And Issuer has a published DID for ANONCRED
- And Holder has an unpublished DID for ANONCRED
+ And Issuer has a published DID for 'ANONCRED'
+ And Holder has an unpublished DID for 'ANONCRED'
Scenario: Issuing anoncred with published PRISM DID
Given Issuer has an anoncred schema definition
diff --git a/tests/integration-tests/src/test/resources/features/credential/anoncred/present_proof.feature b/tests/integration-tests/src/test/resources/features/credential/anoncred/present_proof.feature
index 8bc05395c0..539bc1f0f7 100644
--- a/tests/integration-tests/src/test/resources/features/credential/anoncred/present_proof.feature
+++ b/tests/integration-tests/src/test/resources/features/credential/anoncred/present_proof.feature
@@ -4,8 +4,8 @@ Feature: Present Proof Protocol
Scenario: Holder presents anoncreds credential proof to verifier
Given Issuer and Holder have an existing connection
And Verifier and Holder have an existing connection
- And Issuer has a published DID for ANONCRED
- And Holder has an unpublished DID for ANONCRED
+ And Issuer has a published DID for 'ANONCRED'
+ And Holder has an unpublished DID for 'ANONCRED'
And Issuer has an anoncred schema definition
And Issuer offers anoncred to Holder
And Holder receives the credential offer
diff --git a/tests/integration-tests/src/test/resources/features/credential/jwt/issuance.feature b/tests/integration-tests/src/test/resources/features/credential/jwt/issuance.feature
index 6258cf5fdb..5e15b98f8f 100644
--- a/tests/integration-tests/src/test/resources/features/credential/jwt/issuance.feature
+++ b/tests/integration-tests/src/test/resources/features/credential/jwt/issuance.feature
@@ -1,61 +1,73 @@
@jwt @issuance
Feature: Issue JWT credential
-
- Scenario: Issuing jwt credential with published PRISM DID
+ Scenario Outline: Issuing jwt credential using assertion
Given Issuer and Holder have an existing connection
- And Issuer has a published DID for JWT
- And Holder has an unpublished DID for JWT
- When Issuer offers a jwt credential to Holder with "short" form DID
+ And Holder creates unpublished DID for 'JWT'
+ When Issuer prepares a custom PRISM DID
+ And Issuer adds a '' key for 'assertionMethod' purpose with '' name to the custom PRISM DID
+ And Issuer creates the custom PRISM DID
+ And Issuer publishes DID to ledger
+ When Issuer offers a jwt credential to Holder with 'short' form DID using issuingKid ''
And Holder receives the credential offer
- And Holder accepts jwt credential offer
+ And Holder accepts jwt credential offer using 'auth-1' key id
And Issuer issues the credential
Then Holder receives the issued credential
+ When Issuer revokes the credential issued to Holder
+ Then Issuer should see the credential was revoked
+ When Issuer sends a request for jwt proof presentation to Holder
+ And Holder receives the presentation proof request
+ And Holder makes the jwt presentation of the proof
+ Then Issuer sees the proof returned verification failed
+ Examples:
+ | assertionMethod | assertionName |
+ | secp256k1 | assert-1 |
+ | ed25519 | assert-1 |
- Scenario: Issuing jwt credential with published PRISM DID using Ed25519
+ Scenario: Issuing jwt credential with published PRISM DID
Given Issuer and Holder have an existing connection
- And Issuer has a published DID for JWT
- And Holder has an unpublished DID for JWT
- When Issuer offers a jwt credential to Holder with "short" form DID using issuingKid "assertion-2"
+ And Issuer has a published DID for 'JWT'
+ And Holder has an unpublished DID for 'JWT'
+ When Issuer offers a jwt credential to Holder with 'short' form DID
And Holder receives the credential offer
- And Holder accepts jwt credential offer with keyId "auth-2"
+ And Holder accepts jwt credential offer using 'auth-1' key id
And Issuer issues the credential
Then Holder receives the issued credential
Scenario: Issuing jwt credential with a schema
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 using STUDENT_SCHEMA schema
+ 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 using 'STUDENT_SCHEMA' schema
And Holder receives the credential offer
- And Holder accepts jwt credential offer
+ And Holder accepts jwt credential offer using 'auth-1' key id
And Issuer issues the credential
Then Holder receives the issued credential
Scenario: Issuing jwt credential with wrong claim structure for schema
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 with wrong claims structure using STUDENT_SCHEMA schema
+ 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 with wrong claims structure using 'STUDENT_SCHEMA' schema
Then Issuer should see that credential issuance has failed
Scenario: Issuing jwt credential with unpublished PRISM DID
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 offers a jwt credential to Holder with "long" form DID
+ And Issuer has an unpublished DID for 'JWT'
+ And Holder has an unpublished DID for 'JWT'
+ And Issuer offers a jwt credential to Holder with 'long' form DID
And Holder receives the credential offer
- And Holder accepts jwt credential offer
+ And Holder accepts jwt credential offer using 'auth-1' key id
And Issuer issues the credential
Then Holder receives the issued credential
Scenario: Connectionless issuance of JWT credential using OOB invitation
- Given Issuer has a published DID for JWT
- And Holder has an unpublished DID for JWT
- When Issuer creates a "JWT" credential offer invitation with "short" form DID
+ Given Issuer has a published DID for 'JWT'
+ And Holder has an unpublished DID for 'JWT'
+ When Issuer creates a 'JWT' credential offer invitation with 'short' form DID
And Holder accepts the credential offer invitation from Issuer
- And Holder accepts jwt credential offer
+ And Holder accepts jwt credential offer using 'auth-1' key id
And Issuer issues the credential
- Then Holder receives the issued credential
\ No newline at end of file
+ Then Holder receives the issued credential
diff --git a/tests/integration-tests/src/test/resources/features/credential/jwt/present_proof.feature b/tests/integration-tests/src/test/resources/features/credential/jwt/present_proof.feature
index 43612873d6..8c627d03d9 100644
--- a/tests/integration-tests/src/test/resources/features/credential/jwt/present_proof.feature
+++ b/tests/integration-tests/src/test/resources/features/credential/jwt/present_proof.feature
@@ -25,10 +25,48 @@ Feature: Present Proof Protocol
And Holder rejects the proof
Then Holder sees the proof is rejected
+ Scenario Outline: Verifying jwt credential using assertion
+ Given Issuer and Holder have an existing connection
+ And Verifier and Holder have an existing connection
+ And Holder creates unpublished DID for 'JWT'
+ When Issuer prepares a custom PRISM DID
+ And Issuer adds a '' key for 'assertionMethod' purpose with '' name to the custom PRISM DID
+ And Issuer creates the custom PRISM DID
+ When Issuer offers a jwt credential to Holder with 'long' form DID using issuingKid ''
+ And Holder receives the credential offer
+ And Holder accepts jwt credential offer using 'auth-1' key id
+ And Issuer issues the credential
+ Then Holder receives the issued credential
+ When Verifier sends a request for jwt proof presentation to Holder
+ And Holder receives the presentation proof request
+ And Holder makes the jwt presentation of the proof
+ Then Verifier has the proof verified
+ Examples:
+ | assertionMethod | assertionName |
+ | secp256k1 | assert-1 |
+ | ed25519 | assert-1 |
+
Scenario: Connectionless Verification Holder presents jwt credential proof to verifier
Given Holder has a jwt issued credential from Issuer
When Verifier creates a OOB Invitation request for JWT proof presentation
And Holder accepts the OOB invitation request for JWT proof presentation from Verifier
And Holder receives the presentation proof request
And Holder makes the jwt presentation of the proof
- Then Verifier has the proof verified
\ No newline at end of file
+ Then Verifier has the proof verified
+
+ Scenario: Verifier request for jwt proof presentation to Holder from trusted issuer using specified schema
+ Given Verifier and Holder have an existing connection
+ And Holder has a jwt issued credential with 'STUDENT_SCHEMA' schema from Issuer
+ When Verifier sends a request for jwt proof from trustedIssuer Issuer using STUDENT_SCHEMA schema presentation to Holder
+ And Holder receives the presentation proof request
+ And Holder makes the jwt presentation of the proof
+ Then Verifier has the proof verified
+
+ Scenario: Verifier request for jwt proof presentation to Holder from trusted issuer using specified schema
+ Given Verifier and Holder have an existing connection
+ And Holder has a jwt issued credential with 'STUDENT_SCHEMA' schema from Issuer
+ And Holder has a jwt issued credential with 'EMPLOYEE_SCHEMA' schema from Issuer
+ When Verifier sends a request for jwt proof from trustedIssuer Issuer using STUDENT_SCHEMA schema presentation to Holder
+ And Holder receives the presentation proof request
+ And Holder makes the jwt presentation of the proof
+ Then Verifier sees the proof returned verification failed
diff --git a/tests/integration-tests/src/test/resources/features/credential/jwt/revocation.feature b/tests/integration-tests/src/test/resources/features/credential/jwt/revocation.feature
index 508380402d..284f008a60 100644
--- a/tests/integration-tests/src/test/resources/features/credential/jwt/revocation.feature
+++ b/tests/integration-tests/src/test/resources/features/credential/jwt/revocation.feature
@@ -1,10 +1,8 @@
@jwt @revocation
Feature: JWT Credential revocation
- Background:
- Given Holder has a jwt issued credential from Issuer
-
Scenario: Revoke jwt issued credential
+ Given Holder has a jwt issued credential from Issuer
When Issuer revokes the credential issued to Holder
Then Issuer should see the credential was revoked
When Issuer sends a request for jwt proof presentation to Holder
@@ -13,6 +11,7 @@ Feature: JWT Credential revocation
Then Issuer sees the proof returned verification failed
Scenario: Holder tries to revoke jwt credential from issuer
+ Given Holder has a jwt issued credential from Issuer
When Holder tries to revoke credential from Issuer
And Issuer sends a request for jwt proof presentation to Holder
And Holder receives the presentation proof request
diff --git a/tests/integration-tests/src/test/resources/features/credential/sdjwt/issuance.feature b/tests/integration-tests/src/test/resources/features/credential/sdjwt/issuance.feature
index a96c24f04f..2edc63f073 100644
--- a/tests/integration-tests/src/test/resources/features/credential/sdjwt/issuance.feature
+++ b/tests/integration-tests/src/test/resources/features/credential/sdjwt/issuance.feature
@@ -1,21 +1,28 @@
@sdjwt @issuance
Feature: Issue SD-JWT credential
- Scenario: Issuing sd-jwt credential
+ Scenario Outline: Issuing sd-jwt credential
Given Issuer and Holder have an existing connection
- And Issuer has a published DID for SD_JWT
- And Holder has an unpublished DID for SD_JWT
+ And Holder has an unpublished DID for 'SD_JWT'
+ When Issuer prepares a custom PRISM DID
+ And Issuer adds a '' key for 'assertionMethod' purpose with '' name to the custom PRISM DID
+ And Issuer adds a '' key for 'authentication' purpose with '' name to the custom PRISM DID
+ And Issuer creates the custom PRISM DID
+ And Issuer publishes DID to ledger
When Issuer offers a sd-jwt credential to Holder
And Holder receives the credential offer
And Holder accepts credential offer for sd-jwt
And Issuer issues the credential
Then Holder receives the issued credential
And Holder checks the sd-jwt credential contents
+ Examples:
+ | assertionMethod | assertionName | authentication | authenticationName |
+ | ed25519 | assert-1 | ed25519 | auth-1 |
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 Holder has an unpublished DID for SD_JWT
+ And Issuer has a published DID for 'SD_JWT'
+ And Holder has an unpublished DID for 'SD_JWT'
When Issuer offers a sd-jwt credential to Holder
And Holder receives the credential offer
And Holder accepts credential offer for sd-jwt with 'auth-1' key binding
@@ -24,25 +31,11 @@ Feature: Issue SD-JWT credential
Then Holder checks the sd-jwt credential contents with holder binding
Scenario: Connectionless issuance of sd-jwt credential with holder binding
- And Issuer has a published DID for SD_JWT
- And Holder has an unpublished DID for SD_JWT
- When Issuer creates a "SDJWT" credential offer invitation with "short" form DID
+ And Issuer has a published DID for 'SD_JWT'
+ And Holder has an unpublished DID for 'SD_JWT'
+ When Issuer creates a 'SDJWT' credential offer invitation with 'short' form DID
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
Then Holder receives the issued credential
Then Holder checks the sd-jwt credential contents with holder binding
-
-
-# Scenario: Issuing sd-jwt with wrong algorithm
-# Given Issuer and Holder have an existing connection
-# When Issuer prepares a custom PRISM DID
-# And Issuer adds a 'secp256k1' key for 'assertionMethod' purpose with 'assert-1' name to the custom PRISM DID
-# And Issuer adds a 'secp256k1' key for 'authentication' purpose with 'auth-1' name to the custom PRISM DID
-# And Issuer creates the custom PRISM DID
-# And Holder has an unpublished DID for SD_JWT
-# And Issuer offers a sd-jwt credential to Holder
-# And Holder receives the credential offer
-# And Holder accepts credential offer for sd-jwt
-# And Issuer tries to issue the credential
-# Then Issuer should see that credential issuance has failed
diff --git a/tests/integration-tests/src/test/resources/features/credential/sdjwt/present_proof.feature b/tests/integration-tests/src/test/resources/features/credential/sdjwt/present_proof.feature
index 96e8f4e961..d0d3ca9dd5 100644
--- a/tests/integration-tests/src/test/resources/features/credential/sdjwt/present_proof.feature
+++ b/tests/integration-tests/src/test/resources/features/credential/sdjwt/present_proof.feature
@@ -25,7 +25,7 @@ Feature: Present SD-JWT Proof Protocol
| Verifier |
| Issuer |
- Scenario Outline: Holder presents sd-jwt proof to
+ Scenario Outline: Holder presents sd-jwt out-of-band proof to
Given Holder has a sd-jwt issued credential from Issuer
When creates a OOB Invitation request for sd-jwt proof presentation requesting [firstName] claims
And Holder accepts the OOB invitation request for JWT proof presentation from
diff --git a/tests/integration-tests/src/test/resources/features/did/create_did.feature b/tests/integration-tests/src/test/resources/features/did/create_did.feature
index 55ebe81a21..172fc301b0 100644
--- a/tests/integration-tests/src/test/resources/features/did/create_did.feature
+++ b/tests/integration-tests/src/test/resources/features/did/create_did.feature
@@ -1,7 +1,7 @@
@DLT @did @create
Feature: Create and publish DID
- Scenario Outline: Create PRISM DID
+ Scenario Outline: Create PRISM DID with for
When Issuer creates PRISM DID with key having purpose
Then He sees PRISM DID was created successfully
And He sees PRISM DID data was stored correctly with and
@@ -13,7 +13,7 @@ Feature: Create and publish DID
| Ed25519 | assertionMethod |
| X25519 | keyAgreement |
- Scenario Outline: Create PRISM DID with disallowed key purpose
+ Scenario Outline: Create PRISM DID with for should not work
When Issuer creates PRISM DID with key having purpose
Then He sees PRISM DID was not successfully created
Examples:
@@ -23,6 +23,6 @@ Feature: Create and publish DID
| X25519 | assertionMethod |
Scenario: Successfully publish DID to ledger
- Given Issuer creates unpublished DID
+ Given Issuer creates empty unpublished DID
When He publishes DID to ledger
Then He resolves DID document corresponds to W3C standard
diff --git a/tests/integration-tests/src/test/resources/features/did/deactivate_did.feature b/tests/integration-tests/src/test/resources/features/did/deactivate_did.feature
index 13b3ea03e3..37a1c3bebb 100644
--- a/tests/integration-tests/src/test/resources/features/did/deactivate_did.feature
+++ b/tests/integration-tests/src/test/resources/features/did/deactivate_did.feature
@@ -2,7 +2,7 @@
Feature: Deactivate DID
Scenario: Deactivate DID
- Given Issuer creates unpublished DID
+ Given Issuer creates empty unpublished DID
And Issuer publishes DID to ledger
When Issuer deactivates PRISM DID
Then He sees that PRISM DID is successfully deactivated
diff --git a/tests/integration-tests/src/test/resources/features/did/update_did.feature b/tests/integration-tests/src/test/resources/features/did/update_did.feature
index 9aeb2e122f..6e3166fd78 100644
--- a/tests/integration-tests/src/test/resources/features/did/update_did.feature
+++ b/tests/integration-tests/src/test/resources/features/did/update_did.feature
@@ -2,7 +2,7 @@
Feature: Update DID
Background: Published DID is created
- Given Issuer has a published DID for JWT
+ Given Issuer has a published DID for 'JWT'
Scenario: Update PRISM DID services
When Issuer updates PRISM DID with new services
@@ -17,7 +17,7 @@ Feature: Update DID
Then He sees the PRISM DID should have been updated successfully
And He sees the PRISM DID should have the service removed
- Scenario Outline: Update PRISM DID keys
+ Scenario Outline: Update PRISM DID keys using for
When Issuer updates PRISM DID by adding new key with curve and purpose
Then He sees PRISM DID was successfully updated with new keys of purpose
diff --git a/tests/integration-tests/src/test/resources/features/multitenancy/wallets.feature b/tests/integration-tests/src/test/resources/features/multitenancy/wallets.feature
index f6f0cdf0c7..83ba9f0459 100644
--- a/tests/integration-tests/src/test/resources/features/multitenancy/wallets.feature
+++ b/tests/integration-tests/src/test/resources/features/multitenancy/wallets.feature
@@ -2,8 +2,8 @@
Feature: Wallets management
Scenario Outline: Successful creation of a new wallet
- When Admin creates new wallet with name
- Then Admin should have a wallet with name
+ When Admin creates new wallet with name ''
+ Then Admin should have a wallet with name ''
Examples:
| name |
| "wallet-1" |
diff --git a/tests/integration-tests/src/test/resources/features/oid4vci/issue_jwt.feature b/tests/integration-tests/src/test/resources/features/oid4vci/issue_jwt.feature
index 00c7bf2f45..a48859a8e5 100644
--- a/tests/integration-tests/src/test/resources/features/oid4vci/issue_jwt.feature
+++ b/tests/integration-tests/src/test/resources/features/oid4vci/issue_jwt.feature
@@ -2,20 +2,20 @@
Feature: Issue JWT Credentials using OID4VCI authorization code flow
Background:
- Given Issuer has a published DID for OIDC_JWT
- And Issuer has published STUDENT_SCHEMA schema
+ Given Issuer has a published DID for 'OIDC_JWT'
+ And Issuer has published 'STUDENT_SCHEMA' schema
And Issuer has an existing oid4vci issuer
- And Issuer has "StudentProfile" credential configuration created from STUDENT_SCHEMA
+ And Issuer has 'StudentProfile' credential configuration created from 'STUDENT_SCHEMA'
Scenario: Issuing credential with published PRISM DID
- When Issuer creates an offer using "StudentProfile" configuration with "short" form DID
+ When Issuer creates an offer using 'StudentProfile' configuration with 'short' form DID
And Holder receives oid4vci offer from Issuer
And Holder resolves oid4vci issuer metadata and login via front-end channel
And Holder presents the access token with JWT proof on CredentialEndpoint
Then Holder sees credential issued successfully from CredentialEndpoint
Scenario: Issuing credential with unpublished PRISM DID
- When Issuer creates an offer using "StudentProfile" configuration with "long" form DID
+ When Issuer creates an offer using 'StudentProfile' configuration with 'long' form DID
And Holder receives oid4vci offer from Issuer
And Holder resolves oid4vci issuer metadata and login via front-end channel
And Holder presents the access token with JWT proof on CredentialEndpoint
diff --git a/tests/integration-tests/src/test/resources/features/oid4vci/manage_credential_config.feature b/tests/integration-tests/src/test/resources/features/oid4vci/manage_credential_config.feature
index 669fe6977e..991f93ea24 100644
--- a/tests/integration-tests/src/test/resources/features/oid4vci/manage_credential_config.feature
+++ b/tests/integration-tests/src/test/resources/features/oid4vci/manage_credential_config.feature
@@ -2,22 +2,22 @@
Feature: Manage OID4VCI credential configuration
Background:
- Given Issuer has a published DID for OIDC_JWT
- And Issuer has published STUDENT_SCHEMA schema
+ Given Issuer has a published DID for 'OIDC_JWT'
+ And Issuer has published 'STUDENT_SCHEMA' schema
And Issuer has an existing oid4vci issuer
Scenario: Successfully create credential configuration
- Given Issuer has "StudentProfile" credential configuration created from STUDENT_SCHEMA
- Then Issuer sees the "StudentProfile" configuration on IssuerMetadata endpoint
+ Given Issuer has 'StudentProfile' credential configuration created from 'STUDENT_SCHEMA'
+ Then Issuer sees the 'StudentProfile' configuration on IssuerMetadata endpoint
Scenario: Successfully delete credential configuration
- Given Issuer has "StudentProfile" credential configuration created from STUDENT_SCHEMA
- When Issuer deletes "StudentProfile" credential configuration
- Then Issuer cannot see the "StudentProfile" configuration on IssuerMetadata endpoint
+ Given Issuer has 'StudentProfile' credential configuration created from 'STUDENT_SCHEMA'
+ When Issuer deletes 'StudentProfile' credential configuration
+ Then Issuer cannot see the 'StudentProfile' configuration on IssuerMetadata endpoint
Scenario Outline: Create configuration with expect code
When Issuer creates a new credential configuration request
- And Issuer uses issuer id for credential configuration
+ And Issuer uses '' issuer id for credential configuration
And Issuer adds '' configuration id for credential configuration request
And Issuer adds '' format for credential configuration request
And Issuer adds '' schemaId for credential configuration request
@@ -35,5 +35,5 @@ Feature: Manage OID4VCI credential configuration
| existing | StudentProfile | jwt_vc_json | STUDENT_SCHEMA | 409 | Duplicated credential | duplicated configuration id |
Scenario: Delete non existent credential configuration
- When Issuer deletes a non existent "NonExistentProfile" credential configuration
+ When Issuer deletes a non existent 'NonExistentProfile' credential configuration
Then Issuer should see that create credential configuration has failed with '404' status code and 'There is no credential configuration' detail
diff --git a/tests/integration-tests/src/test/resources/features/oid4vci/manage_issuer.feature b/tests/integration-tests/src/test/resources/features/oid4vci/manage_issuer.feature
index 6259934824..4ba9f9bbf7 100644
--- a/tests/integration-tests/src/test/resources/features/oid4vci/manage_issuer.feature
+++ b/tests/integration-tests/src/test/resources/features/oid4vci/manage_issuer.feature
@@ -18,18 +18,18 @@ Feature: Manage OID4VCI credential issuer
Then Issuer cannot see the oid4vci issuer on the agent
And Issuer cannot see the oid4vci IssuerMetadata endpoint
- Scenario Outline: Create issuer with expect response
+ Scenario Outline: Create issuer with [id=; url=; clientId=; clientSecret=] expect response
When Issuer tries to create oid4vci issuer with '', '', '' and ''
Then Issuer should see the oid4vci '' http status response with '' detail
Examples:
- | id | url | clientId | clientSecret | httpStatus | errorDetail | description |
- | null | null | null | null | 400 | authorizationServer.url | null values |
- | null | malformed | id | secret | 400 | Relative URL 'malformed' is not | malformed url |
- | null | http://example.com | id | null | 400 | authorizationServer.clientSecret | null client secret |
- | null | http://example.com | null | secret | 400 | authorizationServer.clientId | null client id |
- | null | null | id | secret | 400 | authorizationServer.url | null url |
- | 4048ef76-749d-4296-8c6c-07c8a20733a0 | http://example.com | id | secret | 201 | | right values |
- | 4048ef76-749d-4296-8c6c-07c8a20733a0 | http://example.com | id | secret | 500 | | duplicated id |
+ | id | url | clientId | clientSecret | httpStatus | errorDetail |
+ | null | null | null | null | 400 | authorizationServer.url |
+ | null | malformed | id | secret | 400 | Relative URL 'malformed' is not |
+ | null | http://example.com | id | null | 400 | authorizationServer.clientSecret |
+ | null | http://example.com | null | secret | 400 | authorizationServer.clientId |
+ | null | null | id | secret | 400 | authorizationServer.url |
+ | 4048ef76-749d-4296-8c6c-07c8a20733a0 | http://example.com | id | secret | 201 | |
+ | 4048ef76-749d-4296-8c6c-07c8a20733a0 | http://example.com | id | secret | 500 | |
Scenario Outline: Update issuer with expect response
Given Issuer has an existing oid4vci issuer
diff --git a/tests/integration-tests/src/test/resources/features/schemas/credential_schemas.feature b/tests/integration-tests/src/test/resources/features/schemas/credential_schemas.feature
index fdbbbc911f..d06b5a0090 100644
--- a/tests/integration-tests/src/test/resources/features/schemas/credential_schemas.feature
+++ b/tests/integration-tests/src/test/resources/features/schemas/credential_schemas.feature
@@ -2,10 +2,10 @@
Feature: Credential schemas
Background:
- Given Issuer creates unpublished DID
+ Given Issuer creates empty unpublished DID
Scenario: Successful schema creation
- When Issuer creates a new credential STUDENT_SCHEMA schema
+ When Issuer creates a new credential 'STUDENT_SCHEMA' schema
Then He sees new credential schema is available
Scenario Outline: Multiple schema creation
@@ -15,7 +15,7 @@ Feature: Credential schemas
| schemas |
| 4 |
- Scenario Outline: Schema creation should fail for cases
+ Scenario Outline: Schema creation should fail for
When Issuer creates a schema containing '' issue
Then Issuer should see the schema creation failed
Examples:
diff --git a/tests/integration-tests/src/test/resources/features/verificationapi/vc_verification.feature b/tests/integration-tests/src/test/resources/features/verificationapi/vc_verification.feature
index 3db147f66d..6b74dc000c 100644
--- a/tests/integration-tests/src/test/resources/features/verificationapi/vc_verification.feature
+++ b/tests/integration-tests/src/test/resources/features/verificationapi/vc_verification.feature
@@ -1,8 +1,8 @@
@verification @api
-Feature: Vc Verification schemas
+Feature: Verification API
- Scenario: Receive a jwt vc from cloud-agent and verify it
- Given Holder has a jwt issued credential with STUDENT_SCHEMA schema from Issuer
+ Scenario: Verify a jwt credential using verification api
+ Given Holder has a jwt issued credential with 'STUDENT_SCHEMA' schema from Issuer
And Holder uses that JWT VC issued from Issuer for Verification API
And Holder sends the JWT Credential to Issuer Verification API
| ALGORITHM_VERIFICATION | true |
@@ -14,7 +14,7 @@ Feature: Vc Verification schemas
| SEMANTIC_CHECK_OF_CLAIMS | true |
Then Holder should see that all checks have passed
- Scenario: Expected checks for generated JWT VC
+ Scenario: Verify a pre-generated jwt credential using verification api
Given Holder has a JWT VC for Verification API
When Holder sends the JWT Credential to Issuer Verification API
| ALGORITHM_VERIFICATION | true |
@@ -26,11 +26,11 @@ Feature: Vc Verification schemas
| SEMANTIC_CHECK_OF_CLAIMS | true |
Then Holder should see that all checks have passed
- Scenario Outline: Expected failures
- Given Holder has a problem in the Verifiable Credential
+ Scenario Outline: Verify credential with problem
+ Given Holder has a '' problem in the Verifiable Credential
When Holder sends the JWT Credential to Issuer Verification API
| | false |
- Then Holder should see that verification has failed with problem
+ Then Holder should see that verification has failed with '' problem
Examples:
| problem |
| ALGORITHM_VERIFICATION |
@@ -41,7 +41,7 @@ Feature: Vc Verification schemas
| SIGNATURE_VERIFICATION |
| SEMANTIC_CHECK_OF_CLAIMS |
- Scenario Outline: Unsupported verification check should fail
+ Scenario Outline: Unsupported verification check should fail
Given Holder has a JWT VC for Verification API
When Holder sends the JWT Credential to Issuer Verification API
| | false |
diff --git a/tests/performance-tests/agent-performance-tests-k6/src/common/ProofsService.ts b/tests/performance-tests/agent-performance-tests-k6/src/common/ProofsService.ts
index 2624de0713..2be18cce6f 100644
--- a/tests/performance-tests/agent-performance-tests-k6/src/common/ProofsService.ts
+++ b/tests/performance-tests/agent-performance-tests-k6/src/common/ProofsService.ts
@@ -24,14 +24,7 @@ export class ProofsService extends HttpService {
"challenge": "11c91493-01b3-4c4d-ac36-b336bab5bddf",
"domain": "https://example-verifier.com"
},
- "proofs":[
- {
- "schemaId": "https://schema.org/${vu.vu.idInInstance}-${vu.vu.idInTest}-${vu.vu.iterationInScenario}",
- "trustIssuers": [
- "did:web:atalaprism.io/users/testUser"
- ]
- }
- ]
+ "proofs":[]
}`
const res = this.post("present-proof/presentations", payload);
try {