fix: spec and docs behind auth (#284)
This commit is contained in:
@ -5,6 +5,7 @@
|
|||||||
### Added
|
### Added
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
- Can now put redoc route behind authentication
|
||||||
|
|
||||||
### Remove
|
### Remove
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package io.bkbn.kompendium.core.routes
|
|||||||
import io.ktor.http.HttpStatusCode
|
import io.ktor.http.HttpStatusCode
|
||||||
import io.ktor.server.application.call
|
import io.ktor.server.application.call
|
||||||
import io.ktor.server.html.respondHtml
|
import io.ktor.server.html.respondHtml
|
||||||
import io.ktor.server.routing.Routing
|
import io.ktor.server.routing.Route
|
||||||
import io.ktor.server.routing.get
|
import io.ktor.server.routing.get
|
||||||
import io.ktor.server.routing.route
|
import io.ktor.server.routing.route
|
||||||
import kotlinx.html.body
|
import kotlinx.html.body
|
||||||
@ -20,7 +20,7 @@ import kotlinx.html.unsafe
|
|||||||
* @param pageTitle Webpage title you wish to be displayed on your docs
|
* @param pageTitle Webpage title you wish to be displayed on your docs
|
||||||
* @param specUrl url to point ReDoc to the OpenAPI json document
|
* @param specUrl url to point ReDoc to the OpenAPI json document
|
||||||
*/
|
*/
|
||||||
fun Routing.redoc(pageTitle: String = "Docs", specUrl: String = "/openapi.json") {
|
fun Route.redoc(pageTitle: String = "Docs", specUrl: String = "/openapi.json") {
|
||||||
route("/docs") {
|
route("/docs") {
|
||||||
get {
|
get {
|
||||||
call.respondHtml(HttpStatusCode.OK) {
|
call.respondHtml(HttpStatusCode.OK) {
|
||||||
|
@ -30,10 +30,6 @@ import io.ktor.server.routing.route
|
|||||||
import io.ktor.server.routing.routing
|
import io.ktor.server.routing.routing
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
/**
|
|
||||||
* Application entrypoint. Run this and head on over to `localhost:8081/docs`
|
|
||||||
* to see a very simple yet beautifully documented API
|
|
||||||
*/
|
|
||||||
fun main() {
|
fun main() {
|
||||||
embeddedServer(
|
embeddedServer(
|
||||||
Netty,
|
Netty,
|
||||||
@ -43,7 +39,6 @@ fun main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun Application.mainModule() {
|
private fun Application.mainModule() {
|
||||||
// Installs Simple JSON Content Negotiation
|
|
||||||
install(ContentNegotiation) {
|
install(ContentNegotiation) {
|
||||||
json(Json {
|
json(Json {
|
||||||
serializersModule = KompendiumSerializersModule.module
|
serializersModule = KompendiumSerializersModule.module
|
||||||
@ -75,10 +70,6 @@ private fun Application.mainModule() {
|
|||||||
routing {
|
routing {
|
||||||
redoc(pageTitle = "Simple API Docs")
|
redoc(pageTitle = "Simple API Docs")
|
||||||
authenticate("basic") {
|
authenticate("basic") {
|
||||||
// This adds ReDoc support at the `/docs` endpoint.
|
|
||||||
// By default, it will point at the `/openapi.json` created by Kompendium
|
|
||||||
|
|
||||||
// Route with a get handler
|
|
||||||
route("/{id}") {
|
route("/{id}") {
|
||||||
idDocumentation()
|
idDocumentation()
|
||||||
get {
|
get {
|
||||||
@ -89,7 +80,6 @@ private fun Application.mainModule() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Documentation for our route
|
|
||||||
private fun Route.idDocumentation() {
|
private fun Route.idDocumentation() {
|
||||||
install(NotarizedRoute()) {
|
install(NotarizedRoute()) {
|
||||||
parameters = listOf(
|
parameters = listOf(
|
||||||
|
@ -0,0 +1,116 @@
|
|||||||
|
package io.bkbn.kompendium.playground
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.attribute.KompendiumAttributes
|
||||||
|
import io.bkbn.kompendium.core.metadata.GetInfo
|
||||||
|
import io.bkbn.kompendium.core.plugin.NotarizedApplication
|
||||||
|
import io.bkbn.kompendium.core.plugin.NotarizedRoute
|
||||||
|
import io.bkbn.kompendium.core.routes.redoc
|
||||||
|
import io.bkbn.kompendium.json.schema.definition.TypeDefinition
|
||||||
|
import io.bkbn.kompendium.oas.component.Components
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
import io.bkbn.kompendium.oas.security.BasicAuth
|
||||||
|
import io.bkbn.kompendium.oas.serialization.KompendiumSerializersModule
|
||||||
|
import io.bkbn.kompendium.playground.util.ExampleResponse
|
||||||
|
import io.bkbn.kompendium.playground.util.Util.baseSpec
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.serialization.kotlinx.json.json
|
||||||
|
import io.ktor.server.application.Application
|
||||||
|
import io.ktor.server.application.call
|
||||||
|
import io.ktor.server.application.install
|
||||||
|
import io.ktor.server.auth.Authentication
|
||||||
|
import io.ktor.server.auth.UserIdPrincipal
|
||||||
|
import io.ktor.server.auth.authenticate
|
||||||
|
import io.ktor.server.auth.basic
|
||||||
|
import io.ktor.server.engine.embeddedServer
|
||||||
|
import io.ktor.server.netty.Netty
|
||||||
|
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.application
|
||||||
|
import io.ktor.server.routing.get
|
||||||
|
import io.ktor.server.routing.route
|
||||||
|
import io.ktor.server.routing.routing
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
embeddedServer(
|
||||||
|
Netty,
|
||||||
|
port = 8081,
|
||||||
|
module = Application::mainModule
|
||||||
|
).start(wait = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Application.mainModule() {
|
||||||
|
install(ContentNegotiation) {
|
||||||
|
json(Json {
|
||||||
|
serializersModule = KompendiumSerializersModule.module
|
||||||
|
encodeDefaults = true
|
||||||
|
explicitNulls = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
install(Authentication) {
|
||||||
|
basic("basic") {
|
||||||
|
realm = "Ktor Server"
|
||||||
|
validate { credentials ->
|
||||||
|
if (credentials.name == credentials.password) {
|
||||||
|
UserIdPrincipal(credentials.name)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
install(NotarizedApplication()) {
|
||||||
|
spec = baseSpec.copy(
|
||||||
|
components = Components(
|
||||||
|
securitySchemes = mutableMapOf(
|
||||||
|
"basic" to BasicAuth()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
openApiJson = {
|
||||||
|
authenticate("basic") {
|
||||||
|
route("/openapi.json") {
|
||||||
|
get {
|
||||||
|
call.respond(HttpStatusCode.OK, this@route.application.attributes[KompendiumAttributes.openApiSpec])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
routing {
|
||||||
|
authenticate("basic") {
|
||||||
|
redoc(pageTitle = "Simple API Docs")
|
||||||
|
route("/{id}") {
|
||||||
|
idDocumentation()
|
||||||
|
get {
|
||||||
|
call.respond(HttpStatusCode.OK, ExampleResponse(true))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Route.idDocumentation() {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = listOf(
|
||||||
|
Parameter(
|
||||||
|
name = "id",
|
||||||
|
`in` = Parameter.Location.path,
|
||||||
|
schema = TypeDefinition.STRING
|
||||||
|
)
|
||||||
|
)
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary("Get user by id")
|
||||||
|
description("A very neat endpoint!")
|
||||||
|
security = mapOf(
|
||||||
|
"basic" to emptyList()
|
||||||
|
)
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<ExampleResponse>()
|
||||||
|
description("Will return whether or not the user is real 😱")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user