From bd38a29b6d7759aa1ce6ae15c4b0880b5fdb7fa5 Mon Sep 17 00:00:00 2001 From: efim Date: Fri, 28 Apr 2023 00:46:25 +0400 Subject: [PATCH] backend: move roomService usage to httpService no longer used in auth module, ready to connect rest routes to room service --- .../sunshine/planningpoker/Auth.scala | 52 ++++++------------- .../sunshine/planningpoker/BackendApp.scala | 8 ++- .../planningpoker/MyHttpService.scala | 34 ++++++------ .../sunshine/planningpoker/RoomService.scala | 1 - 4 files changed, 34 insertions(+), 61 deletions(-) diff --git a/backend/src/main/scala/industries/sunshine/planningpoker/Auth.scala b/backend/src/main/scala/industries/sunshine/planningpoker/Auth.scala index 6476f24..6c22960 100644 --- a/backend/src/main/scala/industries/sunshine/planningpoker/Auth.scala +++ b/backend/src/main/scala/industries/sunshine/planningpoker/Auth.scala @@ -25,53 +25,33 @@ trait Auth[F[_]] { * check that room exists, password is valid call to add user to the players create session * mapping and return cookie */ - def joinRoom( - roomName: String, - roomPassword: String, - nickName: String, - nickPassword: String - ): F[Either[String, ResponseCookie]] + def joinRoom(roomId: RoomID, playerId: PlayerID): F[ResponseCookie] - def deleteSession( - sessionId: Long - ): F[Unit] + def deleteSession(sessionId: Long): F[Unit] } object Auth { type SessionsMap = Map[Long, (RoomID, PlayerID)] - class SimpleAuth[F[_]: Sync]( - sessions: Ref[F, SessionsMap], - roomService: RoomService[F] - ) extends Auth[F] { + class SimpleAuth[F[_]: Sync](sessions: Ref[F, SessionsMap]) extends Auth[F] { val authcookieName = "authcookie" - override def joinRoom( - roomName: String, - roomPassword: String, - nickName: String, - nickPassword: String - ): F[Either[String, ResponseCookie]] = { + override def joinRoom(roomId: RoomID, playerId: PlayerID): F[ResponseCookie] = { // TODO check for existing session for same room // and do i want to logout if existing session for another room? ugh - val roomId = RoomID(roomName) - val result = for { - playerId <- EitherT( - roomService.joinRoom(roomId, nickName, nickPassword, roomPassword) + // newSessionId = Random.nextLong() // TODO return after i stop mocking RoomService + val newSessionId = TestModels.testSessionId + sessions + .update(_.updated(newSessionId, (roomId, playerId))) + .as( + ResponseCookie( + name = authcookieName, + content = newSessionId.toString(), + secure = true + ) ) - .leftMap(_.toString()) - // newSessionId = Random.nextLong() // TODO return after i stop mocking RoomService - newSessionId = TestModels.testSessionId - _ <- EitherT.liftF(sessions.update(_.updated(newSessionId, (roomId, playerId)))) - } yield ResponseCookie( - name = authcookieName, - content = newSessionId.toString(), - secure = true - ) - - result.value } override def authUser @@ -92,8 +72,8 @@ object Auth { } } - def make[F[_]: Sync](roomsService: RoomService[F]): F[Auth[F]] = + def make[F[_]: Sync](): F[Auth[F]] = for { sessionsMap <- Ref.of[F, SessionsMap](TestModels.testSessions) - } yield new SimpleAuth(sessionsMap, roomsService) + } yield new SimpleAuth(sessionsMap) } diff --git a/backend/src/main/scala/industries/sunshine/planningpoker/BackendApp.scala b/backend/src/main/scala/industries/sunshine/planningpoker/BackendApp.scala index bb68f73..ea02766 100644 --- a/backend/src/main/scala/industries/sunshine/planningpoker/BackendApp.scala +++ b/backend/src/main/scala/industries/sunshine/planningpoker/BackendApp.scala @@ -14,8 +14,8 @@ object BackendApp extends IOApp { val wiring = for { roomService <- Resource.eval(RoomService.make[IO]) - auth <- Resource.eval(Auth.make(roomService)) - httpService = MyHttpService.create(auth) + auth <- Resource.eval(Auth.make[IO]()) + httpService = MyHttpService.create(auth, roomService) server <- EmberServerBuilder .default[IO] .withHost(host) @@ -25,9 +25,7 @@ object BackendApp extends IOApp { } yield server wiring.use(server => - IO.delay(println(s"Server Has Started at ${server.address}")) >> IO.never - .as(ExitCode.Success) - ) + IO.delay(println(s"Server Has Started at ${server.address}")) >> IO.never.as(ExitCode.Success)) } } diff --git a/backend/src/main/scala/industries/sunshine/planningpoker/MyHttpService.scala b/backend/src/main/scala/industries/sunshine/planningpoker/MyHttpService.scala index d742499..9cc7fb1 100644 --- a/backend/src/main/scala/industries/sunshine/planningpoker/MyHttpService.scala +++ b/backend/src/main/scala/industries/sunshine/planningpoker/MyHttpService.scala @@ -4,7 +4,6 @@ import cats.effect._ import cats.syntax.all._ import org.http4s._, org.http4s.dsl.io._, org.http4s.implicits._ import org.http4s.websocket.WebSocketFrame -// import io.circe.generic.auto._ import io.circe.syntax._ import org.http4s.circe.CirceEntityDecoder._ import scala.concurrent.duration._ @@ -16,8 +15,8 @@ import org.http4s.server.AuthMiddleware.apply import org.http4s.server.AuthMiddleware object MyHttpService { - def create(auth: Auth[IO])( - wsb: WebSocketBuilder[cats.effect.IO] + def create(auth: Auth[IO], roomService: RoomService[IO])( + wsb: WebSocketBuilder[IO] ): HttpApp[cats.effect.IO] = { val authedRoomRoutes: AuthedRoutes[(PlayerID, RoomID), IO] = @@ -56,26 +55,23 @@ object MyHttpService { val authMiddleware = AuthMiddleware(auth.authUser) val aa = authMiddleware(authedRoomRoutes) + import cats.data.EitherT val authenticationRoute = HttpRoutes .of[IO] { case req @ POST -> Root / "login" => { - for { - data <- req.as[Requests.LogIn] - authResult <- auth.joinRoom( - data.roomName, - data.password, - data.nickname, - data.nickPassword - ) - resp <- authResult match { - case Left(error) => - Forbidden(error) - case Right(authCookie) => { - IO(println(s"> logging in ${data.nickname} to ${data.roomName}")) >> - Ok().map(_.addCookie(authCookie)) - } - } + val responseOrError = for { + data <- EitherT.right(req.as[Requests.LogIn]) + Requests.LogIn(roomName, nickName, roomPassword, nickPassword) = data + roomId = RoomID(roomName) + playerId <- EitherT(roomService.joinRoom(roomId, nickName, nickPassword, roomPassword)) + authCookie <- EitherT.liftF(auth.joinRoom(roomId, playerId)) + _ <- EitherT.liftF(IO(println(s"> logging in $nickName to $roomName"))) + resp <- EitherT.liftF(Ok().flatTap(resp => IO(resp.addCookie(authCookie)))) } yield resp + + val response = responseOrError.leftSemiflatMap(error => Forbidden(error.toString())).merge + + response } } diff --git a/backend/src/main/scala/industries/sunshine/planningpoker/RoomService.scala b/backend/src/main/scala/industries/sunshine/planningpoker/RoomService.scala index 754d2ae..cc4f7a7 100644 --- a/backend/src/main/scala/industries/sunshine/planningpoker/RoomService.scala +++ b/backend/src/main/scala/industries/sunshine/planningpoker/RoomService.scala @@ -3,7 +3,6 @@ package industries.sunshine.planningpoker import industries.sunshine.planningpoker.common.Models.* import cats.effect.{Ref, Sync} import cats.syntax.all._ -import cats.data.EitherT enum RoomError { case RoomAlreadyExists(name: String)