SimpleNotes/api/src/routing/AuthController.kt

72 lines
2.3 KiB
Kotlin

package be.vandewalleh.routing
import be.vandewalleh.auth.SimpleJWT
import be.vandewalleh.auth.UserDbIdPrincipal
import be.vandewalleh.auth.UsernamePasswordCredential
import be.vandewalleh.extensions.respondStatus
import be.vandewalleh.services.UserService
import com.auth0.jwt.exceptions.JWTVerificationException
import io.ktor.application.*
import io.ktor.auth.*
import io.ktor.http.*
import io.ktor.request.*
import io.ktor.response.*
import io.ktor.routing.*
import org.kodein.di.Kodein
import org.kodein.di.generic.instance
import org.mindrot.jbcrypt.BCrypt
data class RefreshToken(val refreshToken: String)
data class DualToken(val token: String, val refreshToken: String)
fun Routing.auth(kodein: Kodein) {
val authSimpleJwt by kodein.instance<SimpleJWT>("auth")
val refreshSimpleJwt by kodein.instance<SimpleJWT>("refresh")
val userService by kodein.instance<UserService>()
post("/user/login") {
val credential = call.receive<UsernamePasswordCredential>()
val user = userService.getFromUsername(credential.username)
?: return@post call.respondStatus(HttpStatusCode.Unauthorized)
if (!BCrypt.checkpw(credential.password, user.password)) {
return@post call.respondStatus(HttpStatusCode.Unauthorized)
}
val response = DualToken(
token = authSimpleJwt.sign(user.id),
refreshToken = refreshSimpleJwt.sign(user.id)
)
return@post call.respond(response)
}
post("/user/refresh_token") {
val token = call.receive<RefreshToken>().refreshToken
val id = try {
val decodedJWT = refreshSimpleJwt.verifier.verify(token)
decodedJWT.getClaim("id").asInt()
} catch (e: JWTVerificationException) {
return@post call.respondStatus(HttpStatusCode.Unauthorized)
}
val response = DualToken(
token = authSimpleJwt.sign(id),
refreshToken = refreshSimpleJwt.sign(id)
)
return@post call.respond(response)
}
authenticate {
get("/user/me") {
// retrieve email from token
val id = call.principal<UserDbIdPrincipal>()!!.id
val info = userService.getUserInfo(id)
if (info != null) call.respond(mapOf("user" to info))
else call.respondStatus(HttpStatusCode.Unauthorized)
}
}
}