Skip to content

Commit

Permalink
Merge branch 'main' into fix/1484
Browse files Browse the repository at this point in the history
  • Loading branch information
yshyn-iohk authored Jan 14, 2025
2 parents 0a22d9d + 4199fca commit 1da17e8
Show file tree
Hide file tree
Showing 18 changed files with 228 additions and 90 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ jobs:
- name: Publish Cloud-Agent Open API Specification
id: upload-oas
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: cloud-agent-openapi-spec-${{ env.OAS_CHECKSUM}}
path: ./cloud-agent-openapi-spec-${{ env.REVISION_VERSION}}.yaml
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-clients.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:
- name: Download OpenAPI specification
if: ${{ !inputs.releaseTag }}
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: cloud-agent-openapi-spec-${{ inputs.check_sum }}
path: ./cloud-agent/service/api/http
Expand Down
12 changes: 8 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ inThisBuild(
// scalacOptions += "-Ysafe-init",
// scalacOptions += "-Werror", // <=> "-Xfatal-warnings"
scalacOptions += "-Dquill.macro.log=false", // disable quill macro logs // TODO https://github.com/zio/zio-protoquill/issues/470,
scalacOptions ++= Seq("-Xmax-inlines", "50")
scalacOptions ++= Seq("-Xmax-inlines", "50") // increase above 32 (https://github.com/circe/circe/issues/2162)
)
)

Expand Down Expand Up @@ -104,15 +104,19 @@ lazy val D = new {
val zioConcurrent: ModuleID = "dev.zio" %% "zio-concurrent" % V.zio
val zioHttp: ModuleID = "dev.zio" %% "zio-http" % V.zioHttp
val zioKafka: ModuleID = "dev.zio" %% "zio-kafka" % V.zioKafka excludeAll (
ExclusionRule("dev.zio", "zio_3"), ExclusionRule("dev.zio", "zio-streams_3")
ExclusionRule("dev.zio", "zio_3"),
ExclusionRule("dev.zio", "zio-streams_3")
)
val zioCatsInterop: ModuleID = "dev.zio" %% "zio-interop-cats" % V.zioCatsInterop
val zioMetricsConnectorMicrometer: ModuleID = "dev.zio" %% "zio-metrics-connectors-micrometer" % V.zioMetricsConnector
val tapirPrometheusMetrics: ModuleID = "com.softwaremill.sttp.tapir" %% "tapir-prometheus-metrics" % V.tapir
val micrometer: ModuleID = "io.micrometer" % "micrometer-registry-prometheus" % V.micrometer
val micrometerPrometheusRegistry = "io.micrometer" % "micrometer-core" % V.micrometer
val scalaUri = Seq(
"io.lemonlabs" %% "scala-uri" % V.scalaUri exclude ("org.typelevel", "cats-parse_3"), // Exclude cats-parse to avoid deps conflict
"io.lemonlabs" %% "scala-uri" % V.scalaUri exclude (
"org.typelevel",
"cats-parse_3"
), // Exclude cats-parse to avoid deps conflict
"org.typelevel" % "cats-parse_3" % "1.0.0", // Replace with version 1.0.0
)

Expand Down Expand Up @@ -905,7 +909,7 @@ lazy val cloudAgentServer = project
Docker / maintainer := "atala-coredid@iohk.io",
Docker / dockerUsername := Some("hyperledger"), // https://github.com/hyperledger
Docker / dockerRepository := Some("ghcr.io"),
dockerExposedPorts := Seq(8080, 8085, 8090),
dockerExposedPorts := Seq(8085, 8090),
// Official docker image for openjdk 21 with curl and bash
dockerBaseImage := "openjdk:21-jdk",
buildInfoKeys := Seq[BuildInfoKey](name, version, scalaVersion, sbtVersion),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ prismNode {
}
}

featureFlag {
enableAnoncred = false
enableAnoncred = ${?ENABLE_ANONCRED}
}

pollux {
database {
host = "localhost"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,12 @@ object MainApp extends ZIOAppDefault {
.ignore

appConfig <- ZIO.service[AppConfig].provide(SystemModule.configLayer)
flags = appConfig.featureFlag
_ <- Console.printLine(s"""### Feature Flags: ####
| - Support for the credential type JWT VC is ${if (flags.enableJWT) "ENABLED" else "DISABLED"}
| - Support for the credential type SD JWT VC is ${if (flags.enableSDJWT) "ENABLED" else "DISABLED"}
| - Support for the credential type Anoncred is ${if (flags.enableAnoncred) "ENABLED" else "DISABLED"}
|""")
// these services are added to any DID document by default when they are created.
defaultDidDocumentServices = Set(
DidDocumentService(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.hyperledger.identus.shared.db.DbConfig
import org.hyperledger.identus.shared.messaging.MessagingServiceConfig
import zio.config.magnolia.*
import zio.Config
import zio.ZIO

import java.net.URL
import java.time.Duration
Expand All @@ -17,6 +18,7 @@ final case class AppConfig(
agent: AgentConfig,
connect: ConnectConfig,
prismNode: PrismNodeConfig,
featureFlag: FeatureFlagConfig
) {
def validate: Either[String, Unit] =
for {
Expand All @@ -39,6 +41,33 @@ object AppConfig {

}

final case class FeatureFlagConfig(
enableAnoncred: Boolean
) {
def enableJWT: Boolean = true // Hardcoded for now // TODO FeatureNotImplemented
def enableSDJWT: Boolean = true // Hardcoded for now // TODO FeatureNotImplemented

def ifJWTIsEnabled[R, E, A](program: ZIO[R, E, A]) =
if (enableJWT) program else ZIO.logWarning(FeatureFlagConfig.messageIfDisableForJWT)
def ifSDJWTIsEnabled[R, E, A](program: ZIO[R, E, A]) =
if (enableSDJWT) program else ZIO.logWarning(FeatureFlagConfig.messageIfDisableForSDJWT)
def ifAnoncredIsEnabled[R, E, A](program: ZIO[R, E, A]) =
if (enableAnoncred) program else ZIO.logWarning(FeatureFlagConfig.messageIfDisableForAnoncred)

def ifJWTIsDisable[R, E, A](program: ZIO[R, E, A]) =
if (!enableJWT) ZIO.logWarning(FeatureFlagConfig.messageIfDisableForJWT) *> program else ZIO.unit
def ifSDJWTIsDisable[R, E, A](program: ZIO[R, E, A]) =
if (!enableSDJWT) ZIO.logWarning(FeatureFlagConfig.messageIfDisableForSDJWT) *> program else ZIO.unit
def ifAnoncredIsDisable[R, E, A](program: ZIO[R, E, A]) =
if (!enableAnoncred) ZIO.logWarning(FeatureFlagConfig.messageIfDisableForAnoncred) *> program else ZIO.unit
}

object FeatureFlagConfig {
def messageIfDisableForJWT = "Feature Disabled: Credential format JWT VC"
def messageIfDisableForSDJWT = "Feature Disabled: Credential format SD JWT VC"
def messageIfDisableForAnoncred = "Feature Disabled: Credential format Anoncred"
}

final case class VaultConfig(
address: String,
token: Option[String],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,17 +273,20 @@ object IssueBackgroundJobs extends BackgroundJobsHelper {
_
) =>
val holderPendingToGeneratedFlow = for {
walletAccessContext <- ZIO
.fromOption(offer.to)
.mapError(_ => CredentialServiceError.CredentialOfferMissingField(id.value, "recipient"))
.flatMap(buildWalletAccessContextLayer)
result <- for {
credentialService <- ZIO.service[CredentialService]
_ <- credentialService
.generateJWTCredentialRequest(id)
.provideSomeLayer(ZLayer.succeed(walletAccessContext))
} yield ()
} yield result
flags <- ZIO.service[AppConfig].map(_.featureFlag)
ret <- flags.ifJWTIsEnabled(
for {
walletAccessContext <- ZIO
.fromOption(offer.to)
.mapError(_ => CredentialServiceError.CredentialOfferMissingField(id.value, "recipient"))
.flatMap(buildWalletAccessContextLayer)
credentialService <- ZIO.service[CredentialService]
_ <- credentialService
.generateJWTCredentialRequest(id)
.provideSomeLayer(ZLayer.succeed(walletAccessContext))
} yield ()
)
} yield ret

holderPendingToGeneratedFlow @@ HolderPendingToGeneratedSuccess.trackSuccess
@@ HolderPendingToGeneratedFailed.trackError
Expand Down Expand Up @@ -319,18 +322,20 @@ object IssueBackgroundJobs extends BackgroundJobsHelper {
_
) =>
val holderPendingToGeneratedFlow = for {
walletAccessContext <- ZIO
.fromOption(offer.to)
.mapError(_ => CredentialServiceError.CredentialOfferMissingField(id.value, "recipient"))
.flatMap(buildWalletAccessContextLayer)
result <- for {
credentialService <- ZIO.service[CredentialService]
_ <- credentialService
.generateSDJWTCredentialRequest(id)
.provideSomeLayer(ZLayer.succeed(walletAccessContext))
} yield ()
} yield result

flags <- ZIO.service[AppConfig].map(_.featureFlag)
ret <- flags.ifSDJWTIsEnabled(
for {
walletAccessContext <- ZIO
.fromOption(offer.to)
.mapError(_ => CredentialServiceError.CredentialOfferMissingField(id.value, "recipient"))
.flatMap(buildWalletAccessContextLayer)
credentialService <- ZIO.service[CredentialService]
_ <- credentialService
.generateSDJWTCredentialRequest(id)
.provideSomeLayer(ZLayer.succeed(walletAccessContext))
} yield ()
)
} yield ret
holderPendingToGeneratedFlow @@ HolderPendingToGeneratedSuccess.trackSuccess
@@ HolderPendingToGeneratedFailed.trackError
@@ HolderPendingToGeneratedAll
Expand Down Expand Up @@ -365,19 +370,20 @@ object IssueBackgroundJobs extends BackgroundJobsHelper {
_
) =>
val holderPendingToGeneratedFlow = for {
walletAccessContext <- ZIO
.fromOption(offer.to)
.mapError(_ => CredentialServiceError.CredentialOfferMissingField(id.value, "recipient"))
.flatMap(buildWalletAccessContextLayer)

result <- for {
credentialService <- ZIO.service[CredentialService]
_ <- credentialService
.generateAnonCredsCredentialRequest(id)
.provideSomeLayer(ZLayer.succeed(walletAccessContext))
} yield ()
} yield result

flags <- ZIO.service[AppConfig].map(_.featureFlag)
ret <- flags.ifAnoncredIsEnabled(
for {
walletAccessContext <- ZIO
.fromOption(offer.to)
.mapError(_ => CredentialServiceError.CredentialOfferMissingField(id.value, "recipient"))
.flatMap(buildWalletAccessContextLayer)
credentialService <- ZIO.service[CredentialService]
_ <- credentialService
.generateAnonCredsCredentialRequest(id)
.provideSomeLayer(ZLayer.succeed(walletAccessContext))
} yield ()
)
} yield ret
holderPendingToGeneratedFlow @@ HolderPendingToGeneratedSuccess.trackSuccess
@@ HolderPendingToGeneratedFailed.trackError
@@ HolderPendingToGeneratedAll
Expand Down Expand Up @@ -517,15 +523,18 @@ object IssueBackgroundJobs extends BackgroundJobsHelper {
// Set ProtocolState to CredentialGenerated
// TODO Move all logic to service
val issuerPendingToGeneratedFlow = for {
walletAccessContext <- buildWalletAccessContextLayer(issue.from)
result <- (for {
credentialService <- ZIO.service[CredentialService]
config <- ZIO.service[AppConfig]
_ <- credentialService
.generateJWTCredential(id, config.pollux.statusListRegistry.publicEndpointUrl.toExternalForm)
.provideSomeLayer(ZLayer.succeed(walletAccessContext))
} yield ()).mapError(e => (walletAccessContext, e))
} yield result
config <- ZIO.service[AppConfig]
ret <- config.featureFlag.ifJWTIsEnabled(
for {
walletAccessContext <- buildWalletAccessContextLayer(issue.from)
credentialService <- ZIO.service[CredentialService]
_ <- credentialService
.generateJWTCredential(id, config.pollux.statusListRegistry.publicEndpointUrl.toExternalForm)
.provideSomeLayer(ZLayer.succeed(walletAccessContext))
.mapError(e => (walletAccessContext, e))
} yield ()
)
} yield ret

issuerPendingToGeneratedFlow @@ IssuerPendingToGeneratedSuccess.trackSuccess
@@ IssuerPendingToGeneratedFailed.trackError
Expand Down Expand Up @@ -565,15 +574,20 @@ object IssueBackgroundJobs extends BackgroundJobsHelper {
// Set ProtocolState to CredentialGenerated
// TODO Move all logic to service
val issuerPendingToGeneratedFlow = for {
walletAccessContext <- buildWalletAccessContextLayer(issue.from)
result <- (for {
credentialService <- ZIO.service[CredentialService]
config <- ZIO.service[AppConfig]
_ <- credentialService
.generateSDJWTCredential(id, config.pollux.credentialSdJwtExpirationTime)
.provideSomeLayer(ZLayer.succeed(walletAccessContext))
} yield ()).mapError(e => (walletAccessContext, e))
} yield result
config <- ZIO.service[AppConfig]
ret <- config.featureFlag.ifSDJWTIsEnabled(
for {
walletAccessContext <- buildWalletAccessContextLayer(issue.from)
result <- (for {
credentialService <- ZIO.service[CredentialService]
config <- ZIO.service[AppConfig]
_ <- credentialService
.generateSDJWTCredential(id, config.pollux.credentialSdJwtExpirationTime)
.provideSomeLayer(ZLayer.succeed(walletAccessContext))
} yield ()).mapError(e => (walletAccessContext, e))
} yield result
)
} yield ret

issuerPendingToGeneratedFlow @@ IssuerPendingToGeneratedSuccess.trackSuccess
@@ IssuerPendingToGeneratedFailed.trackError
Expand Down Expand Up @@ -609,14 +623,20 @@ object IssueBackgroundJobs extends BackgroundJobsHelper {
_,
) =>
val issuerPendingToGeneratedFlow = for {
walletAccessContext <- buildWalletAccessContextLayer(issue.from)
result <- (for {
credentialService <- ZIO.service[CredentialService]
_ <- credentialService
.generateAnonCredsCredential(id)
.provideSomeLayer(ZLayer.succeed(walletAccessContext))
} yield ()).mapError(e => (walletAccessContext, e))
} yield result
config <- ZIO.service[AppConfig]
ret <-
config.featureFlag.ifAnoncredIsEnabled(
for {
walletAccessContext <- buildWalletAccessContextLayer(issue.from)
result <- (for {
credentialService <- ZIO.service[CredentialService]
_ <- credentialService
.generateAnonCredsCredential(id)
.provideSomeLayer(ZLayer.succeed(walletAccessContext))
} yield ()).mapError(e => (walletAccessContext, e))
} yield result
)
} yield ret

issuerPendingToGeneratedFlow @@ IssuerPendingToGeneratedSuccess.trackSuccess
@@ IssuerPendingToGeneratedFailed.trackError
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -658,16 +658,21 @@ object PresentBackgroundJobs extends BackgroundJobsHelper {
requestPresentation: RequestPresentation,
credentialFormat: CredentialFormat
): ZIO[
CredentialService & DIDService & COMMON_RESOURCES,
AppConfig & CredentialService & DIDService & COMMON_RESOURCES,
ERROR,
Unit
] = {
val result =
credentialFormat match {
case CredentialFormat.JWT => handle_JWT_VC(id, credentialsToUse, requestPresentation)
case CredentialFormat.SDJWT => handle_SD_JWT_VC(id, credentialsToUse, requestPresentation)
case CredentialFormat.AnonCreds => handleAnoncred(id, maybeCredentialsToUseJson, requestPresentation)
val result = for {
flags <- ZIO.service[AppConfig].map(_.featureFlag)
ret <- credentialFormat match {
case CredentialFormat.JWT =>
flags.ifJWTIsEnabled(handle_JWT_VC(id, credentialsToUse, requestPresentation))
case CredentialFormat.SDJWT =>
flags.ifSDJWTIsEnabled(handle_SD_JWT_VC(id, credentialsToUse, requestPresentation))
case CredentialFormat.AnonCreds =>
flags.ifSDJWTIsEnabled(handleAnoncred(id, maybeCredentialsToUseJson, requestPresentation))
}
} yield ret
result @@ metric
}

Expand Down Expand Up @@ -1067,12 +1072,17 @@ object PresentBackgroundJobs extends BackgroundJobsHelper {
Failure,
Unit
] = {
val result =
credentialFormat match {
case CredentialFormat.JWT => handleJWT(id, requestPresentation, presentation, invitation)
case CredentialFormat.SDJWT => handleSDJWT(id, presentation, invitation)
case CredentialFormat.AnonCreds => handleAnoncred(id, requestPresentation, presentation, invitation)
val result = for {
flags <- ZIO.service[AppConfig].map(_.featureFlag)
ret <- credentialFormat match {
case CredentialFormat.JWT =>
flags.ifJWTIsEnabled(handleJWT(id, requestPresentation, presentation, invitation))
case CredentialFormat.SDJWT =>
flags.ifSDJWTIsEnabled(handleSDJWT(id, presentation, invitation))
case CredentialFormat.AnonCreds =>
flags.ifAnoncredIsEnabled(handleAnoncred(id, requestPresentation, presentation, invitation))
}
} yield ret
result @@ metric
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@ object ErrorResponse {
detail = detail
)

def badRequestDisabled(detail: String) =
ErrorResponse(
StatusCode.BadRequest.code,
`type` = "BadRequest",
title = "BadRequest_FeatureDisabled",
detail = Some(detail)
)

def unprocessableEntity(title: String = "UnprocessableEntity", detail: Option[String] = None) =
ErrorResponse(
StatusCode.UnprocessableEntity.code,
Expand Down
Loading

0 comments on commit 1da17e8

Please sign in to comment.