backend: move roomService usage to httpService

no longer used in auth module,
ready to connect rest routes to room service
This commit is contained in:
efim 2023-04-28 00:46:25 +04:00
parent ed6d30ec42
commit bd38a29b6d
4 changed files with 34 additions and 61 deletions

View File

@ -25,53 +25,33 @@ trait Auth[F[_]] {
* check that room exists, password is valid call to add user to the players create session * check that room exists, password is valid call to add user to the players create session
* mapping and return cookie * mapping and return cookie
*/ */
def joinRoom( def joinRoom(roomId: RoomID, playerId: PlayerID): F[ResponseCookie]
roomName: String,
roomPassword: String,
nickName: String,
nickPassword: String
): F[Either[String, ResponseCookie]]
def deleteSession( def deleteSession(sessionId: Long): F[Unit]
sessionId: Long
): F[Unit]
} }
object Auth { object Auth {
type SessionsMap = Map[Long, (RoomID, PlayerID)] type SessionsMap = Map[Long, (RoomID, PlayerID)]
class SimpleAuth[F[_]: Sync]( class SimpleAuth[F[_]: Sync](sessions: Ref[F, SessionsMap]) extends Auth[F] {
sessions: Ref[F, SessionsMap],
roomService: RoomService[F]
) extends Auth[F] {
val authcookieName = "authcookie" val authcookieName = "authcookie"
override def joinRoom( override def joinRoom(roomId: RoomID, playerId: PlayerID): F[ResponseCookie] = {
roomName: String,
roomPassword: String,
nickName: String,
nickPassword: String
): F[Either[String, ResponseCookie]] = {
// TODO check for existing session for same room // TODO check for existing session for same room
// and do i want to logout if existing session for another room? ugh // and do i want to logout if existing session for another room? ugh
val roomId = RoomID(roomName) // newSessionId = Random.nextLong() // TODO return after i stop mocking RoomService
val result = for { val newSessionId = TestModels.testSessionId
playerId <- EitherT( sessions
roomService.joinRoom(roomId, nickName, nickPassword, roomPassword) .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 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 { for {
sessionsMap <- Ref.of[F, SessionsMap](TestModels.testSessions) sessionsMap <- Ref.of[F, SessionsMap](TestModels.testSessions)
} yield new SimpleAuth(sessionsMap, roomsService) } yield new SimpleAuth(sessionsMap)
} }

View File

@ -14,8 +14,8 @@ object BackendApp extends IOApp {
val wiring = for { val wiring = for {
roomService <- Resource.eval(RoomService.make[IO]) roomService <- Resource.eval(RoomService.make[IO])
auth <- Resource.eval(Auth.make(roomService)) auth <- Resource.eval(Auth.make[IO]())
httpService = MyHttpService.create(auth) httpService = MyHttpService.create(auth, roomService)
server <- EmberServerBuilder server <- EmberServerBuilder
.default[IO] .default[IO]
.withHost(host) .withHost(host)
@ -25,9 +25,7 @@ object BackendApp extends IOApp {
} yield server } yield server
wiring.use(server => wiring.use(server =>
IO.delay(println(s"Server Has Started at ${server.address}")) >> IO.never IO.delay(println(s"Server Has Started at ${server.address}")) >> IO.never.as(ExitCode.Success))
.as(ExitCode.Success)
)
} }
} }

View File

@ -4,7 +4,6 @@ import cats.effect._
import cats.syntax.all._ import cats.syntax.all._
import org.http4s._, org.http4s.dsl.io._, org.http4s.implicits._ import org.http4s._, org.http4s.dsl.io._, org.http4s.implicits._
import org.http4s.websocket.WebSocketFrame import org.http4s.websocket.WebSocketFrame
// import io.circe.generic.auto._
import io.circe.syntax._ import io.circe.syntax._
import org.http4s.circe.CirceEntityDecoder._ import org.http4s.circe.CirceEntityDecoder._
import scala.concurrent.duration._ import scala.concurrent.duration._
@ -16,8 +15,8 @@ import org.http4s.server.AuthMiddleware.apply
import org.http4s.server.AuthMiddleware import org.http4s.server.AuthMiddleware
object MyHttpService { object MyHttpService {
def create(auth: Auth[IO])( def create(auth: Auth[IO], roomService: RoomService[IO])(
wsb: WebSocketBuilder[cats.effect.IO] wsb: WebSocketBuilder[IO]
): HttpApp[cats.effect.IO] = { ): HttpApp[cats.effect.IO] = {
val authedRoomRoutes: AuthedRoutes[(PlayerID, RoomID), IO] = val authedRoomRoutes: AuthedRoutes[(PlayerID, RoomID), IO] =
@ -56,26 +55,23 @@ object MyHttpService {
val authMiddleware = AuthMiddleware(auth.authUser) val authMiddleware = AuthMiddleware(auth.authUser)
val aa = authMiddleware(authedRoomRoutes) val aa = authMiddleware(authedRoomRoutes)
import cats.data.EitherT
val authenticationRoute = HttpRoutes val authenticationRoute = HttpRoutes
.of[IO] { .of[IO] {
case req @ POST -> Root / "login" => { case req @ POST -> Root / "login" => {
for { val responseOrError = for {
data <- req.as[Requests.LogIn] data <- EitherT.right(req.as[Requests.LogIn])
authResult <- auth.joinRoom( Requests.LogIn(roomName, nickName, roomPassword, nickPassword) = data
data.roomName, roomId = RoomID(roomName)
data.password, playerId <- EitherT(roomService.joinRoom(roomId, nickName, nickPassword, roomPassword))
data.nickname, authCookie <- EitherT.liftF(auth.joinRoom(roomId, playerId))
data.nickPassword _ <- EitherT.liftF(IO(println(s"> logging in $nickName to $roomName")))
) resp <- EitherT.liftF(Ok().flatTap(resp => IO(resp.addCookie(authCookie))))
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))
}
}
} yield resp } yield resp
val response = responseOrError.leftSemiflatMap(error => Forbidden(error.toString())).merge
response
} }
} }

View File

@ -3,7 +3,6 @@ package industries.sunshine.planningpoker
import industries.sunshine.planningpoker.common.Models.* import industries.sunshine.planningpoker.common.Models.*
import cats.effect.{Ref, Sync} import cats.effect.{Ref, Sync}
import cats.syntax.all._ import cats.syntax.all._
import cats.data.EitherT
enum RoomError { enum RoomError {
case RoomAlreadyExists(name: String) case RoomAlreadyExists(name: String)