Skip to content

Commit

Permalink
more router amendments
Browse files Browse the repository at this point in the history
  • Loading branch information
RawToast committed Apr 2, 2018
1 parent 2afd2c2 commit 46b60a5
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 72 deletions.
8 changes: 3 additions & 5 deletions dokusho-server/src/main/scala/Main.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import cats.effect.IO
import dokusho.middleware.Auth0Middleware
import dokusho.{MongoRepository, ReadingHistoryRouter, AltReadingHistoryRouter, ReadingHistoryService}
import dokusho.{MongoRepository, ReadingHistoryRouter, ReadingHistoryService}
import fs2.StreamApp.ExitCode
import fs2.{Stream, StreamApp}
import org.http4s.client.Client
Expand All @@ -21,12 +21,10 @@ object Main extends StreamApp[IO] {
lazy val pclient: Client[IO] = PooledHttp1Client[IO]()

val authMiddleware: Auth0Middleware = new Auth0Middleware(pclient)

val readingHistoryService = new ReadingHistoryService(mongo)
val historyService: ReadingHistoryRouter = new ReadingHistoryRouter(readingHistoryService)
val altHistoryService = new AltReadingHistoryRouter(readingHistoryService)
val historyService = new ReadingHistoryRouter(readingHistoryService)

val authHistory = authMiddleware.authenticationMiddleware(altHistoryService.routes)
val authHistory = authMiddleware.authenticationMiddleware(historyService.routes)


override def stream(args: List[String], requestShutdown: IO[Unit]): Stream[IO, ExitCode] =
Expand Down
103 changes: 38 additions & 65 deletions dokusho-server/src/main/scala/dokusho/ReadingHistoryRouter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,88 +2,61 @@ package dokusho

import cats.data.OptionT
import cats.effect.IO
import io.circe.Json
import org.http4s.util.CaseInsensitiveString
import org.http4s.{Header, HttpService, Request, Response}

class ReadingHistoryRouter(readingHistoryService: ReadingHistoryService) extends Http4sRouter {

case class SuccessfulPut(userId: String)

val routes: HttpService[IO] = HttpService[IO] {
case GET -> Root / "history" / userId =>
for {
userReadingHistory <- readingHistoryService.getReadingHistory(userId)
json: Option[Json] = userReadingHistory.map(_.asJson)
resp <- json.fold(NotFound())(j => Ok(j))
} yield resp
case req@PUT -> Root / "history" / userId =>
for {
readingHistory <- req.as[ReadingHistory]
storedHistory <- readingHistoryService.upsert(UserReadingHistory(userId, readingHistory))
json: Json = SuccessfulPut(storedHistory.userId).asJson
response <- Ok(json)
} yield response
case req@POST -> Root / "history" / userId / "add" =>
for {
entry <- req.as[NewEntry]
storedHistory <- readingHistoryService.addNewEntry(userId, entry)
json = storedHistory.map(_.asJson)
result <- json.fold(NotFound())(j => Ok(j))
} yield result
case PUT -> Root / "history" / userId / "reset" =>
readingHistoryService.reset(userId)
.map(_.asJson)
.flatMap(j => Ok(j))
}
}

class AltReadingHistoryRouter(readingHistoryService: ReadingHistoryService) extends Http4sRouter {

private val service = readingHistoryService
case class SuccessfulPut(userId: String)

def getUserId(req: Request[IO]): IO[Option[String]] =
IO(req.headers.find(_.name == CaseInsensitiveString("User")).map(_.value))

implicit class ReqHelper(req: Request[IO]) {
def withReadingHistory(f: ReadingHistory => IO[UserReadingHistory]): IO[UserReadingHistory] =
req.as[ReadingHistory].flatMap(f(_))

def withEntry(f: NewEntry => IO[UserReadingHistory]): IO[UserReadingHistory] =
req.as[NewEntry].flatMap(f(_))
}

implicit private def routeWithErrorHandling(io: OptionT[IO, IO[Response[IO]]]): IO[Response[IO]] =
io.value.flatMap(_.getOrElse(NotFound()))

val orNotFound = (io: OptionT[IO, IO[Response[IO]]]) =>
io.value.flatMap(_.getOrElse(NotFound()))

val routes: HttpService[IO] = HttpService[IO] {
case req@GET -> Root / "history" =>
for {
userId <- OptionT(getUserId(req))
userReadingHistory <- OptionT(readingHistoryService.getReadingHistory(userId))
json: Json = userReadingHistory.asJson
resp = Ok(json)
} yield resp
OptionT(getUserId(req))
.flatMapF(userId => service.getReadingHistory(userId))
.map(_.asJson)
.map(json => Ok(json))
.value.flatMap(_.getOrElse(NotFound()))
case req@PUT -> Root / "history" =>
for {
userId <- OptionT(getUserId(req))
readingHistory <- OptionT.liftF(req.as[ReadingHistory])
storedHistory <- OptionT.liftF(readingHistoryService.upsert(UserReadingHistory(userId, readingHistory)))
json: Json = SuccessfulPut(storedHistory.userId).asJson
response = Ok(json)
} yield response
OptionT(getUserId(req))
.semiflatMap(userId => req.withReadingHistory(rh => service.upsert(UserReadingHistory(userId, rh))))
.map(storedHistory => SuccessfulPut(storedHistory.userId))
.map(sp => Ok(sp.asJson))
.value.flatMap(_.getOrElse(NotFound()))
case req@POST -> Root / "history" / "add" =>
for {
userId <- OptionT(getUserId(req))
entry <- OptionT.liftF(req.as[NewEntry])
storedHistory <- OptionT(readingHistoryService.addNewEntry(userId, entry))
json = storedHistory.asJson
response = Ok(json)
} yield response
OptionT(getUserId(req))
.semiflatMap(userId => req.withEntry(e => service.upsertNewEntry(userId, e)))
.map(storedHistory => storedHistory.asJson)
.map(json => Ok(json))
.value.flatMap(_.getOrElse(BadRequest()))
case req@PUT -> Root / "history" / "reset" =>
OptionT(getUserId(req))
.semiflatMap(userId => readingHistoryService.reset(userId))
.map(_.asJson)
.map(j => Ok(j))
case req@GET -> Root / "auth" => {
// This endpoint should be removed, but right now it's handy for development
val headerOpt: Header = req.headers
.find(_.name == CaseInsensitiveString("User"))
.getOrElse(Header("User", "None"))

Ok("Hello: " + headerOpt.value)
}
.semiflatMap(userId => service.reset(userId))
.map(_.asJson)
.map(j => Ok(j))
.value.flatMap(_.getOrElse(BadRequest()))
case req@GET -> Root / "auth" =>
// This endpoint should be removed, but right now it's handy for development
val headerOpt: Header = req.headers
.find(_.name == CaseInsensitiveString("User"))
.getOrElse(Header("User", "None"))

Ok("Hello: " + headerOpt.value)
}
}
12 changes: 12 additions & 0 deletions dokusho-server/src/main/scala/dokusho/ReadingHistoryService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ class ReadingHistoryService(mongoRepository: HistoryRepository) {
def getReadingHistory(userId: String): IO[Option[UserReadingHistory]] =
mongoRepository.get(userId)

def getOrMakeReadingHistory(userId: String): IO[UserReadingHistory] =
OptionT(mongoRepository.get(userId))
.getOrElseF(reset(userId))

def addNewEntry(userId: String, newEntry: NewEntry): IO[Option[UserReadingHistory]] = {
lazy val update = daysLens.modify(updateDay(newEntry))
OptionT(getReadingHistory(userId))
Expand All @@ -22,6 +26,14 @@ class ReadingHistoryService(mongoRepository: HistoryRepository) {
.value
}

def upsertNewEntry(userId: String, newEntry: NewEntry): IO[UserReadingHistory] = {
lazy val update = daysLens.modify(updateDay(newEntry))
OptionT(getReadingHistory(userId))
.getOrElseF(reset(userId))
.map(update)
.flatMap(upsert)
}

def upsert(userReadingHistory: UserReadingHistory): IO[UserReadingHistory] =
mongoRepository.put(userReadingHistory)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ class Auth0Middleware(client: Client[IO]) extends Http4sRouter {
}

private def callService(c: Client[IO], authToken: Header): IO[String] = {
println("Header: " + authToken.name + " " + authToken.value)

c.fetch(Request.apply[IO](
method = GET,
uri = Uri.unsafeFromString("https://dokusho.eu.auth0.com/userinfo"),
Expand Down

0 comments on commit 46b60a5

Please sign in to comment.