From 40f2fdb52c2af7e4710c9770ba2e92a0208503b1 Mon Sep 17 00:00:00 2001 From: atala-dev <57987237+atala-dev@users.noreply.github.com> Date: Tue, 24 Oct 2023 12:13:03 +0100 Subject: [PATCH 1/9] Update sbt to 1.9.7 in main (#143) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index dde206f7..d4151995 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.6 \ No newline at end of file +sbt.version=1.9.7 \ No newline at end of file From df522cf57e550827dbfa3bff665c00b63051018e Mon Sep 17 00:00:00 2001 From: Shailesh Patil <53746241+mineme0110@users.noreply.github.com> Date: Fri, 27 Oct 2023 12:27:48 +0100 Subject: [PATCH 2/9] fix: Send problemReport for duplicate message (#157) fix: Sendproblem report for duplicate message Signed-off-by: mineme0110 --- .../scala/io/iohk/atala/mediator/Error.scala | 6 ++++ .../atala/mediator/app/MediatorAgent.scala | 36 ++++++++++++++----- .../atala/mediator/db/MessageItemRepo.scala | 8 +++-- .../atala/mediator/protocols/Problems.scala | 17 +++++++++ .../mediator/db/MessageItemRepoSpec.scala | 13 +++++++ 5 files changed, 70 insertions(+), 10 deletions(-) diff --git a/mediator/src/main/scala/io/iohk/atala/mediator/Error.scala b/mediator/src/main/scala/io/iohk/atala/mediator/Error.scala index a75f023b..c4aa84a0 100644 --- a/mediator/src/main/scala/io/iohk/atala/mediator/Error.scala +++ b/mediator/src/main/scala/io/iohk/atala/mediator/Error.scala @@ -36,6 +36,12 @@ object StorageThrowable { def apply(throwable: Throwable) = new StorageThrowable(throwable.getClass.getName() + ":" + throwable.getMessage) } +final case class DuplicateMessage(val error: String) extends StorageError +object DuplicateMessage { + val code = 11000 + def apply(throwable: Throwable) = new DuplicateMessage(throwable.getClass.getName() + ":" + throwable.getMessage) +} + // ProtocolError sealed trait ProtocolError extends MediatorError { def piuri: PIURI diff --git a/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala b/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala index ccaeaeab..dba3230f 100644 --- a/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala +++ b/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala @@ -102,7 +102,7 @@ case class MediatorAgent( maybeSyncReplyMsg <- receiveMessage(msg) } yield (maybeSyncReplyMsg) - def receiveMessage(msg: EncryptedMessage): ZIO[ + private def receiveMessage(msg: EncryptedMessage): ZIO[ Operations & Resolver & MessageDispatcher & MediatorAgent & MessageItemRepo & UserAccountRepo & OutboxMessageRepo, MediatorError | StorageError, Option[SignedMessage | EncryptedMessage] @@ -122,9 +122,7 @@ case class MediatorAgent( plaintextMessage <- decrypt(msg) maybeActionStorageError <- messageItemRepo .insert(msg) // store all message - .map(_ /*WriteResult*/ => None - // TODO messages already on the database -> so this might be a replay attack - ) + .map(_ /*WriteResult*/ => None) .catchSome { case StorageCollection(error) => // This deals with connection errors to the database. @@ -163,6 +161,24 @@ case class MediatorAgent( ) ) ) + case DuplicateMessage(error) => + ZIO.logWarning(s"Error DuplicateMessageError: $error") *> + ZIO + .service[Agent] + .map(agent => + Some( + Reply( + Problems + .dejavuError( + to = plaintextMessage.from.map(_.asTO).toSet, + from = agent.id, + pthid = plaintextMessage.id, + piuri = plaintextMessage.`type`, + ) + .toPlaintextMessage + ) + ) + ) } // TODO Store context of the decrypt unwarping // TODO SreceiveMessagetore context with MsgID and PIURI @@ -173,10 +189,11 @@ case class MediatorAgent( }.tapError(ex => ZIO.logError(s"Error when execute Protocol: $ex")) } yield ret }.catchAll { - case ex: MediatorError => ZIO.fail(ex) - case pr: ProblemReport => ActionUtils.packResponse(None, Reply(pr.toPlaintextMessage)) - case ex: StorageCollection => ZIO.fail(ex) - case ex: StorageThrowable => ZIO.fail(ex) + case ex: MediatorError => ZIO.fail(ex) + case pr: ProblemReport => ActionUtils.packResponse(None, Reply(pr.toPlaintextMessage)) + case ex: StorageCollection => ZIO.fail(ex) + case ex: StorageThrowable => ZIO.fail(ex) + case ex: DuplicateMessage => ZIO.fail(ex) } } yield maybeSyncReplyMsg } @@ -267,6 +284,9 @@ object MediatorAgent { case StorageThrowable(error) => ZIO.logError(s"Error StorageThrowable: $error") *> ZIO.succeed(Response.status(Status.BadRequest)) + case DuplicateMessage(error) => + ZIO.logError(s"Error DuplicateKeyError: $error") *> + ZIO.succeed(Response.status(Status.BadRequest)) case MissingProtocolError(piuri) => ZIO.logError(s"MissingProtocolError ('$piuri')") *> ZIO.succeed(Response.status(Status.BadRequest)) // TODO diff --git a/mediator/src/main/scala/io/iohk/atala/mediator/db/MessageItemRepo.scala b/mediator/src/main/scala/io/iohk/atala/mediator/db/MessageItemRepo.scala index f5143477..023e3ab7 100644 --- a/mediator/src/main/scala/io/iohk/atala/mediator/db/MessageItemRepo.scala +++ b/mediator/src/main/scala/io/iohk/atala/mediator/db/MessageItemRepo.scala @@ -2,12 +2,13 @@ package io.iohk.atala.mediator.db import fmgp.did.* import fmgp.did.comm.EncryptedMessage -import io.iohk.atala.mediator.{StorageCollection, StorageError, StorageThrowable} +import io.iohk.atala.mediator.{DuplicateMessage, StorageCollection, StorageError, StorageThrowable} import reactivemongo.api.bson.* import reactivemongo.api.bson.collection.BSONCollection import reactivemongo.api.commands.WriteResult import reactivemongo.api.{Cursor, CursorProducer} import zio.* +import reactivemongo.core.errors.DatabaseException import scala.concurrent.ExecutionContext object MessageItemRepo { @@ -34,7 +35,10 @@ class MessageItemRepo(reactiveMongoApi: ReactiveMongoApi)(using ec: ExecutionCon result <- ZIO .fromFuture(implicit ec => coll.insert.one(MessageItem(msg, xRequestId))) .tapError(err => ZIO.logError(s"insert : ${err.getMessage}")) - .mapError(ex => StorageThrowable(ex)) + .mapError { + case ex: DatabaseException if (ex.code.contains(DuplicateMessage.code)) => DuplicateMessage(ex) + case ex => StorageThrowable(ex) + } } yield result } diff --git a/mediator/src/main/scala/io/iohk/atala/mediator/protocols/Problems.scala b/mediator/src/main/scala/io/iohk/atala/mediator/protocols/Problems.scala index 7536834e..479356a9 100644 --- a/mediator/src/main/scala/io/iohk/atala/mediator/protocols/Problems.scala +++ b/mediator/src/main/scala/io/iohk/atala/mediator/protocols/Problems.scala @@ -94,6 +94,23 @@ object Problems { escalate_to = email, ) + def dejavuError( + to: Set[TO], + from: FROM, + pthid: MsgID, + piuri: PIURI, + ) = ProblemReport( + // id: MsgID = MsgID(), + to = to, + from = from, + pthid = pthid, + ack = None, + code = ProblemCode.ErroFail("crypto", "message", "dejavu"), + comment = None, + args = None, + escalate_to = email, + ) + def notEnroledError( to: Option[TO], from: FROM, diff --git a/mediator/src/test/scala/io/iohk/atala/mediator/db/MessageItemRepoSpec.scala b/mediator/src/test/scala/io/iohk/atala/mediator/db/MessageItemRepoSpec.scala index a40611b2..0840452c 100644 --- a/mediator/src/test/scala/io/iohk/atala/mediator/db/MessageItemRepoSpec.scala +++ b/mediator/src/test/scala/io/iohk/atala/mediator/db/MessageItemRepoSpec.scala @@ -1,12 +1,14 @@ package io.iohk.atala.mediator.db import fmgp.did.comm.EncryptedMessage +import io.iohk.atala.mediator.{DuplicateMessage, StorageError, StorageThrowable} import zio.* import zio.ExecutionStrategy.Sequential import zio.json.* import zio.test.* import zio.test.Assertion.* import io.iohk.atala.mediator.db.EmbeddedMongoDBInstance.* +import reactivemongo.core.errors.DatabaseException object MessageItemRepoSpec extends ZIOSpecDefault with DidAccountStubSetup { @@ -23,7 +25,18 @@ object MessageItemRepoSpec extends ZIOSpecDefault with DidAccountStubSetup { assertTrue(result.n == 1) } } + }, + test("insert same message again") { + ZIO.logAnnotate(XRequestId.value, "b373423c-c78f-4cbc-a3fe-89cbc1351835") { + for { + messageItem <- ZIO.service[MessageItemRepo] + msg <- ZIO.fromEither(encryptedMessageAlice) + result <- messageItem.insert(msg).exit + } yield { + assert(result)(fails(isSubtype[DuplicateMessage](anything))) + } + } }, test("findById message") { for { From a8116b09ac8da249b36b8aff25a1844c618fbe42 Mon Sep 17 00:00:00 2001 From: atala-dev Date: Mon, 6 Nov 2023 14:41:48 +0000 Subject: [PATCH 3/9] chore(release): cut prism mediator 0.10.2 release ## [0.10.2](https://github.com/input-output-hk/atala-prism-mediator/compare/prism-mediator-v0.10.1...prism-mediator-v0.10.2) (2023-11-06) ### Bug Fixes * Send problemReport for duplicate message ([#157](https://github.com/input-output-hk/atala-prism-mediator/issues/157)) ([df522cf](https://github.com/input-output-hk/atala-prism-mediator/commit/df522cf57e550827dbfa3bff665c00b63051018e)) --- CHANGELOG.md | 7 +++++++ infrastructure/charts/mediator/Chart.yaml | 2 +- package-lock.json | 4 ++-- package.json | 2 +- version.sbt | 2 +- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04839dee..0c0d99e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [0.10.2](https://github.com/input-output-hk/atala-prism-mediator/compare/prism-mediator-v0.10.1...prism-mediator-v0.10.2) (2023-11-06) + + +### Bug Fixes + +* Send problemReport for duplicate message ([#157](https://github.com/input-output-hk/atala-prism-mediator/issues/157)) ([df522cf](https://github.com/input-output-hk/atala-prism-mediator/commit/df522cf57e550827dbfa3bff665c00b63051018e)) + ## [0.10.1](https://github.com/input-output-hk/atala-prism-mediator/compare/prism-mediator-v0.10.0...prism-mediator-v0.10.1) (2023-10-13) diff --git a/infrastructure/charts/mediator/Chart.yaml b/infrastructure/charts/mediator/Chart.yaml index 7048500c..f13d2b04 100644 --- a/infrastructure/charts/mediator/Chart.yaml +++ b/infrastructure/charts/mediator/Chart.yaml @@ -18,5 +18,5 @@ version: 0.1.0 # 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: "0.10.1" +appVersion: "0.10.2" dependencies: [] diff --git a/package-lock.json b/package-lock.json index d31ea066..3cdb5911 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "atala-prism-mediator", - "version": "0.10.1", + "version": "0.10.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "atala-prism-mediator", - "version": "0.10.1", + "version": "0.10.2", "devDependencies": { "@commitlint/cli": "^17.0.3", "@commitlint/config-conventional": "^17.0.3", diff --git a/package.json b/package.json index d4d1001c..91907a8e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "atala-prism-mediator", - "version": "0.10.1", + "version": "0.10.2", "engines": { "node": ">=16.13.0" }, diff --git a/version.sbt b/version.sbt index aa2cbb42..e1b9bbdc 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -ThisBuild / version := "0.10.1-SNAPSHOT" +ThisBuild / version := "0.10.2-SNAPSHOT" From 6d8b9b8493f32d27c31c44c170268cdd3cb5170b Mon Sep 17 00:00:00 2001 From: Shailesh Patil <53746241+mineme0110@users.noreply.github.com> Date: Mon, 6 Nov 2023 21:54:28 +0000 Subject: [PATCH 4/9] fix: incorrect body of the message results in problem report (#161) * fix: incorrect body of the message results in problemreport * fix: incorrect body of the message results in problemreport --- .../atala/mediator/app/MediatorAgent.scala | 27 +++++++++++++++---- .../protocols/BasicMessageExecuter.scala | 8 +++--- .../atala/mediator/protocols/Problems.scala | 17 ++++++++++++ 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala b/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala index dba3230f..a79dd525 100644 --- a/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala +++ b/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala @@ -182,18 +182,35 @@ case class MediatorAgent( } // TODO Store context of the decrypt unwarping // TODO SreceiveMessagetore context with MsgID and PIURI + agent <- ZIO.service[Agent] ret <- { maybeActionStorageError match case Some(reply) => ActionUtils.packResponse(Some(plaintextMessage), reply) case None => protocolHandler.execute(plaintextMessage) }.tapError(ex => ZIO.logError(s"Error when execute Protocol: $ex")) + .catchSome { case MediatorDidError(error) => + ZIO.logError(s"Error MediatorDidError: $error") *> + ActionUtils.packResponse( + Some(plaintextMessage), + Reply( + Problems + .malformedError( + to = plaintextMessage.from.map(_.asTO).toSet, + from = agent.id, + pthid = plaintextMessage.id, + piuri = plaintextMessage.`type`, + ) + .toPlaintextMessage + ) + ) + } } yield ret }.catchAll { - case ex: MediatorError => ZIO.fail(ex) - case pr: ProblemReport => ActionUtils.packResponse(None, Reply(pr.toPlaintextMessage)) - case ex: StorageCollection => ZIO.fail(ex) - case ex: StorageThrowable => ZIO.fail(ex) - case ex: DuplicateMessage => ZIO.fail(ex) + case ex: MediatorError => ZIO.fail(ex) + case pr: ProblemReport => ActionUtils.packResponse(None, Reply(pr.toPlaintextMessage)) + case ex: StorageCollection => ZIO.fail(ex) + case ex: StorageThrowable => ZIO.fail(ex) + case ex: DuplicateMessage => ZIO.fail(ex) } } yield maybeSyncReplyMsg } diff --git a/mediator/src/main/scala/io/iohk/atala/mediator/protocols/BasicMessageExecuter.scala b/mediator/src/main/scala/io/iohk/atala/mediator/protocols/BasicMessageExecuter.scala index 71bb73ba..4f128d1b 100644 --- a/mediator/src/main/scala/io/iohk/atala/mediator/protocols/BasicMessageExecuter.scala +++ b/mediator/src/main/scala/io/iohk/atala/mediator/protocols/BasicMessageExecuter.scala @@ -1,10 +1,10 @@ package io.iohk.atala.mediator.protocols import fmgp.crypto.error.FailToParse -import fmgp.did.comm.{PIURI, PlaintextMessage, SignedMessage, EncryptedMessage} +import fmgp.did.comm.{EncryptedMessage, PIURI, PlaintextMessage, SignedMessage} import fmgp.did.comm.protocol.basicmessage2.BasicMessage -import io.iohk.atala.mediator.{MediatorError, MediatorDidError, MediatorThrowable} -import io.iohk.atala.mediator.actions.{NoReply, ProtocolExecuter} +import io.iohk.atala.mediator.{MediatorDidError, MediatorError, MediatorThrowable, StorageError} +import io.iohk.atala.mediator.actions.{Action, NoReply, ProtocolExecuter} import zio.{Console, ZIO} object BasicMessageExecuter extends ProtocolExecuter[Any, MediatorError] { @@ -16,7 +16,7 @@ object BasicMessageExecuter extends ProtocolExecuter[Any, MediatorError] { ): ZIO[R, MediatorError, Option[SignedMessage | EncryptedMessage]] = program(plaintextMessage).debug *> ZIO.none - override def program[R1 <: Any](plaintextMessage: PlaintextMessage) = for { + override def program[R1 <: Any](plaintextMessage: PlaintextMessage): ZIO[R1, MediatorError, Action] = for { job <- BasicMessage.fromPlaintextMessage(plaintextMessage) match case Left(error) => ZIO.fail(MediatorDidError(FailToParse(error))) case Right(bm) => Console.printLine(bm.toString).mapError(ex => MediatorThrowable(ex)) diff --git a/mediator/src/main/scala/io/iohk/atala/mediator/protocols/Problems.scala b/mediator/src/main/scala/io/iohk/atala/mediator/protocols/Problems.scala index 479356a9..97c603f1 100644 --- a/mediator/src/main/scala/io/iohk/atala/mediator/protocols/Problems.scala +++ b/mediator/src/main/scala/io/iohk/atala/mediator/protocols/Problems.scala @@ -129,4 +129,21 @@ object Problems { escalate_to = email, ) + def malformedError( + to: Set[TO], + from: FROM, + pthid: MsgID, + piuri: PIURI, + ) = ProblemReport( + // id: MsgID = MsgID(), + to = to, + from = from, + pthid = pthid, + ack = None, + code = ProblemCode.ErroFail("msg", piuri.value), + comment = None, + args = None, + escalate_to = email, + ) + } From 9220858111d992c099aff9e41cce90d7d06f0235 Mon Sep 17 00:00:00 2001 From: Fabio Pinheiro Date: Tue, 7 Nov 2023 13:07:04 +0000 Subject: [PATCH 5/9] feat: Support protocol discover-features 2.0 (#154) * [WIP] feat: Support protocol discover-features 2.0 * add test * added test for non match * added test for non match --------- Co-authored-by: mineme0110 --- .../protocols/DiscoverFeaturesExecuter.scala | 80 +++++++++++++++++++ .../io/iohk/atala/mediator/db/AgentStub.scala | 1 + .../mediator/db/DidAccountStubSetup.scala | 59 ++++++++------ .../mediator/db/UserAccountRepoSpec.scala | 48 +++++------ .../DiscoverFeaturesExecuterSpec.scala | 79 ++++++++++++++++++ .../ForwardMessageExecutorSpec.scala | 9 +-- .../MediatorCoordinationExecuterSpec.scala | 4 +- .../mediator/protocols/MessageSetup.scala | 40 +++++++++- 8 files changed, 261 insertions(+), 59 deletions(-) create mode 100644 mediator/src/main/scala/io/iohk/atala/mediator/protocols/DiscoverFeaturesExecuter.scala create mode 100644 mediator/src/test/scala/io/iohk/atala/mediator/protocols/DiscoverFeaturesExecuterSpec.scala diff --git a/mediator/src/main/scala/io/iohk/atala/mediator/protocols/DiscoverFeaturesExecuter.scala b/mediator/src/main/scala/io/iohk/atala/mediator/protocols/DiscoverFeaturesExecuter.scala new file mode 100644 index 00000000..537eb7fc --- /dev/null +++ b/mediator/src/main/scala/io/iohk/atala/mediator/protocols/DiscoverFeaturesExecuter.scala @@ -0,0 +1,80 @@ +package io.iohk.atala.mediator.protocols + +import fmgp.crypto.error.FailToParse +import fmgp.did.Agent +import fmgp.did.comm.{PIURI, PlaintextMessage} +import fmgp.did.comm.protocol.discoverfeatures2._ +import io.iohk.atala.mediator.{MediatorDidError, MediatorError} +import io.iohk.atala.mediator.actions.{Action, NoReply, ProtocolExecuter, ProtocolExecuterWithServices, Reply} +import zio.ZIO + +object DiscoverFeaturesExecuter extends ProtocolExecuterWithServices[ProtocolExecuter.Services, MediatorError] { + + override def supportedPIURI: Seq[PIURI] = Seq(FeatureQuery.piuri, FeatureDisclose.piuri) + + override def program[R1 <: Agent]( + plaintextMessage: PlaintextMessage + ): ZIO[R1, MediatorError, Action] = { + // the val is from the match to be definitely stable + val piuriFeatureQuery = FeatureQuery.piuri + val piuriFeatureDisclose = FeatureDisclose.piuri + + plaintextMessage.`type` match + case `piuriFeatureQuery` => + for { + ret <- plaintextMessage.toFeatureQuery match + case Left(error) => + ZIO.logError(s"Fail in FeatureQuery: $error") *> + ZIO.fail(MediatorDidError(FailToParse(error))) + case Right(featureQuery) => + for { + _ <- ZIO.logInfo(featureQuery.toString()) + agent <- ZIO.service[Agent] + allProtocols = Seq( + FeatureDisclose.Disclose( + `feature-type` = "protocol", + id = "https://didcomm.org/routing/2.0", + roles = Some(Seq("mediator")), // sender + ), + FeatureDisclose.Disclose( + `feature-type` = "protocol", + id = "https://didcomm.org/coordinate-mediation/2.0", + roles = Some(Seq("responder")), // requester + ), + FeatureDisclose.Disclose( + `feature-type` = "protocol", + id = "https://didcomm.org/messagepickup/3.0", + roles = Some(Seq("mediator")), // recipient + ), + FeatureDisclose.Disclose( + `feature-type` = "protocol", + id = "https://didcomm.org/trust-ping/2.0", + roles = Some(Seq("receiver")), // sender + ), + FeatureDisclose.Disclose( + `feature-type` = "protocol", + id = "https://didcomm.org/discover-features/2.0", + roles = Some(Seq("responder")), // requester + ), + ) + filter = featureQuery.queries + .filter(q => q.`feature-type` == "protocol") + .map(q => scala.util.matching.Regex(q.`match`)) + discloses = filter.flatMap(reg => allProtocols.filter(e => reg.matches(e.id))).toSet + } yield FeatureDisclose( + thid = Some(featureQuery.id), + to = Set(featureQuery.from.asTO), + from = agent.id, + disclosures = discloses.toSeq, + ) + } yield Reply(ret.toPlaintextMessage) + + case `piuriFeatureDisclose` => + for { + _ <- plaintextMessage.toFeatureDisclose match + case Left(error) => ZIO.fail(MediatorDidError(FailToParse(error))) + case Right(featureDisclose) => ZIO.logInfo(featureDisclose.toString()) + } yield NoReply + } + +} diff --git a/mediator/src/test/scala/io/iohk/atala/mediator/db/AgentStub.scala b/mediator/src/test/scala/io/iohk/atala/mediator/db/AgentStub.scala index 57dde06d..d2e3bf99 100644 --- a/mediator/src/test/scala/io/iohk/atala/mediator/db/AgentStub.scala +++ b/mediator/src/test/scala/io/iohk/atala/mediator/db/AgentStub.scala @@ -45,6 +45,7 @@ object AgentStub { def bobAgentLayer: ULayer[Agent] = ZLayer.succeed(bobAgent) + /** Mediator */ val agentLayer = mediatorConfig.agentLayer } diff --git a/mediator/src/test/scala/io/iohk/atala/mediator/db/DidAccountStubSetup.scala b/mediator/src/test/scala/io/iohk/atala/mediator/db/DidAccountStubSetup.scala index 3ea4fd57..4292404d 100644 --- a/mediator/src/test/scala/io/iohk/atala/mediator/db/DidAccountStubSetup.scala +++ b/mediator/src/test/scala/io/iohk/atala/mediator/db/DidAccountStubSetup.scala @@ -1,37 +1,44 @@ package io.iohk.atala.mediator.db +import fmgp.did.DIDSubject import fmgp.did.comm.{EncryptedMessage, PlaintextMessage} import fmgp.did.method.peer.{DIDPeer2, DIDPeerServiceEncoded} //import io.iohk.atala.mediator.db.AgentStub.{keyAgreement, keyAuthentication} import zio.json.* trait DidAccountStubSetup { val alice = - "did:peer:2.Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y.Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd.SeyJ0IjoiZG0iLCJzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwIiwiciI6W10sImEiOlsiZGlkY29tbS92MiJdfQ" + DIDSubject( + "did:peer:2.Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y.Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd.SeyJ0IjoiZG0iLCJzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwIiwiciI6W10sImEiOlsiZGlkY29tbS92MiJdfQ" + ) val bob = - "did:peer:2.Ez6LSkGy3e2z54uP4U9HyXJXRpaF2ytsnTuVgh6SNNmCyGZQZ.Vz6Mkjdwvf9hWc6ibZndW9B97si92DSk9hWAhGYBgP9kUFk8Z.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9ib2IuZGlkLmZtZ3AuYXBwLyIsInIiOltdLCJhIjpbImRpZGNvbW0vdjIiXX0" + DIDSubject( + "did:peer:2.Ez6LSkGy3e2z54uP4U9HyXJXRpaF2ytsnTuVgh6SNNmCyGZQZ.Vz6Mkjdwvf9hWc6ibZndW9B97si92DSk9hWAhGYBgP9kUFk8Z.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9ib2IuZGlkLmZtZ3AuYXBwLyIsInIiOltdLCJhIjpbImRpZGNvbW0vdjIiXX0" + ) - val encryptedMessageAlice: Either[String, EncryptedMessage] = """{ - | "ciphertext": "L8wzawffzL7kbVyDcMiHgQMwlqLUqWDYOwH4f0VOFK7sJL8vO-H_JBDCADu7gvH1MDHdVJDXQmSv5dDXp6JYubagcSfBqyZGKGOQDQz-1Ir6-sqZ9K5xRPMt76dYbSswrxhaROVJvtAXyrTmN3KEv8SgP_vt8za5QU6B8cM6gp2CycJKoIhETnhVEVjHnrX0YcyzBsLhd-ZKb8e1Nlz_XSh-3cw1oIQMFjXHnU3PSjrqXcrC-4qSGpVVpHvMSOF3o2EbLGEpP-8UbI0psgSLd9a2VUF9xV55r7Bvn_zJp6tC3-KZKNLO0Rc2K-6JRgyyZjo7O_8aj7Ns6Lx0OjUXoKLiA6B79goHiv8qxJ04k5EWD_h8gt4M3_oByH_cVXH35RDK5SwNV6cVl6zRqiHUR9Ilivh6kfOLGqM2sXCKpXE78qRgHOBeOtl08JHFQO5oFkt1ob8iDqczX0nu-qwlckiibnPK1VvhFnmgLyc9lIUsi_xlCNKqIBZCKoi03xrjNobcM1dWFG7yE04nT-sSiakRNwVHBmNCyA5JhEFQ92d1xpXFGM1ojtiHCPkN5nqe7lMYVM2r7QFnN1xTHwaDWddKprW3vkz_RP7tpoPlWk6X8rLoYUvYc3MqNdbj91QMlho5rU472EX3gprIDeNV7VQiKWoAksFe1hdt62zLH8mJJjUZ3lyq4YjOmrqg7g6RArUWC6KbPgmnuJCqwigpjlwRUCBTPISzaZETAisyluIyuMW8QlRCSQdWnfPZAU2fpLBcviMODMzZTULECvRBef05Fvtd_xRCCbpKpDkGxAY", - | "protected": "eyJlcGsiOnsia3R5IjoiT0tQIiwiY3J2IjoiWDI1NTE5IiwieCI6Ikp2TXhvYXZJaUxaUWVrNDA2eXNtWThQOGpkZGFHSjVIaVNRR0ltWHZWQ2MifSwiYXB2IjoiLWNOQ3l0eFVrSHpSRE5SckV2Vm05S0VmZzhZcUtQVnVVcVg1a0VLbU9yMCIsInNraWQiOiJkaWQ6cGVlcjoyLkV6NkxTa0d5M2UyejU0dVA0VTlIeVhKWFJwYUYyeXRzblR1VmdoNlNOTm1DeUdaUVouVno2TWtqZHd2ZjloV2M2aWJabmRXOUI5N3NpOTJEU2s5aFdBaEdZQmdQOWtVRms4Wi5TZXlKMElqb2laRzBpTENKeklqb2lhSFIwY0hNNkx5OWliMkl1Wkdsa0xtWnRaM0F1WVhCd0x5SXNJbklpT2x0ZExDSmhJanBiSW1ScFpHTnZiVzB2ZGpJaVhYMCM2TFNrR3kzZTJ6NTR1UDRVOUh5WEpYUnBhRjJ5dHNuVHVWZ2g2U05ObUN5R1pRWiIsImFwdSI6IlpHbGtPbkJsWlhJNk1pNUZlalpNVTJ0SGVUTmxNbm8xTkhWUU5GVTVTSGxZU2xoU2NHRkdNbmwwYzI1VWRWWm5hRFpUVGs1dFEzbEhXbEZhTGxaNk5rMXJhbVIzZG1ZNWFGZGpObWxpV201a1Z6bENPVGR6YVRreVJGTnJPV2hYUVdoSFdVSm5VRGxyVlVack9Gb3VVMlY1U2pCSmFtOXBXa2N3YVV4RFNucEphbTlwWVVoU01HTklUVFpNZVRscFlqSkpkVnBIYkd0TWJWcDBXak5CZFZsWVFuZE1lVWx6U1c1SmFVOXNkR1JNUTBwb1NXcHdZa2x0VW5CYVIwNTJZbGN3ZG1ScVNXbFlXREFqTmt4VGEwZDVNMlV5ZWpVMGRWQTBWVGxJZVZoS1dGSndZVVl5ZVhSemJsUjFWbWRvTmxOT1RtMURlVWRhVVZvIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJhbGciOiJFQ0RILTFQVStBMjU2S1cifQ", - | "recipients": [{ - | "encrypted_key": "eFHcJkoUle7ZkksvZjvhJHLagF7y5B5gDQX11tc1kus2xa3Vn_QmzyVwFzScOHTCEjWRUe7r63rHBFBw0El2ukZW2tcitxr8", - | "header": { - | "kid": "did:peer:2.Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y.Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9hbGljZS5kaWQuZm1ncC5hcHAvIiwiciI6W10sImEiOlsiZGlkY29tbS92MiJdfQ#6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y" - | } - | }], - | "tag": "6MUE-lIZFVRId9qX-0If18EsPcfld_a3r2gQXXq4ms4", - | "iv": "plEK7sqstAIkIxVKyfuuYg" - |}""".stripMargin.fromJson[EncryptedMessage] - val encryptedMessageBob: Either[String, EncryptedMessage] = """{ - | "ciphertext": "-dyjeU0aRQ8F87yAJFbOmmuon0UtEhQpmDQhYclMiTAqi06wH2bLTjtJNIOFG9sJ12uIyaQahPzCFBUyR2X22Oyl-1-Un0LOCAoRP584JuN19NdgKIytmSm4pg4VeSJ56SKO5D3Qe3G8XQa_7vO8O9-b_6V9mQXXZDkknNbphuiD7S53ss_VJzbgQVLRxkBrbnU1PL7yC6AhkAZNkUNCS8GGYbdEKFeRsdWjoROEnuQ1zzPN28eO3T4Wmt2APQ10vHum3Bl1RTiPRGCx3C-fSi05F-521jyP0rwyLeMZdBLruDz2IrUudtimFI3CKQ8_BcmuXTlLa1vw2hKlhk1_ppAmggW-qrjyZPiC9-XIN02OxZox5Xzba-cmg05Dj2zmEXryrxqFfyJlrV5FKSvWDfqeNAA9QNE0aUsgpKK9gOmu5pJRCuYNL96lbxdSCR4BiuX1G_ma2gagdIIY-70d22UPGcrZTw7Blet574i5U_bIDpZw4Az0UxoKNDbCDPOpn-Shojo5n_5FFbaPky0H0N99-9cx-Ns-3NMQecpupPQ9QJ-A2KWBTLYrJofLCBWv_ysqJ3Cde9fQ3xi5DTB13dhbxKVCgzdHKlwnqPC0C3mjFs_eZ1jnzBiUAKLvD_aWMwqx7y8GUhSfXlX3hImqtXaKBu2Koc1esUOvQwadHUj5pSmsNKJJcQLzsOcuYz8U9peRevrft3sy7fm9Ne2L3SSsoCFJP1N8U8bRLmyhY0CDuCNlvXxy_VFoSdPms40d1BNZObhgwO9Ca8kp1r0ITl22repvpMQYcQ83m9fkTXg", - | "protected": "eyJlcGsiOnsia3R5IjoiT0tQIiwiY3J2IjoiWDI1NTE5IiwieCI6ImNKRzZVeVJRbnhOM2RCa3ZQcndmZXZabFBwRzA0SzFyTzZHTjdnQkNyVFUifSwiYXB2IjoiLWNOQ3l0eFVrSHpSRE5SckV2Vm05S0VmZzhZcUtQVnVVcVg1a0VLbU9yMCIsInNraWQiOiJkaWQ6cGVlcjoyLkV6NkxTa0d5M2UyejU0dVA0VTlIeVhKWFJwYUYyeXRzblR1VmdoNlNOTm1DeUdaUVouVno2TWtqZHd2ZjloV2M2aWJabmRXOUI5N3NpOTJEU2s5aFdBaEdZQmdQOWtVRms4Wi5TZXlKMElqb2laRzBpTENKeklqb2lhSFIwY0hNNkx5OWliMkl1Wkdsa0xtWnRaM0F1WVhCd0x5SXNJbklpT2x0ZExDSmhJanBiSW1ScFpHTnZiVzB2ZGpJaVhYMCM2TFNrR3kzZTJ6NTR1UDRVOUh5WEpYUnBhRjJ5dHNuVHVWZ2g2U05ObUN5R1pRWiIsImFwdSI6IlpHbGtPbkJsWlhJNk1pNUZlalpNVTJ0SGVUTmxNbm8xTkhWUU5GVTVTSGxZU2xoU2NHRkdNbmwwYzI1VWRWWm5hRFpUVGs1dFEzbEhXbEZhTGxaNk5rMXJhbVIzZG1ZNWFGZGpObWxpV201a1Z6bENPVGR6YVRreVJGTnJPV2hYUVdoSFdVSm5VRGxyVlVack9Gb3VVMlY1U2pCSmFtOXBXa2N3YVV4RFNucEphbTlwWVVoU01HTklUVFpNZVRscFlqSkpkVnBIYkd0TWJWcDBXak5CZFZsWVFuZE1lVWx6U1c1SmFVOXNkR1JNUTBwb1NXcHdZa2x0VW5CYVIwNTJZbGN3ZG1ScVNXbFlXREFqTmt4VGEwZDVNMlV5ZWpVMGRWQTBWVGxJZVZoS1dGSndZVVl5ZVhSemJsUjFWbWRvTmxOT1RtMURlVWRhVVZvIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJhbGciOiJFQ0RILTFQVStBMjU2S1cifQ", - | "recipients": [{ - | "encrypted_key": "KCjv83os8FnpVaIUgcuYV-5TIw4VYuGIoHozQ0JVlIwK2sEkxwWg10yh0UlbbcnNVfF_OBr4OkJUczj7pB0spRhvjoDHBM_s", - | "header": { - | "kid": "did:peer:2.Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y.Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9hbGljZS5kaWQuZm1ncC5hcHAvIiwiciI6W10sImEiOlsiZGlkY29tbS92MiJdfQ#6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y" - | } - | }], - | "tag": "iR0meUd8R3X5dleMywNHq5NaGJ4g0h2tok414SJ7UGI", - | "iv": "T-I0b4fIktFXVhAIFoSmQg" - |}""".stripMargin.fromJson[EncryptedMessage] + val encryptedMessageAlice: Either[String, EncryptedMessage] = + """{ + | "ciphertext": "L8wzawffzL7kbVyDcMiHgQMwlqLUqWDYOwH4f0VOFK7sJL8vO-H_JBDCADu7gvH1MDHdVJDXQmSv5dDXp6JYubagcSfBqyZGKGOQDQz-1Ir6-sqZ9K5xRPMt76dYbSswrxhaROVJvtAXyrTmN3KEv8SgP_vt8za5QU6B8cM6gp2CycJKoIhETnhVEVjHnrX0YcyzBsLhd-ZKb8e1Nlz_XSh-3cw1oIQMFjXHnU3PSjrqXcrC-4qSGpVVpHvMSOF3o2EbLGEpP-8UbI0psgSLd9a2VUF9xV55r7Bvn_zJp6tC3-KZKNLO0Rc2K-6JRgyyZjo7O_8aj7Ns6Lx0OjUXoKLiA6B79goHiv8qxJ04k5EWD_h8gt4M3_oByH_cVXH35RDK5SwNV6cVl6zRqiHUR9Ilivh6kfOLGqM2sXCKpXE78qRgHOBeOtl08JHFQO5oFkt1ob8iDqczX0nu-qwlckiibnPK1VvhFnmgLyc9lIUsi_xlCNKqIBZCKoi03xrjNobcM1dWFG7yE04nT-sSiakRNwVHBmNCyA5JhEFQ92d1xpXFGM1ojtiHCPkN5nqe7lMYVM2r7QFnN1xTHwaDWddKprW3vkz_RP7tpoPlWk6X8rLoYUvYc3MqNdbj91QMlho5rU472EX3gprIDeNV7VQiKWoAksFe1hdt62zLH8mJJjUZ3lyq4YjOmrqg7g6RArUWC6KbPgmnuJCqwigpjlwRUCBTPISzaZETAisyluIyuMW8QlRCSQdWnfPZAU2fpLBcviMODMzZTULECvRBef05Fvtd_xRCCbpKpDkGxAY", + | "protected": "eyJlcGsiOnsia3R5IjoiT0tQIiwiY3J2IjoiWDI1NTE5IiwieCI6Ikp2TXhvYXZJaUxaUWVrNDA2eXNtWThQOGpkZGFHSjVIaVNRR0ltWHZWQ2MifSwiYXB2IjoiLWNOQ3l0eFVrSHpSRE5SckV2Vm05S0VmZzhZcUtQVnVVcVg1a0VLbU9yMCIsInNraWQiOiJkaWQ6cGVlcjoyLkV6NkxTa0d5M2UyejU0dVA0VTlIeVhKWFJwYUYyeXRzblR1VmdoNlNOTm1DeUdaUVouVno2TWtqZHd2ZjloV2M2aWJabmRXOUI5N3NpOTJEU2s5aFdBaEdZQmdQOWtVRms4Wi5TZXlKMElqb2laRzBpTENKeklqb2lhSFIwY0hNNkx5OWliMkl1Wkdsa0xtWnRaM0F1WVhCd0x5SXNJbklpT2x0ZExDSmhJanBiSW1ScFpHTnZiVzB2ZGpJaVhYMCM2TFNrR3kzZTJ6NTR1UDRVOUh5WEpYUnBhRjJ5dHNuVHVWZ2g2U05ObUN5R1pRWiIsImFwdSI6IlpHbGtPbkJsWlhJNk1pNUZlalpNVTJ0SGVUTmxNbm8xTkhWUU5GVTVTSGxZU2xoU2NHRkdNbmwwYzI1VWRWWm5hRFpUVGs1dFEzbEhXbEZhTGxaNk5rMXJhbVIzZG1ZNWFGZGpObWxpV201a1Z6bENPVGR6YVRreVJGTnJPV2hYUVdoSFdVSm5VRGxyVlVack9Gb3VVMlY1U2pCSmFtOXBXa2N3YVV4RFNucEphbTlwWVVoU01HTklUVFpNZVRscFlqSkpkVnBIYkd0TWJWcDBXak5CZFZsWVFuZE1lVWx6U1c1SmFVOXNkR1JNUTBwb1NXcHdZa2x0VW5CYVIwNTJZbGN3ZG1ScVNXbFlXREFqTmt4VGEwZDVNMlV5ZWpVMGRWQTBWVGxJZVZoS1dGSndZVVl5ZVhSemJsUjFWbWRvTmxOT1RtMURlVWRhVVZvIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJhbGciOiJFQ0RILTFQVStBMjU2S1cifQ", + | "recipients": [{ + | "encrypted_key": "eFHcJkoUle7ZkksvZjvhJHLagF7y5B5gDQX11tc1kus2xa3Vn_QmzyVwFzScOHTCEjWRUe7r63rHBFBw0El2ukZW2tcitxr8", + | "header": { + | "kid": "did:peer:2.Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y.Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9hbGljZS5kaWQuZm1ncC5hcHAvIiwiciI6W10sImEiOlsiZGlkY29tbS92MiJdfQ#6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y" + | } + | }], + | "tag": "6MUE-lIZFVRId9qX-0If18EsPcfld_a3r2gQXXq4ms4", + | "iv": "plEK7sqstAIkIxVKyfuuYg" + |}""".stripMargin.fromJson[EncryptedMessage] + val encryptedMessageBob: Either[String, EncryptedMessage] = + """{ + | "ciphertext": "-dyjeU0aRQ8F87yAJFbOmmuon0UtEhQpmDQhYclMiTAqi06wH2bLTjtJNIOFG9sJ12uIyaQahPzCFBUyR2X22Oyl-1-Un0LOCAoRP584JuN19NdgKIytmSm4pg4VeSJ56SKO5D3Qe3G8XQa_7vO8O9-b_6V9mQXXZDkknNbphuiD7S53ss_VJzbgQVLRxkBrbnU1PL7yC6AhkAZNkUNCS8GGYbdEKFeRsdWjoROEnuQ1zzPN28eO3T4Wmt2APQ10vHum3Bl1RTiPRGCx3C-fSi05F-521jyP0rwyLeMZdBLruDz2IrUudtimFI3CKQ8_BcmuXTlLa1vw2hKlhk1_ppAmggW-qrjyZPiC9-XIN02OxZox5Xzba-cmg05Dj2zmEXryrxqFfyJlrV5FKSvWDfqeNAA9QNE0aUsgpKK9gOmu5pJRCuYNL96lbxdSCR4BiuX1G_ma2gagdIIY-70d22UPGcrZTw7Blet574i5U_bIDpZw4Az0UxoKNDbCDPOpn-Shojo5n_5FFbaPky0H0N99-9cx-Ns-3NMQecpupPQ9QJ-A2KWBTLYrJofLCBWv_ysqJ3Cde9fQ3xi5DTB13dhbxKVCgzdHKlwnqPC0C3mjFs_eZ1jnzBiUAKLvD_aWMwqx7y8GUhSfXlX3hImqtXaKBu2Koc1esUOvQwadHUj5pSmsNKJJcQLzsOcuYz8U9peRevrft3sy7fm9Ne2L3SSsoCFJP1N8U8bRLmyhY0CDuCNlvXxy_VFoSdPms40d1BNZObhgwO9Ca8kp1r0ITl22repvpMQYcQ83m9fkTXg", + | "protected": "eyJlcGsiOnsia3R5IjoiT0tQIiwiY3J2IjoiWDI1NTE5IiwieCI6ImNKRzZVeVJRbnhOM2RCa3ZQcndmZXZabFBwRzA0SzFyTzZHTjdnQkNyVFUifSwiYXB2IjoiLWNOQ3l0eFVrSHpSRE5SckV2Vm05S0VmZzhZcUtQVnVVcVg1a0VLbU9yMCIsInNraWQiOiJkaWQ6cGVlcjoyLkV6NkxTa0d5M2UyejU0dVA0VTlIeVhKWFJwYUYyeXRzblR1VmdoNlNOTm1DeUdaUVouVno2TWtqZHd2ZjloV2M2aWJabmRXOUI5N3NpOTJEU2s5aFdBaEdZQmdQOWtVRms4Wi5TZXlKMElqb2laRzBpTENKeklqb2lhSFIwY0hNNkx5OWliMkl1Wkdsa0xtWnRaM0F1WVhCd0x5SXNJbklpT2x0ZExDSmhJanBiSW1ScFpHTnZiVzB2ZGpJaVhYMCM2TFNrR3kzZTJ6NTR1UDRVOUh5WEpYUnBhRjJ5dHNuVHVWZ2g2U05ObUN5R1pRWiIsImFwdSI6IlpHbGtPbkJsWlhJNk1pNUZlalpNVTJ0SGVUTmxNbm8xTkhWUU5GVTVTSGxZU2xoU2NHRkdNbmwwYzI1VWRWWm5hRFpUVGs1dFEzbEhXbEZhTGxaNk5rMXJhbVIzZG1ZNWFGZGpObWxpV201a1Z6bENPVGR6YVRreVJGTnJPV2hYUVdoSFdVSm5VRGxyVlVack9Gb3VVMlY1U2pCSmFtOXBXa2N3YVV4RFNucEphbTlwWVVoU01HTklUVFpNZVRscFlqSkpkVnBIYkd0TWJWcDBXak5CZFZsWVFuZE1lVWx6U1c1SmFVOXNkR1JNUTBwb1NXcHdZa2x0VW5CYVIwNTJZbGN3ZG1ScVNXbFlXREFqTmt4VGEwZDVNMlV5ZWpVMGRWQTBWVGxJZVZoS1dGSndZVVl5ZVhSemJsUjFWbWRvTmxOT1RtMURlVWRhVVZvIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJhbGciOiJFQ0RILTFQVStBMjU2S1cifQ", + | "recipients": [{ + | "encrypted_key": "KCjv83os8FnpVaIUgcuYV-5TIw4VYuGIoHozQ0JVlIwK2sEkxwWg10yh0UlbbcnNVfF_OBr4OkJUczj7pB0spRhvjoDHBM_s", + | "header": { + | "kid": "did:peer:2.Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y.Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9hbGljZS5kaWQuZm1ncC5hcHAvIiwiciI6W10sImEiOlsiZGlkY29tbS92MiJdfQ#6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y" + | } + | }], + | "tag": "iR0meUd8R3X5dleMywNHq5NaGJ4g0h2tok414SJ7UGI", + | "iv": "T-I0b4fIktFXVhAIFoSmQg" + |}""".stripMargin.fromJson[EncryptedMessage] } diff --git a/mediator/src/test/scala/io/iohk/atala/mediator/db/UserAccountRepoSpec.scala b/mediator/src/test/scala/io/iohk/atala/mediator/db/UserAccountRepoSpec.scala index 6c748d8b..3a4eb9db 100644 --- a/mediator/src/test/scala/io/iohk/atala/mediator/db/UserAccountRepoSpec.scala +++ b/mediator/src/test/scala/io/iohk/atala/mediator/db/UserAccountRepoSpec.scala @@ -21,7 +21,7 @@ object UserAccountRepoSpec extends ZIOSpecDefault with DidAccountStubSetup with userAccount <- ZIO.service[UserAccountRepo] col <- userAccount.collection _ = col.indexesManager.create(index) - result <- userAccount.createOrFindDidAccount(DIDSubject(alice)) + result <- userAccount.createOrFindDidAccount(alice) } yield { assertTrue(result.isRight) } @@ -29,7 +29,7 @@ object UserAccountRepoSpec extends ZIOSpecDefault with DidAccountStubSetup with test("insert same Did should NOT fail") { for { userAccount <- ZIO.service[UserAccountRepo] - result <- userAccount.createOrFindDidAccount(DIDSubject(alice)) + result <- userAccount.createOrFindDidAccount(alice) } yield { assertTrue(result.isRight) } @@ -37,15 +37,15 @@ object UserAccountRepoSpec extends ZIOSpecDefault with DidAccountStubSetup with test("Get Did Account") { for { userAccount <- ZIO.service[UserAccountRepo] - result <- userAccount.getDidAccount(DIDSubject(alice)) + result <- userAccount.getDidAccount(alice) } yield { - assertTrue(result.isDefined) && assertTrue(result.exists(_.did == DIDSubject(alice))) + assertTrue(result.isDefined) && assertTrue(result.exists(_.did == alice)) } }, test("Get Did Account return for unknown did") { for { userAccount <- ZIO.service[UserAccountRepo] - result <- userAccount.getDidAccount(DIDSubject(bob)) + result <- userAccount.getDidAccount(bob) } yield { assertTrue(result.isEmpty) } @@ -53,8 +53,8 @@ object UserAccountRepoSpec extends ZIOSpecDefault with DidAccountStubSetup with test("Add alias to existing Did Account return right nModified value 1") { for { userAccount <- ZIO.service[UserAccountRepo] - result <- userAccount.addAlias(owner = DIDSubject(alice), newAlias = DIDSubject(bob)) - didAccount <- userAccount.getDidAccount(DIDSubject(alice)) + result <- userAccount.addAlias(owner = alice, newAlias = bob) + didAccount <- userAccount.getDidAccount(alice) } yield { val alias: Seq[String] = didAccount.map(_.alias.map(_.did)).getOrElse(Seq.empty) assertTrue(result.isRight) && @@ -66,7 +66,7 @@ object UserAccountRepoSpec extends ZIOSpecDefault with DidAccountStubSetup with test("insert/create a UserAccount for a DID that is used as a alias should fail") { for { userAccount <- ZIO.service[UserAccountRepo] - result <- userAccount.createOrFindDidAccount(DIDSubject(bob)) + result <- userAccount.createOrFindDidAccount(bob) } yield { assertTrue(result.isLeft) } @@ -74,34 +74,34 @@ object UserAccountRepoSpec extends ZIOSpecDefault with DidAccountStubSetup with test("Add owner as alias to existing Did Account return right with nModified value 1") { for { userAccount <- ZIO.service[UserAccountRepo] - result <- userAccount.addAlias(owner = DIDSubject(alice), newAlias = DIDSubject(alice)) - didAccount <- userAccount.getDidAccount(DIDSubject(alice)) + result <- userAccount.addAlias(owner = alice, newAlias = alice) + didAccount <- userAccount.getDidAccount(alice) } yield { val alias: Seq[String] = didAccount.map(_.alias.map(_.did)).getOrElse(Seq.empty) assertTrue(result.isRight) && assertTrue(result == Right(1)) && assertTrue(didAccount.isDefined) && - assertTrue(alias.sorted == Seq(alice, bob).sorted) + assertTrue(alias.sorted == Seq(alice.did, bob.did).sorted) } }, test("Add same alias to existing Did Account return right with nModified value 0") { for { userAccount <- ZIO.service[UserAccountRepo] - result <- userAccount.addAlias(owner = DIDSubject(alice), newAlias = DIDSubject(alice)) - didAccount <- userAccount.getDidAccount(DIDSubject(alice)) + result <- userAccount.addAlias(owner = alice, newAlias = alice) + didAccount <- userAccount.getDidAccount(alice) } yield { val alias: Seq[String] = didAccount.map(_.alias.map(_.did)).getOrElse(Seq.empty) assertTrue(result.isRight) && assertTrue(result == Right(0)) && assertTrue(didAccount.isDefined) && - assertTrue(alias.sorted == Seq(alice, bob).sorted) + assertTrue(alias.sorted == Seq(alice.did, bob.did).sorted) } }, test("Remove alias to existing Did Account should return right with nModified value 1 ") { for { userAccount <- ZIO.service[UserAccountRepo] - result <- userAccount.removeAlias(DIDSubject(alice), DIDSubject(bob)) - didAccount <- userAccount.getDidAccount(DIDSubject(alice)) + result <- userAccount.removeAlias(alice, bob) + didAccount <- userAccount.getDidAccount(alice) } yield { val alias: Seq[String] = didAccount.map(_.alias.map(_.did)).getOrElse(Seq.empty) assertTrue(result.isRight) && @@ -113,8 +113,8 @@ object UserAccountRepoSpec extends ZIOSpecDefault with DidAccountStubSetup with test("Remove alias to unknown or unregister alias Did should return right with noModified value 0") { for { userAccount <- ZIO.service[UserAccountRepo] - result <- userAccount.removeAlias(DIDSubject(alice), DIDSubject(bob)) - didAccount <- userAccount.getDidAccount(DIDSubject(alice)) + result <- userAccount.removeAlias(alice, bob) + didAccount <- userAccount.getDidAccount(alice) } yield { val alias: Seq[String] = didAccount.map(_.alias.map(_.did)).getOrElse(Seq.empty) assertTrue(result.isRight) && @@ -129,11 +129,11 @@ object UserAccountRepoSpec extends ZIOSpecDefault with DidAccountStubSetup with for { userAccount <- ZIO.service[UserAccountRepo] messageItem <- ZIO.service[MessageItemRepo] - result <- userAccount.addAlias(DIDSubject(alice), DIDSubject(bob)) + result <- userAccount.addAlias(alice, bob) msg <- ZIO.fromEither(encryptedMessageAlice) msgAdded <- messageItem.insert(msg) - addedToInbox <- userAccount.addToInboxes(Set(DIDSubject(bob)), msg) - didAccount <- userAccount.getDidAccount(DIDSubject(alice)) + addedToInbox <- userAccount.addToInboxes(Set(bob), msg) + didAccount <- userAccount.getDidAccount(alice) } yield { val messageMetaData: Seq[MessageMetaData] = didAccount.map(_.messagesRef).getOrElse(Seq.empty) @@ -145,7 +145,7 @@ object UserAccountRepoSpec extends ZIOSpecDefault with DidAccountStubSetup with assert(messageMetaData)( forall( hasField("hash", (m: MessageMetaData) => m.hash, equalTo(msg.sha1)) - && hasField("recipient", (m: MessageMetaData) => m.recipient, equalTo(DIDSubject(bob))) + && hasField("recipient", (m: MessageMetaData) => m.recipient, equalTo(bob)) && hasField("xRequestId", (m: MessageMetaData) => m.xRequestId, equalTo(Some(xRequestId))) ) ) @@ -156,8 +156,8 @@ object UserAccountRepoSpec extends ZIOSpecDefault with DidAccountStubSetup with for { userAccount <- ZIO.service[UserAccountRepo] msg <- ZIO.fromEither(encryptedMessageAlice) - markedDelivered <- userAccount.markAsDelivered(DIDSubject(alice), Seq(msg.sha1)) - didAccount <- userAccount.getDidAccount(DIDSubject(alice)) + markedDelivered <- userAccount.markAsDelivered(alice, Seq(msg.sha1)) + didAccount <- userAccount.getDidAccount(alice) } yield { val messageMetaData: Seq[MessageMetaData] = didAccount.map(_.messagesRef).getOrElse(Seq.empty) assertTrue(markedDelivered == 1) && diff --git a/mediator/src/test/scala/io/iohk/atala/mediator/protocols/DiscoverFeaturesExecuterSpec.scala b/mediator/src/test/scala/io/iohk/atala/mediator/protocols/DiscoverFeaturesExecuterSpec.scala new file mode 100644 index 00000000..40170e7d --- /dev/null +++ b/mediator/src/test/scala/io/iohk/atala/mediator/protocols/DiscoverFeaturesExecuterSpec.scala @@ -0,0 +1,79 @@ +package io.iohk.atala.mediator.protocols + +import fmgp.did.DIDSubject +import fmgp.did.comm.protocol.reportproblem2.{ProblemCode, ProblemReport} +import fmgp.did.comm.protocol.discoverfeatures2.* +import fmgp.did.comm.{EncryptedMessage, Operations, PlaintextMessage, SignedMessage, layerDefault} +import fmgp.did.method.peer.DidPeerResolver +import fmgp.util.Base64 +import io.iohk.atala.mediator.comm.MessageDispatcherJVM +import io.iohk.atala.mediator.db.* +import io.iohk.atala.mediator.db.MessageItemRepoSpec.encryptedMessageAlice +import io.iohk.atala.mediator.protocols.DiscoverFeaturesExecuter +import zio.* +import zio.ExecutionStrategy.Sequential +import zio.http.Client +import zio.json.* +import zio.test.* +import zio.test.Assertion.* +import fmgp.did.comm.FROM +import fmgp.did.comm.TO + +import scala.concurrent.ExecutionContext.Implicits.global +import io.iohk.atala.mediator.db.EmbeddedMongoDBInstance.* +import reactivemongo.api.bson.BSONDocument +import fmgp.did.DIDSubject.* +import fmgp.did.comm.Operations.authDecrypt +import io.iohk.atala.mediator.app.MediatorAgent +import io.iohk.atala.mediator.db.AgentStub.{bobAgent, bobAgentLayer} +object DiscoverFeaturesExecuterSpec extends ZIOSpecDefault with DidAccountStubSetup with MessageSetup { + + override def spec = suite("DiscoverFeaturesExecuterSpec")( + test("DiscoverFeatures Query message should return the disclose message containing the matched protocols") { + val executer = DiscoverFeaturesExecuter + for { + agent <- ZIO.service[MediatorAgent] + msg <- ZIO.fromEither(plaintextDiscoverFeatureRequestMessage(bobAgent.id.did, agent.id.did)) + result <- executer.execute(msg) + message <- ZIO.fromOption(result) + decryptedMessage <- authDecrypt(message.asInstanceOf[EncryptedMessage]).provideSomeLayer(bobAgentLayer) + featureDisclose <- ZIO.fromEither(decryptedMessage.asInstanceOf[PlaintextMessage].toFeatureDisclose) + } yield { + val plainText = decryptedMessage.asInstanceOf[PlaintextMessage] + assertTrue(plainText.`type` == FeatureDisclose.piuri) && + assertTrue(featureDisclose.disclosures.nonEmpty) && + assertTrue(featureDisclose.disclosures.head.id.contains("routing")) + } + } @@ TestAspect.before(setupAndClean), + test( + "DiscoverFeatures Query message doesn't match regex pattern, it should yield a disclose message with an empty body" + ) { + val executer = DiscoverFeaturesExecuter + for { + agent <- ZIO.service[MediatorAgent] + msg <- ZIO.fromEither(plaintextDiscoverFeatureRequestMessageNoMatch(bobAgent.id.did, agent.id.did)) + result <- executer.execute(msg) + message <- ZIO.fromOption(result) + decryptedMessage <- authDecrypt(message.asInstanceOf[EncryptedMessage]).provideSomeLayer(bobAgentLayer) + featureDisclose <- ZIO.fromEither(decryptedMessage.asInstanceOf[PlaintextMessage].toFeatureDisclose) + + } yield { + val plainText = decryptedMessage.asInstanceOf[PlaintextMessage] + assertTrue(plainText.`type` == FeatureDisclose.piuri) && + assertTrue(featureDisclose.disclosures.isEmpty) + + } + } @@ TestAspect.before(setupAndClean), + ).provideSomeLayer(DidPeerResolver.layerDidPeerResolver) + .provideSomeLayer(Operations.layerDefault) + .provideSomeLayer(Scope.default >>> Client.default >>> MessageDispatcherJVM.layer) + .provideSomeLayer(DidPeerResolver.layerDidPeerResolver) + .provideSomeLayer(AgentStub.agentLayer) + .provideLayerShared(dataAccessLayer) @@ TestAspect.sequential + + val dataAccessLayer = EmbeddedMongoDBInstance.layer(port, hostIp) + >>> AsyncDriverResource.layer + >>> ReactiveMongoApi.layer(connectionString) + >>> (UserAccountRepo.layer ++ MessageItemRepo.layer ++ OutboxMessageRepo.layer) + +} diff --git a/mediator/src/test/scala/io/iohk/atala/mediator/protocols/ForwardMessageExecutorSpec.scala b/mediator/src/test/scala/io/iohk/atala/mediator/protocols/ForwardMessageExecutorSpec.scala index 07129cb9..da85e4db 100644 --- a/mediator/src/test/scala/io/iohk/atala/mediator/protocols/ForwardMessageExecutorSpec.scala +++ b/mediator/src/test/scala/io/iohk/atala/mediator/protocols/ForwardMessageExecutorSpec.scala @@ -18,7 +18,6 @@ import fmgp.did.DIDSubject import scala.concurrent.ExecutionContext.Implicits.global import io.iohk.atala.mediator.db.EmbeddedMongoDBInstance.* -import io.iohk.atala.mediator.protocols.MediatorCoordinationExecuterSpec.setupAndClean import reactivemongo.api.bson.BSONDocument object ForwardMessageExecutorSpec extends ZIOSpecDefault with DidAccountStubSetup with MessageSetup { @@ -27,7 +26,7 @@ object ForwardMessageExecutorSpec extends ZIOSpecDefault with DidAccountStubSetu val executer = ForwardMessageExecuter for { userAccount <- ZIO.service[UserAccountRepo] - result <- userAccount.createOrFindDidAccount(DIDSubject(alice)) + result <- userAccount.createOrFindDidAccount(alice) msg <- ZIO.fromEither(plaintextForwardNotEnrolledDidMessage) result <- executer.execute(msg) message <- ZIO.fromOption(result) @@ -52,8 +51,8 @@ object ForwardMessageExecutorSpec extends ZIOSpecDefault with DidAccountStubSetu val executer = ForwardMessageExecuter for { userAccount <- ZIO.service[UserAccountRepo] - result <- userAccount.createOrFindDidAccount(DIDSubject(alice)) - result <- userAccount.addAlias(owner = DIDSubject(alice), newAlias = DIDSubject(alice)) + result <- userAccount.createOrFindDidAccount(alice) + result <- userAccount.addAlias(owner = alice, newAlias = alice) msg <- ZIO.fromEither(plaintextForwardEnrolledDidMessage) result <- executer.execute(msg) } yield assertTrue(result.isEmpty) @@ -66,8 +65,6 @@ object ForwardMessageExecutorSpec extends ZIOSpecDefault with DidAccountStubSetu .provideSomeLayer(AgentStub.agentLayer) .provideLayerShared(dataAccessLayer) @@ TestAspect.sequential - - val dataAccessLayer = EmbeddedMongoDBInstance.layer(port, hostIp) >>> AsyncDriverResource.layer >>> ReactiveMongoApi.layer(connectionString) diff --git a/mediator/src/test/scala/io/iohk/atala/mediator/protocols/MediatorCoordinationExecuterSpec.scala b/mediator/src/test/scala/io/iohk/atala/mediator/protocols/MediatorCoordinationExecuterSpec.scala index 25367fc6..abd8b192 100644 --- a/mediator/src/test/scala/io/iohk/atala/mediator/protocols/MediatorCoordinationExecuterSpec.scala +++ b/mediator/src/test/scala/io/iohk/atala/mediator/protocols/MediatorCoordinationExecuterSpec.scala @@ -47,8 +47,8 @@ object MediatorCoordinationExecuterSpec extends ZIOSpecDefault with DidAccountSt for { userAccount <- ZIO.service[UserAccountRepo] agent <- ZIO.service[MediatorAgent] - result <- userAccount.createOrFindDidAccount(DIDSubject(alice)) - result <- userAccount.addAlias(owner = DIDSubject(alice), newAlias = DIDSubject(aliceAgent.id.did)) + result <- userAccount.createOrFindDidAccount(alice) + result <- userAccount.addAlias(owner = alice, newAlias = DIDSubject(aliceAgent.id.did)) msg <- ZIO.fromEither(plaintextMediationRequestMessage(aliceAgent.id.did, agent.id.did)) result <- executer.execute(msg) message <- ZIO.fromOption(result) diff --git a/mediator/src/test/scala/io/iohk/atala/mediator/protocols/MessageSetup.scala b/mediator/src/test/scala/io/iohk/atala/mediator/protocols/MessageSetup.scala index 0174687c..5f630579 100644 --- a/mediator/src/test/scala/io/iohk/atala/mediator/protocols/MessageSetup.scala +++ b/mediator/src/test/scala/io/iohk/atala/mediator/protocols/MessageSetup.scala @@ -5,7 +5,9 @@ import io.iohk.atala.mediator.db.UserAccountRepo import reactivemongo.api.bson.BSONDocument import zio.ZIO import zio.json.* +import fmgp.did.comm import reactivemongo.api.indexes.{Index, IndexType} +import fmgp.did.DIDSubject trait MessageSetup { val index = Index( @@ -28,8 +30,10 @@ trait MessageSetup { } yield {} } - val mediatorDid = + val mediatorDid = DIDSubject( "did:peer:2.Ez6LSkGy3e2z54uP4U9HyXJXRpaF2ytsnTuVgh6SNNmCyGZQZ.Vz6Mkjdwvf9hWc6ibZndW9B97si92DSk9hWAhGYBgP9kUFk8Z.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9ib2IuZGlkLmZtZ3AuYXBwLyIsInIiOltdLCJhIjpbImRpZGNvbW0vdjIiXX0" + ) + val plaintextForwardNotEnrolledDidMessage: Either[String, PlaintextMessage] = """{ | "id" : "c8f9712a-fdad-45d0-81d9-c610daaa9285", @@ -135,6 +139,40 @@ trait MessageSetup { | "typ" : "application/didcomm-plain+json" |}""".stripMargin.fromJson[PlaintextMessage] + val plaintextDiscoverFeatureRequestMessage = (didFrom: String, mediatorDid: String) => + s"""{ + | "id" : "17f9f122-f762-4ba8-9011-39b9e7efb177", + | "type" : "https://didcomm.org/discover-features/2.0/queries", + | "to" : [ + | "$mediatorDid" + | ], + | "from" : "$didFrom", + | "body" : { + | "queries": [ + | { "feature-type": "protocol", "match": ".*routing.*" } + | ] + | }, + | "return_route" : "all", + | "typ" : "application/didcomm-plain+json" + |}""".stripMargin + .fromJson[PlaintextMessage] + val plaintextDiscoverFeatureRequestMessageNoMatch = (didFrom: String, mediatorDid: String) => + s"""{ + | "id" : "17f9f122-f762-4ba8-9011-39b9e7efb177", + | "type" : "https://didcomm.org/discover-features/2.0/queries", + | "to" : [ + | "$mediatorDid" + | ], + | "from" : "$didFrom", + | "body" : { + | "queries": [ + | { "feature-type": "protocol", "match": "routing" } + | ] + | }, + | "return_route" : "all", + | "typ" : "application/didcomm-plain+json" + |}""".stripMargin + .fromJson[PlaintextMessage] val plaintextKeyListUpdateRequestMessage = (didFrom: String, mediatorDid: String, recipientDid: String) => s"""{ | "id" : "cf64e501-d524-4fd9-8314-4dc4bc652983", | "type" : "https://didcomm.org/coordinate-mediation/2.0/keylist-update", From 0c06b769f0050865fae585078e08b9832478f476 Mon Sep 17 00:00:00 2001 From: atala-dev <57987237+atala-dev@users.noreply.github.com> Date: Tue, 7 Nov 2023 14:59:27 +0000 Subject: [PATCH 6/9] Update sbt-assembly to 2.1.4 in main (#159) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index c1dee538..652998b3 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -51,7 +51,7 @@ addSbtPlugin("io.spray" % "sbt-revolver" % "0.10.0") addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.11.1") // Deploy demo -addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.1.3") +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.1.4") addSbtPlugin("com.typesafe.sbt" % "sbt-gzip" % "1.0.2") // Release From 1b881b577b7460412fe49f9def0e14bd2d7de171 Mon Sep 17 00:00:00 2001 From: atala-dev <57987237+atala-dev@users.noreply.github.com> Date: Tue, 7 Nov 2023 15:01:18 +0000 Subject: [PATCH 7/9] Update scalafmt-core to 3.7.15 in main (#153) * Update scalafmt-core to 3.7.15 in main * Reformat with scalafmt 3.7.15 Executed command: scalafmt --non-interactive * Add 'Reformat with scalafmt 3.7.15' to .git-blame-ignore-revs --------- Signed-off-by: Fabio Pinheiro Co-authored-by: Fabio Pinheiro --- .git-blame-ignore-revs | 3 ++ .scalafmt.conf | 2 +- .../mediator/protocols/PickupExecuter.scala | 28 ++++++++++--------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 86b9c5ce..13dccddd 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -3,3 +3,6 @@ # Scala Steward: Reformat with scalafmt 3.7.8 7f0ad6980840682687eb6bc0017014e08ae46421 + +# Scala Steward: Reformat with scalafmt 3.7.15 +3e95a584d68fdb4506caa91a0c7833d277dc8c8d diff --git a/.scalafmt.conf b/.scalafmt.conf index 91dcc5d3..3f4c1329 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = "3.7.14" +version = "3.7.15" runner.dialect = scala3 maxColumn = 120 diff --git a/mediator/src/main/scala/io/iohk/atala/mediator/protocols/PickupExecuter.scala b/mediator/src/main/scala/io/iohk/atala/mediator/protocols/PickupExecuter.scala index 6f560cee..38eb77bc 100644 --- a/mediator/src/main/scala/io/iohk/atala/mediator/protocols/PickupExecuter.scala +++ b/mediator/src/main/scala/io/iohk/atala/mediator/protocols/PickupExecuter.scala @@ -114,18 +114,20 @@ object PickupExecuter case Some(didAccount) => val msgHash = didAccount.messagesRef.filter(_.state == false).map(_.hash) if (msgHash.isEmpty) { - ZIO.succeed(Status( - thid = m.id, - from = m.to.asFROM, - to = m.from.asTO, - recipient_did = m.recipient_did, - message_count = msgHash.size, - longest_waited_seconds = None, // TODO - newest_received_time = None, // TODO - oldest_received_time = None, // TODO - total_bytes = None, // TODO - live_delivery = None, // TODO - ).toPlaintextMessage) + ZIO.succeed( + Status( + thid = m.id, + from = m.to.asFROM, + to = m.from.asTO, + recipient_did = m.recipient_did, + message_count = msgHash.size, + longest_waited_seconds = None, // TODO + newest_received_time = None, // TODO + oldest_received_time = None, // TODO + total_bytes = None, // TODO + live_delivery = None, // TODO + ).toPlaintextMessage + ) } else { for { allMessagesFor <- repoMessageItem.findByIds(msgHash) @@ -145,7 +147,7 @@ object PickupExecuter recipient_did = m.recipient_did, attachments = messagesToReturn.map(m => (m._id, m.msg)).toMap, ).toPlaintextMessage - } + } } yield SyncReplyOnly(ret) case m: MessageDelivery => From 231530dfed2d75f49ff99ba17b6b3d11e386cee0 Mon Sep 17 00:00:00 2001 From: atala-dev <57987237+atala-dev@users.noreply.github.com> Date: Tue, 7 Nov 2023 15:01:47 +0000 Subject: [PATCH 8/9] Update de.flapdoodle.embed.mongo to 4.9.3 in main (#156) --- .github/workflows/ci.yml | 4 ++-- build.sbt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4209aa6b..90836c2b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,9 +35,9 @@ jobs: uses: actions/cache@v2 with: path: ~/.embedmongo - key: ${{ runner.os }}-embedmongo-4.9.2 + key: ${{ runner.os }}-embedmongo-4.9.3 restore-keys: | - ${{ runner.os }}-embedmongo-4.9.2 + ${{ runner.os }}-embedmongo-4.9.3 ### Compile and TESTS ### - run: sbt -mem 2048 -J-Xmx5120m "test" env: diff --git a/build.sbt b/build.sbt index 7ab8da06..2dfdcaa3 100644 --- a/build.sbt +++ b/build.sbt @@ -31,7 +31,7 @@ lazy val V = new { val logstash = "7.4" val jansi = "2.4.1" val mongo = "1.1.0-RC10" - val embedMongo = "4.9.2" + val embedMongo = "4.9.3" val munitZio = "0.1.1" val zioTest = "2.0.18" val zioTestSbt = "2.0.18" From d08a8a6fef6b9b11a1690151bcdc0e11cdd833e4 Mon Sep 17 00:00:00 2001 From: Fabio Pinheiro Date: Tue, 7 Nov 2023 17:20:01 +0000 Subject: [PATCH 9/9] Update zio-http to 3.0.0-RC3 (#165) --- build.sbt | 2 +- .../mediator/comm/MessageDispatcherJVM.scala | 12 +- .../atala/mediator/utils/HttpHelpers.scala | 2 + .../iohk/atala/mediator/app/IndexHtml.scala | 57 +++--- .../atala/mediator/app/MediatorAgent.scala | 173 ++++++++---------- .../mediator/app/MediatorStandalone.scala | 26 +-- .../io/iohk/atala/mediator/AppUtils.scala | 3 +- 7 files changed, 121 insertions(+), 154 deletions(-) diff --git a/build.sbt b/build.sbt index 2dfdcaa3..16a75996 100644 --- a/build.sbt +++ b/build.sbt @@ -23,7 +23,7 @@ lazy val V = new { val zio = "2.0.18" val zioJson = "0.6.2" // val zioMunitTest = "0.1.1" - val zioHttp = "3.0.0-RC2" + val zioHttp = "3.0.0-RC3" val zioConfig = "4.0.0-RC16" val zioLogging = "2.1.14" val zioSl4j = "2.1.14" diff --git a/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/comm/MessageDispatcherJVM.scala b/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/comm/MessageDispatcherJVM.scala index 81623bfd..2704c260 100644 --- a/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/comm/MessageDispatcherJVM.scala +++ b/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/comm/MessageDispatcherJVM.scala @@ -33,14 +33,12 @@ class MessageDispatcherJVM(client: Client) extends MessageDispatcher { .pipe(e => Header.ContentType(ZMediaType.application.any.copy(subType = "didcomm-encrypted+json"))) val xForwardedHostHeader = xForwardedHost.map(x => Header.Custom(customName = MyHeaders.xForwardedHost, x)) - // xForwardedHost.map(x => Header.(MyHeaders.xForwardedHost, x)) for { res <- Client .request( - url = destination, - method = Method.POST, - headers = Headers(Seq(Some(contentTypeHeader), xForwardedHostHeader).flatten), - content = Body.fromCharSequence(msg.toJson), + Request + .post(destination, Body.fromCharSequence(msg.toJson)) + .setHeaders(Headers(Seq(Some(contentTypeHeader), xForwardedHostHeader).flatten)) ) .tapError(ex => ZIO.logWarning(s"Fail when calling '$destination': ${ex.toString}")) .mapError(ex => DispatcherError(ex)) @@ -51,5 +49,7 @@ class MessageDispatcherJVM(client: Client) extends MessageDispatcher { case true => ZIO.logWarning(data) case false => ZIO.logInfo(data) } yield (data) - }.provideEnvironment(ZEnvironment(client)) + } + .provideSomeLayer(Scope.default) + .provideEnvironment(ZEnvironment(client)) } diff --git a/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/utils/HttpHelpers.scala b/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/utils/HttpHelpers.scala index 48577fa1..1038b029 100644 --- a/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/utils/HttpHelpers.scala +++ b/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/utils/HttpHelpers.scala @@ -1,3 +1,4 @@ +/* package io.iohk.atala.mediator.utils import zio.* @@ -50,3 +51,4 @@ object MiddlewareUtils { } } + */ diff --git a/mediator/src/main/scala/io/iohk/atala/mediator/app/IndexHtml.scala b/mediator/src/main/scala/io/iohk/atala/mediator/app/IndexHtml.scala index f5923e5e..0af47f53 100644 --- a/mediator/src/main/scala/io/iohk/atala/mediator/app/IndexHtml.scala +++ b/mediator/src/main/scala/io/iohk/atala/mediator/app/IndexHtml.scala @@ -1,31 +1,38 @@ package io.iohk.atala.mediator.app -import zio.http.Response +import zio.http._ import fmgp.did.DID object IndexHtml { - // TODO use the html.Html.fromDomElement() - def html(identity: DID) = Response.html(s""" - | - | - | IOHK Mediator - | - | - | - | - | - | - | - | - | - | - | - |
- | - | - |""".stripMargin) + def html(identity: DID) = + Response( + status = Status.Ok, + headers = Headers(Header.ContentType(MediaType.text.html).untyped), + body = Body.fromString( + s""" + | + | + | + | IOHK Mediator + | + | + | + | + | + | + | + | + | + | + | + |
+ | + | + |""".stripMargin + ), + ) } diff --git a/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala b/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala index a79dd525..6da8785d 100644 --- a/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala +++ b/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala @@ -14,7 +14,6 @@ import io.iohk.atala.mediator.db.* import io.iohk.atala.mediator.protocols.* import io.iohk.atala.mediator.utils.* import io.netty.handler.codec.http.HttpHeaderNames -import reactivemongo.api.bson.Macros.{*, given} import reactivemongo.api.bson.{*, given} import zio.* import zio.http.* @@ -23,7 +22,6 @@ import zio.json.* import scala.concurrent.ExecutionContext.Implicits.global import scala.util.Try import scala.io.Source -import zio.http.internal.middlewares.Cors.CorsConfig import zio.http.Header.AccessControlAllowOrigin import zio.http.Header.AccessControlAllowMethods @@ -223,18 +221,20 @@ object MediatorAgent { def make(id: DID, keyStore: KeyStore): ZIO[Any, Nothing, MediatorAgent] = ZIO.succeed(MediatorAgent(id, keyStore)) def didCommApp = { - Http.collectZIO[Request] { - case req @ Method.GET -> Root / "headers" => + Routes( + Method.GET / "headers" -> handler { (req: Request) => val data = req.headers.toSeq.map(e => (e.headerName, e.renderedValue)) ZIO.succeed(Response.text("HEADERS:\n" + data.mkString("\n") + "\nRemoteAddress:" + req.remoteAddress)).debug - case req @ Method.GET -> Root / "health" => ZIO.succeed(Response.ok) - case Method.GET -> Root / "version" => ZIO.succeed(Response.text(MediatorBuildInfo.version)) - case Method.GET -> Root / "did" => + }, + Method.GET / "health" -> handler { (req: Request) => ZIO.succeed(Response.ok) }, + Method.GET / "version" -> handler { (req: Request) => ZIO.succeed(Response.text(MediatorBuildInfo.version)) }, + Method.GET / "did" -> handler { (req: Request) => for { agent <- ZIO.service[MediatorAgent] ret <- ZIO.succeed(Response.text(agent.id.string)) } yield (ret) - case Method.GET -> Root / "invitation" => + }, + Method.GET / "invitation" -> handler { (req: Request) => for { agent <- ZIO.service[MediatorAgent] annotationMap <- ZIO.logAnnotations.map(_.map(e => LogAnnotation(e._1, e._2)).toSeq) @@ -247,7 +247,8 @@ object MediatorAgent { _ <- ZIO.log("New mediate invitation MsgID: " + invitation.id.value) ret <- ZIO.succeed(Response.json(invitation.toPlaintextMessage.toJson)) } yield (ret) - case Method.GET -> Root / "invitationOOB" => + }, + Method.GET / "invitationOOB" -> handler { (req: Request) => for { agent <- ZIO.service[MediatorAgent] annotationMap <- ZIO.logAnnotations.map(_.map(e => LogAnnotation(e._1, e._2)).toSeq) @@ -263,98 +264,78 @@ object MediatorAgent { OutOfBandPlaintext.from(invitation.toPlaintextMessage).makeURI("") ) ) - } yield (ret) - case req @ Method.POST -> Root - if req.headers - // .header(Header.ContentType) // TODO BUG? this does not work - .get("content-type") - .exists { h => - // TODO after fix BUG - // h.mediaType.mainType == "application" && - // (h.mediaType.subType == "didcomm-signed+json" || h.mediaType.subType == "didcomm-encrypted+json") - // TODO after update lib - // h.mediaType.mainType == ZMediaTypes.mainType && - // (h.mediaType.subType == MediaTypes.SIGNED.subType || h.mediaType.subType == MediaTypes.ENCRYPTED.subType) - h == MediaTypes.SIGNED.typ || h == MediaTypes.ENCRYPTED.typ - } => - for { - agent <- ZIO.service[MediatorAgent] - data <- req.body.asString - ret <- agent - .receiveMessage(data) - .map { - case None => Response.ok - case Some(value: SignedMessage) => Response.json(value.toJson) - case Some(value: EncryptedMessage) => Response.json(value.toJson) - } - .catchAll { - case MediatorDidError(error) => - ZIO.logError(s"Error MediatorDidError: $error") *> - ZIO.succeed(Response.status(Status.BadRequest)) - case MediatorThrowable(error) => - ZIO.logError(s"Error MediatorThrowable: $error") *> - ZIO.succeed(Response.status(Status.BadRequest)) - case StorageCollection(error) => - ZIO.logError(s"Error StorageCollection: $error") *> - ZIO.succeed(Response.status(Status.BadRequest)) - case StorageThrowable(error) => - ZIO.logError(s"Error StorageThrowable: $error") *> - ZIO.succeed(Response.status(Status.BadRequest)) - case DuplicateMessage(error) => - ZIO.logError(s"Error DuplicateKeyError: $error") *> - ZIO.succeed(Response.status(Status.BadRequest)) - case MissingProtocolError(piuri) => - ZIO.logError(s"MissingProtocolError ('$piuri')") *> - ZIO.succeed(Response.status(Status.BadRequest)) // TODO - } - } yield ret - // TODO [return_route extension](https://github.com/decentralized-identity/didcomm-messaging/blob/main/extensions/return_route/main.md) - case req @ Method.POST -> Root => - ZIO - .logError(s"Request Headers: ${req.headers.mkString(",")}") - .as( - Response - .text(s"The content-type must be ${MediaTypes.SIGNED.typ} or ${MediaTypes.ENCRYPTED.typ}") - .copy(status = Status.BadRequest) - ) - case req @ Method.GET -> Root => { // html.Html.fromDomElement() + }, + Method.POST / trailing -> handler { (req: Request) => + { + if ( + req.headers + .get("content-type") + .exists { h => h == MediaTypes.SIGNED.typ || h == MediaTypes.ENCRYPTED.typ } + ) { + for { + agent <- ZIO.service[MediatorAgent] + data <- req.body.asString + .catchAll(ex => ZIO.fail(Response.badRequest("Unable to read the body of the request"))) + ret <- agent + .receiveMessage(data) + .map { + case None => Response.ok + case Some(value: SignedMessage) => Response.json(value.toJson) + case Some(value: EncryptedMessage) => Response.json(value.toJson) + } + .catchAll { + case MediatorDidError(error) => + ZIO.logError(s"Error MediatorDidError: $error") *> + ZIO.succeed(Response.status(Status.BadRequest)) + case MediatorThrowable(error) => + ZIO.logError(s"Error MediatorThrowable: $error") *> + ZIO.succeed(Response.status(Status.BadRequest)) + case StorageCollection(error) => + ZIO.logError(s"Error StorageCollection: $error") *> + ZIO.succeed(Response.status(Status.BadRequest)) + case StorageThrowable(error) => + ZIO.logError(s"Error StorageThrowable: $error") *> + ZIO.succeed(Response.status(Status.BadRequest)) + case DuplicateMessage(error) => + ZIO.logError(s"Error DuplicateKeyError: $error") *> + ZIO.succeed(Response.status(Status.BadRequest)) + case MissingProtocolError(piuri) => + ZIO.logError(s"MissingProtocolError ('$piuri')") *> + ZIO.succeed(Response.status(Status.BadRequest)) // TODO + } + } yield ret + } else + ZIO + .logError(s"Request Headers: ${req.headers.mkString(",")}") + .as( + Response + .text(s"The content-type must be ${MediaTypes.SIGNED.typ} or ${MediaTypes.ENCRYPTED.typ}") + .copy(status = Status.BadRequest) + ) + } + }, + Method.GET / trailing -> handler { (req: Request) => for { agent <- ZIO.service[MediatorAgent] _ <- ZIO.log("index.html") ret <- ZIO.succeed(IndexHtml.html(agent.id)) } yield ret - } - }: Http[ - Operations & Resolver & MessageDispatcher & MediatorAgent & MessageItemRepo & UserAccountRepo & OutboxMessageRepo, - Throwable, - Request, - Response - ] - } ++ Http - .fromResource(s"public/webapp-fastopt-bundle.js.gz") - .map(_.setHeaders(Headers(Header.ContentType(MediaType.application.javascript), Header.ContentEncoding.GZip))) - .when { - case Method.GET -> Root / "public" / "webapp-fastopt-bundle.js" => true - case _ => false - } - @@ HttpAppMiddleware.cors( - CorsConfig( - allowedOrigin = { - // case origin @ Origin.Value(_, host, _) if host == "dev" => Some(AccessControlAllowOrigin.Specific(origin)) - case _ => Some(AccessControlAllowOrigin.All) - }, - allowedMethods = AccessControlAllowMethods(Method.GET, Method.POST, Method.OPTIONS), - ) + }, + Method.GET / "public" / string("path") -> handler { (path: String, req: Request) => + // RoutesMiddleware + // TODO https://zio.dev/reference/stream/zpipeline/#:~:text=ZPipeline.gzip%20%E2%80%94%20The%20gzip%20pipeline%20compresses%20a%20stream%20of%20bytes%20as%20using%20gzip%20method%3A + val fullPath = s"public/$path" + val classLoader = Thread.currentThread().getContextClassLoader() + val headerContentType = fullPath match + case s if s.endsWith(".html") => Header.ContentType(MediaType.text.html) + case s if s.endsWith(".js") => Header.ContentType(MediaType.text.javascript) + case s if s.endsWith(".css") => Header.ContentType(MediaType.text.css) + case s if s.endsWith(".svg") => Header.ContentType(MediaType.image.`svg+xml`) + case s => Header.ContentType(MediaType.text.plain) + Handler.fromResource(fullPath).map(_.addHeader(headerContentType)) + }.flatten ) - // @@ - // HttpAppMiddleware.updateHeaders(headers => - // Headers( - // headers.map(h => - // if (h.key == HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN) { - // Header(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*") - // } else h - // ) - // ) - // ) + }.sandbox.toHttpApp + } diff --git a/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorStandalone.scala b/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorStandalone.scala index 5b1b49ec..e7d36fa4 100644 --- a/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorStandalone.scala +++ b/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorStandalone.scala @@ -16,8 +16,6 @@ import zio.config.* import zio.config.magnolia.* import zio.config.typesafe.* import zio.http.* -import zio.http.Http.{Empty, Static} -import zio.http.ZClient.ClientLive import zio.json.* import zio.logging.LogFormat.* import zio.logging.backend.SLF4J @@ -57,17 +55,6 @@ object MediatorStandalone extends ZIOAppDefault { override val bootstrap: ZLayer[ZIOAppArgs, Any, Any] = Runtime.removeDefaultLoggers >>> SLF4J.slf4j(mediatorColorFormat) - // val app: HttpApp[ // type HttpApp[-R, +Err] = Http[R, Err, Request, Response] - // Hub[String] & Operations & MessageDispatcher & MediatorAgent & Resolver & MessageItemRepo & UserAccountRepo & - // OutboxMessageRepo, - // Throwable - // ] - val app: Http[ - Operations & Resolver & UserAccountRepo & OutboxMessageRepo & MessageDispatcher & MediatorAgent & MessageItemRepo, - (HttpAppMiddleware[Nothing, Any, Nothing, Any] | HttpAppMiddleware[Nothing, Any, Nothing, Any])#OutErr[Throwable], - Request, - Response - ] = MediatorAgent.didCommApp override val run = for { _ <- Console.printLine( // https://patorjk.com/software/taag/#p=display&f=ANSI%20Shadow&t=Mediator """███╗ ███╗███████╗██████╗ ██╗ █████╗ ████████╗ ██████╗ ██████╗ @@ -103,18 +90,7 @@ object MediatorStandalone extends ZIOAppDefault { client = Scope.default >>> Client.default inboundHub <- Hub.bounded[String](5) myServer <- Server - .serve( - (app @@ (MiddlewareUtils.annotateHeaders ++ MiddlewareUtils.serverTime)) - .tapUnhandledZIO(ZIO.logError("Unhandled Endpoint")) - .tapErrorCauseZIO(cause => ZIO.logErrorCause(cause)) // THIS is to log all the erros - .mapError(err => - Response( - status = Status.BadRequest, - headers = Headers.empty, - body = Body.fromString(err.toString()), // Body.fromString(err.getMessage()), - ) - ) - ) + .serve(MediatorAgent.didCommApp @@ (Middleware.cors)) .provideSomeLayer(DidPeerResolver.layerDidPeerResolver) .provideSomeLayer(mediatorConfig.agentLayer) // .provideSomeLayer(AgentByHost.layer) .provideSomeLayer( diff --git a/webapp/src/main/scala/io/iohk/atala/mediator/AppUtils.scala b/webapp/src/main/scala/io/iohk/atala/mediator/AppUtils.scala index aebe5586..9a0c044b 100644 --- a/webapp/src/main/scala/io/iohk/atala/mediator/AppUtils.scala +++ b/webapp/src/main/scala/io/iohk/atala/mediator/AppUtils.scala @@ -96,7 +96,8 @@ object AppUtils { href := "https://atalaprism.io", target := "_blank", img( - src := "https://atalaprism.io/images/atala-prism-logo-suite.svg", + // src := "https://atalaprism.io/images/atala-prism-logo-suite.svg", + src := "public/atala-prism-logo-suite.svg", // Note: this is not the best server for CDN className := "logo vanilla", alt := "Prism Mediator" ),