Implement user creation endpoint + persistance and hash to db
This commit is contained in:
parent
542eaa21cc
commit
14aa195bb3
@ -17,6 +17,7 @@
|
|||||||
<kodein_version>6.5.4</kodein_version>
|
<kodein_version>6.5.4</kodein_version>
|
||||||
<flyway_version>6.3.3</flyway_version>
|
<flyway_version>6.3.3</flyway_version>
|
||||||
<javajwt_version>3.10.2</javajwt_version>
|
<javajwt_version>3.10.2</javajwt_version>
|
||||||
|
<jbcrypt_version>0.4</jbcrypt_version>
|
||||||
|
|
||||||
<kotlin.code.style>official</kotlin.code.style>
|
<kotlin.code.style>official</kotlin.code.style>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
@ -127,6 +128,11 @@
|
|||||||
<artifactId>flyway-core</artifactId>
|
<artifactId>flyway-core</artifactId>
|
||||||
<version>${flyway_version}</version>
|
<version>${flyway_version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mindrot</groupId>
|
||||||
|
<artifactId>jbcrypt</artifactId>
|
||||||
|
<version>${jbcrypt_version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<sourceDirectory>${project.basedir}/src</sourceDirectory>
|
<sourceDirectory>${project.basedir}/src</sourceDirectory>
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import io.ktor.features.ContentNegotiation
|
|||||||
import io.ktor.jackson.jackson
|
import io.ktor.jackson.jackson
|
||||||
import io.ktor.locations.Locations
|
import io.ktor.locations.Locations
|
||||||
import io.ktor.routing.routing
|
import io.ktor.routing.routing
|
||||||
|
import me.liuwj.ktorm.database.Database
|
||||||
import org.kodein.di.Kodein
|
import org.kodein.di.Kodein
|
||||||
import org.kodein.di.description
|
import org.kodein.di.description
|
||||||
import org.kodein.di.generic.bind
|
import org.kodein.di.generic.bind
|
||||||
@ -35,12 +36,14 @@ fun Application.module() {
|
|||||||
import(configurationModule)
|
import(configurationModule)
|
||||||
|
|
||||||
bind<Feature>() with singleton { Migration(this.kodein) }
|
bind<Feature>() with singleton { Migration(this.kodein) }
|
||||||
|
bind<Database>() with singleton { Database.Companion.connect(this.instance<DataSource>()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
features()
|
features()
|
||||||
|
|
||||||
log.debug(kodein.container.tree.bindings.description())
|
log.debug(kodein.container.tree.bindings.description())
|
||||||
|
|
||||||
|
// TODO, clean this (migration)
|
||||||
val feature: Feature by kodein.instance()
|
val feature: Feature by kodein.instance()
|
||||||
feature.execute()
|
feature.execute()
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,9 @@ package be.vandewalleh.controllers
|
|||||||
|
|
||||||
import be.vandewalleh.auth.SimpleJWT
|
import be.vandewalleh.auth.SimpleJWT
|
||||||
import be.vandewalleh.auth.UsernamePasswordCredential
|
import be.vandewalleh.auth.UsernamePasswordCredential
|
||||||
|
import be.vandewalleh.entities.User
|
||||||
import be.vandewalleh.errors.ApiError
|
import be.vandewalleh.errors.ApiError
|
||||||
|
import be.vandewalleh.tables.Users
|
||||||
import io.ktor.application.call
|
import io.ktor.application.call
|
||||||
import io.ktor.http.HttpStatusCode
|
import io.ktor.http.HttpStatusCode
|
||||||
import io.ktor.locations.Location
|
import io.ktor.locations.Location
|
||||||
@ -10,26 +12,74 @@ import io.ktor.locations.post
|
|||||||
import io.ktor.request.receive
|
import io.ktor.request.receive
|
||||||
import io.ktor.response.respond
|
import io.ktor.response.respond
|
||||||
import io.ktor.routing.Routing
|
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.Kodein
|
||||||
import org.kodein.di.generic.instance
|
import org.kodein.di.generic.instance
|
||||||
|
import org.mindrot.jbcrypt.BCrypt
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
class UserController(kodein: Kodein) : KodeinController(kodein) {
|
class UserController(kodein: Kodein) : KodeinController(kodein) {
|
||||||
private val simpleJwt by instance<SimpleJWT>()
|
private val simpleJwt by instance<SimpleJWT>()
|
||||||
|
private val db by instance<Database>()
|
||||||
|
|
||||||
override fun Routing.registerRoutes() {
|
override fun Routing.registerRoutes() {
|
||||||
post<Routes.Auth> {
|
post<Routes.SignIn> {
|
||||||
val post = call.receive<UsernamePasswordCredential>()
|
data class Response(val token: String)
|
||||||
|
|
||||||
// TODO check db
|
val credential = call.receive<UsernamePasswordCredential>()
|
||||||
if (post.username != "test" || post.password != "test")
|
|
||||||
|
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(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 {
|
object Routes {
|
||||||
@Location("/auth")
|
@Location("/signin")
|
||||||
class Auth
|
class SignIn
|
||||||
|
|
||||||
|
@Location("/signup")
|
||||||
|
class SignUp
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class SignUpInfo(val username: String, val email: String, val password: String)
|
||||||
Loading…
x
Reference in New Issue
Block a user