#69 Format HTTP error

add 403 for /articles route
This commit is contained in:
2021-03-26 01:53:41 +01:00
parent 6b66130ddc
commit 5f0b8de159
3 changed files with 97 additions and 8 deletions

View File

@@ -11,23 +11,72 @@ import io.ktor.http.HttpStatusCode
import io.ktor.response.respond
import java.util.concurrent.CompletionException
class HttpError(
statusCode: HttpStatusCode,
val cause: Throwable? = null,
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(
val name: String,
val reason: String
)
}
fun statusPagesInstallation(): StatusPages.Configuration.() -> Unit = {
exception<CompletionException> { e ->
val parent = e.cause?.cause
if (parent is GenericDatabaseException) {
call.respond(HttpStatusCode.BadRequest, parent.errorMessage.message!!)
HttpError(
HttpStatusCode.BadRequest,
cause = parent
).let {
call.respond(HttpStatusCode.BadRequest, it)
}
} else {
throw e
HttpError(
HttpStatusCode.BadRequest,
cause = e
).let {
call.respond(HttpStatusCode.InternalServerError, it)
}
}
}
exception<NotFoundException> { e ->
call.respond(HttpStatusCode.NotFound, e.message!!)
}
exception<AccessDeniedException> {
if (call.user == null) call.respond(HttpStatusCode.Unauthorized)
else call.respond(HttpStatusCode.Forbidden)
}
exception<ForbiddenException> {
call.respond(HttpStatusCode.Forbidden)
HttpError(
HttpStatusCode.NotFound,
cause = e
).let {
call.respond(HttpStatusCode.NotFound, it)
}
}
exception<AccessDeniedException> { e ->
if (call.user == null) {
HttpError(
HttpStatusCode.Unauthorized,
cause = e
).let {
call.respond(HttpStatusCode.Unauthorized, it)
}
} else {
HttpError(
HttpStatusCode.Forbidden,
cause = e
).let {
call.respond(HttpStatusCode.Forbidden, it)
}
}
}
exception<ForbiddenException> { e ->
HttpError(
HttpStatusCode.Forbidden,
cause = e
).let {
call.respond(HttpStatusCode.Forbidden, it)
}
}
}

View File

@@ -108,6 +108,18 @@ paths:
type: integer
401:
$ref: '#/components/responses/401'
403:
description: Forbiden
content:
application/json:
schema:
description: Forbiden
properties:
statusCode:
type: integer
title:
type: string
/articles/{article}:
parameters:
- $ref: '#/components/parameters/article'

View File

@@ -12,11 +12,13 @@ import integration.steps.given.`authenticated as`
import integration.steps.then.`And have property`
import integration.steps.then.`And the response should contain list`
import integration.steps.then.`And the response should contain pattern`
import integration.steps.then.`And the response should contain`
import integration.steps.then.`And the response should not be null`
import integration.steps.then.`And the response should not contain`
import integration.steps.then.`Then the response should be`
import integration.steps.then.`whish contains`
import integration.steps.then.and
import io.ktor.http.HttpStatusCode.Companion.Forbidden
import io.ktor.http.HttpStatusCode.Companion.OK
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Tags
@@ -104,4 +106,30 @@ class `Article routes` : BaseTest() {
}
}
}
@Test
fun `I cannot create an article if I'm not connected`() {
withIntegrationApplication {
`When I send a POST request`("/articles") {
`with body`(
"""
{
"versionId": "e3c7ce42-241c-4caf-9a59-aba4e466440e",
"title": "title2",
"anonymous": false,
"content": "content2",
"description": "description2",
"tags": [
"green"
]
}
"""
)
} `Then the response should be` Forbidden and {
`And the response should not be null`()
`And the response should contain`("$.statusCode", 403)
`And the response should contain`("$.title", "No User Connected")
}
}
}
}