Skip to content

Commit

Permalink
Merge branch 'main' into feat/migrate-from-circe-to-zio-json
Browse files Browse the repository at this point in the history
Signed-off-by: Benjamin Voiturier <[email protected]>
  • Loading branch information
bvoiturier committed Dec 4, 2024
2 parents a097cb4 + c6a3e0c commit c517f9d
Show file tree
Hide file tree
Showing 40 changed files with 580 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ object StatusListCredential {
given stringOrCredentialIssuerDecoder: JsonDecoder[String | CredentialIssuer] =
JsonDecoder[CredentialIssuer]
.map(issuer => issuer: String | CredentialIssuer)
.orElse(JsonDecoder[String].map(schemaId => schemaId: String | CredentialIssuer))
.orElse(JsonDecoder[String].map(issuerId => issuerId: String | CredentialIssuer))

given statusListCredentialEncoder: JsonEncoder[StatusListCredential] =
DeriveJsonEncoder.gen[StatusListCredential]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package org.hyperledger.identus.issue.controller

import org.hyperledger.identus.api.http.ErrorResponse
import org.hyperledger.identus.issue.controller.http.CredentialSchemaRef as HTTPCredentialSchemaRef
import org.hyperledger.identus.pollux.core.model.primitives.UriString
import org.hyperledger.identus.pollux.core.model.schema.{
CredentialSchemaRef as DomainCredentialSchemaRef,
CredentialSchemaRefType
}
import zio.{IO, ZIO}

trait CredentialSchemaReferenceParsingLogic {

// According to VCDM 1.1, the property "credentialSchema" is required to issue JWT, JSON, and JSON-LD credentials.
// The "id" property in the "credentialSchema" object is a URI that points to the schema of the credential.
// The "type" property in the "credentialSchema" object must be "JsonSchemaValidator2018".
// Multiple schemas are not allowed in VCDM 1.1.
def parseCredentialSchemaRef_VCDM1_1(
deprecatedSchemaIdProperty: Option[String | List[String]],
credentialSchemaRefOption: Option[HTTPCredentialSchemaRef]
): IO[ErrorResponse, DomainCredentialSchemaRef] = {
credentialSchemaRefOption match {
case Some(csr) if csr.`type` == "JsonSchemaValidator2018" =>
makeDomainCredentialSchemaRef(csr.id)
case Some(csr) =>
ZIO.fail(ErrorResponse.badRequest(detail = Some(s"Invalid credentialSchema type: ${csr.`type`}.")))
case None =>
handleDeprecatedSchemaId(deprecatedSchemaIdProperty)
.flatMap(makeDomainCredentialSchemaRef)
}
}

def parseSchemaIdForAnonCredsModelV1(
deprecatedSchemaIdProperty: Option[String | List[String]],
schemaIdProperty: Option[String]
): IO[ErrorResponse, UriString] = {
schemaIdProperty
.map(makeUriStringOrErrorResponse)
.getOrElse(handleDeprecatedSchemaId(deprecatedSchemaIdProperty).flatMap(makeUriStringOrErrorResponse))
}

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

private def makeDomainCredentialSchemaRef(input: String): IO[ErrorResponse, DomainCredentialSchemaRef] =
makeUriStringOrErrorResponse(input).map(
DomainCredentialSchemaRef(CredentialSchemaRefType.JsonSchemaValidator2018, _)
)

private def makeUriStringOrErrorResponse(input: String): IO[ErrorResponse, UriString] =
UriString.make(input).toZIO.mapError(uriParseError => ErrorResponse.badRequest(detail = Some(uriParseError)))
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class IssueControllerImpl(
managedDIDService: ManagedDIDService,
appConfig: AppConfig
) extends IssueController
with ControllerHelper {
with ControllerHelper
with CredentialSchemaReferenceParsingLogic {

private case class OfferContext(
pairwiseIssuerDID: DidId,
Expand Down Expand Up @@ -64,16 +65,17 @@ class IssueControllerImpl(
for {
issuingDID <- getIssuingDidFromRequest(request)
_ <- validatePrismDID(issuingDID, allowUnpublished = true, Role.Issuer)
credentialSchemaRef <- parseCredentialSchemaRef_VCDM1_1(
request.schemaId,
request.jwtVcPropertiesV1.map(_.credentialSchema)
)
record <- credentialService
.createJWTIssueCredentialRecord(
pairwiseIssuerDID = offerContext.pairwiseIssuerDID,
pairwiseHolderDID = offerContext.pairwiseHolderDID,
kidIssuer = request.issuingKid,
thid = DidCommID(),
maybeSchemaIds = request.schemaId.map {
case schemaId: String => List(schemaId)
case schemaIds: List[String] => schemaIds
},
credentialSchemaRef = Some(credentialSchemaRef),
claims = request.claims,
validityPeriod = request.validityPeriod,
automaticIssuance = request.automaticIssuance.orElse(Some(true)),
Expand All @@ -88,16 +90,17 @@ class IssueControllerImpl(
for {
issuingDID <- getIssuingDidFromRequest(request)
_ <- validatePrismDID(issuingDID, allowUnpublished = true, Role.Issuer)
credentialSchemaRef <- parseCredentialSchemaRef_VCDM1_1(
request.schemaId,
request.sdJwtVcPropertiesV1.map(_.credentialSchema)
)
record <- credentialService
.createSDJWTIssueCredentialRecord(
pairwiseIssuerDID = offerContext.pairwiseIssuerDID,
pairwiseHolderDID = offerContext.pairwiseHolderDID,
kidIssuer = request.issuingKid,
thid = DidCommID(),
maybeSchemaIds = request.schemaId.map {
case schemaId: String => List(schemaId)
case schemaIds: List[String] => schemaIds
},
credentialSchemaRef = Option(credentialSchemaRef),
claims = request.claims,
validityPeriod = request.validityPeriod,
automaticIssuance = request.automaticIssuance.orElse(Some(true)),
Expand Down
Loading

0 comments on commit c517f9d

Please sign in to comment.