Skip to content

Commit

Permalink
feat: Add config from application.conf and docker-compose and an exam…
Browse files Browse the repository at this point in the history
…ple (#10)
  • Loading branch information
FabioPinheiro authored and mineme0110 committed Apr 30, 2024
1 parent 5e767c8 commit 2f661e7
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 53 deletions.
11 changes: 8 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ lazy val V = new {
// val zioJson = "0.4.2"
// val zioMunitTest = "0.1.1"
val zioHttp = "0.0.5"
val zioConfig = "4.0.0-RC16"
// val zioPrelude = "1.0.0-RC19"

// // https://mvnrepository.com/artifact/io.github.cquiroz/scala-java-time
Expand Down Expand Up @@ -61,7 +62,10 @@ lazy val D = new {
// val zio = Def.setting("dev.zio" %%% "zio" % V.zio)
// val zioStreams = Def.setting("dev.zio" %%% "zio-streams" % V.zio)
// val zioJson = Def.setting("dev.zio" %%% "zio-json" % V.zioJson)
val ziohttp = Def.setting("dev.zio" %% "zio-http" % V.zioHttp)
val zioHttp = Def.setting("dev.zio" %% "zio-http" % V.zioHttp)
val zioConfig = Def.setting("dev.zio" %% "zio-config" % V.zioConfig)
val zioConfigMagnolia = Def.setting("dev.zio" %% "zio-config-magnolia" % V.zioConfig) // For deriveConfig
val zioConfigTypesafe = Def.setting("dev.zio" %% "zio-config-typesafe" % V.zioConfig) // For HOCON
// val zioPrelude = Def.setting("dev.zio" %%% "zio-prelude" % V.zioPrelude)
// // val zioTest = Def.setting("dev.zio" %%% "zio-test" % V.zio % Test)
// // val zioTestSBT = Def.setting("dev.zio" %%% "zio-test-sbt" % V.zio % Test)
Expand Down Expand Up @@ -171,7 +175,7 @@ lazy val httpUtils = crossProject(JSPlatform, JVMPlatform) // project
libraryDependencies += D.scalaDID.value,
)
.jvmSettings(
libraryDependencies += D.ziohttp.value,
libraryDependencies += D.zioHttp.value,
)

lazy val mediator = project
Expand All @@ -180,7 +184,8 @@ lazy val mediator = project
.settings(
libraryDependencies += D.scalaDID_imp.value,
libraryDependencies += D.scalaDID_peer.value,
libraryDependencies += D.ziohttp.value,
libraryDependencies += D.zioHttp.value,
libraryDependencies ++= Seq(D.zioConfig.value, D.zioConfigMagnolia.value, D.zioConfigTypesafe.value),
)
.settings(
Compile / mainClass := Some("fmgp.did.demo.MediatorStandalone"),
Expand Down
24 changes: 24 additions & 0 deletions did-mediator/src/main/resources/application.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
mediator = {
identity = {
keyAgreement = {
kty = "OKP"
crv = "X25519"
d = "Z6D8LduZgZ6LnrOHPrMTS6uU2u5Btsrk1SGs4fn8M7c"
d = ${?KEY_AGREEMENT_D}
x = "Sr4SkIskjN_VdKTn0zkjYbhGTWArdUNE4j_DmUpnQGw"
x = ${?KEY_AGREEMENT_X}
}
keyAuthentication = {
kty = "OKP"
crv = "Ed25519"
d = "INXCnxFEl0atLIIQYruHzGd5sUivMRyQOzu87qVerug"
d = ${?KEY_AUTHENTICATION_D}
x = "MBjnXZxkMcoQVVL21hahWAw43RuAG-i64ipbeKKqwoA"
x = ${?KEY_AUTHENTICATION_X}
}
endpoint = "https://k8s-int.atalaprism.io/mediator"
endpoint = ${?SERVICE_ENDPOINT}
}
server.http.port = 8080
# server.http.port = ${?PORT}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import zio.http.socket._
import zio.http.ZClient.ClientLive
import zio.http.Http.Empty
import zio.http.Http.Static
import zio.config._
import zio.config.magnolia._
import zio.config.typesafe._

import scala.io.Source

Expand All @@ -19,7 +22,15 @@ import fmgp.did._
import fmgp.did.comm._
import fmgp.did.comm.mediator._
import fmgp.did.comm.protocol._
import fmgp.did.method.peer.DidPeerResolver
import fmgp.did.method.peer._

case class MediatorConfig(endpoint: java.net.URI, keyAgreement: OKPPrivateKey, keyAuthentication: OKPPrivateKey) {
val did = DIDPeer2.makeAgent(
Seq(keyAgreement, keyAuthentication),
Seq(DIDPeerServiceEncoded(s = endpoint.toString()))
)
val agentLayer = ZLayer(MediatorAgent.make(id = did.id, keyStore = did.keyStore))
}

object MediatorStandalone extends ZIOAppDefault {

Expand All @@ -31,40 +42,6 @@ object MediatorStandalone extends ZIOAppDefault {
.collectZIO[Request] { case Method.GET -> !! / "hello" =>
ZIO.succeed(Response.text("Hello World! DID Comm Mediator APP")).debug
}

val mediatorAgentLayer = ZLayer(
MediatorAgent.make( // https://k8s-int.atalaprism.io/
DIDSubject(
"did:peer:2"
+ ".Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y"
+ ".Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd"
+ ".SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9rOHMtaW50LmF0YWxhcHJpc20uaW8vbWVkaWF0b3IiLCJyIjpbXSwiYSI6WyJkaWRjb21tL3YyIl19"
),
KeyStore(
Set(
OKPPrivateKey(
kty = KTY.OKP,
crv = Curve.X25519,
d = "Z6D8LduZgZ6LnrOHPrMTS6uU2u5Btsrk1SGs4fn8M7c",
x = "Sr4SkIskjN_VdKTn0zkjYbhGTWArdUNE4j_DmUpnQGw",
kid = Some(
"did:peer:2.Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y.Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9rOHMtaW50LmF0YWxhcHJpc20uaW8vbWVkaWF0b3IiLCJyIjpbXSwiYSI6WyJkaWRjb21tL3YyIl19#6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y"
)
), // keyAgreement
OKPPrivateKey(
kty = KTY.OKP,
crv = Curve.Ed25519,
d = "INXCnxFEl0atLIIQYruHzGd5sUivMRyQOzu87qVerug",
x = "MBjnXZxkMcoQVVL21hahWAw43RuAG-i64ipbeKKqwoA",
kid = Some(
"did:peer:2.Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y.Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9rOHMtaW50LmF0YWxhcHJpc20uaW8vbWVkaWF0b3IiLCJyIjpbXSwiYSI6WyJkaWRjb21tL3YyIl19#6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd"
)
)
)
),
)
)

override val run = for {
_ <- Console.printLine( // https://patorjk.com/software/taag/#p=display&f=ANSI%20Shadow&t=Mediator
"""███╗ ███╗███████╗██████╗ ██╗ █████╗ ████████╗ ██████╗ ██████╗
Expand All @@ -76,23 +53,18 @@ object MediatorStandalone extends ZIOAppDefault {
|Yet another server simpler Mediator server DID Comm v2.
|Vist: https://github.com/input-output-hk/atala-prism-mediator""".stripMargin
)
configs = ConfigProvider.fromResourcePath()
mediatorConfig <- configs.nested("identity").nested("mediator").load(deriveConfig[MediatorConfig])
_ <- ZIO.log(s"Mediator APP. See https://github.com/input-output-hk/atala-prism-mediator")
_ <- ZIO.log(s"MediatorConfig: $mediatorConfig")
_ <- ZIO.log(s"DID: ${mediatorConfig.did.id.string}")
myHub <- Hub.sliding[String](5)
_ <- ZStream.fromHub(myHub).run(ZSink.foreach((str: String) => ZIO.logInfo("HUB: " + str))).fork
// pord <- System
// .property("PORD")
// .flatMap {
// case None => System.property("pord")
// case Some(value) => ZIO.succeed(Some(value))
// }
// .map(_.flatMap(_.toBooleanOption).getOrElse(false))
port <- System
.property("PORT")
.flatMap {
case None => System.property("port")
case Some(value) => ZIO.succeed(Some(value))
}
.map(_.flatMap(_.toIntOption).getOrElse(8080))
port <- configs
.nested("http")
.nested("server")
.nested("mediator")
.load(Config.int("port"))
_ <- ZIO.log(s"Starting server on port: $port")
server = {
val config = ServerConfig(address = new java.net.InetSocketAddress(port))
Expand All @@ -114,7 +86,7 @@ object MediatorStandalone extends ZIOAppDefault {
)
)
.provideSomeLayer(DidPeerResolver.layerDidPeerResolver)
.provideSomeLayer(mediatorAgentLayer) // .provideSomeLayer(AgentByHost.layer)
.provideSomeLayer(mediatorConfig.agentLayer) // .provideSomeLayer(AgentByHost.layer)
.provideSomeLayer(Operations.layerDefault)
.provideSomeLayer(client >>> MessageDispatcherJVM.layer)
.provideSomeLayer(ZLayer.fromZIO(Ref.make[MediatorDB](MediatorDB.empty))) // TODO move into AgentByHost
Expand Down
38 changes: 38 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
version: '3.9'

services:
# mongo:
# image: mongo:5.0
# ports:
# - 27017:27017
# #volumes:
# # - ./tmp/mongo:/data/db
# environment:
# - MONGO_INITDB_ROOT_USERNAME=admin
# - MONGO_INITDB_ROOT_PASSWORD=admin

atalaprism-mediator:
image: ghcr.io/input-output-hk/mediator:0.1.1-SNAPSHOT
ports:
- 8080:8080
network_mode: host
environment:
# Creates the identity: "did:peer:2.Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y.Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9rOHMtaW50LmF0YWxhcHJpc20uaW8vbWVkaWF0b3IiLCJyIjpbXSwiYSI6WyJkaWRjb21tL3YyIl19"
- KEY_AGREEMENT_D=Z6D8LduZgZ6LnrOHPrMTS6uU2u5Btsrk1SGs4fn8M7c
- KEY_AGREEMENT_X=Sr4SkIskjN_VdKTn0zkjYbhGTWArdUNE4j_DmUpnQGw
- KEY_AUTHENTICATION_D=INXCnxFEl0atLIIQYruHzGd5sUivMRyQOzu87qVerug
- KEY_AUTHENTICATION_X=MBjnXZxkMcoQVVL21hahWAw43RuAG-i64ipbeKKqwoA
- SERVICE_ENDPOINT=https://k8s-int.atalaprism.io/mediator
# Config storage
#- DB_URL=mongodb://admin:admin@mongo:27017
#- MONGODB_USER=admin
#- MONGODB_PASSWORD=admin
# depends_on:
# - "mongo"


# RUN
# docker-compose up -d
# docker-compose ps
# docker-compose exec mongo /bin/sh
# docker exec -it mongo-1 bash
89 changes: 89 additions & 0 deletions make-trust-ping-example.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@

# Test Mediator (Trust Ping)

## Compile and Run the Mediator on docker

```shell
docker:publishLocal # Compile and create the mediator image
docker-compose up #docker run -p 8080:8080 ghcr.io/input-output-hk/mediator:0.1.0-SNAPSHOT
```

## Run the client

```shell
scala-cli repl \
--dependency app.fmgp::did::0.1.0-M2 \
--dependency app.fmgp::did-imp::0.1.0-M2 \
--dependency app.fmgp::did-method-peer::0.1.0-M2 \
--repo https://oss.sonatype.org/content/repositories/releases
```


```scala
import zio._
import zio.json._
import fmgp.crypto._
import fmgp.did._
import fmgp.did.comm._
import fmgp.did.comm.protocol.trustping2._
import fmgp.did.method.peer._

val agent = DIDPeer2.makeAgent(
Seq(
OKPPrivateKey(// keyAgreement
kty = KTY.OKP,
crv = Curve.X25519,
d = "Z6D8LduZgZ6LnrOHPrMTS6uU2u5Btsrk1SGs4fn8M7c",
x = "Sr4SkIskjN_VdKTn0zkjYbhGTWArdUNE4j_DmUpnQGw",
kid = None
),
OKPPrivateKey(//keyAuthentication
kty = KTY.OKP,
crv = Curve.Ed25519,
d = "INXCnxFEl0atLIIQYruHzGd5sUivMRyQOzu87qVerug",
x = "MBjnXZxkMcoQVVL21hahWAw43RuAG-i64ipbeKKqwoA",
kid = None
)
),
Seq(DIDPeerServiceEncoded(s = "http://localhost:5000/"))
)

val mediator = "did:peer:2.Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y.Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9rOHMtaW50LmF0YWxhcHJpc20uaW8vbWVkaWF0b3IiLCJyIjpbXSwiYSI6WyJkaWRjb21tL3YyIl19"

val ping = TrustPingWithRequestedResponse(from = agent.id, to = TO(mediator))

val program = for {
msg <- Operations.authEncrypt(ping.toPlaintextMessage)
_ <- Console.printLine(msg.toJson)
} yield ()

Unsafe.unsafe { implicit unsafe => // Run side efect
Runtime.default.unsafe
.run(program.provide(Operations.layerDefault ++ DidPeerResolver.layer ++ ZLayer.succeed(agent)))
.getOrThrowFiberFailure()
}
```

To send the trust ping you can do a request with curl `curl -X POST http://localhost:8080 -H 'content-type: application/didcomm-encrypted+json' -d'...'` (replace `...` with the encrypted DID Comm message you get from the code above).

To receive the reply you can have netcat running like `nc -nl -p 5000`.

Then you can decrypt reply with the follow code:

```scala

val reply = """{"ciphertext":"863YmjDPR5mYlJtTEfTUFW11wpCKxsVKpDeEWtQPAqbPlECVIDKaCkh0j_tjpSQomgQL93MjrtjuTo3OnIU2EfHDX8t2mkf84muUSmeQtfMnN_ZmRYPxKw3WG_XUGrE25m8zAcce3RClm13TK9Y3XHeM4vrrExfOBYFcIIUoT9yWPIWb6Y39fRNyvlbNuYcEbsPR3RfvecOcBQJ3YaTlpzVjdgXaICZ4oC_5aVRX3EXsIhmEfjt6lBOGmstGT3zPAsLoP8mjb9GbwOIwpbj4u2BczjMDkUsezuzHsyCeilMGziG5Zr7D64Cjbt8Pg2F11vx4sLW11U3hfjRJ0gnShyBzSAOZmrR_TVBWGaP2KOELRtY4Inp8SzP4-YG89Ie2Cu9ZJesZr4eHYe5qFbI7IZg5lALazTtKodoehFuUDk9YklW8xip5_4-yIWKvj0_j79VBoTf3NiEyRz6CmPiW3Mtx5QJwt56Gb1DkLIkgyO5p_N6mUO3wntOa-bwW4ukYCG8eGnM05ENkIOpVW6DU2b5kvfuQarlG_QRXeUPy5hSjZjDa6WM6HwrbiXCFPc6-s3iMKs7IfrezVt7lN-hUynInR9duWNQLJEbyr_-Ete7r7YJDoORLemF6VGAfihO4ut1ceYIeYpF30saz9n6avVasaDSO_mErx8HvucXpZ8CzwyIO3PBImFi_EFP3VI1JGCE3b5EwUDXbkmUKIj1QbOrt_5kpmojgGP5h9Bi5Fzca9DEJrXsB2MTrXCNMhc1vUH5btMQy3guCmERrzcKIPPFhC8LMZshUzDRU1TDFKBUsUzcPitbi2wxz1zWV9ENnpLWil6pxu0LyNfjfz83GBA","protected":"eyJlcGsiOnsia3R5IjoiT0tQIiwiY3J2IjoiWDI1NTE5IiwieCI6InE1dW1XUnQ0dE5YeWM1eUlWOG84R1Jaekc5YUZmWlhkeHYxMlIwaktNRDgifSwiYXB2IjoidWRmdmFEZFpKNTFEdFJPZm8tOW1nMXRCOTRhM3ZxRFFhaFdpZXNNZjd3VSIsInNraWQiOiJkaWQ6cGVlcjoyLkV6NkxTZ2h3U0U0Mzd3bkRFMXB0M1g2aFZEVVF6U2pzSHppbnBYM1hGdk1qUkFtN3kuVno2TWtoaDFlNUNFWVlxNkpCVWNUWjZDcDJyYW5DV1JydjdZYXgzTGU0TjU5UjZkZC5TZXlKMElqb2laRzBpTENKeklqb2lhSFIwY0hNNkx5OXJPSE10YVc1MExtRjBZV3hoY0hKcGMyMHVhVzh2YldWa2FXRjBiM0lpTENKeUlqcGJYU3dpWVNJNld5SmthV1JqYjIxdEwzWXlJbDE5IzZMU2dod1NFNDM3d25ERTFwdDNYNmhWRFVRelNqc0h6aW5wWDNYRnZNalJBbTd5IiwiYXB1IjoiWkdsa09uQmxaWEk2TWk1RmVqWk1VMmRvZDFORk5ETTNkMjVFUlRGd2RETllObWhXUkZWUmVsTnFjMGg2YVc1d1dETllSblpOYWxKQmJUZDVMbFo2TmsxcmFHZ3haVFZEUlZsWmNUWktRbFZqVkZvMlEzQXljbUZ1UTFkU2NuWTNXV0Y0TTB4bE5FNDFPVkkyWkdRdVUyVjVTakJKYW05cFdrY3dhVXhEU25wSmFtOXBZVWhTTUdOSVRUWk1lVGx5VDBoTmRHRlhOVEJNYlVZd1dWZDRhR05JU25Cak1qQjFZVmM0ZG1KWFZtdGhWMFl3WWpOSmFVeERTbmxKYW5CaVdGTjNhVmxUU1RaWGVVcHJZVmRTYW1JeU1YUk1NMWw1U1d3eE9TTTJURk5uYUhkVFJUUXpOM2R1UkVVeGNIUXpXRFpvVmtSVlVYcFRhbk5JZW1sdWNGZ3pXRVoyVFdwU1FXMDNlUSIsInR5cCI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tZW5jcnlwdGVkK2pzb24iLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwiYWxnIjoiRUNESC0xUFUrQTI1NktXIn0","recipients":[{"encrypted_key":"yhqQA2n2QRm5e8m15hVsRWoL4BcEooLBlROwAYenUIOOwc90jK-9uDO2qAiV8eamgU9GQZ0dNYFM2oyaRQaewnIbCIyM6nwg","header":{"kid":"did:peer:2.Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y.Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd.SeyJ0IjoiZG0iLCJzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwLyIsInIiOltdLCJhIjpbImRpZGNvbW0vdjIiXX0#6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y"}}],"tag":"Xm_uDGCkZVjgWc8d0dr_N2L5gN8ll_rPvLyexiiImlM","iv":"46H81iydYSwZColseMrf-g"}"""
.fromJson[EncryptedMessage]
.getOrElse(???)

val program2 = for {
msg <- Operations.anonDecrypt(reply)
_ <- Console.printLine(msg.toJson)
} yield ()

Unsafe.unsafe { implicit unsafe => // Run side efect
Runtime.default.unsafe
.run(program2.provide(Operations.layerDefault ++ DidPeerResolver.layer ++ ZLayer.succeed(agent)))
.getOrThrowFiberFailure()
}
```

0 comments on commit 2f661e7

Please sign in to comment.