new auth method for joining room

This commit is contained in:
efim 2023-04-25 12:17:37 +04:00
parent 1b71c942ec
commit b29d1a1ef1
3 changed files with 49 additions and 12 deletions

View File

@ -10,6 +10,7 @@ import java.util.UUID
import industries.sunshine.planningpoker.common.Models.{RoomID, Room} import industries.sunshine.planningpoker.common.Models.{RoomID, Room}
import org.http4s.ResponseCookie import org.http4s.ResponseCookie
import cats.data.EitherT import cats.data.EitherT
import scala.util.Random
trait Auth[F[_]] { trait Auth[F[_]] {
@ -29,7 +30,7 @@ trait Auth[F[_]] {
roomPassword: String, roomPassword: String,
nickName: String, nickName: String,
nickPassword: String nickPassword: String
): F[Either[Unit, ResponseCookie]] ): F[Either[String, ResponseCookie]]
def deleteSession( def deleteSession(
sessionId: Long sessionId: Long
@ -70,16 +71,27 @@ object Auth {
roomService: RoomService[F] roomService: RoomService[F]
) extends Auth[F] { ) extends Auth[F] {
val authcookie = "authcookie"
override def joinRoom( override def joinRoom(
roomName: String, roomName: String,
roomPassword: String, roomPassword: String,
nickName: String, nickName: String,
nickPassword: String nickPassword: String
): F[Either[Unit, ResponseCookie]] = { ): F[Either[String, ResponseCookie]] = {
for { // TODO check for existing session for same room
joinedRoom <- roomService.joinRoom(RoomID(roomName), nickName, nickPassword, roomPassword) // and do i want to logout if existing session for another room? ugh
} yield () val roomId = RoomID(roomName)
??? val result = for {
playerId <- EitherT(
roomService.joinRoom(roomId, nickName, nickPassword, roomPassword)
)
.leftMap(_.toString())
newSessionId = Random.nextLong()
_ <- EitherT.liftF(sessions.update(_.updated(newSessionId, (roomId, playerId))))
} yield ResponseCookie(name = authcookie, content = newSessionId.toString(), secure = true)
result.value
} }
override def authUser override def authUser

View File

@ -20,7 +20,7 @@ trait RoomService[F[_]] {
nickName: String, nickName: String,
nickPassword: String, nickPassword: String,
roomPassword: String roomPassword: String
): F[Either[RoomError, Room]] ): F[Either[RoomError, PlayerID]]
def deleteRoom(roomID: RoomID): F[Unit] def deleteRoom(roomID: RoomID): F[Unit]
def getRoom(roomID: RoomID): F[Option[Room]] def getRoom(roomID: RoomID): F[Option[Room]]
} }
@ -49,8 +49,29 @@ class InMemoryRoomService[F[_]: Sync](stateRef: Ref[F, Map[RoomID, Room]]) exten
nickName: String, nickName: String,
nickPassword: String, nickPassword: String,
roomPassword: String roomPassword: String
): F[Either[RoomError, Room]] = stateRef.modify[Either[RoomError, Room]] { rooms => ): F[Either[RoomError, PlayerID]] = stateRef.modify { rooms =>
val joinedRoom = for { // need to cover cases:
// - player already present, then return as is, i guess
// - nick not known - add new player and new nick-password mapping
// - nick known - add new player
def addPlayer(room: Room): (PlayerID, Room) = {
room.players.find(_.name == nickName) match {
case Some(player) => player.id -> room
case None => // player is not present, but potentially was previously
val addingPlayer = Player.create(nickPassword)
val roomWithPlayer = room.copy(players = addingPlayer :: room.players)
room.playersPasswords.get(nickName) match {
case Some(_) => addingPlayer.id -> roomWithPlayer
case None =>
addingPlayer.id -> roomWithPlayer.copy(playersPasswords =
roomWithPlayer.playersPasswords.updated(nickName, nickPassword)
)
}
}
}
val joiningWithChecks = for {
room <- rooms.get(id).toRight(RoomError.RoomMissing(id.name)) room <- rooms.get(id).toRight(RoomError.RoomMissing(id.name))
_ <- Either.cond(room.password == roomPassword, (), RoomError.RoomPassIncorrect) _ <- Either.cond(room.password == roomPassword, (), RoomError.RoomPassIncorrect)
isNickPassCorrect = room.playersPasswords isNickPassCorrect = room.playersPasswords
@ -61,10 +82,10 @@ class InMemoryRoomService[F[_]: Sync](stateRef: Ref[F, Map[RoomID, Room]]) exten
(), (),
RoomError.NickPassIncorrect RoomError.NickPassIncorrect
) )
updatedRoom = room (playerId, updatedRoom) = addPlayer(room)
} yield updatedRoom } yield playerId
rooms -> joinedRoom rooms -> joiningWithChecks
} }
} }

View File

@ -2,6 +2,7 @@ package industries.sunshine.planningpoker.common
import java.util.UUID import java.util.UUID
import io.circe._ import io.circe._
import scala.util.Random
object Models { object Models {
@ -53,6 +54,9 @@ object Models {
final case class PlayerID(id: Long) derives Codec.AsObject final case class PlayerID(id: Long) derives Codec.AsObject
final case class Player(name: String, id: PlayerID) derives Codec.AsObject final case class Player(name: String, id: PlayerID) derives Codec.AsObject
object Player {
def create(name: String) = Player(name, PlayerID(Random.nextLong))
}
final case class RoomID(name: String) derives Codec.AsObject final case class RoomID(name: String) derives Codec.AsObject