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" %% "upickle" % "3.1.2"
|
||||||
libraryDependencies += "com.lihaoyi" %% "requests" % "0.8.0"
|
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-bottom-width: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.border-t-8 {
|
|
||||||
border-top-width: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-r-8 {
|
|
||||||
border-right-width: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-blue-400 {
|
.border-blue-400 {
|
||||||
--tw-border-opacity: 1;
|
--tw-border-opacity: 1;
|
||||||
border-color: rgb(96 165 250 / var(--tw-border-opacity));
|
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
|
package example
|
||||||
|
|
||||||
@main def main(args: String*): Unit =
|
import mainargs.{main, arg, ParserForMethods}
|
||||||
println(s"Hello ${args.mkString}")
|
|
||||||
|
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