Valider les resource entrente #91

Merged
flecomte merged 46 commits from 21-valid-input into master 2021-04-16 03:27:11 +02:00
4 changed files with 52 additions and 43 deletions
Showing only changes of commit 2ef9f65f2c - Show all commits

View File

@@ -0,0 +1,35 @@
package fr.dcproject.application.http
import fr.dcproject.application.http.HttpErrorBadRequest.InvalidParam
import io.konform.validation.ValidationResult
import io.ktor.http.HttpStatusCode
class BadRequestException(val httpError: HttpErrorBadRequest) : Exception()
class HttpErrorBadRequest(
statusCode: HttpStatusCode,
val title: String = statusCode.description,
val invalidParams: List<InvalidParam>,
) {
val statusCode: Int = statusCode.value
data class InvalidParam(
val name: String,
val reason: String
)
}
fun ValidationResult<*>.toOutput() = HttpErrorBadRequest(
HttpStatusCode.BadRequest,
invalidParams = this.errors.map {
InvalidParam(
it.dataPath,
it.message
)
}
)
fun ValidationResult<*>.badRequestIfNotValid() {
if (errors.size > 0) {
throw BadRequestException(toOutput())
}
}

View File

@@ -4,14 +4,11 @@ import com.github.jasync.sql.db.postgresql.exceptions.GenericDatabaseException
import fr.dcproject.common.security.AccessDeniedException
import fr.dcproject.component.auth.ForbiddenException
import fr.dcproject.component.auth.user
import io.konform.validation.ValidationResult
import io.ktor.application.ApplicationCall
import io.ktor.application.call
import io.ktor.features.NotFoundException
import io.ktor.features.StatusPages
import io.ktor.http.HttpStatusCode
import io.ktor.response.respond
import io.ktor.util.pipeline.PipelineContext
import java.util.concurrent.CompletionException
class HttpError(
@@ -20,8 +17,6 @@ class HttpError(
val type: String? = null,
val title: String = cause?.message ?: statusCode.description,
val detail: String? = null,
val invalidParams: List<InvalidParam>? = null,
val stackTrace: String? = cause?.stackTraceToString()
) {
val statusCode: Int = statusCode.value
data class InvalidParam(
@@ -30,30 +25,6 @@ class HttpError(
)
}
fun ValidationResult<*>.toOutput(): HttpError {
return HttpError(
HttpStatusCode.BadRequest,
invalidParams = this.errors.map {
HttpError.InvalidParam(
it.dataPath,
it.message
)
}
)
}
suspend fun PipelineContext<*, ApplicationCall>.respondIfNotValid(validationResult: ValidationResult<*>): HttpError? {
if (validationResult.errors.size > 0) {
val out = validationResult.toOutput()
this.call.respond(
HttpStatusCode.BadRequest,
out
)
return out
}
return null
}
fun statusPagesInstallation(): StatusPages.Configuration.() -> Unit = {
exception<CompletionException> { e ->
val parent = e.cause?.cause
@@ -106,4 +77,7 @@ fun statusPagesInstallation(): StatusPages.Configuration.() -> Unit = {
call.respond(HttpStatusCode.Forbidden, it)
}
}
exception<BadRequestException> { e ->
call.respond(HttpStatusCode.BadRequest, e.httpError)
}
}

View File

@@ -1,6 +1,6 @@
package fr.dcproject.component.article.routes
import fr.dcproject.application.http.respondIfNotValid
import fr.dcproject.application.http.badRequestIfNotValid
import fr.dcproject.common.response.toOutput
import fr.dcproject.common.security.assert
import fr.dcproject.common.validation.isUuid
@@ -74,7 +74,7 @@ object FindArticles {
fun Route.findArticles(repo: ArticleRepository, ac: ArticleAccessControl) {
get<ArticlesRequest> {
respondIfNotValid(it.validate())?.apply { return@get }
it.validate().badRequestIfNotValid()
repo.findArticles(it)
.apply { ac.assert { canView(result, citizenOrNull) } }

View File

@@ -134,6 +134,12 @@ paths:
tags:
- article
operationId: getArticle
parameters:
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/limit'
- $ref: '#/components/parameters/sort'
- $ref: '#/components/parameters/direction'
- $ref: '#/components/parameters/search'
responses:
200:
description: The Article objects
@@ -149,6 +155,12 @@ paths:
tags:
- article
operationId: getArticleVersions
parameters:
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/limit'
- $ref: '#/components/parameters/sort'
- $ref: '#/components/parameters/direction'
- $ref: '#/components/parameters/search'
responses:
200:
description: The versions of Article
@@ -2224,20 +2236,8 @@ components:
properties:
statusCode:
type: integer
type:
type: string
nullable: true
title:
type: string
detail:
type: string
nullable: true
cause:
type: string
nullable: true
stackTrace:
type: string
nullable: true
invalidParams:
type: array
items: