Valid FindArticles request with Konform

This commit is contained in:
2021-04-03 00:52:52 +02:00
parent 3a18ef0554
commit a300e275d4
4 changed files with 57 additions and 3 deletions

View File

@@ -327,8 +327,9 @@ dependencyCheck {
repositories {
mavenLocal()
jcenter()
maven { url = uri("https://kotlin.bintray.com/ktor") }
maven { url = uri("https://jitpack.io") }
maven("https://kotlin.bintray.com/ktor")
maven("https://jitpack.io")
maven("https://dl.bintray.com/konform-kt/konform")
}
dependencies {
@@ -359,6 +360,7 @@ dependencies {
implementation("org.elasticsearch.client:elasticsearch-rest-client:6.7.1")
implementation("com.jayway.jsonpath:json-path:2.5.0")
implementation("com.avast.gradle:gradle-docker-compose-plugin:0.14.0")
implementation("io.konform:konform-jvm:0.2.0")
testImplementation("io.ktor:ktor-server-tests:$ktorVersion")
testImplementation("io.ktor:ktor-client-mock:$ktorVersion")

View File

@@ -0,0 +1,14 @@
package fr.dcproject.common.validation
import io.konform.validation.ValidationBuilder
import java.util.UUID
fun ValidationBuilder<String>.isUuid() =
addConstraint("must be UUID") {
try {
UUID.fromString(it)
true
} catch (exception: IllegalArgumentException) {
false
}
}

View File

@@ -2,6 +2,7 @@ package fr.dcproject.component.article.routes
import fr.dcproject.common.response.toOutput
import fr.dcproject.common.security.assert
import fr.dcproject.common.validation.isUuid
import fr.dcproject.component.article.ArticleAccessControl
import fr.dcproject.component.article.database.ArticleForListing
import fr.dcproject.component.article.database.ArticleRepository
@@ -10,7 +11,12 @@ import fr.dcproject.routes.PaginatedRequest
import fr.dcproject.routes.PaginatedRequestI
import fr.postgresjson.connexion.Paginated
import fr.postgresjson.repository.RepositoryI
import io.konform.validation.Validation
import io.konform.validation.jsonschema.enum
import io.konform.validation.jsonschema.maximum
import io.konform.validation.jsonschema.minimum
import io.ktor.application.call
import io.ktor.http.HttpStatusCode
import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.locations.Location
import io.ktor.locations.get
@@ -28,7 +34,32 @@ object FindArticles {
val search: String? = null,
val createdBy: String? = null,
val workgroup: String? = null
) : PaginatedRequestI by PaginatedRequest(page, limit)
) : PaginatedRequestI by PaginatedRequest(page, limit) {
fun validate() = Validation<ArticlesRequest> {
ArticlesRequest::page {
minimum(1)
maximum(100)
}
ArticlesRequest::limit {
minimum(1)
maximum(50)
}
ArticlesRequest::sort ifPresent {
enum(
"title",
"createdAt",
"vote",
"popularity",
)
}
ArticlesRequest::createdBy ifPresent {
isUuid()
}
ArticlesRequest::workgroup ifPresent {
isUuid()
}
}.validate(this)
}
private fun ArticleRepository.findArticles(request: ArticlesRequest): Paginated<ArticleForListing> {
return find(
@@ -43,6 +74,11 @@ object FindArticles {
fun Route.findArticles(repo: ArticleRepository, ac: ArticleAccessControl) {
get<ArticlesRequest> {
if (it.validate().errors.size > 0) {
call.respond(HttpStatusCode.BadRequest)
return@get
}
repo.findArticles(it)
.apply { ac.assert { canView(result, citizenOrNull) } }
.let {

View File

@@ -41,6 +41,8 @@ paths:
maxItems: 50
items:
$ref: '#/components/schemas/ArticleListingResponse'
400:
$ref: '#/components/responses/400'
post:
security:
- JWTAuth: []