import java.time.Clock
import zio._
import zio.http._
import zio.http.Middleware.bearerAuth
import zio.http.codec.PathCodec.string
import pdi.jwt.{Jwt, JwtAlgorithm, JwtClaim}
object AuthenticationServer extends ZIOAppDefault {
val SECRET_KEY = "secretKey"
implicit val clock: Clock = Clock.systemUTC
def jwtEncode(username: String): String = {
val json = s"""{"user": "${username}"}"""
val claim = JwtClaim {
json
}.issuedNow.expiresIn(300)
Jwt.encode(claim, SECRET_KEY, JwtAlgorithm.HS512)
}
def jwtDecode(token: String): Option[JwtClaim] = {
Jwt.decode(token, SECRET_KEY, Seq(JwtAlgorithm.HS512)).toOption
}
def user: HttpApp[Any] = Routes(
Method.GET / "user" / string("name") / "greet" -> handler { (name: String, req: Request) =>
Response.text(s"Welcome to the ZIO party! ${name}")
},
).toHttpApp @@ bearerAuth(jwtDecode(_).isDefined)
def login: HttpApp[Any] =
Routes(
Method.GET / "login" / string("username") / string("password") ->
handler { (username: String, password: String, req: Request) =>
if (password.reverse.hashCode == username.hashCode) Response.text(jwtEncode(username))
else Response.text("Invalid username or password.").status(Status.Unauthorized)
},
).toHttpApp
val app: HttpApp[Any] = login ++ user
override val run = Server.serve(app).provide(Server.default)
}