89 lines
2.7 KiB
Scala
89 lines
2.7 KiB
Scala
package industries.sunshine.planningpoker
|
|
|
|
import cats.effect._
|
|
import cats.syntax.all._
|
|
import cats.data.Kleisli
|
|
import cats.data.OptionT
|
|
import org.http4s.Request
|
|
import industries.sunshine.planningpoker.common.Models.PlayerID
|
|
import java.util.UUID
|
|
import industries.sunshine.planningpoker.common.Models.{RoomID, Room}
|
|
import org.http4s.ResponseCookie
|
|
import cats.data.EitherT
|
|
import scala.util.Random
|
|
|
|
trait Auth[F[_]] {
|
|
|
|
/** for middleware that converts sessionId into PlayerId
|
|
*/
|
|
def authUser: Kleisli[[A] =>> cats.data.OptionT[F, A], Request[F], (PlayerID, RoomID)]
|
|
|
|
/** Get sessionId for accessing a room
|
|
* @param roomPassword
|
|
* \- requirement to get access to the room
|
|
*
|
|
* check that room exists, password is valid call to add user to the players create session
|
|
* mapping and return cookie
|
|
*/
|
|
def joinRoom(roomId: RoomID, playerId: PlayerID): F[ResponseCookie]
|
|
|
|
def deleteSession(sessionId: Long): F[ResponseCookie]
|
|
|
|
}
|
|
|
|
object Auth {
|
|
type SessionsMap = Map[Long, (RoomID, PlayerID)]
|
|
|
|
// TODO make "remove session usable from authed route"
|
|
val authcookieName = "authcookie"
|
|
|
|
class SimpleAuth[F[_]: Sync](sessions: Ref[F, SessionsMap]) extends Auth[F] {
|
|
|
|
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
|
|
// 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
|
|
)
|
|
)
|
|
}
|
|
|
|
override def authUser
|
|
: Kleisli[[A] =>> cats.data.OptionT[F, A], Request[F], (PlayerID, RoomID)] = {
|
|
Kleisli { (request: Request[F]) =>
|
|
OptionT(sessions.get.map { sessionsMap =>
|
|
for {
|
|
authcookie <- request.cookies.find(_.name == authcookieName)
|
|
sessionId <- authcookie.content.toLongOption
|
|
(roomId, playerId) <- sessionsMap.get(sessionId)
|
|
} yield (playerId, roomId)
|
|
})
|
|
}
|
|
}
|
|
|
|
override def deleteSession(sessionId: Long): F[ResponseCookie] = {
|
|
sessions
|
|
.update(_.removed(sessionId))
|
|
.as(
|
|
ResponseCookie(
|
|
name = authcookieName,
|
|
content = "",
|
|
secure = true
|
|
).clearCookie
|
|
)
|
|
}
|
|
}
|
|
|
|
def make[F[_]: Sync](): F[Auth[F]] =
|
|
for {
|
|
sessionsMap <- Ref.of[F, SessionsMap](TestModels.testSessions)
|
|
} yield new SimpleAuth(sessionsMap)
|
|
}
|