Skip to content

Commit

Permalink
Merge pull request #284 from dres-dev/fix/283-client-openapi
Browse files Browse the repository at this point in the history
Fixed #283 by adding approriate excludes in OAS generation
  • Loading branch information
lucaro authored Oct 15, 2021
2 parents d949206 + f60d97d commit 94754c0
Show file tree
Hide file tree
Showing 3 changed files with 323 additions and 12 deletions.
36 changes: 25 additions & 11 deletions backend/src/main/kotlin/dev/dres/api/rest/OpenApiEndpointOptions.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.dres.api.rest

import io.javalin.plugin.openapi.annotations.HttpMethod
import okhttp3.internal.toImmutableList

/**
* Options to configure an OpenApi Specifications endpoint in use with Javalin OpenApi Plugin.
Expand All @@ -20,35 +21,48 @@ data class OpenApiEndpointOptions(
private val ignores: List<String> = listOf()
) {

val ignored = ignores.map {
fun ignored(): List<Pair<String, List<HttpMethod>>> {
return _ignored.toImmutableList()
}

private val _ignored = ignores.map {
/* Small routine to distinguish between "internal" (prefixed with /api/) and "public" endpoints */
if(!it.startsWith("#")){
"/api/v1$it" to HttpMethod.values().map { it } //FIXME deal with version number
}else{
it.substring(it.indexOf("#")+1) to HttpMethod.values().map { it }
}
}.toMutableList()

fun withIgnores(ignores: List<Pair<String, List<HttpMethod>>>) : OpenApiEndpointOptions {
this._ignored.addAll(ignores)
return this
}

companion object {
val commonIgnores = mutableListOf(
"/external/*",
"/user*",
"/collection*", "/collection/*",
"/competition*", "/competition/*",
"/run*", "/run/*",
"/audit*", "/audit/*",
"/mediaItem*", "/mediaItem/*",
"/score*", "/score/*"
)
val lessCommonIgnores = listOf(
"/login", "/logout", "/status/*", "/user/*"
)

val dresDefaultOptions = OpenApiEndpointOptions("/swagger-docs", "/swagger-ui")
val dresLogOnly = OpenApiEndpointOptions("/logging-oas", "/swagger-log",
ignores = commonIgnores + listOf("/submit"))
val dresSubmissionOnly = OpenApiEndpointOptions("/submission-oas", "/swagger-submit",
ignores = commonIgnores + listOf("/log*", "/log/*") )

val dresSubmittingClientOptions = OpenApiEndpointOptions("/client-oas", "/swagger-client", ignores= commonIgnores + listOf("/user/list", "/user/session/*"))
val dresSubmittingClientOptions = OpenApiEndpointOptions(
"/client-oas",
"/swagger-client",
ignores= commonIgnores +
listOf(
"/user/list",
"/user/session/*"
)
).withIgnores(listOf(
"/api/v1/user" to HttpMethod.values().map { it }.filter { it.ordinal != HttpMethod.GET.ordinal },
"/api/v1/user/{userId}" to HttpMethod.values().map{it}
))
}
}
}
2 changes: 1 addition & 1 deletion backend/src/main/kotlin/dev/dres/api/rest/RestApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ object RestApi {
path(options.oasPath) // endpoint for OpenAPI json
swagger(SwaggerOptions(options.swaggerUi)) // endpoint for swagger-ui
activateAnnotationScanningFor("dev.dres.api.rest.handler")
options.ignored.forEach { ignorePath(it.first) }
options.ignored().forEach { it.second.forEach { method -> ignorePath(it.first, method) } }
toJsonMapper(JacksonToJsonMapper(jacksonMapper))
}

Expand Down
297 changes: 297 additions & 0 deletions doc/oas-client.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,278 @@
}
}
},
"/api/v1/user" : {
"get" : {
"tags" : [ "User" ],
"summary" : "Get information about the current user.",
"operationId" : "getApiV1User",
"responses" : {
"200" : {
"description" : "OK",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/UserDetails"
}
}
}
},
"500" : {
"description" : "Server Error",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/ErrorStatus"
}
}
}
}
}
},
"post" : {
"tags" : [ "User" ],
"summary" : "Creates a new user, if the username is not already taken. Requires ADMIN privileges",
"operationId" : "postApiV1User",
"requestBody" : {
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/UserRequest"
}
}
}
},
"responses" : {
"200" : {
"description" : "OK",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/UserDetails"
}
}
}
},
"400" : {
"description" : "If the username is already taken",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/ErrorStatus"
}
}
}
},
"500" : {
"description" : "Server Error",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/ErrorStatus"
}
}
}
}
}
}
},
"/api/v1/user/{userId}" : {
"get" : {
"tags" : [ "User" ],
"summary" : "Gets details of the user with the given id",
"operationId" : "getApiV1UserWithUserid",
"parameters" : [ {
"name" : "userId",
"in" : "path",
"description" : "User's UID",
"required" : true,
"schema" : {
"type" : "string"
}
} ],
"responses" : {
"200" : {
"description" : "OK",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/UserDetails"
}
}
}
},
"404" : {
"description" : "If the user could not be found",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/ErrorStatus"
}
}
}
},
"500" : {
"description" : "Server Error",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/ErrorStatus"
}
}
}
}
}
},
"delete" : {
"tags" : [ "User" ],
"summary" : "Deletes the specified user. Requires ADMIN privileges",
"operationId" : "deleteApiV1UserWithUserid",
"parameters" : [ {
"name" : "userId",
"in" : "path",
"description" : "User ID",
"required" : true,
"schema" : {
"type" : "integer",
"format" : "int64"
}
} ],
"responses" : {
"200" : {
"description" : "OK",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/UserDetails"
}
}
}
},
"404" : {
"description" : "If the user could not be found",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/ErrorStatus"
}
}
}
},
"500" : {
"description" : "Server Error",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/ErrorStatus"
}
}
}
}
}
},
"patch" : {
"tags" : [ "User" ],
"summary" : "Updates the specified user, if it exists. Anyone is allowed to update their data, however only ADMINs are allowed to update anyone",
"operationId" : "patchApiV1UserWithUserid",
"parameters" : [ {
"name" : "userId",
"in" : "path",
"description" : "User ID",
"required" : true,
"schema" : {
"type" : "string"
}
} ],
"requestBody" : {
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/UserRequest"
}
}
}
},
"responses" : {
"200" : {
"description" : "OK",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/UserDetails"
}
}
}
},
"400" : {
"description" : "Bad Request",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/ErrorStatus"
}
}
}
},
"404" : {
"description" : "Not Found",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/ErrorStatus"
}
}
}
},
"500" : {
"description" : "Server Error",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/ErrorStatus"
}
}
}
}
}
}
},
"/api/v1/user/session" : {
"get" : {
"tags" : [ "User" ],
"summary" : "Get current sessionId",
"operationId" : "getApiV1UserSession",
"parameters" : [ {
"name" : "session",
"in" : "query",
"description" : "Session Token",
"schema" : {
"type" : "string"
}
} ],
"responses" : {
"200" : {
"description" : "OK",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/SessionId"
}
}
}
},
"500" : {
"description" : "Server Error",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/ErrorStatus"
}
}
}
}
}
}
},
"/api/v1/submit" : {
"get" : {
"tags" : [ "Submission" ],
Expand Down Expand Up @@ -667,6 +939,31 @@
}
}
},
"UserRequest" : {
"required" : [ "username" ],
"type" : "object",
"properties" : {
"username" : {
"type" : "string"
},
"password" : {
"type" : "string"
},
"role" : {
"type" : "string",
"enum" : [ "ADMIN", "JUDGE", "VIEWER", "PARTICIPANT" ]
}
}
},
"SessionId" : {
"required" : [ "sessionId" ],
"type" : "object",
"properties" : {
"sessionId" : {
"type" : "string"
}
}
},
"SuccessfulSubmissionsStatus" : {
"required" : [ "description", "status", "submission" ],
"type" : "object",
Expand Down

0 comments on commit 94754c0

Please sign in to comment.