From 234a2725614b05466391894f248c7175fb62c5b6 Mon Sep 17 00:00:00 2001 From: patlo-iog Date: Wed, 6 Mar 2024 11:33:02 +0700 Subject: [PATCH 1/6] fix: allow configurable path convention for vault secrets (#918) Signed-off-by: Pat Losoponkul --- docs/docusaurus/secrets/operation.md | 36 +++++- .../src/main/resources/application.conf | 5 + .../io/iohk/atala/agent/server/Modules.scala | 57 +++++----- .../atala/agent/server/config/AppConfig.scala | 3 +- .../server/AgentInitializationSpec.scala | 1 - .../agent/server/config/AppConfigSpec.scala | 1 + .../agent/walletapi/vault/VaultClient.scala | 106 +++++++++++++++--- .../vault/VaultDIDSecretStorage.scala | 26 +++-- .../vault/VaultGenericSecretStorage.scala | 29 +++-- .../atala/agent/walletapi/vault/package.scala | 7 ++ .../walletapi/benchmark/KeyDerivation.scala | 2 +- .../service/ManagedDIDServiceSpec.scala | 4 +- .../service/WalletManagementServiceSpec.scala | 2 +- .../storage/DIDSecretStorageSpec.scala | 34 +++++- .../storage/GenericSecretStorageSpec.scala | 21 +++- .../storage/WalletSecretStorageSpec.scala | 2 +- .../atala/test/container/VaultLayer.scala | 4 +- .../container/VaultTestContainerSupport.scala | 15 ++- .../containers/VaultContainerCustom.scala | 26 ++++- .../containers/VaultTestContainer.scala | 8 +- 20 files changed, 300 insertions(+), 89 deletions(-) diff --git a/docs/docusaurus/secrets/operation.md b/docs/docusaurus/secrets/operation.md index 62f6088b5c..fd4de5bc84 100644 --- a/docs/docusaurus/secrets/operation.md +++ b/docs/docusaurus/secrets/operation.md @@ -27,15 +27,18 @@ Secret storage supports various backends like the Vault service or Postgres data By default, the backend chosen for secret storage is Vault, which is suitable for production environments. There are multiple supported backend implementations, each catering to specific use cases. -__HashiCorp Vault__ +### HashiCorp Vault When operating in a production environment, the agent has the option to utilize Vault as a secure secret storage backend. This choice is deemed suitable for production because all data is encrypted and it also offers additional security-related capabilities. By default, the agent uses this backend but the option is configurable. To utilize this backend, set the `SECRET_STORAGE_BACKEND` variable to `vault`. + +__Authentication and Authorization__ + The agent expects to read and write secrets to the path `/secret/*`, -to ensure the provisioned permissions. +so ensure the appropriate permissions are provisioned. Example Vault policy @@ -53,7 +56,34 @@ The agent prefers token authentication if provided with multiple authentication Another method is [AppRole authentication](https://developer.hashicorp.com/vault/docs/auth/approle) which is suitable for automatic workflows. To use AppRole authentication, set the environment variable `VAULT_APPROLE_ROLE_ID` and `VAULT_APPROLE_SECRET_ID`. -__Postgres__ +__Storage Backend__ + +HashiCorp Vault supports multiple backends for storage, such as filesystem, Etcd, PostgreSQL, or Integrated Storage (Raft). +Each backend has different properties, which have implications for how secrets can be stored. +The agent logically stores secrets in the following hierarchies. + +``` +# Wallet seed +/secret//seed + +# Peer DID keys +/secret//dids/peer//keys/ + +# Generic secrets +/secret//generic-secrets/ +``` + +Each storage backend has certain limitations, such as size, number of sub-paths, or path length. +Some backends can support path lengths of up to 32,768 characters, while others only allow a few hundred characters. +In some cases, the storage backends might not support the above logical convention due to excessively long paths. + +To address this issue, the agent supports path shortening. +This feature can be toggled by setting the environment variable `VAULT_USE_SEMANTIC_PATH=false`. +When it is disabled, the unbounded portion of the path will be replaced by a SHA-256 digest of the original relative path. +Additionally, the original path will be stored in the secret metadata. + + +### Postgres Postgres is an alternative backend option for secret storage. However, this option must be explicitly chosen and will replace Vault. diff --git a/prism-agent/service/server/src/main/resources/application.conf b/prism-agent/service/server/src/main/resources/application.conf index e8b8588423..697cb6030d 100644 --- a/prism-agent/service/server/src/main/resources/application.conf +++ b/prism-agent/service/server/src/main/resources/application.conf @@ -203,6 +203,11 @@ agent { address = "http://localhost:8200" address = ${?VAULT_ADDR} + # Store secrets in Vault with meaningful convention for path segments. + # Can be disabled for fixed-length secret path if vault storage backend has small limit for path length. + useSemanticPath = true + useSemanticPath = ${?VAULT_USE_SEMANTIC_PATH} + # Vault token authentication. # Can be omitted if other authentication mechanism is provided. token = ${?VAULT_TOKEN} diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/Modules.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/Modules.scala index 5a710cf4e3..68372d2afc 100644 --- a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/Modules.scala +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/Modules.scala @@ -225,42 +225,45 @@ object RepoModule { } yield vaultKVClient } - SystemModule.configLayer >>> vaultClient + SystemModule.configLayer ++ SystemModule.zioHttpClientLayer >>> vaultClient } val allSecretStorageLayer: TaskLayer[DIDSecretStorage & WalletSecretStorage & GenericSecretStorage] = { ZLayer.fromZIO { ZIO .service[AppConfig] - .map(_.agent.secretStorage.backend) - .tap(backend => ZIO.logInfo(s"Using '$backend' as a secret storage backend")) - .flatMap { - case SecretStorageBackend.vault => - ZIO.succeed( - ZLayer.make[DIDSecretStorage & WalletSecretStorage & GenericSecretStorage]( - VaultDIDSecretStorage.layer, - VaultWalletSecretStorage.layer, - VaultGenericSecretStorage.layer, - vaultClientLayer, + .map(_.agent.secretStorage) + .tap(conf => ZIO.logInfo(s"Using '${conf.backend}' as a secret storage backend")) + .flatMap { conf => + val useSemanticPath = conf.vault.map(_.useSemanticPath).getOrElse(true) + conf.backend match { + case SecretStorageBackend.vault => + ZIO.succeed( + ZLayer.make[DIDSecretStorage & WalletSecretStorage & GenericSecretStorage]( + VaultDIDSecretStorage.layer(useSemanticPath), + VaultGenericSecretStorage.layer(useSemanticPath), + VaultWalletSecretStorage.layer, + vaultClientLayer, + ) ) - ) - case SecretStorageBackend.postgres => - ZIO.succeed( - ZLayer.make[DIDSecretStorage & WalletSecretStorage & GenericSecretStorage]( - JdbcDIDSecretStorage.layer, - JdbcWalletSecretStorage.layer, - JdbcGenericSecretStorage.layer, - agentContextAwareTransactorLayer, + case SecretStorageBackend.postgres => + ZIO.succeed( + ZLayer.make[DIDSecretStorage & WalletSecretStorage & GenericSecretStorage]( + JdbcDIDSecretStorage.layer, + JdbcGenericSecretStorage.layer, + JdbcWalletSecretStorage.layer, + agentContextAwareTransactorLayer, + ) ) - ) - case SecretStorageBackend.memory => - ZIO.succeed( - ZLayer.make[DIDSecretStorage & WalletSecretStorage & GenericSecretStorage]( - DIDSecretStorageInMemory.layer, - WalletSecretStorageInMemory.layer, - GenericSecretStorageInMemory.layer + case SecretStorageBackend.memory => + ZIO.succeed( + ZLayer.make[DIDSecretStorage & WalletSecretStorage & GenericSecretStorage]( + DIDSecretStorageInMemory.layer, + GenericSecretStorageInMemory.layer, + WalletSecretStorageInMemory.layer, + ) ) - ) + } } .provide(SystemModule.configLayer) }.flatten diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/config/AppConfig.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/config/AppConfig.scala index d94bcbcdef..d998e11dc4 100644 --- a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/config/AppConfig.scala +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/config/AppConfig.scala @@ -31,7 +31,8 @@ final case class VaultConfig( address: String, token: Option[String], appRoleRoleId: Option[String], - appRoleSecretId: Option[String] + appRoleSecretId: Option[String], + useSemanticPath: Boolean ) { def validate: Either[String, ValidatedVaultConfig] = val tokenConfig = token.map(ValidatedVaultConfig.TokenAuth(address, _)) diff --git a/prism-agent/service/server/src/test/scala/io/iohk/atala/agent/server/AgentInitializationSpec.scala b/prism-agent/service/server/src/test/scala/io/iohk/atala/agent/server/AgentInitializationSpec.scala index c5b8ffa81b..4acb8f88e9 100644 --- a/prism-agent/service/server/src/test/scala/io/iohk/atala/agent/server/AgentInitializationSpec.scala +++ b/prism-agent/service/server/src/test/scala/io/iohk/atala/agent/server/AgentInitializationSpec.scala @@ -1,7 +1,6 @@ package io.iohk.atala.agent.server import io.iohk.atala.agent.server.config.AppConfig -import io.iohk.atala.agent.server.config.VaultConfig import io.iohk.atala.agent.walletapi.crypto.ApolloSpecHelper import io.iohk.atala.agent.walletapi.service.EntityServiceImpl import io.iohk.atala.agent.walletapi.service.WalletManagementService diff --git a/prism-agent/service/server/src/test/scala/io/iohk/atala/agent/server/config/AppConfigSpec.scala b/prism-agent/service/server/src/test/scala/io/iohk/atala/agent/server/config/AppConfigSpec.scala index c2eb57e006..7f31ac6ec8 100644 --- a/prism-agent/service/server/src/test/scala/io/iohk/atala/agent/server/config/AppConfigSpec.scala +++ b/prism-agent/service/server/src/test/scala/io/iohk/atala/agent/server/config/AppConfigSpec.scala @@ -14,6 +14,7 @@ object AppConfigSpec extends ZIOSpecDefault { token = None, appRoleRoleId = None, appRoleSecretId = None, + useSemanticPath = true, ) override def spec = suite("AppConfigSpec")( diff --git a/prism-agent/service/wallet-api/src/main/scala/io/iohk/atala/agent/walletapi/vault/VaultClient.scala b/prism-agent/service/wallet-api/src/main/scala/io/iohk/atala/agent/walletapi/vault/VaultClient.scala index e8d229d894..74d1011534 100644 --- a/prism-agent/service/wallet-api/src/main/scala/io/iohk/atala/agent/walletapi/vault/VaultClient.scala +++ b/prism-agent/service/wallet-api/src/main/scala/io/iohk/atala/agent/walletapi/vault/VaultClient.scala @@ -2,23 +2,28 @@ package io.iohk.atala.agent.walletapi.vault import io.github.jopenlibs.vault.Vault import io.github.jopenlibs.vault.VaultConfig +import io.github.jopenlibs.vault.VaultException +import io.github.jopenlibs.vault.api.Logical +import io.github.jopenlibs.vault.api.LogicalUtilities import io.github.jopenlibs.vault.response.LogicalResponse import zio.* +import zio.http.* +import zio.json.* import java.nio.charset.StandardCharsets import scala.jdk.CollectionConverters.* trait VaultKVClient { def get[T: KVCodec](path: String): Task[Option[T]] - def set[T: KVCodec](path: String, data: T): Task[Unit] + def set[T: KVCodec](path: String, data: T, customMetadata: Map[String, String] = Map.empty): Task[Unit] } -class VaultKVClientImpl(vaultRef: Ref[Vault]) extends VaultKVClient { +class VaultKVClientImpl(vaultRef: Ref[(Vault, VaultConfig)], client: Client) extends VaultKVClient { import VaultKVClientImpl.* override def get[T: KVCodec](path: String): Task[Option[T]] = { for { - vault <- vaultRef.get + vault <- vaultRef.get.map(_._1) maybeData <- ZIO .attemptBlocking( vault @@ -31,10 +36,11 @@ class VaultKVClientImpl(vaultRef: Ref[Vault]) extends VaultKVClient { } yield decodedData } - override def set[T: KVCodec](path: String, data: T): Task[Unit] = { + override def set[T: KVCodec](path: String, data: T, customMetadata: Map[String, String]): Task[Unit] = { val kv = summon[KVCodec[T]].encode(data) for { - vault <- vaultRef.get + vaultWithConfig <- vaultRef.get + (vault, vaultConfig) = vaultWithConfig _ <- ZIO .attemptBlocking { vault @@ -42,26 +48,30 @@ class VaultKVClientImpl(vaultRef: Ref[Vault]) extends VaultKVClient { .write(path, kv.asJava) } .handleVaultError("Error writing a secret to Vault.") + _ <- ExtendedLogical(vaultConfig, client) + .writeMetadata(path, customMetadata) + .when(customMetadata.nonEmpty) } yield () } - } object VaultKVClientImpl { private final case class TokenRefreshState(leaseDuration: Duration) - def fromToken(address: String, token: String): Task[VaultKVClient] = + def fromToken(address: String, token: String): RIO[Client, VaultKVClient] = for { + client <- ZIO.service[Client] vault <- createVaultInstance(address, Some(token)) vaultRef <- Ref.make(vault) - } yield VaultKVClientImpl(vaultRef) + } yield VaultKVClientImpl(vaultRef, client) - def fromAppRole(address: String, roleId: String, secretId: String): Task[VaultKVClient] = + def fromAppRole(address: String, roleId: String, secretId: String): RIO[Client, VaultKVClient] = for { + client <- ZIO.service[Client] vault <- createVaultInstance(address) - vaultRef <- vaultTokenRefreshLogic(vault, address, roleId, secretId) - } yield VaultKVClientImpl(vaultRef) + vaultRef <- vaultTokenRefreshLogic(vault._1, address, roleId, secretId) + } yield VaultKVClientImpl(vaultRef, client) private def vaultTokenRefreshLogic( authVault: Vault, @@ -70,7 +80,7 @@ object VaultKVClientImpl { secretId: String, tokenRefreshBuffer: Duration = 15.seconds, retrySchedule: Schedule[Any, Any, Any] = Schedule.spaced(5.second) && Schedule.recurs(10) - ): Task[Ref[Vault]] = { + ): Task[Ref[(Vault, VaultConfig)]] = { val getToken = ZIO .attempt { val authResponse = authVault.auth().loginByAppRole(roleId, secretId) @@ -100,13 +110,14 @@ object VaultKVClientImpl { } yield vaultRef } - private def createVaultInstance(address: String, token: Option[String] = None): Task[Vault] = + private def createVaultInstance(address: String, token: Option[String] = None): Task[(Vault, VaultConfig)] = ZIO.attempt { - val config = VaultConfig() + val configBuilder = VaultConfig() .engineVersion(2) .address(address) - token.foreach(config.token) - Vault.create(config.build()) + token.foreach(configBuilder.token) + val config = configBuilder.build() + Vault.create(config) -> config } extension [R](resp: RIO[R, LogicalResponse]) { @@ -147,4 +158,67 @@ object VaultKVClientImpl { } } + private final case class WriteMetadataRequest( + custom_metadata: Map[String, String] + ) + + private object WriteMetadataRequest { + given JsonEncoder[WriteMetadataRequest] = JsonEncoder.derived + given JsonDecoder[WriteMetadataRequest] = JsonDecoder.derived + } + + private class ExtendedLogical(config: VaultConfig, client: Client) extends Logical(config) { + // based on https://github.com/jopenlibs/vault-java-driver/blob/e49312a8cbcd14b260dacb2822c19223feb1b7af/src/main/java/io/github/jopenlibs/vault/api/Logical.java#L275 + def writeMetadata(path: String, metadata: Map[String, String]): Task[Unit] = { + val pathSegments = path.split("/") + val pathDepth = config.getPrefixPathDepth() + val adjustedPath = LogicalUtilities.addQualifierToPath(pathSegments.toSeq.asJava, pathDepth, "metadata") + val url = config.getAddress() + "/v1/" + adjustedPath + + val baseHeaders = Headers( + Header.ContentType(MediaType.application.json), + Header.Custom("X-Vault-Request", "true"), + ) + val additionalHeaders = Headers( + Seq( + Option(config.getToken()).map(Header.Custom("X-Vault-Token", _)), + Option(config.getNameSpace()).map(Header.Custom("X-Vault-Namespace", _)), + ).flatten + ) + + for { + url <- ZIO.fromEither(URL.decode(url)).orDie + request = + Request( + url = url, + method = Method.POST, + headers = baseHeaders ++ additionalHeaders, + body = Body.fromString(WriteMetadataRequest(custom_metadata = metadata).toJson) + ) + _ <- ZIO + .scoped(client.request(request)) + .timeoutFail(new RuntimeException("Client request timed out"))(5.seconds) + .flatMap { resp => + if (resp.status.isSuccess) ZIO.unit + else { + resp.body + .asString(StandardCharsets.UTF_8) + .flatMap { body => + ZIO.fail( + VaultException( + s"Expecting HTTP status 2xx, but instead receiving ${resp.status.code}.\n Response body: ${body}", + resp.status.code + ) + ) + } + } + } + .retry { + val maxRetry = Option(config.getMaxRetries()).getOrElse(0) + val retryIntervalMillis = Option(config.getRetryIntervalMilliseconds()).getOrElse(0) + Schedule.recurs(maxRetry) && Schedule.spaced(retryIntervalMillis.millis) + } + } yield () + } + } } diff --git a/prism-agent/service/wallet-api/src/main/scala/io/iohk/atala/agent/walletapi/vault/VaultDIDSecretStorage.scala b/prism-agent/service/wallet-api/src/main/scala/io/iohk/atala/agent/walletapi/vault/VaultDIDSecretStorage.scala index 261032a624..133572740c 100644 --- a/prism-agent/service/wallet-api/src/main/scala/io/iohk/atala/agent/walletapi/vault/VaultDIDSecretStorage.scala +++ b/prism-agent/service/wallet-api/src/main/scala/io/iohk/atala/agent/walletapi/vault/VaultDIDSecretStorage.scala @@ -3,19 +3,22 @@ package io.iohk.atala.agent.walletapi.vault import com.nimbusds.jose.jwk.OctetKeyPair import io.iohk.atala.agent.walletapi.storage.DIDSecretStorage import io.iohk.atala.mercury.model.DidId +import io.iohk.atala.prism.crypto.Sha256 import io.iohk.atala.shared.models.WalletAccessContext import io.iohk.atala.shared.models.WalletId import zio.* -class VaultDIDSecretStorage(vaultKV: VaultKVClient) extends DIDSecretStorage { +import java.nio.charset.StandardCharsets + +class VaultDIDSecretStorage(vaultKV: VaultKVClient, useSemanticPath: Boolean) extends DIDSecretStorage { override def insertKey(did: DidId, keyId: String, keyPair: OctetKeyPair): RIO[WalletAccessContext, Int] = { for { walletId <- ZIO.serviceWith[WalletAccessContext](_.walletId) - path = peerDidKeyPath(walletId)(did, keyId) + (path, metadata) = peerDidKeyPath(walletId)(did, keyId) alreadyExist <- vaultKV.get[OctetKeyPair](path).map(_.isDefined) _ <- vaultKV - .set[OctetKeyPair](path, keyPair) + .set[OctetKeyPair](path, keyPair, metadata) .when(!alreadyExist) .someOrFail(Exception(s"Secret on path $path already exists.")) } yield 1 @@ -24,16 +27,25 @@ class VaultDIDSecretStorage(vaultKV: VaultKVClient) extends DIDSecretStorage { override def getKey(did: DidId, keyId: String): RIO[WalletAccessContext, Option[OctetKeyPair]] = { for { walletId <- ZIO.serviceWith[WalletAccessContext](_.walletId) - path = peerDidKeyPath(walletId)(did, keyId) + (path, _) = peerDidKeyPath(walletId)(did, keyId) keyPair <- vaultKV.get[OctetKeyPair](path) } yield keyPair } - private def peerDidKeyPath(walletId: WalletId)(did: DidId, keyId: String): String = { - s"secret/${walletId.toUUID}/dids/peer/${did.value}/keys/$keyId" + /** @return A tuple of secret path and a secret custom_metadata */ + private def peerDidKeyPath(walletId: WalletId)(did: DidId, keyId: String): (String, Map[String, String]) = { + val basePath = s"${walletBasePath(walletId)}/dids/peer" + val relativePath = s"${did.value}/keys/$keyId" + if (useSemanticPath) { + s"$basePath/$relativePath" -> Map.empty + } else { + val relativePathHash = Sha256.compute(relativePath.getBytes(StandardCharsets.UTF_8)).getHexValue() + s"$basePath/$relativePathHash" -> Map(SEMANTIC_PATH_METADATA_KEY -> relativePath) + } } } object VaultDIDSecretStorage { - def layer: URLayer[VaultKVClient, DIDSecretStorage] = ZLayer.fromFunction(VaultDIDSecretStorage(_)) + def layer(useSemanticPath: Boolean): URLayer[VaultKVClient, DIDSecretStorage] = + ZLayer.fromFunction(VaultDIDSecretStorage(_, useSemanticPath)) } diff --git a/prism-agent/service/wallet-api/src/main/scala/io/iohk/atala/agent/walletapi/vault/VaultGenericSecretStorage.scala b/prism-agent/service/wallet-api/src/main/scala/io/iohk/atala/agent/walletapi/vault/VaultGenericSecretStorage.scala index 6022d138d4..fec9d1870c 100644 --- a/prism-agent/service/wallet-api/src/main/scala/io/iohk/atala/agent/walletapi/vault/VaultGenericSecretStorage.scala +++ b/prism-agent/service/wallet-api/src/main/scala/io/iohk/atala/agent/walletapi/vault/VaultGenericSecretStorage.scala @@ -2,21 +2,24 @@ package io.iohk.atala.agent.walletapi.vault import io.iohk.atala.agent.walletapi.storage.GenericSecret import io.iohk.atala.agent.walletapi.storage.GenericSecretStorage +import io.iohk.atala.prism.crypto.Sha256 import io.iohk.atala.shared.models.WalletAccessContext import io.iohk.atala.shared.models.WalletId import zio.* import zio.json.ast.Json -class VaultGenericSecretStorage(vaultKV: VaultKVClient) extends GenericSecretStorage { +import java.nio.charset.StandardCharsets + +class VaultGenericSecretStorage(vaultKV: VaultKVClient, useSemanticPath: Boolean) extends GenericSecretStorage { override def set[K, V](key: K, secret: V)(implicit ev: GenericSecret[K, V]): RIO[WalletAccessContext, Unit] = { val payload = ev.encodeValue(secret) for { walletId <- ZIO.serviceWith[WalletAccessContext](_.walletId) - path = constructKeyPath(walletId)(key) + (path, metadata) = constructKeyPath(walletId)(key) alreadyExist <- vaultKV.get[Json](path).map(_.isDefined) _ <- vaultKV - .set[Json](path, payload) + .set[Json](path, payload, metadata) .when(!alreadyExist) .someOrFail(Exception(s"Secret on path $path already exists.")) } yield () @@ -25,19 +28,29 @@ class VaultGenericSecretStorage(vaultKV: VaultKVClient) extends GenericSecretSto override def get[K, V](key: K)(implicit ev: GenericSecret[K, V]): RIO[WalletAccessContext, Option[V]] = { for { walletId <- ZIO.serviceWith[WalletAccessContext](_.walletId) - path = constructKeyPath(walletId)(key) + (path, _) = constructKeyPath(walletId)(key) json <- vaultKV.get[Json](path) result <- json.fold(ZIO.none)(json => ZIO.fromTry(ev.decodeValue(json)).asSome) } yield result } - private def constructKeyPath[K, V](walletId: WalletId)(key: K)(implicit ev: GenericSecret[K, V]): String = { - val keyPath = ev.keyPath(key) - s"secret/${walletId.toUUID}/generic-secrets/$keyPath" + /** @return A tuple of secret path and a secret custom_metadata */ + private def constructKeyPath[K, V]( + walletId: WalletId + )(key: K)(implicit ev: GenericSecret[K, V]): (String, Map[String, String]) = { + val basePath = s"${walletBasePath(walletId)}/generic-secrets" + val relativePath = ev.keyPath(key) + if (useSemanticPath) { + s"$basePath/$relativePath" -> Map.empty + } else { + val relativePathHash = Sha256.compute(relativePath.getBytes(StandardCharsets.UTF_8)).getHexValue() + s"$basePath/$relativePathHash" -> Map(SEMANTIC_PATH_METADATA_KEY -> relativePath) + } } } object VaultGenericSecretStorage { - def layer: URLayer[VaultKVClient, GenericSecretStorage] = ZLayer.fromFunction(VaultGenericSecretStorage(_)) + def layer(useSemanticPath: Boolean): URLayer[VaultKVClient, GenericSecretStorage] = + ZLayer.fromFunction(VaultGenericSecretStorage(_, useSemanticPath)) } diff --git a/prism-agent/service/wallet-api/src/main/scala/io/iohk/atala/agent/walletapi/vault/package.scala b/prism-agent/service/wallet-api/src/main/scala/io/iohk/atala/agent/walletapi/vault/package.scala index 7e320abd56..2576b73a6b 100644 --- a/prism-agent/service/wallet-api/src/main/scala/io/iohk/atala/agent/walletapi/vault/package.scala +++ b/prism-agent/service/wallet-api/src/main/scala/io/iohk/atala/agent/walletapi/vault/package.scala @@ -3,6 +3,7 @@ package io.iohk.atala.agent.walletapi import com.nimbusds.jose.jwk.OctetKeyPair import io.iohk.atala.agent.walletapi.model.WalletSeed import io.iohk.atala.shared.models.HexString +import io.iohk.atala.shared.models.WalletId import zio.json.* import zio.json.ast.Json import zio.json.ast.Json.* @@ -11,6 +12,12 @@ import scala.util.Failure import scala.util.Try package object vault { + val SEMANTIC_PATH_METADATA_KEY: String = "semanticPath" + + private[vault] def walletBasePath(walletId: WalletId): String = { + s"secret/${walletId.toUUID}" + } + trait KVCodec[T] { def encode(value: T): Map[String, String] def decode(kv: Map[String, String]): Try[T] diff --git a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/benchmark/KeyDerivation.scala b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/benchmark/KeyDerivation.scala index be3f5e2baf..fa71d8db0e 100644 --- a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/benchmark/KeyDerivation.scala +++ b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/benchmark/KeyDerivation.scala @@ -38,7 +38,7 @@ object KeyDerivation extends ZIOSpecDefault, VaultTestContainerSupport { override def spec = suite("Key derivation benchmark")( deriveKeyBenchmark.provide(Apollo.prism14Layer), - queryKeyBenchmark.provide(vaultKvClientLayer, Apollo.prism14Layer) + queryKeyBenchmark.provide(vaultKvClientLayer(), Apollo.prism14Layer) ) @@ TestAspect.sequential @@ TestAspect.timed @@ TestAspect.tag("benchmark") @@ TestAspect.ignore private val deriveKeyBenchmark = suite("Key derivation benchmark")( diff --git a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/service/ManagedDIDServiceSpec.scala b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/service/ManagedDIDServiceSpec.scala index 2349f43db8..017b7928fa 100644 --- a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/service/ManagedDIDServiceSpec.scala +++ b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/service/ManagedDIDServiceSpec.scala @@ -77,9 +77,9 @@ object ManagedDIDServiceSpec private def vaultSecretStorageLayer = ZLayer.make[DIDSecretStorage & WalletSecretStorage]( - VaultDIDSecretStorage.layer, + VaultDIDSecretStorage.layer(useSemanticPath = true), VaultWalletSecretStorage.layer, - vaultKvClientLayer + vaultKvClientLayer() ) private def serviceLayer = diff --git a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/service/WalletManagementServiceSpec.scala b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/service/WalletManagementServiceSpec.scala index c7c08e3c06..5ae0beb1e9 100644 --- a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/service/WalletManagementServiceSpec.scala +++ b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/service/WalletManagementServiceSpec.scala @@ -51,7 +51,7 @@ object WalletManagementServiceSpec contextAwareTransactorLayer, pgContainerLayer, apolloLayer, - vaultKvClientLayer, + vaultKvClientLayer(), ) suite("WalletManagementService")(suite1, suite2) diff --git a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/storage/DIDSecretStorageSpec.scala b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/storage/DIDSecretStorageSpec.scala index 9304f9fc7b..5bf81da6ce 100644 --- a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/storage/DIDSecretStorageSpec.scala +++ b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/storage/DIDSecretStorageSpec.scala @@ -52,12 +52,25 @@ object DIDSecretStorageSpec val vaultTestSuite = commonSpec("VaultDIDSecretStorage") .provide( JdbcDIDNonSecretStorage.layer, - VaultDIDSecretStorage.layer, + VaultDIDSecretStorage.layer(useSemanticPath = true), VaultWalletSecretStorage.layer, systemTransactorLayer, contextAwareTransactorLayer, pgContainerLayer, - vaultKvClientLayer, + vaultKvClientLayer(), + walletManagementServiceLayer, + ZLayer.succeed(WalletAdministrationContext.Admin()) + ) + + val vaultFsTestSuite = commonSpec("VaultDIDSecretStorage - file backend") + .provide( + JdbcDIDNonSecretStorage.layer, + VaultDIDSecretStorage.layer(useSemanticPath = false), + VaultWalletSecretStorage.layer, + systemTransactorLayer, + contextAwareTransactorLayer, + pgContainerLayer, + vaultKvClientLayer(useFileBackend = true), walletManagementServiceLayer, ZLayer.succeed(WalletAdministrationContext.Admin()) ) @@ -74,7 +87,12 @@ object DIDSecretStorageSpec ZLayer.succeed(WalletAdministrationContext.Admin()) ) - suite("DIDSecretStorage")(jdbcTestSuite, vaultTestSuite, inMemoryTestSuite) @@ TestAspect.sequential + suite("DIDSecretStorage")( + jdbcTestSuite, + vaultTestSuite, + vaultFsTestSuite, + inMemoryTestSuite + ) @@ TestAspect.sequential } private def commonSpec(name: String) = @@ -118,6 +136,16 @@ object DIDSecretStorageSpec key1 <- secretStorage.getKey(peerDID.did, "agreement") } yield assert(key1)(isNone) }, + test("insert with long DID does not fail") { + for { + nonSecretStorage <- ZIO.service[DIDNonSecretStorage] + secretStorage <- ZIO.service[DIDSecretStorage] + peerDID = PeerDID.makePeerDid(serviceEndpoint = Some("http://localhost/" + ("a" * 100))) + _ <- nonSecretStorage.createPeerDIDRecord(peerDID.did) + _ <- secretStorage.insertKey(peerDID.did, "agreement", peerDID.jwkForKeyAgreement) + _ <- secretStorage.insertKey(peerDID.did, "authentication", peerDID.jwkForKeyAuthentication) + } yield assertCompletes + } ).globalWallet private val multiWalletSpec = suite("multi-wallet")( diff --git a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/storage/GenericSecretStorageSpec.scala b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/storage/GenericSecretStorageSpec.scala index c44996a68b..87ac10110b 100644 --- a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/storage/GenericSecretStorageSpec.scala +++ b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/storage/GenericSecretStorageSpec.scala @@ -56,9 +56,19 @@ object GenericSecretStorageSpec val vaultTestSuite = commonSpec("VaultGenericSecretStorage") .provide( VaultWalletSecretStorage.layer, - VaultGenericSecretStorage.layer, + VaultGenericSecretStorage.layer(useSemanticPath = true), pgContainerLayer, - vaultKvClientLayer, + vaultKvClientLayer(), + walletManagementServiceLayer, + ZLayer.succeed(WalletAdministrationContext.Admin()) + ) + + val vaultFsTestSuite = commonSpec("VaultGenericSecretStorage - file backend") + .provide( + VaultWalletSecretStorage.layer, + VaultGenericSecretStorage.layer(useSemanticPath = false), + pgContainerLayer, + vaultKvClientLayer(useFileBackend = true), walletManagementServiceLayer, ZLayer.succeed(WalletAdministrationContext.Admin()) ) @@ -73,7 +83,12 @@ object GenericSecretStorageSpec ZLayer.succeed(WalletAdministrationContext.Admin()) ) - suite("GenericSecretStorage")(jdbcTestSuite, vaultTestSuite, inMemoryTestSuite) @@ TestAspect.sequential + suite("GenericSecretStorage")( + jdbcTestSuite, + vaultTestSuite, + vaultFsTestSuite, + inMemoryTestSuite + ) @@ TestAspect.sequential } private def commonSpec(name: String) = diff --git a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/storage/WalletSecretStorageSpec.scala b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/storage/WalletSecretStorageSpec.scala index ca46a9db48..d913d1dea9 100644 --- a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/storage/WalletSecretStorageSpec.scala +++ b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/storage/WalletSecretStorageSpec.scala @@ -34,7 +34,7 @@ object WalletSecretStorageSpec extends ZIOSpecDefault, PostgresTestContainerSupp JdbcWalletNonSecretStorage.layer, contextAwareTransactorLayer, pgContainerLayer, - vaultKvClientLayer + vaultKvClientLayer() ) suite("WalletSecretStorage")(suite1, suite2) diff --git a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/test/container/VaultLayer.scala b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/test/container/VaultLayer.scala index 12868fb7af..bbbbc4d508 100644 --- a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/test/container/VaultLayer.scala +++ b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/test/container/VaultLayer.scala @@ -6,12 +6,12 @@ import io.iohk.atala.sharedtest.containers.VaultContainerCustom object VaultLayer { - def vaultLayer(vaultToken: String): TaskLayer[VaultContainerCustom] = { + def vaultLayer(vaultToken: String, useFileBackend: Boolean): TaskLayer[VaultContainerCustom] = { ZLayer .scoped { ZIO .acquireRelease(ZIO.attemptBlocking { - VaultTestContainer.vaultContainer(vaultToken = Some(vaultToken)) + VaultTestContainer.vaultContainer(vaultToken = Some(vaultToken), useFileBackend = useFileBackend) })(container => ZIO.attemptBlocking(container.stop()).orDie) // Start the container outside the aquireRelease as this might fail // to ensure contianer.stop() is added to the finalizer diff --git a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/test/container/VaultTestContainerSupport.scala b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/test/container/VaultTestContainerSupport.scala index d7de8b0456..03447a1dbd 100644 --- a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/test/container/VaultTestContainerSupport.scala +++ b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/test/container/VaultTestContainerSupport.scala @@ -1,23 +1,22 @@ package io.iohk.atala.test.container -import zio.* import io.iohk.atala.agent.walletapi.vault.VaultKVClient import io.iohk.atala.agent.walletapi.vault.VaultKVClientImpl import io.iohk.atala.sharedtest.containers.VaultContainerCustom +import zio.* +import zio.http.Client trait VaultTestContainerSupport { private val TEST_TOKEN = "root" - protected val vaultContainerLayer: TaskLayer[VaultContainerCustom] = VaultLayer.vaultLayer(vaultToken = TEST_TOKEN) + protected def vaultContainerLayer(useFileBackend: Boolean): TaskLayer[VaultContainerCustom] = + VaultLayer.vaultLayer(vaultToken = TEST_TOKEN, useFileBackend = useFileBackend) - protected def vaultKvClientLayer: TaskLayer[VaultKVClient] = - vaultContainerLayer >>> ZLayer.fromFunction { (container: VaultContainerCustom) => + protected def vaultKvClientLayer(useFileBackend: Boolean = false): TaskLayer[VaultKVClient] = + vaultContainerLayer(useFileBackend) ++ Client.default >>> ZLayer.fromFunction { (container: VaultContainerCustom) => val address = container.container.getHttpHostAddress() - ZLayer.fromZIO( - VaultKVClientImpl - .fromToken(address, TEST_TOKEN) - ) + ZLayer.fromZIO(VaultKVClientImpl.fromToken(address, TEST_TOKEN)) }.flatten } diff --git a/shared-test/src/test/scala/io/iohk/atala/sharedtest/containers/VaultContainerCustom.scala b/shared-test/src/test/scala/io/iohk/atala/sharedtest/containers/VaultContainerCustom.scala index 3500076bfd..6265b031a9 100644 --- a/shared-test/src/test/scala/io/iohk/atala/sharedtest/containers/VaultContainerCustom.scala +++ b/shared-test/src/test/scala/io/iohk/atala/sharedtest/containers/VaultContainerCustom.scala @@ -9,9 +9,26 @@ class VaultContainerCustom( dockerImageNameOverride: DockerImageName, vaultToken: Option[String] = None, secrets: Option[VaultContainer.Secrets] = None, - isOnGithubRunner: Boolean = false + isOnGithubRunner: Boolean = false, + useFileBackend: Boolean = false ) extends SingleContainer[JavaVaultContainer[_]] { + private val vaultFSBackendConfig: String = + """{ + | "storage": { + | "file": { "path": "/vault/data" } + | } + |} + """.stripMargin + + private val vaultMemBackendConfig: String = + """{ + | "storage": { + | "inmem": {} + | } + |} + """.stripMargin + private val vaultContainer: JavaVaultContainer[_] = new JavaVaultContainer(dockerImageNameOverride) { override def getHost: String = { if (isOnGithubRunner) super.getContainerId().take(12) @@ -28,5 +45,10 @@ class VaultContainerCustom( vaultContainer.withSecretInVault(x.path, x.firstSecret, x.secrets: _*) } - override val container: JavaVaultContainer[_] = vaultContainer + override val container: JavaVaultContainer[_] = { + val con = vaultContainer + if (useFileBackend) con.addEnv("VAULT_LOCAL_CONFIG", vaultFSBackendConfig) + else con.addEnv("VAULT_LOCAL_CONFIG", vaultMemBackendConfig) + con + } } diff --git a/shared-test/src/test/scala/io/iohk/atala/sharedtest/containers/VaultTestContainer.scala b/shared-test/src/test/scala/io/iohk/atala/sharedtest/containers/VaultTestContainer.scala index afb8dcdd7b..f7e8f9adf1 100644 --- a/shared-test/src/test/scala/io/iohk/atala/sharedtest/containers/VaultTestContainer.scala +++ b/shared-test/src/test/scala/io/iohk/atala/sharedtest/containers/VaultTestContainer.scala @@ -5,16 +5,18 @@ import org.testcontainers.utility.DockerImageName object VaultTestContainer { def vaultContainer( - imageName: String = "hashicorp/vault:1.15.0", + imageName: String = "hashicorp/vault:1.15.6", vaultToken: Option[String] = None, - verbose: Boolean = false + verbose: Boolean = false, + useFileBackend: Boolean = false ): VaultContainerCustom = { val isOnGithubRunner = sys.env.contains("GITHUB_NETWORK") val container = new VaultContainerCustom( dockerImageNameOverride = DockerImageName.parse(imageName), vaultToken = vaultToken, - isOnGithubRunner = isOnGithubRunner + isOnGithubRunner = isOnGithubRunner, + useFileBackend = useFileBackend ) sys.env.get("GITHUB_NETWORK").map { network => container.container.withNetworkMode(network) From 4a1705873712173e3206c9e954defe76841126dc Mon Sep 17 00:00:00 2001 From: atala-dev Date: Wed, 6 Mar 2024 05:04:12 +0000 Subject: [PATCH 2/6] chore(release): cut open enterprise agent 1.30.1 release ## [1.30.1](https://github.com/hyperledger-labs/open-enterprise-agent/compare/prism-agent-v1.30.0...prism-agent-v1.30.1) (2024-03-06) ### Bug Fixes * allow configurable path convention for vault secrets ([#918](https://github.com/hyperledger-labs/open-enterprise-agent/issues/918)) ([234a272](https://github.com/hyperledger-labs/open-enterprise-agent/commit/234a2725614b05466391894f248c7175fb62c5b6)) * integration test ([#915](https://github.com/hyperledger-labs/open-enterprise-agent/issues/915)) ([320ab6a](https://github.com/hyperledger-labs/open-enterprise-agent/commit/320ab6a876606eb68f48fe7d78983b4e044b5084)) Signed-off-by: Anton Baliasnikov --- CHANGELOG.md | 8 +++ DEPENDENCIES.md | 54 ++++++++-------- infrastructure/charts/agent/Chart.yaml | 4 +- infrastructure/charts/index.yaml | 60 ++++++++++++------ infrastructure/charts/prism-agent-1.30.1.tgz | Bin 0 -> 160942 bytes infrastructure/local/.env | 2 +- package-lock.json | 4 +- package.json | 2 +- .../api/http/prism-agent-openapi-spec.yaml | 4 +- version.sbt | 2 +- 10 files changed, 83 insertions(+), 57 deletions(-) create mode 100644 infrastructure/charts/prism-agent-1.30.1.tgz diff --git a/CHANGELOG.md b/CHANGELOG.md index 50b98d02cf..a56f0208fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [1.30.1](https://github.com/hyperledger-labs/open-enterprise-agent/compare/prism-agent-v1.30.0...prism-agent-v1.30.1) (2024-03-06) + + +### Bug Fixes + +* allow configurable path convention for vault secrets ([#918](https://github.com/hyperledger-labs/open-enterprise-agent/issues/918)) ([234a272](https://github.com/hyperledger-labs/open-enterprise-agent/commit/234a2725614b05466391894f248c7175fb62c5b6)) +* integration test ([#915](https://github.com/hyperledger-labs/open-enterprise-agent/issues/915)) ([320ab6a](https://github.com/hyperledger-labs/open-enterprise-agent/commit/320ab6a876606eb68f48fe7d78983b4e044b5084)) + # [1.30.0](https://github.com/hyperledger-labs/open-enterprise-agent/compare/prism-agent-v1.29.0...prism-agent-v1.30.0) (2024-03-01) diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index ee723b837f..6a7dd2a125 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -444,32 +444,32 @@ MIT | [The MIT License (MIT)](https://opensource.org/licenses/MIT) | [com.dimafe MIT | [The MIT License (MIT)](https://opensource.org/licenses/MIT) | [com.dimafeng # testcontainers-scala-vault_3 # 0.41.0](https://github.com/testcontainers/testcontainers-scala) | Public Domain | [Public Domain, per Creative Commons CC0](http://creativecommons.org/publicdomain/zero/1.0/) | [org.hdrhistogram # HdrHistogram # 2.1.12](http://hdrhistogram.github.io/HdrHistogram/) | Public Domain | [Public Domain, per Creative Commons CC0](http://creativecommons.org/publicdomain/zero/1.0/) | [org.latencyutils # LatencyUtils # 2.0.3](http://latencyutils.github.io/LatencyUtils/) | -none specified | []() | [io.iohk.atala # castor-core_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # connect-core_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # connect-sql-doobie_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # event-notification_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # mercury-agent-core_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # mercury-agent-didcommx_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # mercury-data-models_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # mercury-protocol-connection_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # mercury-protocol-coordinate-mediation_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # mercury-protocol-invitation_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # mercury-protocol-issue-credential_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # mercury-protocol-mailbox_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # mercury-protocol-outofband-login_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # mercury-protocol-present-proof_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # mercury-protocol-report-problem_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # mercury-protocol-routing-2-0_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # mercury-protocol-trust-ping_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # mercury-resolver_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # mercury-verifiable-credentials_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # pollux-anoncreds_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # pollux-core_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # pollux-sql-doobie_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # pollux-vc-jwt_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # prism-agent-wallet-api_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # prism-node-client_3 # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # shared # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | -none specified | []() | [io.iohk.atala # sharedtest # 1.29.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # castor-core_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # connect-core_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # connect-sql-doobie_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # event-notification_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # mercury-agent-core_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # mercury-agent-didcommx_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # mercury-data-models_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # mercury-protocol-connection_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # mercury-protocol-coordinate-mediation_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # mercury-protocol-invitation_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # mercury-protocol-issue-credential_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # mercury-protocol-mailbox_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # mercury-protocol-outofband-login_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # mercury-protocol-present-proof_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # mercury-protocol-report-problem_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # mercury-protocol-routing-2-0_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # mercury-protocol-trust-ping_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # mercury-resolver_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # mercury-verifiable-credentials_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # pollux-anoncreds_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # pollux-core_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # pollux-sql-doobie_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # pollux-vc-jwt_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # prism-agent-wallet-api_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # prism-node-client_3 # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # shared # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | +none specified | []() | [io.iohk.atala # sharedtest # 1.30.0-SNAPSHOT](https://github.com/input-output-hk/atala-prism-building-blocks) | none specified | []() | [net.jcip # jcip-annotations # 1.0](http://jcip.net/) | diff --git a/infrastructure/charts/agent/Chart.yaml b/infrastructure/charts/agent/Chart.yaml index ffad12fd49..b395e46c4f 100644 --- a/infrastructure/charts/agent/Chart.yaml +++ b/infrastructure/charts/agent/Chart.yaml @@ -13,12 +13,12 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.30.0 +version: 1.30.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: 1.30.0 +appVersion: 1.30.1 dependencies: - name: vault version: 0.24.1 diff --git a/infrastructure/charts/index.yaml b/infrastructure/charts/index.yaml index 357f47d52d..d4eaf2484b 100644 --- a/infrastructure/charts/index.yaml +++ b/infrastructure/charts/index.yaml @@ -1,9 +1,27 @@ apiVersion: v1 entries: prism-agent: + - apiVersion: v2 + appVersion: 1.30.1 + created: "2024-03-06T05:03:44.668594792Z" + dependencies: + - name: vault + repository: https://helm.releases.hashicorp.com + version: 0.24.1 + - condition: keycloak.enabled + name: keycloak + repository: https://charts.bitnami.com/bitnami + version: 17.2.0 + description: A Helm chart for deploying prism-agent + digest: 8ef2ce679bd5f0605309f08f5cefa46a1a7c4eebe066d160dbdfe6a9a39e9dc2 + name: prism-agent + type: application + urls: + - https://raw.githubusercontent.com/hyperledger-labs/open-enterprise-agent/main/infrastructure/charts/prism-agent-1.30.1.tgz + version: 1.30.1 - apiVersion: v2 appVersion: 1.30.0 - created: "2024-03-01T13:43:38.018475129Z" + created: "2024-03-06T05:03:44.658884796Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -21,7 +39,7 @@ entries: version: 1.30.0 - apiVersion: v2 appVersion: 1.29.0 - created: "2024-03-01T13:43:38.008623073Z" + created: "2024-03-06T05:03:44.64836988Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -39,7 +57,7 @@ entries: version: 1.29.0 - apiVersion: v2 appVersion: 1.28.0 - created: "2024-03-01T13:43:37.99812486Z" + created: "2024-03-06T05:03:44.637984979Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -57,7 +75,7 @@ entries: version: 1.28.0 - apiVersion: v2 appVersion: 1.27.0 - created: "2024-03-01T13:43:37.988356721Z" + created: "2024-03-06T05:03:44.628476289Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -75,7 +93,7 @@ entries: version: 1.27.0 - apiVersion: v2 appVersion: 1.26.0 - created: "2024-03-01T13:43:37.977235414Z" + created: "2024-03-06T05:03:44.617258513Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -93,7 +111,7 @@ entries: version: 1.26.0 - apiVersion: v2 appVersion: 1.25.0 - created: "2024-03-01T13:43:37.96765169Z" + created: "2024-03-06T05:03:44.607709598Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -111,7 +129,7 @@ entries: version: 1.25.0 - apiVersion: v2 appVersion: 1.24.0 - created: "2024-03-01T13:43:37.957145264Z" + created: "2024-03-06T05:03:44.59743332Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -129,7 +147,7 @@ entries: version: 1.24.0 - apiVersion: v2 appVersion: 1.23.0 - created: "2024-03-01T13:43:37.946954593Z" + created: "2024-03-06T05:03:44.587255564Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -147,7 +165,7 @@ entries: version: 1.23.0 - apiVersion: v2 appVersion: 1.22.0 - created: "2024-03-01T13:43:37.937369025Z" + created: "2024-03-06T05:03:44.577877249Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -165,7 +183,7 @@ entries: version: 1.22.0 - apiVersion: v2 appVersion: 1.21.1 - created: "2024-03-01T13:43:37.92692771Z" + created: "2024-03-06T05:03:44.566885483Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -183,7 +201,7 @@ entries: version: 1.21.1 - apiVersion: v2 appVersion: 1.21.0 - created: "2024-03-01T13:43:37.917096223Z" + created: "2024-03-06T05:03:44.557137836Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -201,7 +219,7 @@ entries: version: 1.21.0 - apiVersion: v2 appVersion: 1.20.1 - created: "2024-03-01T13:43:37.90613842Z" + created: "2024-03-06T05:03:44.54595658Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -219,7 +237,7 @@ entries: version: 1.20.1 - apiVersion: v2 appVersion: 1.20.0 - created: "2024-03-01T13:43:37.895871319Z" + created: "2024-03-06T05:03:44.536323918Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -237,7 +255,7 @@ entries: version: 1.20.0 - apiVersion: v2 appVersion: 1.19.1 - created: "2024-03-01T13:43:37.886669488Z" + created: "2024-03-06T05:03:44.524682058Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -255,7 +273,7 @@ entries: version: 1.19.1 - apiVersion: v2 appVersion: 1.19.0 - created: "2024-03-01T13:43:37.876469849Z" + created: "2024-03-06T05:03:44.515379364Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -273,7 +291,7 @@ entries: version: 1.19.0 - apiVersion: v2 appVersion: 1.18.0 - created: "2024-03-01T13:43:37.866517812Z" + created: "2024-03-06T05:03:44.505674984Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -287,7 +305,7 @@ entries: version: 1.18.0 - apiVersion: v2 appVersion: 1.17.0 - created: "2024-03-01T13:43:37.863613737Z" + created: "2024-03-06T05:03:44.502075456Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -301,7 +319,7 @@ entries: version: 1.17.0 - apiVersion: v2 appVersion: 1.16.4 - created: "2024-03-01T13:43:37.860264367Z" + created: "2024-03-06T05:03:44.499126168Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -315,7 +333,7 @@ entries: version: 1.16.4 - apiVersion: v2 appVersion: 1.16.3 - created: "2024-03-01T13:43:37.857474204Z" + created: "2024-03-06T05:03:44.49635206Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -329,7 +347,7 @@ entries: version: 1.16.3 - apiVersion: v2 appVersion: 1.16.2 - created: "2024-03-01T13:43:37.854660308Z" + created: "2024-03-06T05:03:44.492681188Z" dependencies: - name: vault repository: https://helm.releases.hashicorp.com @@ -341,4 +359,4 @@ entries: urls: - https://raw.githubusercontent.com/hyperledger-labs/open-enterprise-agent/main/infrastructure/charts/prism-agent-1.16.2.tgz version: 1.16.2 -generated: "2024-03-01T13:43:37.850777463Z" +generated: "2024-03-06T05:03:44.489402063Z" diff --git a/infrastructure/charts/prism-agent-1.30.1.tgz b/infrastructure/charts/prism-agent-1.30.1.tgz new file mode 100644 index 0000000000000000000000000000000000000000..5bc50937ce3f6ab4dac5bc1a5754d30ffc69f5a5 GIT binary patch literal 160942 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
$A(Zr{`D4-#tHjdwTZ$@$2W;Z(p2UU!I>_ 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ⅅ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 O0RR8IU5`WnoDcw_qFXQk literal 0 HcmV?d00001 diff --git a/infrastructure/local/.env b/infrastructure/local/.env index b0f907aeb0..6d46418fb3 100644 --- a/infrastructure/local/.env +++ b/infrastructure/local/.env @@ -1,3 +1,3 @@ -PRISM_AGENT_VERSION=1.30.0 +PRISM_AGENT_VERSION=1.30.1 PRISM_NODE_VERSION=2.2.1 VAULT_DEV_ROOT_TOKEN_ID=root diff --git a/package-lock.json b/package-lock.json index 1878b6ca1a..9874366a40 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "atala-prism-building-blocks", - "version": "1.30.0", + "version": "1.30.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "atala-prism-building-blocks", - "version": "1.30.0", + "version": "1.30.1", "devDependencies": { "@commitlint/cli": "^17.0.3", "@commitlint/config-conventional": "^17.0.3", diff --git a/package.json b/package.json index c7a1e5ec51..fb69355426 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "atala-prism-building-blocks", - "version": "1.30.0", + "version": "1.30.1", "engines": { "node": ">=16.13.0" }, diff --git a/prism-agent/service/api/http/prism-agent-openapi-spec.yaml b/prism-agent/service/api/http/prism-agent-openapi-spec.yaml index 694feb91fe..84e63f6d61 100644 --- a/prism-agent/service/api/http/prism-agent-openapi-spec.yaml +++ b/prism-agent/service/api/http/prism-agent-openapi-spec.yaml @@ -1,7 +1,7 @@ openapi: 3.0.3 info: title: Open Enterprise Agent API Reference - version: 1.30.0 + version: 1.30.1 description: |2 The Open Enterprise Agent API facilitates the integration and management of self-sovereign identity capabilities within applications. @@ -4119,7 +4119,7 @@ components: type: string description: The date and time when the issue credential record was created. format: date-time - example: '2024-03-01T13:23:42.558546498Z' + example: '2024-03-06T04:43:17.213830704Z' updatedAt: type: string description: The date and time when the issue credential record was last diff --git a/version.sbt b/version.sbt index 631ead575c..e77d74b163 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -ThisBuild / version := "1.30.0-SNAPSHOT" +ThisBuild / version := "1.30.1-SNAPSHOT" From acbba3ce92ee9e16893b4978c4a9ec4ce0757d53 Mon Sep 17 00:00:00 2001 From: Bassam Date: Wed, 6 Mar 2024 12:44:31 -0500 Subject: [PATCH 3/6] feat: Fix Update Schema and CredentialDef on Receive Credential (#920) Signed-off-by: Bassam Riman --- .../repository/CredentialRepository.scala | 2 + .../CredentialRepositoryInMemory.scala | 6 +- .../core/service/CredentialServiceImpl.scala | 129 ++++++++++-------- .../service/MockPresentationService.scala | 2 - .../core/service/PresentationService.scala | 2 - .../service/PresentationServiceImpl.scala | 58 ++++---- .../service/PresentationServiceNotifier.scala | 6 +- .../CredentialRepositorySpecSuite.scala | 8 ++ .../service/PresentationServiceSpec.scala | 10 +- .../repository/JdbcCredentialRepository.scala | 9 +- .../server/jobs/PresentBackgroundJobs.scala | 5 - 11 files changed, 141 insertions(+), 96 deletions(-) diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialRepository.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialRepository.scala index 2f2b9615e5..f919f33e46 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialRepository.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialRepository.scala @@ -67,6 +67,8 @@ trait CredentialRepository { recordId: DidCommID, issue: IssueCredential, issuedRawCredential: String, + schemaUri: Option[String], + credentialDefinitionUri: Option[String], protocolState: ProtocolState ): RIO[WalletAccessContext, Int] diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialRepositoryInMemory.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialRepositoryInMemory.scala index 2bc9bce4c5..a952b8b223 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialRepositoryInMemory.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialRepositoryInMemory.scala @@ -98,6 +98,8 @@ class CredentialRepositoryInMemory( recordId: DidCommID, issue: IssueCredential, issuedRawCredential: String, + schemaUri: Option[String], + credentialDefinitionUri: Option[String], protocolState: ProtocolState ): RIO[WalletAccessContext, Int] = { for { @@ -111,6 +113,8 @@ class CredentialRepositoryInMemory( recordId, record.copy( updatedAt = Some(Instant.now), + schemaUri = schemaUri, + credentialDefinitionUri = credentialDefinitionUri, issueCredentialData = Some(issue), issuedCredentialRaw = Some(issuedRawCredential), protocolState = protocolState, @@ -149,7 +153,7 @@ class CredentialRepositoryInMemory( rec.id ) && rec.issueCredentialData.isDefined && rec.schemaUri.isDefined - && rec.credentialDefinitionId.isDefined + && rec.credentialDefinitionUri.isDefined && rec.credentialFormat == CredentialFormat.AnonCreds ) .map(rec => diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialServiceImpl.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialServiceImpl.scala index 8b273ebdb5..0d4250c9a2 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialServiceImpl.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialServiceImpl.scala @@ -607,67 +607,86 @@ private class CredentialServiceImpl( override def receiveCredentialIssue( issueCredential: IssueCredential - ): ZIO[WalletAccessContext, CredentialServiceError, IssueCredentialRecord] = { - for { - // TODO Move this type of generic/reusable code to a helper trait - record <- getRecordFromThreadIdWithState( - issueCredential.thid.map(DidCommID(_)), - ignoreWithZeroRetries = true, - ProtocolState.RequestPending, - ProtocolState.RequestSent + ): ZIO[WalletAccessContext, CredentialServiceError, IssueCredentialRecord] = for { + // TODO Move this type of generic/reusable code to a helper trait + record <- getRecordFromThreadIdWithState( + issueCredential.thid.map(DidCommID(_)), + ignoreWithZeroRetries = true, + ProtocolState.RequestPending, + ProtocolState.RequestSent + ) + attachment <- ZIO + .fromOption(issueCredential.attachments.headOption) + .mapError(_ => CredentialServiceError.UnexpectedError("Missing attachment in credential issued credential")) + + _ <- { + val result = attachment match { + case AttachmentDescriptor( + id, + media_type, + Base64(v), + Some(IssueCredentialIssuedFormat.Anoncred.name), + _, + _, + _, + _ + ) => + for { + processedCredential <- processAnonCredsCredential(record, java.util.Base64.getUrlDecoder.decode(v)) + attachment = AttachmentDescriptor.buildBase64Attachment( + id = id, + mediaType = media_type, + format = Some(IssueCredentialIssuedFormat.Anoncred.name), + payload = processedCredential.data.getBytes + ) + processedIssuedCredential = issueCredential.copy(attachments = Seq(attachment)) + result <- + updateWithCredential( + processedIssuedCredential, + record, + attachment, + Some(processedCredential.getSchemaId), + Some(processedCredential.getCredDefId) + ) + } yield result + case attachment => + updateWithCredential(issueCredential, record, attachment, None, None) + } + result + } + record <- credentialRepository + .getIssueCredentialRecord(record.id) + .mapError(RepositoryError.apply) + .someOrFail(RecordIdNotFound(record.id)) + } yield record + + private def updateWithCredential( + issueCredential: IssueCredential, + record: IssueCredentialRecord, + attachment: AttachmentDescriptor, + schemaId: Option[String], + credDefId: Option[String] + ) = { + credentialRepository + .updateWithIssuedRawCredential( + record.id, + issueCredential, + attachment.data.asJson.noSpaces, + schemaId, + credDefId, + ProtocolState.CredentialReceived ) - processedAttachments <- { - import IssueCredentialIssuedFormat.Anoncred - ZIO.collectAll( - issueCredential.attachments - .map { - case AttachmentDescriptor( - id, - media_type, - Base64(v), - Some(Anoncred.name), - _, - _, - _, - _ - ) => - processAnonCredsCredential(record, java.util.Base64.getUrlDecoder.decode(v)) - .map(processedCredential => - AttachmentDescriptor.buildBase64Attachment( - id = id, - mediaType = media_type, - format = Some(IssueCredentialIssuedFormat.Anoncred.name), - payload = processedCredential - ) - ) - case attachment => ZIO.succeed(attachment) - } - ) + .flatMap { + case 1 => ZIO.succeed(()) + case n => ZIO.fail(UnexpectedException(s"Invalid row count result: $n")) } - processedIssuedCredential = issueCredential.copy(attachments = processedAttachments) - _ <- credentialRepository - .updateWithIssuedRawCredential( - record.id, - processedIssuedCredential, - processedIssuedCredential.attachments.map(_.data.asJson.noSpaces).headOption.getOrElse("???"), - ProtocolState.CredentialReceived - ) - .flatMap { - case 1 => ZIO.succeed(()) - case n => ZIO.fail(UnexpectedException(s"Invalid row count result: $n")) - } - .mapError(RepositoryError.apply) - record <- credentialRepository - .getIssueCredentialRecord(record.id) - .mapError(RepositoryError.apply) - .someOrFail(RecordIdNotFound(record.id)) - } yield record + .mapError(RepositoryError.apply) } private[this] def processAnonCredsCredential( record: IssueCredentialRecord, credentialBytes: Array[Byte] - ): ZIO[WalletAccessContext, CredentialServiceError, Array[Byte]] = { + ): ZIO[WalletAccessContext, CredentialServiceError, anoncreds.AnoncredCredential] = { for { credential <- ZIO.succeed(anoncreds.AnoncredCredential(new String(credentialBytes))) credDefContent <- uriDereferencer @@ -690,7 +709,7 @@ private class CredentialServiceImpl( ) ) .mapError(error => UnexpectedError(s"AnonCreds credential processing error: ${error.getMessage}")) - } yield credential.data.getBytes() + } yield credential } override def markOfferSent( diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/MockPresentationService.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/MockPresentationService.scala index 6049790a99..3faba1a4c9 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/MockPresentationService.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/MockPresentationService.scala @@ -173,7 +173,6 @@ object MockPresentationService extends Mock[PresentationService] { override def createAnoncredPresentationPayloadFromRecord( record: DidCommID, - issuer: Issuer, anoncredCredentialProof: AnoncredCredentialProofsV1, issuanceDate: Instant ): IO[PresentationError, AnoncredPresentation] = ??? @@ -181,7 +180,6 @@ object MockPresentationService extends Mock[PresentationService] { override def createAnoncredPresentation( requestPresentation: RequestPresentation, recordId: DidCommID, - prover: Issuer, anoncredCredentialProof: AnoncredCredentialProofsV1, issuanceDate: Instant ): ZIO[WalletAccessContext, PresentationError, Presentation] = ??? diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/PresentationService.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/PresentationService.scala index 9727983870..b54df6784c 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/PresentationService.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/PresentationService.scala @@ -47,7 +47,6 @@ trait PresentationService { def createAnoncredPresentationPayloadFromRecord( record: DidCommID, - issuer: Issuer, anoncredCredentialProof: AnoncredCredentialProofsV1, issuanceDate: Instant ): ZIO[WalletAccessContext, PresentationError, AnoncredPresentation] @@ -55,7 +54,6 @@ trait PresentationService { def createAnoncredPresentation( requestPresentation: RequestPresentation, recordId: DidCommID, - prover: Issuer, anoncredCredentialProof: AnoncredCredentialProofsV1, issuanceDate: Instant ): ZIO[WalletAccessContext, PresentationError, Presentation] diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/PresentationServiceImpl.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/PresentationServiceImpl.scala index d75e785f19..a355f9d847 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/PresentationServiceImpl.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/PresentationServiceImpl.scala @@ -108,7 +108,6 @@ private class PresentationServiceImpl( override def createAnoncredPresentationPayloadFromRecord( recordId: DidCommID, - prover: Issuer, anoncredCredentialProof: AnoncredCredentialProofsV1, issuanceDate: Instant ): ZIO[WalletAccessContext, PresentationError, AnoncredPresentation] = { @@ -151,7 +150,6 @@ private class PresentationServiceImpl( def createAnoncredPresentation( requestPresentation: RequestPresentation, recordId: DidCommID, - prover: Issuer, anoncredCredentialProof: AnoncredCredentialProofsV1, issuanceDate: Instant ): ZIO[WalletAccessContext, PresentationError, Presentation] = { @@ -159,7 +157,6 @@ private class PresentationServiceImpl( presentationPayload <- createAnoncredPresentationPayloadFromRecord( recordId, - prover, anoncredCredentialProof, issuanceDate ) @@ -605,10 +602,10 @@ private class PresentationServiceImpl( issuedCredentials <- credentialRepository .getValidIssuedCredentials(credentialsToUse.map(DidCommID(_))) .mapError(RepositoryError.apply) + validatedCredentialsFormat <- validateCredentialsFormat(record, issuedCredentials) _ <- validateCredentials( s"No matching issued credentials found in prover db from the given: $credentialsToUse", - record, - issuedCredentials + validatedCredentialsFormat ) count <- presentationRepository .updatePresentationWithCredentialsToUse(recordId, Option(credentialsToUse), ProtocolState.PresentationPending) @@ -641,13 +638,13 @@ private class PresentationServiceImpl( for { record <- getRecordWithState(recordId, ProtocolState.RequestReceived) - issuedCredentials <- credentialRepository - .getValidIssuedCredentials( - credentialsToUse.credentialProofs.map(credentialProof => DidCommID(credentialProof.credential)) - ) - .mapError(RepositoryError.apply) - _ <- validateCredentials( - s"No matching issued credentials found in prover db from the given: $credentialsToUse", + issuedCredentials <- + credentialRepository + .getValidAnoncredIssuedCredentials( + credentialsToUse.credentialProofs.map(credentialProof => DidCommID(credentialProof.credential)) + ) + .mapError(RepositoryError.apply) + _ <- validateFullCredentialsFormat( record, issuedCredentials ) @@ -676,6 +673,23 @@ private class PresentationServiceImpl( private def validateCredentials( errorMessage: String, + issuedCredentials: Seq[ValidIssuedCredentialRecord] + ) = { + val issuedCredentialRaw = issuedCredentials.flatMap(_.issuedCredentialRaw) + for { + _ <- ZIO.fromEither( + Either.cond( + issuedCredentialRaw.nonEmpty, + issuedCredentialRaw, + PresentationError.IssuedCredentialNotFoundError( + new Throwable(errorMessage) + ) + ) + ) + } yield () + } + + private def validateCredentialsFormat( record: PresentationRecord, issuedCredentials: Seq[ValidIssuedCredentialRecord] ) = { @@ -701,19 +715,17 @@ private class PresentationServiceImpl( ) ) ) - signedCredentials = validatedCredentials.flatMap(_.issuedCredentialRaw) - _ <- ZIO.fromEither( - Either.cond( - signedCredentials.nonEmpty, - signedCredentials, - PresentationError.IssuedCredentialNotFoundError( - new Throwable(errorMessage) - ) - ) - ) - } yield () + } yield validatedCredentials } + private def validateFullCredentialsFormat( + record: PresentationRecord, + issuedCredentials: Seq[ValidFullIssuedCredentialRecord] + ) = validateCredentialsFormat( + record, + issuedCredentials.map(cred => ValidIssuedCredentialRecord(cred.id, None, cred.credentialFormat, cred.subjectId)) + ) + override def acceptPresentation( recordId: DidCommID ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = { diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/PresentationServiceNotifier.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/PresentationServiceNotifier.scala index 59afcefd9c..0739b63067 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/PresentationServiceNotifier.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/PresentationServiceNotifier.scala @@ -169,20 +169,18 @@ class PresentationServiceNotifier( override def createAnoncredPresentationPayloadFromRecord( record: DidCommID, - issuer: Issuer, anoncredCredentialProof: AnoncredCredentialProofsV1, issuanceDate: Instant ): ZIO[WalletAccessContext, PresentationError, AnoncredPresentation] = - svc.createAnoncredPresentationPayloadFromRecord(record, issuer, anoncredCredentialProof, issuanceDate) + svc.createAnoncredPresentationPayloadFromRecord(record, anoncredCredentialProof, issuanceDate) override def createAnoncredPresentation( requestPresentation: RequestPresentation, recordId: DidCommID, - prover: Issuer, anoncredCredentialProof: AnoncredCredentialProofsV1, issuanceDate: Instant ): ZIO[WalletAccessContext, PresentationError, Presentation] = - svc.createAnoncredPresentation(requestPresentation, recordId, prover, anoncredCredentialProof, issuanceDate) + svc.createAnoncredPresentation(requestPresentation, recordId, anoncredCredentialProof, issuanceDate) override def getPresentationRecordsByStates( ignoreWithZeroRetries: Boolean, diff --git a/pollux/lib/core/src/test/scala/io/iohk/atala/pollux/core/repository/CredentialRepositorySpecSuite.scala b/pollux/lib/core/src/test/scala/io/iohk/atala/pollux/core/repository/CredentialRepositorySpecSuite.scala index 0d0a1eb1c0..39e3f65995 100644 --- a/pollux/lib/core/src/test/scala/io/iohk/atala/pollux/core/repository/CredentialRepositorySpecSuite.scala +++ b/pollux/lib/core/src/test/scala/io/iohk/atala/pollux/core/repository/CredentialRepositorySpecSuite.scala @@ -269,12 +269,16 @@ object CredentialRepositorySpecSuite { aRecord.id, IssueCredential.makeIssueCredentialFromRequestCredential(requestCredential.makeMessage), "RAW_CREDENTIAL_DATA", + None, + None, ProtocolState.CredentialReceived ) _ <- repo.updateWithIssuedRawCredential( dRecord.id, IssueCredential.makeIssueCredentialFromRequestCredential(requestCredential.makeMessage), "RAW_CREDENTIAL_DATA", + None, + None, ProtocolState.CredentialReceived ) records <- repo.getValidIssuedCredentials(Seq(aRecord.id, bRecord.id, dRecord.id)) @@ -387,6 +391,8 @@ object CredentialRepositorySpecSuite { aRecord.id, issueCredential, "RAW_CREDENTIAL_DATA", + Some("schemaUri"), + Some("credentialDefinitionUri"), ProtocolState.CredentialReceived ) updatedRecord <- repo.getIssueCredentialRecord(aRecord.id) @@ -395,6 +401,8 @@ object CredentialRepositorySpecSuite { assertTrue(record.get.issueCredentialData.isEmpty) && assertTrue(updatedRecord.get.issueCredentialData.contains(issueCredential)) && assertTrue(updatedRecord.get.issuedCredentialRaw.contains("RAW_CREDENTIAL_DATA")) + assertTrue(updatedRecord.get.credentialDefinitionUri.contains("credentialDefinitionUri")) + assertTrue(updatedRecord.get.schemaUri.contains("schemaUri")) } }, test("updateFail (fail one retry) updates record") { diff --git a/pollux/lib/core/src/test/scala/io/iohk/atala/pollux/core/service/PresentationServiceSpec.scala b/pollux/lib/core/src/test/scala/io/iohk/atala/pollux/core/service/PresentationServiceSpec.scala index 1032557c38..abe9b32a1a 100644 --- a/pollux/lib/core/src/test/scala/io/iohk/atala/pollux/core/service/PresentationServiceSpec.scala +++ b/pollux/lib/core/src/test/scala/io/iohk/atala/pollux/core/service/PresentationServiceSpec.scala @@ -232,6 +232,8 @@ object PresentationServiceSpec extends ZIOSpecDefault with PresentationServiceSp aIssueCredentialRecord.id, IssueCredential.makeIssueCredentialFromRequestCredential(requestCredential.makeMessage), rawCredentialData, + None, + None, IssueCredentialRecord.ProtocolState.CredentialReceived ) svc <- ZIO.service[PresentationService] @@ -471,6 +473,8 @@ object PresentationServiceSpec extends ZIOSpecDefault with PresentationServiceSp aIssueCredentialRecord.id, IssueCredential.makeIssueCredentialFromRequestCredential(requestCredential.makeMessage), rawCredentialData, + None, + None, IssueCredentialRecord.ProtocolState.CredentialReceived ) svc <- ZIO.service[PresentationService] @@ -500,6 +504,8 @@ object PresentationServiceSpec extends ZIOSpecDefault with PresentationServiceSp aIssueCredentialRecord.id, IssueCredential.makeIssueCredentialFromRequestCredential(requestCredential.makeMessage), rawCredentialData, + Some("SchemaId"), + Some("CredDefId"), IssueCredentialRecord.ProtocolState.CredentialReceived ) svc <- ZIO.service[PresentationService] @@ -557,6 +563,8 @@ object PresentationServiceSpec extends ZIOSpecDefault with PresentationServiceSp aIssueCredentialRecord.id, IssueCredential.makeIssueCredentialFromRequestCredential(requestCredential.makeMessage), rawCredentialData, + None, + None, IssueCredentialRecord.ProtocolState.CredentialReceived ) svc <- ZIO.service[PresentationService] @@ -888,11 +896,9 @@ object PresentationServiceSpec extends ZIOSpecDefault with PresentationServiceSp Some(credentialsToUseJson), PresentationRecord.ProtocolState.RequestPending ) - issuer = createIssuer(DID("did:prism:issuer")) presentation <- svc.createAnoncredPresentation( aRecord.requestPresentationData.get, aRecord.id, - issuer, credentialsToUse, Instant.now() ) diff --git a/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/JdbcCredentialRepository.scala b/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/JdbcCredentialRepository.scala index 8d86a432df..a6b36aead7 100644 --- a/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/JdbcCredentialRepository.scala +++ b/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/JdbcCredentialRepository.scala @@ -2,6 +2,7 @@ package io.iohk.atala.pollux.sql.repository import cats.data.NonEmptyList import doobie.* +import doobie.free.connection import doobie.implicits.* import doobie.postgres.implicits.* import io.circe.* @@ -19,11 +20,11 @@ import io.iohk.atala.shared.db.Implicits.* import io.iohk.atala.shared.models.WalletAccessContext import org.postgresql.util.PSQLException import zio.* +import zio.interop.catz.* import zio.json.* -import doobie.free.connection import java.time.Instant -import zio.interop.catz.* +import java.util.UUID class JdbcCredentialRepository(xa: Transactor[ContextAwareTask], xb: Transactor[Task], maxRetries: Int) extends CredentialRepository { @@ -500,11 +501,15 @@ class JdbcCredentialRepository(xa: Transactor[ContextAwareTask], xb: Transactor[ recordId: DidCommID, issue: IssueCredential, issuedRawCredential: String, + schemaUri: Option[String], + credentialDefinitionUri: Option[String], protocolState: ProtocolState ): RIO[WalletAccessContext, Int] = { val cxnIO = sql""" | UPDATE public.issue_credential_records | SET + | schema_uri = $schemaUri, + | credential_definition_uri = $credentialDefinitionUri, | issue_credential_data = $issue, | issued_credential_raw = $issuedRawCredential, | protocol_state = $protocolState, diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/jobs/PresentBackgroundJobs.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/jobs/PresentBackgroundJobs.scala index 836be0556d..87c39794a0 100644 --- a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/jobs/PresentBackgroundJobs.scala +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/jobs/PresentBackgroundJobs.scala @@ -373,16 +373,11 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { AnoncredCredentialProofsV1.schemaSerDes .deserialize(credentialsToUseJson) .mapError(error => PresentationError.UnexpectedError(error.error)) - prover <- createPrismDIDIssuerFromPresentationCredentials( - id, - anoncredCredentialProofs.credentialProofs.map(_.credential) - ).provideSomeLayer(ZLayer.succeed(walletAccessContext)) presentation <- presentationService .createAnoncredPresentation( requestPresentation, id, - prover, anoncredCredentialProofs, Instant.now() ) From b579fd86ab96db711425f511154e74be75583896 Mon Sep 17 00:00:00 2001 From: bvoiturier Date: Thu, 7 Mar 2024 14:25:39 +0100 Subject: [PATCH 4/6] docs(prism-agent): Add new ADR "handle errors in background jobs" (#921) Signed-off-by: Benjamin Voiturier --- ...-state-records-and-sending-via-webhooks.md | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 docs/decisions/20240307-handle-errors-in-bg-jobs-by-storing-on-state-records-and-sending-via-webhooks.md diff --git a/docs/decisions/20240307-handle-errors-in-bg-jobs-by-storing-on-state-records-and-sending-via-webhooks.md b/docs/decisions/20240307-handle-errors-in-bg-jobs-by-storing-on-state-records-and-sending-via-webhooks.md new file mode 100644 index 0000000000..7cf6e1e6a1 --- /dev/null +++ b/docs/decisions/20240307-handle-errors-in-bg-jobs-by-storing-on-state-records-and-sending-via-webhooks.md @@ -0,0 +1,83 @@ +# Handle errors in background jobs by storing on state records and sending via webhooks + +- Status: accepted +- Deciders: David Poltorak, Yurii Shynbuiev, Benjamin Voiturier, Fabio Pinheiro +- Date: 2024-03-07 +- Tags: error handling, background jobs, DIDComm, messaging + +## Context and Problem Statement + +In our system, background jobs play a crucial role in handling tasks such as processing DIDComm messages for establishing connections between agents. Currently, if an error occurs in a background job, the original caller is not notified of this error, leading to potential issues in tracking and managing the state of operations. If a ZIO Failure is encountered, a serialised version of the error (string) is stored in the database along the background job record, however, this attribute is not available on the API when checking the status of an operation. + +While the DIDComm Error Reporting protocol effectively handles errors in peer-to-peer communications between agents, our system lacks a robust mechanism for notifying clients of errors occurring in background jobs. This gap in error handling affects transparency and the ability to respond to issues promptly. How can we ensure clients are effectively notified of errors in background jobs, especially when such errors cannot be communicated via DIDComm Error Reporting? + +## Decision Drivers + +- Transparency and traceability of errors +- System reliability and robust error handling, reliability of background job processing +- Minimising the impact of errors on user experience +- Complementing the DIDComm Error Reporting protocol +- Future scalability is not hampered by the solution we put in place + +## Considered Options + +1. Storing error information in database records + - Storing in RFC 9457 Problem Details for HTTP APIs format + - Storing in proprietary format + - Storing as ZIO.Failure string (as is) + - Enhancing the API to return this attribute of the record when checking the status of an operation +2. Creating a central registry of errors +3. Using existing webhook system to send errors to clients +4. Implementing event-driven error notifications + +## Decision Outcome + +Chosen Option: Combined 1 and 3 + +We have opted for enhanced error handling by storing error details on background job records in the RFC 9457 Problem Details for HTTP APIs format and leveraging webhooks for error notifications. This approach is selected because it aligns with our objectives of enhancing system reliability and error handling for background jobs. It provides a transparent mechanism for users to be informed about errors and leverages the existing webhook system, thereby avoiding the introduction of unnecessary complexity through event-driven architecture or a central registry. + +### Implementation Strategy + +- Storing Error Information on Job Records: We will serialise error details into a JSON object that adheres to the RFC 9457 structure and store this information in a dedicated field within the background job records. This method is intended to enhance the visibility of errors and assist in the debugging process. +- Include error attribute in API responses: We will ensure that the error object is returned on any object which represents the state of a background job (Connection, Issuance or Present Proof) +- Webhook Notifications: Our strategy includes making use of the existing webhook system to notify clients of errors in real-time. This utilisation ensures that clients are promptly informed of any issues, enhancing the overall user experience and system responsiveness to error conditions. + +### Positive Consequences + +- Clients receive immediate, standardised notifications of errors, improving transparency. +- Error details are systematically logged, enhancing system monitoring and debugging capabilities. +- The approach scales well with system growth and can adapt to future requirements for error handling. +- **Error messages logged on records will be secured by the active WalletContext** + +### Negative Consequences + +- No central place to access error instances as per RFC 9457 specification. +- Clients will need to manage potential unknown failures of webhook calls to their system (from agent to client) as webhook events are not persisted. +- Error information will need to be made available when retrieving background job processing records through the operation API that generated them. + +### Storing error information in database records + +- Good, because it provides a persistent record of errors. +- Good, RFC 9457 Problem Details for HTTP APIs format, as it provides a standardised way to represent errors. +- Bad, proprietary format, as it requires converting to RFC 9457 to be sent to the user. +- Bad, because it requires manual checking and doesn't proactively notify interested parties. + +### Creating a central registry of errors + +- Good, because it centralises error management. +- Bad, because it can become a bottleneck and still lacks proactive notification. +- Bad, because it carries a lot of complexity that may not get used as data can be made available on other RESTFul APIs in a more cohesive way (such as retrieving a connection record can include the errors about creating that connection). + +### Using existing webhook system to send errors to clients + +- Good, because it leverages existing implementation and communication channels to send events. +- Bad, because it is limited by the existing system (events not persisted). + +### Implementing event-driven error notifications + +- Good, because it provides real-time, scalable notifications. +- Bad, because it requires the setup and management of an event-driven system. + +## Links + +- [DIDComm Messaging Specification](https://identity.foundation/didcomm-messaging/spec/) \ No newline at end of file From 0402a8778eda839521c55a127934fba41c7b79ad Mon Sep 17 00:00:00 2001 From: Shailesh Patil <53746241+mineme0110@users.noreply.github.com> Date: Tue, 12 Mar 2024 13:39:52 +0000 Subject: [PATCH 5/6] fix(prism-agent): add validation for endpoint url (#919) Signed-off-by: mineme0110 --- .../atala/agent/server/config/AppConfig.scala | 20 +++++++++++++--- .../agent/server/config/AppConfigSpec.scala | 23 ++++++++++++++++++- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/config/AppConfig.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/config/AppConfig.scala index d998e11dc4..08b5647f3e 100644 --- a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/config/AppConfig.scala +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/config/AppConfig.scala @@ -6,7 +6,6 @@ import io.iohk.atala.pollux.vc.jwt.* import io.iohk.atala.shared.db.DbConfig import zio.config.* import zio.config.magnolia.Descriptor - import java.net.URL import java.time.Duration import scala.util.Try @@ -163,13 +162,28 @@ final case class AgentConfig( "The default wallet must be enabled if all the authentication methods are disabled. Default wallet is required for the single-tenant mode." ) _ <- secretStorage.validate + _ <- httpEndpoint.validate + _ <- didCommEndpoint.validate } yield () } -final case class HttpEndpointConfig(http: HttpConfig, publicEndpointUrl: String) +object EndpointConfig { + def validate(url: String): Either[String, Unit] = { + val urlRegex = """^(http|https)://[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(:[0-9]{1,5})?(/.*)?$""".r + urlRegex.findFirstMatchIn(url) match + case Some(_) => Right(()) + case _ => Left(s"Invalid URL: $url") + } +} + +final case class HttpEndpointConfig(http: HttpConfig, publicEndpointUrl: String) { + def validate: Either[String, Unit] = EndpointConfig.validate(publicEndpointUrl) +} -final case class DidCommEndpointConfig(http: HttpConfig, publicEndpointUrl: String) +final case class DidCommEndpointConfig(http: HttpConfig, publicEndpointUrl: String) { + def validate: Either[String, Unit] = EndpointConfig.validate(publicEndpointUrl) +} final case class HttpConfig(port: Int) diff --git a/prism-agent/service/server/src/test/scala/io/iohk/atala/agent/server/config/AppConfigSpec.scala b/prism-agent/service/server/src/test/scala/io/iohk/atala/agent/server/config/AppConfigSpec.scala index 7f31ac6ec8..b373e51d80 100644 --- a/prism-agent/service/server/src/test/scala/io/iohk/atala/agent/server/config/AppConfigSpec.scala +++ b/prism-agent/service/server/src/test/scala/io/iohk/atala/agent/server/config/AppConfigSpec.scala @@ -16,6 +16,7 @@ object AppConfigSpec extends ZIOSpecDefault { appRoleSecretId = None, useSemanticPath = true, ) + private val baseInvalidHttpEndpointConfig = "http://:8080" override def spec = suite("AppConfigSpec")( test("load config successfully") { @@ -73,7 +74,27 @@ object AppConfigSpec extends ZIOSpecDefault { appRoleSecretId = Some("secretId"), ) assert(vaultConfig.validate)(isRight(isSubtype[ValidatedVaultConfig.TokenAuth](anything))) - } + }, + test("reject config when invalid http endpoint config provided") { + for { + appConfig <- ZIO.serviceWith[AppConfig]( + _.focus(_.agent.secretStorage.backend) + .replace(SecretStorageBackend.memory) + .focus(_.agent.httpEndpoint.publicEndpointUrl) + .replace(baseInvalidHttpEndpointConfig) + ) + } yield assert(appConfig.validate)(isLeft(containsString("Invalid URL: http://:8080"))) + }, + test("reject config when invalid http didcomm service endpoint url provided") { + for { + appConfig <- ZIO.serviceWith[AppConfig]( + _.focus(_.agent.secretStorage.backend) + .replace(SecretStorageBackend.memory) + .focus(_.agent.didCommEndpoint.publicEndpointUrl) + .replace(baseInvalidHttpEndpointConfig) + ) + } yield assert(appConfig.validate)(isLeft(containsString("Invalid URL: http://:8080"))) + }, ).provide(SystemModule.configLayer) } From 27a157fb5a83a33704230b35eca80f297eec9a85 Mon Sep 17 00:00:00 2001 From: Bassam Date: Wed, 13 Mar 2024 15:05:49 -0400 Subject: [PATCH 6/6] fix: add Anoncreds Integration Test (#923) Signed-off-by: Bassam Riman --- .mega-linter.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.mega-linter.yml b/.mega-linter.yml index fac5888c12..67433327e0 100644 --- a/.mega-linter.yml +++ b/.mega-linter.yml @@ -16,6 +16,7 @@ DISABLE_LINTERS: - C_CPPLINT # For pollux/lib/anoncreds/src/main/c - CPP_CPPLINT # For pollux/lib/anoncreds/src/main/c - JAVA_CHECKSTYLE # For pollux/lib/anoncreds/src/main/java + - GHERKIN_GHERKIN_LINT DISABLE_ERRORS_LINTERS: - KOTLIN_KTLINT