Implement user creation endpoint + persistance and hash to db

This commit is contained in:
Hubert Van De Walle 2020-04-12 02:33:48 +02:00
parent 542eaa21cc
commit 14aa195bb3
3 changed files with 67 additions and 8 deletions

View File

@ -17,6 +17,7 @@
<kodein_version>6.5.4</kodein_version>
<flyway_version>6.3.3</flyway_version>
<javajwt_version>3.10.2</javajwt_version>
<jbcrypt_version>0.4</jbcrypt_version>
<kotlin.code.style>official</kotlin.code.style>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -127,6 +128,11 @@
<artifactId>flyway-core</artifactId>
<version>${flyway_version}</version>
</dependency>
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>${jbcrypt_version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>${project.basedir}/src</sourceDirectory>

View File

@ -16,6 +16,7 @@ import io.ktor.features.ContentNegotiation
import io.ktor.jackson.jackson
import io.ktor.locations.Locations
import io.ktor.routing.routing
import me.liuwj.ktorm.database.Database
import org.kodein.di.Kodein
import org.kodein.di.description
import org.kodein.di.generic.bind
@ -35,12 +36,14 @@ fun Application.module() {
import(configurationModule)
bind<Feature>() with singleton { Migration(this.kodein) }
bind<Database>() with singleton { Database.Companion.connect(this.instance<DataSource>()) }
}
features()
log.debug(kodein.container.tree.bindings.description())
// TODO, clean this (migration)
val feature: Feature by kodein.instance()
feature.execute()

View File

@ -2,7 +2,9 @@ package be.vandewalleh.controllers
import be.vandewalleh.auth.SimpleJWT
import be.vandewalleh.auth.UsernamePasswordCredential
import be.vandewalleh.entities.User
import be.vandewalleh.errors.ApiError
import be.vandewalleh.tables.Users
import io.ktor.application.call
import io.ktor.http.HttpStatusCode
import io.ktor.locations.Location
@ -10,26 +12,74 @@ import io.ktor.locations.post
import io.ktor.request.receive
import io.ktor.response.respond
import io.ktor.routing.Routing
import me.liuwj.ktorm.database.Database
import me.liuwj.ktorm.dsl.eq
import me.liuwj.ktorm.dsl.from
import me.liuwj.ktorm.dsl.select
import me.liuwj.ktorm.dsl.where
import me.liuwj.ktorm.entity.add
import me.liuwj.ktorm.entity.sequenceOf
import org.kodein.di.Kodein
import org.kodein.di.generic.instance
import org.mindrot.jbcrypt.BCrypt
import java.time.LocalDateTime
class UserController(kodein: Kodein) : KodeinController(kodein) {
private val simpleJwt by instance<SimpleJWT>()
private val db by instance<Database>()
override fun Routing.registerRoutes() {
post<Routes.Auth> {
val post = call.receive<UsernamePasswordCredential>()
post<Routes.SignIn> {
data class Response(val token: String)
// TODO check db
if (post.username != "test" || post.password != "test")
val credential = call.receive<UsernamePasswordCredential>()
val (email, password) = db.from(Users)
.select(Users.email, Users.password)
.where { Users.username eq credential.username }
.map { row -> row[Users.email]!! to row[Users.password]!! }
.firstOrNull()
?: return@post call.respond(HttpStatusCode.BadRequest, ApiError.InvalidCredentialError())
if (!BCrypt.checkpw(credential.password, password)) {
return@post call.respond(HttpStatusCode.BadRequest, ApiError.InvalidCredentialError())
}
return@post call.respond(mapOf("token" to simpleJwt.sign("test@test.be")))
return@post call.respond(Response(simpleJwt.sign(email)))
}
post<Routes.SignUp> {
data class Response(val message: String)
val user = call.receive<SignUpInfo>()
// TODO check if user does not already exists
// db won't let you insert it anyway
val hashedPassword = BCrypt.hashpw(user.password, BCrypt.gensalt())
val newUser = User {
this.username = user.username
this.email = user.email
this.password = hashedPassword
this.createdAt = LocalDateTime.now()
}
db.sequenceOf(Users).add(newUser)
call.respond(HttpStatusCode.Created, Response("User created successfully"))
}
}
object Routes {
@Location("/auth")
class Auth
@Location("/signin")
class SignIn
@Location("/signup")
class SignUp
}
}
}
data class SignUpInfo(val username: String, val email: String, val password: String)