Merge branch 'user-validation'
This commit is contained in:
commit
d908d229a6
@ -160,6 +160,11 @@
|
||||
<artifactId>hoplite-yaml</artifactId>
|
||||
<version>${hoplite_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>am.ik.yavi</groupId>
|
||||
<artifactId>yavi</artifactId>
|
||||
<version>0.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.javafaker</groupId>
|
||||
<artifactId>javafaker</artifactId>
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package be.vandewalleh.features
|
||||
|
||||
import am.ik.yavi.core.ViolationDetail
|
||||
import be.vandewalleh.validation.ValidationException
|
||||
import io.ktor.application.*
|
||||
import io.ktor.features.*
|
||||
import io.ktor.http.*
|
||||
@ -11,5 +13,13 @@ fun Application.handleErrors() {
|
||||
exception<IOException> {
|
||||
call.respond(HttpStatusCode.BadRequest)
|
||||
}
|
||||
exception<ValidationException> {
|
||||
val error = ViolationError(it.details[0])
|
||||
call.respond(HttpStatusCode.BadRequest, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ViolationError(detail: ViolationDetail) {
|
||||
val msg = detail.defaultMessage
|
||||
}
|
||||
|
||||
@ -4,6 +4,8 @@ import be.vandewalleh.entities.User
|
||||
import be.vandewalleh.extensions.respondStatus
|
||||
import be.vandewalleh.extensions.userId
|
||||
import be.vandewalleh.services.UserService
|
||||
import be.vandewalleh.validation.receiveValidated
|
||||
import be.vandewalleh.validation.user.registerValidator
|
||||
import io.ktor.application.*
|
||||
import io.ktor.auth.*
|
||||
import io.ktor.http.*
|
||||
@ -18,14 +20,9 @@ import java.time.LocalDateTime
|
||||
fun Routing.user(kodein: Kodein) {
|
||||
val userService by kodein.instance<UserService>()
|
||||
|
||||
post("/user/test") {
|
||||
val user = call.receive<User>()
|
||||
call.respond(user)
|
||||
}
|
||||
|
||||
route("/user") {
|
||||
post {
|
||||
val user = call.receive<User>()
|
||||
val user = call.receiveValidated(registerValidator)
|
||||
|
||||
if (userService.userExists(user.username, user.email))
|
||||
return@post call.respondStatus(HttpStatusCode.Conflict)
|
||||
@ -39,7 +36,7 @@ fun Routing.user(kodein: Kodein) {
|
||||
|
||||
authenticate {
|
||||
put {
|
||||
val user = call.receive<User>()
|
||||
val user = call.receiveValidated(registerValidator)
|
||||
|
||||
if (userService.userExists(user.username, user.email))
|
||||
return@put call.respond(HttpStatusCode.Conflict)
|
||||
|
||||
14
api/src/validation/ValidationExtensions.kt
Normal file
14
api/src/validation/ValidationExtensions.kt
Normal file
@ -0,0 +1,14 @@
|
||||
package be.vandewalleh.validation
|
||||
|
||||
import am.ik.yavi.core.Validator
|
||||
import am.ik.yavi.core.ViolationDetail
|
||||
import io.ktor.application.*
|
||||
import io.ktor.request.*
|
||||
|
||||
suspend inline fun <reified T : Any> ApplicationCall.receiveValidated(validator: Validator<T>): T {
|
||||
val value: T = receive()
|
||||
validator.validate(value).throwIfInvalid { ValidationException(it.details()) }
|
||||
return value
|
||||
}
|
||||
|
||||
data class ValidationException(val details: List<ViolationDetail>) : RuntimeException()
|
||||
18
api/src/validation/user/UserValidation.kt
Normal file
18
api/src/validation/user/UserValidation.kt
Normal file
@ -0,0 +1,18 @@
|
||||
package be.vandewalleh.validation.user
|
||||
|
||||
import am.ik.yavi.builder.ValidatorBuilder
|
||||
import am.ik.yavi.builder.konstraint
|
||||
import am.ik.yavi.core.Validator
|
||||
import be.vandewalleh.entities.User
|
||||
|
||||
val registerValidator: Validator<User> = ValidatorBuilder.of<User>()
|
||||
.konstraint(User::username) {
|
||||
notNull().lessThanOrEqual(50).greaterThanOrEqual(3)
|
||||
}
|
||||
.konstraint(User::email) {
|
||||
notNull().notEmpty().lessThanOrEqual(255).email()
|
||||
}
|
||||
.konstraint(User::password) {
|
||||
notNull().greaterThanOrEqual(6)
|
||||
}
|
||||
.build()
|
||||
@ -1,4 +1,4 @@
|
||||
package routing
|
||||
package integration.routing
|
||||
|
||||
import be.vandewalleh.auth.SimpleJWT
|
||||
import be.vandewalleh.entities.User
|
||||
@ -70,7 +70,7 @@ class UserControllerKtTest {
|
||||
val res = testEngine.post("/user") {
|
||||
json {
|
||||
it["username"] = "new"
|
||||
it["password"] = "test"
|
||||
it["password"] = "test123abc"
|
||||
it["email"] = "new@test.com"
|
||||
}
|
||||
}
|
||||
@ -84,7 +84,7 @@ class UserControllerKtTest {
|
||||
json {
|
||||
it["username"] = "existing"
|
||||
it["email"] = "existing@test.com"
|
||||
it["password"] = "test"
|
||||
it["password"] = "test123abc"
|
||||
}
|
||||
}
|
||||
res.status() `should be equal to` HttpStatusCode.Conflict
|
||||
@ -129,6 +129,7 @@ class UserControllerKtTest {
|
||||
json {
|
||||
it["username"] = "ThisIsMyNewName"
|
||||
it["email"] = "ThisIsMyNewName@mail.com"
|
||||
it["password"] = "ThisIsMyCurrentPassword"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package services
|
||||
package integration.services
|
||||
|
||||
import be.vandewalleh.mainModule
|
||||
import be.vandewalleh.migrations.Migration
|
||||
57
api/test/unit/validation/RegisterValidationTest.kt
Normal file
57
api/test/unit/validation/RegisterValidationTest.kt
Normal file
@ -0,0 +1,57 @@
|
||||
package unit.validation
|
||||
|
||||
import be.vandewalleh.entities.User
|
||||
import be.vandewalleh.validation.user.registerValidator
|
||||
import org.amshove.kluent.*
|
||||
import org.junit.jupiter.api.*
|
||||
import utils.firstInvalid
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class RegisterValidationTest {
|
||||
|
||||
@Test
|
||||
fun `valid register test`() {
|
||||
val violations = registerValidator.validate(User {
|
||||
username = "hubert"
|
||||
password = "definitelyNotMyPassword"
|
||||
email = "test@mail.com"
|
||||
})
|
||||
|
||||
violations.isValid `should be equal to` true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `invalid email test`() {
|
||||
val violations = registerValidator.validate(User {
|
||||
username = "hubert"
|
||||
password = "definitelyNotMyPassword"
|
||||
email = "teom"
|
||||
})
|
||||
|
||||
violations.isValid `should be equal to` false
|
||||
violations.firstInvalid `should be equal to` "email"
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `missing email test`() {
|
||||
val violations = registerValidator.validate(User {
|
||||
username = "hubert"
|
||||
password = "definitelyNotMyPassword"
|
||||
})
|
||||
|
||||
violations.isValid `should be equal to` false
|
||||
violations.firstInvalid `should be equal to` "email"
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `username too long test`() {
|
||||
val violations = registerValidator.validate(User {
|
||||
username = "6X9iboWmEOWjVjkO328ReTJ1gGPTTmB/ZGgBLhB6EzAJoWkJht8"
|
||||
password = "definitelyNotMyPassword"
|
||||
email = "test@mail.com"
|
||||
})
|
||||
|
||||
violations.isValid `should be equal to` false
|
||||
violations.firstInvalid `should be equal to` "username"
|
||||
}
|
||||
}
|
||||
6
api/test/utils/ValidationExtensions.kt
Normal file
6
api/test/utils/ValidationExtensions.kt
Normal file
@ -0,0 +1,6 @@
|
||||
package utils
|
||||
|
||||
import am.ik.yavi.core.ConstraintViolations
|
||||
|
||||
val ConstraintViolations.firstInvalid: Any?
|
||||
get() = this.violations().firstOrNull()?.name()
|
||||
Loading…
x
Reference in New Issue
Block a user