Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: sign ProblemReport when TO is unspecified #105

Merged
merged 1 commit into from
Sep 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ inThisBuild(

/** Versions */
lazy val V = new {
val scalaDID = "0.1.0-M9"
val scalaDID = "0.1.0-M10"
// val scalajsJavaSecureRandom = "1.0.0"

// FIXME another bug in the test framework https://github.com/scalameta/munit/issues/554
Expand Down
2 changes: 1 addition & 1 deletion mediator/src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ mediator = {
endpoint = ${?SERVICE_ENDPOINT}
}
server.http.port = 8080
# server.http.port = ${?PORT}
server.http.port = ${?PORT}
database = {
protocol = mongodb
protocol = ${?MONGODB_PROTOCOL}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,37 @@ object ActionUtils {
): ZIO[
Operations & Agent & Resolver & MessageDispatcher & OutboxMessageRepo,
MediatorError,
Option[EncryptedMessage]
Option[SignedMessage | EncryptedMessage]
] =
action match {
case _: NoReply.type => ZIO.succeed(None)
case action: AnyReply =>
val reply = action.msg
for {
msg <- {
reply.from match
case Some(value) => authEncrypt(reply)
case None => anonEncrypt(reply)
}.mapError(fail => MediatorDidError(fail))

outboxRepo <- ZIO.service[OutboxMessageRepo]
// TODO forward message
maybeSyncReplyMsg <- reply.to.map(_.toSeq) match // TODO improve
case None => ZIO.logWarning("Have a reply but the field 'to' is missing") *> ZIO.none
case Some(Seq()) => ZIO.logWarning("Have a reply but the field 'to' is empty") *> ZIO.none
maybeSyncReplyMsg: Option[SignedMessage | EncryptedMessage] <- reply.to.map(_.toSeq) match // TODO improve
case None =>
ZIO.logWarning("Have a reply but the field 'to' is missing") *>
sign(reply)
.mapError(fail => MediatorDidError(fail))
.map(Some(_))
case Some(Seq()) =>
ZIO.logWarning("Have a reply but the field 'to' is empty") *>
sign(reply)
.mapError(fail => MediatorDidError(fail))
.map(Some(_))
case Some(send2DIDs) =>
ZIO
.foreach(send2DIDs)(to =>
val job: ZIO[MessageDispatcher & (Resolver & Any), MediatorError, Matchable] = for {
for {
msg <- {
reply.from match
case Some(value) => authEncrypt(reply)
case None => anonEncrypt(reply)
}.mapError(fail => MediatorDidError(fail))

replyViaDIDCommMessagingProgramme = ZIO.foreach(send2DIDs) { to =>
for {
messageDispatcher <- ZIO.service[MessageDispatcher]
resolver <- ZIO.service[Resolver]

Expand Down Expand Up @@ -94,19 +104,23 @@ object ActionUtils {
.catchAll { case error => ZIO.logError(s"Store Outbox Error: $error") }
} yield ()
}

} yield (jobToRun)
action match
case Reply(_) =>
job
.when( // this is +- the opposite condition as below
originalMessage
.map { oMsg => oMsg.return_route.isEmpty || oMsg.return_route.contains(ReturnRoute.none) }
.getOrElse(true) // If originalMessage is None
)
case SyncReplyOnly(_) => ZIO.unit
case AsyncReplyOnly(_) => job
) *> ZIO
} yield ()
}
returnTmp <- action match
case Reply(_) =>
if (
originalMessage // this condition is +- the opposite condition as below
.map { oMsg => oMsg.return_route.isEmpty || oMsg.return_route.contains(ReturnRoute.none) }
.getOrElse(true) // If originalMessage is None
) (replyViaDIDCommMessagingProgramme *> ZIO.none)
else ZIO.some(msg)
case SyncReplyOnly(_) => ZIO.some(msg)
case AsyncReplyOnly(_) => replyViaDIDCommMessagingProgramme *> ZIO.none
} yield (returnTmp)
_ <- maybeSyncReplyMsg match {
case None => ZIO.unit
case Some(msg) =>
ZIO // Store send message INLINE_REPLY
.succeed(msg)
.tap(msg =>
outboxRepo
Expand All @@ -127,11 +141,18 @@ object ActionUtils {
.map { oMsg =>
{ // Should replies use the same transport channel?
oMsg.return_route.contains(ReturnRoute.all) || oMsg.return_route.contains(ReturnRoute.thread)
} &&
oMsg.from.map(_.asTO).exists(send2DIDs.contains) // Is the reply back to the original sender?
} && {
msg match
case sMsg: SignedMessage => true // TODO If the Message is only sign shoud we reply back?
case eMsg: EncryptedMessage => // Is the reply back to the original sender/caller?
val recipients = eMsg.recipientsSubject.toSeq.map(subject => TO(subject.did))
oMsg.from.map(_.asTO).exists(recipients.contains)
}
}
.getOrElse(false) // If originalMessage is None
)
}

} yield maybeSyncReplyMsg
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ trait ProtocolExecuter[-R, +E] { // <: MediatorError | StorageError] {
/** @return can return a Sync Reply Msg */
def execute[R1 <: R](
plaintextMessage: PlaintextMessage
): ZIO[R1, E, Option[EncryptedMessage]] =
): ZIO[R1, E, Option[SignedMessage | EncryptedMessage]] =
program(plaintextMessage) *> ZIO.none

def program[R1 <: R](plaintextMessage: PlaintextMessage): ZIO[R1, E, Action]
Expand All @@ -43,7 +43,7 @@ case class ProtocolExecuterCollection[-R <: Agent, +E](

override def execute[R1 <: R](
plaintextMessage: PlaintextMessage,
): ZIO[R1, E, Option[EncryptedMessage]] =
): ZIO[R1, E, Option[SignedMessage | EncryptedMessage]] =
selectExecutersFor(plaintextMessage.`type`) match
// case None => NullProtocolExecuter.execute(plaintextMessage)
case None => MissingProtocolExecuter.execute(plaintextMessage)
Expand All @@ -66,7 +66,7 @@ trait ProtocolExecuterWithServices[
override def execute[R1 <: R](
plaintextMessage: PlaintextMessage,
// context: Context
): ZIO[R1, E, Option[EncryptedMessage]] =
): ZIO[R1, E, Option[SignedMessage | EncryptedMessage]] =
program(plaintextMessage)
.tap(v => ZIO.logDebug(v.toString)) // DEBUG
.flatMap(action => ActionUtils.packResponse(Some(plaintextMessage), action))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ case class MediatorAgent(
): ZIO[
Operations & Resolver & MessageDispatcher & MediatorAgent & MessageItemRepo & UserAccountRepo & OutboxMessageRepo,
MediatorError | StorageError,
Option[EncryptedMessage]
Option[SignedMessage | EncryptedMessage]
] =
for {
msg <- data.fromJson[EncryptedMessage] match
Expand All @@ -114,7 +114,7 @@ case class MediatorAgent(
): ZIO[
Operations & Resolver & MessageDispatcher & MediatorAgent & MessageItemRepo & UserAccountRepo & OutboxMessageRepo,
MediatorError | StorageError,
Option[EncryptedMessage]
Option[SignedMessage | EncryptedMessage]
] =
ZIO
.logAnnotate("msgHash", msg.sha1) {
Expand Down Expand Up @@ -338,8 +338,9 @@ object MediatorAgent {
ret <- agent
.receiveMessage(data, None)
.map {
case None => Response.ok
case Some(value) => Response.json(value.toJson)
case None => Response.ok
case Some(value: SignedMessage) => Response.json(value.toJson)
case Some(value: EncryptedMessage) => Response.json(value.toJson)
}
.catchAll {
case MediatorDidError(error) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,82 @@ given BSONDocumentReader[EncryptedMessage] with {
aux.readDocument(doc)
}

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

given BSONWriter[Payload] with {
import Payload.*
def writeTry(obj: Payload): Try[BSONValue] = Try(BSONString(obj.base64url))
}
given BSONReader[Payload] with {
def readTry(bson: BSONValue): Try[Payload] = bson.asTry[String].map(v => Payload.fromBase64url(v))
}

given BSONWriter[SigningAlgorithm] with {
def writeTry(obj: SigningAlgorithm): Try[BSONValue] = Try(BSONString(obj.toString()))
}
given BSONReader[SigningAlgorithm] with {
def readTry(bson: BSONValue): Try[SigningAlgorithm] = bson.asTry[String].map(v => SigningAlgorithm.valueOf(v))
}

given BSONDocumentWriter[SignProtectedHeader] = Macros.writer[SignProtectedHeader]
given BSONDocumentReader[SignProtectedHeader] = Macros.reader[SignProtectedHeader]

given given_BSONWriter_Base64Obj_SignProtectedHeader: BSONWriter[Base64Obj[SignProtectedHeader]] with {
import Base64Obj.*
def writeTry(obj: Base64Obj[SignProtectedHeader]): Try[BSONValue] = {
val protectedHeader: String = (obj.obj, obj.original) match {
case (_, Some(op)) => op.urlBase64
case (p, None) => obj.base64url
}
Try(BSONString(protectedHeader))
}
}
given given_BSONReader_Base64Obj_SignProtectedHeader: BSONReader[Base64Obj[SignProtectedHeader]] with {
def readTry(bson: BSONValue): Try[Base64Obj[SignProtectedHeader]] =
bson
.asTry[String]
.flatMap { v =>
s""""$v"""".fromJson[Base64Obj[SignProtectedHeader]] match // TODO with a new methods from ScalaDid
case Left(value) => Failure(RuntimeException(value))
case Right(value) => Try(value)
}
}

given BSONWriter[SignatureJWM] with {
import SignatureJWM.*
def writeTry(obj: SignatureJWM): Try[BSONValue] = Try(BSONString(obj.value))
}
given BSONReader[SignatureJWM] with {
def readTry(bson: BSONValue): Try[SignatureJWM] = bson.asTry[String].map(v => SignatureJWM(v))
}

given BSONDocumentWriter[JWMHeader] = Macros.writer[JWMHeader]
given BSONDocumentReader[JWMHeader] = Macros.reader[JWMHeader]

given BSONDocumentWriter[JWMSignatureObj] = Macros.writer[JWMSignatureObj]
given BSONDocumentReader[JWMSignatureObj] = Macros.reader[JWMSignatureObj]

given BSONDocumentWriter[SignedMessage] = Macros.writer[SignedMessage]
given BSONDocumentReader[SignedMessage] = Macros.reader[SignedMessage]

given BSONDocumentWriter[SignedMessage | EncryptedMessage] with {
override def writeTry(obj: SignedMessage | EncryptedMessage): Try[BSONDocument] =
obj match {
case msg: EncryptedMessage => given_BSONDocumentWriter_EncryptedMessage.writeTry(msg)
case msg: SignedMessage => given_BSONDocumentWriter_SignedMessage.writeTry(msg)
}
}
given BSONDocumentReader[SignedMessage | EncryptedMessage] with {
override def readDocument(doc: BSONDocument): Try[SignedMessage | EncryptedMessage] =
given_BSONDocumentReader_EncryptedMessage
.readDocument(doc)
.orElse(
given_BSONDocumentReader_SignedMessage
.readDocument(doc)
)
}

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

given BSONWriter[MsgID] with {
import MsgID.*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import fmgp.did.comm.*
import reactivemongo.api.bson.*
import java.time.Instant
import scala.util.Try
import zio.json._

type HASH = String
// messages
Expand Down Expand Up @@ -43,32 +44,45 @@ object DidAccount {
// messages outbox
case class SentMessageItem(
_id: BSONObjectID = BSONObjectID.generate(),
encrypt: EncryptedMessage,
encrypt: SignedMessage | EncryptedMessage,
hash: HASH,
headers: ProtectedHeader,
headers: ast.Json, // ProtectedHeader | SignProtectedHeader,
plaintext: PlaintextMessage,
transport: Seq[SentMessageItem.TransportInfo],
)

object SentMessageItem {

def apply(
msg: EncryptedMessage,
msg: SignedMessage | EncryptedMessage,
plaintext: PlaintextMessage,
recipient: Set[TO],
distination: Option[String],
sendMethod: MessageSendMethod,
result: Option[String]
): SentMessageItem = {
new SentMessageItem(
encrypt = msg,
hash = msg.sha1,
headers = msg.`protected`.obj,
plaintext = plaintext,
transport = Seq(
TransportInfo(recipient = recipient, distination = distination, sendMethod = sendMethod, result = result)
)
)
msg match
case sMsg: SignedMessage =>
new SentMessageItem(
encrypt = msg,
hash = sMsg.sha1, // FIXME
headers = sMsg.signatures.headOption.flatMap(_.`protected`.obj.toJsonAST.toOption).getOrElse(ast.Json.Null),
plaintext = plaintext,
transport = Seq(
TransportInfo(recipient = recipient, distination = distination, sendMethod = sendMethod, result = result)
)
)
case eMsg: EncryptedMessage =>
new SentMessageItem(
encrypt = msg,
hash = eMsg.sha1,
headers = eMsg.`protected`.obj.toJsonAST.getOrElse(ast.Json.Null),
plaintext = plaintext,
transport = Seq(
TransportInfo(recipient = recipient, distination = distination, sendMethod = sendMethod, result = result)
)
)

}

given BSONDocumentWriter[SentMessageItem] = {
Expand Down
Loading