Use UserService
This commit is contained in:
parent
d6f2489d50
commit
dc7f6b7b3a
@ -2,9 +2,8 @@ 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.services.UserRegistrationDto
|
||||||
import be.vandewalleh.errors.ApiError
|
import be.vandewalleh.services.UserService
|
||||||
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
|
||||||
@ -12,37 +11,26 @@ 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.*
|
|
||||||
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 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>()
|
private val userService by instance<UserService>()
|
||||||
|
|
||||||
override fun Routing.registerRoutes() {
|
override fun Routing.registerRoutes() {
|
||||||
|
|
||||||
|
|
||||||
post<Routes.Login> {
|
post<Routes.Login> {
|
||||||
data class Response(val token: String)
|
data class Response(val token: String)
|
||||||
|
|
||||||
val credential = call.receive<UsernamePasswordCredential>()
|
val credential = call.receive<UsernamePasswordCredential>()
|
||||||
|
|
||||||
val (email, password) = db.from(Users)
|
val (email, password) = userService.getEmailAndPasswordFromUsername(credential.username)
|
||||||
.select(Users.email, Users.password)
|
?: return@post call.respondStatus(HttpStatusCode.Unauthorized)
|
||||||
.where { Users.username eq credential.username }
|
|
||||||
.map { row -> row[Users.email]!! to row[Users.password]!! }
|
|
||||||
.firstOrNull()
|
|
||||||
?: return@post call.respond(HttpStatusCode.Unauthorized, ApiError.InvalidCredentialError)
|
|
||||||
|
|
||||||
|
|
||||||
if (!BCrypt.checkpw(credential.password, password)) {
|
if (!BCrypt.checkpw(credential.password, password)) {
|
||||||
return@post call.respond(HttpStatusCode.Unauthorized, ApiError.InvalidCredentialError)
|
return@post call.respondStatus(HttpStatusCode.Unauthorized)
|
||||||
}
|
}
|
||||||
|
|
||||||
return@post call.respond(Response(simpleJwt.sign(email)))
|
return@post call.respond(Response(simpleJwt.sign(email)))
|
||||||
@ -51,29 +39,18 @@ class UserController(kodein: Kodein) : KodeinController(kodein) {
|
|||||||
post<Routes.Register> {
|
post<Routes.Register> {
|
||||||
data class Response(val message: String)
|
data class Response(val message: String)
|
||||||
|
|
||||||
val user = call.receive<RegisterInfo>()
|
val user = call.receive<UserRegistrationDto>()
|
||||||
|
|
||||||
val exists = db.from(Users)
|
if (userService.userExists(user.username, user.email))
|
||||||
.select()
|
return@post call.respond(HttpStatusCode.Conflict)
|
||||||
.where { (Users.username eq user.username) or (Users.email eq user.email) }
|
|
||||||
.any()
|
|
||||||
|
|
||||||
if (exists) {
|
|
||||||
return@post call.respond(HttpStatusCode.Conflict, ApiError.ExistingUserError)
|
|
||||||
}
|
|
||||||
|
|
||||||
val hashedPassword = BCrypt.hashpw(user.password, BCrypt.gensalt())
|
val hashedPassword = BCrypt.hashpw(user.password, BCrypt.gensalt())
|
||||||
|
|
||||||
val newUser = User {
|
userService.createUser(
|
||||||
this.username = user.username
|
UserRegistrationDto(user.username, user.email, hashedPassword)
|
||||||
this.email = user.email
|
)
|
||||||
this.password = hashedPassword
|
|
||||||
this.createdAt = LocalDateTime.now()
|
|
||||||
}
|
|
||||||
|
|
||||||
db.sequenceOf(Users).add(newUser)
|
return@post call.respondStatus(HttpStatusCode.Created)
|
||||||
|
|
||||||
return@post call.respond(HttpStatusCode.Created, Response("User created successfully"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +62,4 @@ class UserController(kodein: Kodein) : KodeinController(kodein) {
|
|||||||
class Register
|
class Register
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class RegisterInfo(val username: String, val email: String, val password: String)
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
package be.vandewalleh.errors
|
|
||||||
|
|
||||||
sealed class ApiError(val message: String){
|
|
||||||
object InvalidCredentialError : ApiError("Invalid credentials")
|
|
||||||
object ExistingUserError : ApiError("User already exists")
|
|
||||||
object DeletedUserError : ApiError("User has been deleted")
|
|
||||||
}
|
|
||||||
@ -1,11 +1,15 @@
|
|||||||
package be.vandewalleh.services
|
package be.vandewalleh.services
|
||||||
|
|
||||||
|
import be.vandewalleh.entities.User
|
||||||
import be.vandewalleh.tables.Users
|
import be.vandewalleh.tables.Users
|
||||||
import me.liuwj.ktorm.database.Database
|
import me.liuwj.ktorm.database.Database
|
||||||
import me.liuwj.ktorm.dsl.*
|
import me.liuwj.ktorm.dsl.*
|
||||||
|
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.KodeinAware
|
import org.kodein.di.KodeinAware
|
||||||
import org.kodein.di.generic.instance
|
import org.kodein.di.generic.instance
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* service to handle database queries for users.
|
* service to handle database queries for users.
|
||||||
@ -25,4 +29,43 @@ class UserService(override val kodein: Kodein) : KodeinAware {
|
|||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* returns a user email and password from it's email if found or null
|
||||||
|
*/
|
||||||
|
fun getEmailAndPasswordFromUsername(username: String): Pair<String, String>? {
|
||||||
|
return db.from(Users)
|
||||||
|
.select(Users.email, Users.password)
|
||||||
|
.where { Users.username eq username }
|
||||||
|
.limit(0, 1)
|
||||||
|
.map { row -> row[Users.email]!! to row[Users.password]!! }
|
||||||
|
.firstOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun userExists(username: String, email: String): Boolean {
|
||||||
|
return db.from(Users)
|
||||||
|
.select(Users.id)
|
||||||
|
.where { (Users.username eq username) or (Users.email eq email) }
|
||||||
|
.limit(0, 1)
|
||||||
|
.firstOrNull() != null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new user
|
||||||
|
* password should already be hashed
|
||||||
|
*/
|
||||||
|
fun createUser(user: UserRegistrationDto) {
|
||||||
|
db.useTransaction {
|
||||||
|
val newUser = User {
|
||||||
|
this.username = user.username
|
||||||
|
this.email = user.email
|
||||||
|
this.password = user.password
|
||||||
|
this.createdAt = LocalDateTime.now()
|
||||||
|
}
|
||||||
|
|
||||||
|
db.sequenceOf(Users).add(newUser)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data class UserRegistrationDto(val username: String, val email: String, val password: String)
|
||||||
Loading…
x
Reference in New Issue
Block a user