workin on JWT Emmiter and trying to understand how zio handles exceptions
continuous-integration/drone/push Build is failing Details

drone-setup
Override-6 2 years ago
parent d1d9fa22dc
commit ac49d60f31

@ -1,12 +0,0 @@
package org.tbasket.jwt
import zio.Task
import zio.http.{Request, Response}
object JwtGeneration {
def generateTokenResponse(request: Request): Task[Response] = {
???
}
}

@ -0,0 +1,35 @@
package org.tbasket.jwt
import pdi.jwt.*
import zio.*
import zio.http.{Request, Response}
import zio.json.*
import zio.json.ast.Json
import java.lang.System.currentTimeMillis
import java.nio.file.*
import java.security.Key
import java.security.interfaces.RSAPrivateKey
import java.security.spec.PKCS8EncodedKeySpec
import java.util.concurrent.TimeUnit
import java.util.{Date, UUID}
import javax.crypto.SecretKey
import scala.concurrent.duration
object JwtGenerator:
private val ExpirationDate = Duration(15, TimeUnit.DAYS).toMillis
private val Key = Files.readString(Path.of("id_rsa"))
private def claims(content: String) = JwtClaim(
expiration = Some(currentTimeMillis() + ExpirationDate),
issuedAt = Some(currentTimeMillis()),
jwtId = Some(UUID.randomUUID().toString),
content = content
)
def generateTokenResponse(request: Request): Task[Response] =
for
claims <- request.body.asString.map(claims)
jwt <- ZIO.attempt(JwtZIOJson.encode(claims, Key, JwtAlgorithm.RS256))
yield Response.json(jwt)

@ -4,34 +4,40 @@ import zio.*
import zio.stream.*
import zio.http.*
import zio.http.ServerConfig.LeakDetectionLevel
import zio.http.model.Method
object Main extends ZIOAppDefault {
private val app = Http.collectZIO[Request] {
case r@Method.POST -> !! / "/jwt" =>
JwtGeneration.generateTokenResponse(r)
import zio.http.model.{Method, Status}
import java.nio.file.Files
object Main extends ZIOAppDefault:
private def port(args: Chunk[String]): Task[Int] =
args.headOption match
case None => ZIO.dieMessage("Must provide the port argument")
case Some(head) => head.toIntOption match
case Some(port) if port > 0 && port < 65536 => ZIO.succeed(port)
case Some(oorPort) => ZIO.dieMessage(s"'$oorPort' is out of range.'")
case None => ZIO.dieMessage("given argument is not a valid integer")
private val app = Http.collectZIO[Request][Any, Throwable, Response] {
case r @ Method.GET -> _ / "jwt" =>
ZIO.attempt(JwtGenerator)
.flatMap(_.generateTokenResponse(r))
.catchAll(e => ZIO.die(e))
case _ =>
ZIO.succeed(Response(status = Status.NotFound))
}
private def startServer(port: Int) =
val config = ServerConfig.default
.port(port)
.leakDetection(LeakDetectionLevel.PARANOID)
val configLayer = ServerConfig.live(config)
(Server.install(
app
) *> Console.printLine(s"JWT AppToken open on port $port") *> ZIO.never)
.provide(configLayer, Server.live)
val run =
ZIO.serviceWithZIO[ZIOAppArgs] { args =>
for
port <- ZIO.attempt(args.getArgs)
.map(_.head)
.mapError(_ => Console.printError("Must provide at least one argument"))
.map(_.toInt)
.mapError(_ => Console.printError("Port is not a number"))
.filterOrFail(p => 0 < p && p < 65563)(Console.printError("Port is out of range"))
yield
val config = ServerConfig.default
.port(port)
.leakDetection(LeakDetectionLevel.PARANOID)
val configLayer = ServerConfig.live(config)
(Server.install(app) *> Console.printLine("JWT AppToken open on port") *> ZIO.never)
.provideSome(configLayer, Server.live)
}
}
ZIO.serviceWithZIO[ZIOAppArgs](args => port(args.getArgs))
.flatMap(startServer)

@ -5,6 +5,7 @@ trait ServerModule extends ScalaModule with ScalafmtModule {
//override def scalacOptions = Seq("-explain")
override final def scalaVersion = "3.2.0"
override def ivyDeps = Agg(
ivy"dev.zio::zio:2.0.6",
ivy"org.apache.logging.log4j:log4j-slf4j-impl:2.19.0"
@ -14,7 +15,8 @@ trait HttpModule extends ServerModule {
override def ivyDeps = super.ivyDeps() ++ Agg(
ivy"dev.zio::zio-http:0.0.3",
ivy"dev.zio::zio-json:0.4.2",
ivy"dev.zio::zio-streams:2.0.6"
ivy"dev.zio::zio-streams:2.0.6",
ivy"com.github.jwt-scala::jwt-zio-json:9.1.2"
)
}