Skip to content

Commit

Permalink
Fixes grab card signature verification failure
Browse files Browse the repository at this point in the history
  • Loading branch information
vaslabs committed Nov 8, 2020
1 parent b48864a commit 1b13be7
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package cardgame.endpoints

import cardgame.json.circe._
import cardgame.json.circe.requests._
import cardgame.model.{ClockedAction, ClockedResponse, GameId}
import sttp.model.StatusCode
import sttp.tapir._
Expand Down
2 changes: 1 addition & 1 deletion endpoints/src/main/scala/cardgame/endpoints/View.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package cardgame.endpoints
import cardgame.model.{Game, GameId, PlayerId}
import sttp.model.StatusCode
import sttp.tapir._
import cardgame.json.circe._
import cardgame.json.circe.common._
import sttp.tapir.json.circe._

object View {
Expand Down
178 changes: 117 additions & 61 deletions endpoints/src/main/scala/cardgame/json/circe.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,84 +14,140 @@ import cats.implicits._
import scala.util.Try
object circe {

implicit val playerIdEncoder: Encoder[PlayerId] = Encoder.encodeString.contramap(_.value)
implicit val playerIdDecoder: Decoder[PlayerId] = Decoder.decodeString.map(PlayerId)
implicit val cardIdEncoder: Encoder[CardId] = Encoder.encodeUUID.contramap(_.value)
implicit val cardIdDecoder: Decoder[CardId] = Decoder.decodeUUID.map(CardId)
object common {

implicit val deckIdEncoder: Encoder[DeckId] = Encoder.encodeUUID.contramap(_.value)
implicit val deckIdDecoder: Decoder[DeckId] = Decoder.decodeUUID.map(DeckId)
implicit val playerIdEncoder: Encoder[PlayerId] = Encoder.encodeString.contramap(_.value)
implicit val playerIdDecoder: Decoder[PlayerId] = Decoder.decodeString.map(PlayerId)
implicit val cardIdEncoder: Encoder[CardId] = Encoder.encodeUUID.contramap(_.value)
implicit val cardIdDecoder: Decoder[CardId] = Decoder.decodeUUID.map(CardId)

implicit val uriEncoder: Encoder[URI] = Encoder.encodeString.contramap(_.toASCIIString)
implicit val uriDecoder: Decoder[URI] = Decoder.decodeString.emapTry(s => Try(URI.create(s)))
implicit val deckIdEncoder: Encoder[DeckId] = Encoder.encodeUUID.contramap(_.value)
implicit val deckIdDecoder: Decoder[DeckId] = Decoder.decodeUUID.map(DeckId)

implicit val eventEncoder: Encoder[Event] = deriveEncoder
implicit val eventDecoder: Decoder[Event] = deriveDecoder
implicit val uriEncoder: Encoder[URI] = Encoder.encodeString.contramap(_.toASCIIString)
implicit val uriDecoder: Decoder[URI] = Decoder.decodeString.emapTry(s => Try(URI.create(s)))

implicit val gameEncoder: Encoder[Game] = deriveEncoder
implicit val gameDecoder: Decoder[Game] = deriveDecoder
implicit val eventEncoder: Encoder[Event] = deriveEncoder
implicit val eventDecoder: Decoder[Event] = deriveDecoder

implicit val rsaPublicKeyEncoder: Encoder[RSAPublicKey] = Encoder.encodeString.contramap {
rsaPublicKey =>
rsa.show(rsaPublicKey)
}
implicit val gameEncoder: Encoder[Game] = deriveEncoder
implicit val gameDecoder: Decoder[Game] = deriveDecoder

implicit val rsaPublicKeyEncoder: Encoder[RSAPublicKey] = Encoder.encodeString.contramap {
rsaPublicKey =>
rsa.show(rsaPublicKey)
}

implicit val rsaPublicKeyDecoder: Decoder[RSAPublicKey] = Decoder.decodeString.emapTry {
value =>
Try(rsa.fromString(value))
}

implicit val playerIdKeyEncoder: KeyEncoder[PlayerId] = KeyEncoder.encodeKeyString.contramap(_.value)
implicit val playerIdKeyDecoder: KeyDecoder[PlayerId] = KeyDecoder.decodeKeyString.map(PlayerId)

implicit val rsaPublicKeyDecoder: Decoder[RSAPublicKey] = Decoder.decodeString.emapTry {
value =>
Try(rsa.fromString(value))
implicit val playingGameActionCodec: Codec[Action] =
deriveCodec
}

implicit val playerIdKeyEncoder: KeyEncoder[PlayerId] = KeyEncoder.encodeKeyString.contramap(_.value)
implicit val playerIdKeyDecoder: KeyDecoder[PlayerId] = KeyDecoder.decodeKeyString.map(PlayerId)
object requests {
import common._
implicit val clockedActionEncoder: Encoder[ClockedAction] = Encoder.instance {
clockedAction =>
clockedAction.action.asJson.mapObject(_.add("vectorClock", clockedAction.vectorClock.asJson)
.add("serverClock", clockedAction.serverClock.asJson)
.add("signature", clockedAction.signature.asJson)
)

implicit val hiddenCardEncoder: Encoder[HiddenCard] =
Encoder.instance {
hc =>
Json.obj("id" -> hc.id.asJson)
}

implicit val playingGameActionCodec: Codec[Action] =
deriveCodec
implicit val clockedActionDecoder: Decoder[ClockedAction] = Decoder.instance {
hcursor =>
(
hcursor.downField("vectorClock").as[Map[String, Long]].orElse(Right(Map.empty[String, Long])),
hcursor.downField("serverClock").as[Long].orElse(Right(0L)),
hcursor.downField("signature").as[String],
hcursor.as[Action]
).mapN(
(clock, serverClock, signature, action) => ClockedAction(action, clock, serverClock, signature)
)
}.handleErrorWith {
df =>
println(df)
Decoder.failed(df)
}

implicit val clockedResponseEncoder: Encoder[ClockedResponse] = Encoder.instance {
clockedResponse =>
clockedResponse.event.asJson.mapObject(_.add("vectorClock", clockedResponse.clock.asJson)
implicit val clockedResponseEncoder: Encoder[ClockedResponse] = Encoder.instance {
clockedResponse =>
clockedResponse.event.asJson.mapObject(_.add("vectorClock", clockedResponse.clock.asJson)
.add("serverClock", clockedResponse.serverClock.asJson)
)
}
)
}

implicit val clockedResponseDecoder: Decoder[ClockedResponse] = Decoder.instance {
hcursor =>
(
hcursor.downField("vectorClock").as[Map[String, Long]].orElse(Right(Map.empty[String, Long])),
hcursor.downField("serverClock").as[Long],
hcursor.as[Event]
).mapN((vectorClocks, serverClock, events) =>
ClockedResponse(events, vectorClocks, serverClock)
)
implicit val clockedResponseDecoder: Decoder[ClockedResponse] = Decoder.instance {
hcursor =>
(
hcursor.downField("vectorClock").as[Map[String, Long]].orElse(Right(Map.empty[String, Long])),
hcursor.downField("serverClock").as[Long],
hcursor.as[Event]
).mapN((vectorClocks, serverClock, events) =>
ClockedResponse(events, vectorClocks, serverClock)
)
}
}

implicit val clockedActionEncoder: Encoder[ClockedAction] = Encoder.instance {
clockedAction =>
clockedAction.action.asJson.mapObject(_.add("vectorClock", clockedAction.vectorClock.asJson)
.add("serverClock", clockedAction.serverClock.asJson)
)
object responses {
import common._
implicit val hiddenCardEncoder: Encoder[HiddenCard] =
Encoder.instance {
hc =>
Json.obj("id" -> hc.id.asJson)
}

}
implicit val clockedActionEncoder: Encoder[ClockedAction] = Encoder.instance {
clockedAction =>
clockedAction.action.asJson.mapObject(_.add("vectorClock", clockedAction.vectorClock.asJson)
.add("serverClock", clockedAction.serverClock.asJson)
)

implicit val clockedActionDecoder: Decoder[ClockedAction] = Decoder.instance {
hcursor =>
(
hcursor.downField("vectorClock").as[Map[String, Long]].orElse(Right(Map.empty[String, Long])),
hcursor.downField("serverClock").as[Long].orElse(Right(0L)),
hcursor.downField("signature").as[String],
hcursor.as[Action]
).mapN(
(clock, serverClock, signature, action) => ClockedAction(action, clock, serverClock, signature)
)
}.handleErrorWith {
df =>
println(df)
Decoder.failed(df)
}

implicit val clockedActionDecoder: Decoder[ClockedAction] = Decoder.instance {
hcursor =>
(
hcursor.downField("vectorClock").as[Map[String, Long]].orElse(Right(Map.empty[String, Long])),
hcursor.downField("serverClock").as[Long].orElse(Right(0L)),
hcursor.downField("signature").as[String],
hcursor.as[Action]
).mapN(
(clock, serverClock, signature, action) => ClockedAction(action, clock, serverClock, signature)
)
}.handleErrorWith {
df =>
println(df)
Decoder.failed(df)
}

implicit val clockedResponseEncoder: Encoder[ClockedResponse] = Encoder.instance {
clockedResponse =>
clockedResponse.event.asJson.mapObject(_.add("vectorClock", clockedResponse.clock.asJson)
.add("serverClock", clockedResponse.serverClock.asJson)
)
}

implicit val clockedResponseDecoder: Decoder[ClockedResponse] = Decoder.instance {
hcursor =>
(
hcursor.downField("vectorClock").as[Map[String, Long]].orElse(Right(Map.empty[String, Long])),
hcursor.downField("serverClock").as[Long],
hcursor.as[Event]
).mapN((vectorClocks, serverClock, events) =>
ClockedResponse(events, vectorClocks, serverClock)
)
}
}


}


Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package cardgame.endpoints.codecs

import cardgame.json.circe._
import cardgame.json.circe.responses._
import cardgame.model.{Authorise, ClockedAction, PlayerId}
import io.circe.parser._
import org.scalatest.flatspec.AnyFlatSpec
Expand Down
2 changes: 1 addition & 1 deletion service/src/main/scala/cardgame/events/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ package object events {
}
testSignature.getOrElse(false)
}
import cardgame.json.circe._
import io.circe.syntax._

def validateSignature(game: Game, action: ClockedAction): Boolean = {
val plainText = {
import cardgame.json.circe.responses._
action.asJson.mapObject(_.filterKeys(key => key != "signature")).noSpaces
}
val verify = (game, action.action) match {
Expand Down
2 changes: 1 addition & 1 deletion service/src/main/scala/cardgame/routes/routes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import akka.stream.typed.scaladsl.ActorSink
import akka.util.Timeout
import cardgame.endpoints.{JoiningGame, _}
import cardgame.events._
import cardgame.json.circe._
import cardgame.json.circe.requests._
import cardgame.model._
import cardgame.processor.ActiveGames
import cardgame.processor.ActiveGames.api._
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package cardgame.events

import cardgame.endpoints.codecs.rsa
import cardgame.json.circe._
import cardgame.json.circe.responses._
import cardgame.model.{ClockedAction, JoiningPlayer, PlayerId, StartingGame}
import io.circe.Json
import io.circe.parser._
Expand Down

0 comments on commit 1b13be7

Please sign in to comment.