feat: routes with github auth & redirect
This commit is contained in:
parent
c143dc25a6
commit
f742acd6f9
|
@ -2,3 +2,5 @@ ThisBuild / scalaVersion := "3.3.0"
|
|||
|
||||
libraryDependencies += "com.lihaoyi" %% "upickle" % "3.1.2"
|
||||
libraryDependencies += "com.lihaoyi" %% "requests" % "0.8.0"
|
||||
libraryDependencies += "com.lihaoyi" %% "cask" % "0.9.1"
|
||||
libraryDependencies += "com.lihaoyi" %% "mainargs" % "0.5.0"
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
addSbtPlugin("io.spray" % "sbt-revolver" % "0.10.0")
|
|
@ -0,0 +1,6 @@
|
|||
// DO NOT EDIT! This file is auto-generated.
|
||||
|
||||
// This file enables sbt-bloop to create bloop config files.
|
||||
|
||||
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.6")
|
||||
|
|
@ -578,14 +578,6 @@ video {
|
|||
border-bottom-width: 8px;
|
||||
}
|
||||
|
||||
.border-t-8 {
|
||||
border-top-width: 8px;
|
||||
}
|
||||
|
||||
.border-r-8 {
|
||||
border-right-width: 8px;
|
||||
}
|
||||
|
||||
.border-blue-400 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(96 165 250 / var(--tw-border-opacity));
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
package example
|
||||
|
||||
import AuthService._
|
||||
import example.pocketbase.Api
|
||||
|
||||
case class AuthService()(implicit cc: castor.Context, log: cask.Logger)
|
||||
extends cask.Routes {
|
||||
|
||||
@cask.get("/")
|
||||
def getIndex(request: cask.Request) = {
|
||||
println("hellololo")
|
||||
val authCookieOpt = request.cookies.get(authCookieName)
|
||||
|
||||
authCookieOpt match {
|
||||
case None =>
|
||||
cask.Redirect("/login")
|
||||
case Some(authCookie) =>
|
||||
val jwt = authCookie.value
|
||||
???
|
||||
}
|
||||
}
|
||||
|
||||
@cask.get("/login")
|
||||
def getLoginPage() = {
|
||||
// render auth page with the available oauth providers
|
||||
val authOptions = pocketbaseApi.listAuthMethods().authProviders
|
||||
|
||||
val options = s"got following auth opitons: $authOptions"
|
||||
// save states and verifiers into cookie
|
||||
|
||||
val githubOption = authOptions.find(_.name == "github")
|
||||
|
||||
val githubRedirect = githubOption.map(_.authUrl).getOrElse("") ++ getRedirectUrl("github")
|
||||
|
||||
val html = s"""
|
||||
<h1>good enough, right</h1>
|
||||
<p>$options</p>
|
||||
<p>will use ${githubRedirect}</p>
|
||||
<a href="${githubRedirect}">Go to github</a>
|
||||
"""
|
||||
cask.Response(
|
||||
html,
|
||||
headers = Seq("Content-Type" -> "text/html;charset=UTF-8"),
|
||||
)
|
||||
}
|
||||
|
||||
@cask.get(s"${baseRedirectUrl}/:provider")
|
||||
def receiveOauthRedirect(provider: String, state: String, code: String) = {
|
||||
println(s"received redirect for $provider with state: $state and code: $code")
|
||||
/*
|
||||
*
|
||||
get provider from path param, get verifiers and state from cookie,
|
||||
if cookie not present - abort,
|
||||
if state doesn't fit one from redirect params - abort
|
||||
issue 'auth with oauth 2' and based on response code - set the cookie with jwt
|
||||
|
||||
and delete the state\verifiers cookie
|
||||
|
||||
but then what? i guess call for redirect to root page again?
|
||||
which should trigger auth check and main page render?
|
||||
*/
|
||||
s"received redirect for $provider with state: $state and code: $code"
|
||||
}
|
||||
|
||||
initialize()
|
||||
}
|
||||
|
||||
object AuthService {
|
||||
val authCookieName = "auth"
|
||||
val pocketbaseApi = Api("http://127.0.0.1:8090")
|
||||
val selfUri = "http://127.0.0.1:8080"
|
||||
|
||||
// i guess TOOD put that into config
|
||||
val baseRedirectUrl = "/api/oauth2-redirect"
|
||||
|
||||
/*
|
||||
* let's have separate redirect urls for different providers
|
||||
* if we'd have same url for all providers, we'll need way to figure out from state which one was called on front end.
|
||||
* it's possible, but path param looks simpler right now
|
||||
* github redirect : http://127.0.0.1:8080/api/oauth2-redirect/github
|
||||
*/
|
||||
def getRedirectUrl(provider: String): String =
|
||||
s"${selfUri}${baseRedirectUrl}/${provider}"
|
||||
}
|
|
@ -1,4 +1,22 @@
|
|||
package example
|
||||
|
||||
@main def main(args: String*): Unit =
|
||||
println(s"Hello ${args.mkString}")
|
||||
import mainargs.{main, arg, ParserForMethods}
|
||||
|
||||
object Main {
|
||||
@main def run(
|
||||
@arg(name="port", short='p', doc="Port on which server will start service")
|
||||
portArg: Int = 8080,
|
||||
@arg(name="host", doc="Host on which server will start serving")
|
||||
hostArg: String = "localhost"
|
||||
): Unit = {
|
||||
println(s"Will start server on ${hostArg}:${portArg}")
|
||||
val server = new cask.Main {
|
||||
override def allRoutes: Seq[cask.main.Routes] = Seq(AuthService())
|
||||
override def port: Int = portArg
|
||||
override def host: String = hostArg
|
||||
}
|
||||
server.main(Array.empty)
|
||||
}
|
||||
|
||||
def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
# let's check root redirect to auth
|
||||
GET http://localhost:8080/
|
Loading…
Reference in New Issue