Skip to content

Commit

Permalink
fix: correctly serialises security schemes in OpenAPI plugin.
Browse files Browse the repository at this point in the history
  • Loading branch information
outofcoffee committed Dec 2, 2021
1 parent 253560f commit 4928932
Show file tree
Hide file tree
Showing 4 changed files with 272 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ import io.gatehill.imposter.http.HttpExchange
import io.gatehill.imposter.plugin.openapi.config.OpenApiPluginConfig
import io.gatehill.imposter.plugin.openapi.config.OpenApiPluginValidationConfig.ValidationIssueBehaviour
import io.gatehill.imposter.plugin.openapi.util.ValidationReportUtil
import io.gatehill.imposter.util.MapUtil
import io.swagger.models.Scheme
import io.swagger.v3.core.util.Json
import io.swagger.v3.oas.models.Components
import io.swagger.v3.oas.models.ExternalDocumentation
import io.swagger.v3.oas.models.OpenAPI
Expand Down Expand Up @@ -98,7 +98,11 @@ class SpecificationServiceImpl @Inject constructor(
override fun getCombinedSpecSerialised(allSpecs: List<OpenAPI>, deriveBasePathFromServerEntries: Boolean): String {
return cache.get("combinedSpecSerialised") {
try {
return@get MapUtil.JSON_MAPPER.writeValueAsString(
// Use the v3 swagger-core serialiser (io.swagger.v3.core.util.Json) to serialise the spec,
// to benefit from its various mixins that are not present in the io.swagger.util.Json implementation.
// In particular, these mixins correctly serialise extensions and components, like SecurityScheme,
// to their formal values, rather than the Java enum/toString() defaults.
return@get Json.mapper().writeValueAsString(
getCombinedSpec(allSpecs, deriveBasePathFromServerEntries)
)
} catch (e: JsonGenerationException) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright (c) 2016-2021.
*
* This file is part of Imposter.
*
* "Commons Clause" License Condition v1.0
*
* The Software is provided to you by the Licensor under the License, as
* defined below, subject to the following condition.
*
* Without limiting other conditions in the License, the grant of rights
* under the License will not include, and the License does not grant to
* you, the right to Sell the Software.
*
* For purposes of the foregoing, "Sell" means practicing any or all of
* the rights granted to you under the License to provide to third parties,
* for a fee or other consideration (including without limitation fees for
* hosting or consulting/support services related to the Software), a
* product or service whose value derives, entirely or substantially, from
* the functionality of the Software. Any license notice or attribution
* required by the License must also include this Commons Clause License
* Condition notice.
*
* Software: Imposter
*
* License: GNU Lesser General Public License version 3
*
* Licensor: Peter Cornish
*
* Imposter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Imposter is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Imposter. If not, see <https://www.gnu.org/licenses/>.
*/
package io.gatehill.imposter.plugin.openapi

import com.jayway.restassured.RestAssured
import com.jayway.restassured.http.ContentType
import io.gatehill.imposter.server.BaseVerticleTest
import io.gatehill.imposter.util.HttpUtil
import io.vertx.ext.unit.TestContext
import org.hamcrest.Matchers.equalTo
import org.hamcrest.Matchers.notNullValue
import org.junit.Before
import org.junit.Test

/**
* Tests that security schemes are serialised correctly.
*
* @author Pete Cornish
*/
class SecuritySchemesTest : BaseVerticleTest() {
override val pluginClass = OpenApiPluginImpl::class.java

@Before
@Throws(Exception::class)
override fun setUp(testContext: TestContext) {
super.setUp(testContext)
RestAssured.baseURI = "http://$host:$listenPort"
}

override val testConfigDirs = listOf(
"/openapi3/security-schemes"
)

/**
* Expects that securityScheme type is serialised correctly.
*/
@Test
fun testExampleRefReturned() {
RestAssured.given()
.log().ifValidationFails()
.accept(ContentType.JSON)
.`when`()[OpenApiPluginImpl.COMBINED_SPECIFICATION_PATH]
.then()
.log().ifValidationFails()
.statusCode(HttpUtil.HTTP_OK)
.body("components.securitySchemes.httpBasic", notNullValue())
.body("components.securitySchemes.httpBasic.type", equalTo("http"))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
plugin: openapi
specFile: spec.yaml
175 changes: 175 additions & 0 deletions plugin/openapi/src/test/resources/openapi3/security-schemes/spec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
openapi: "3.0.0"
info:
title: Simple API overview
version: 2.0.0
paths:
/:
get:
operationId: listVersionsv2
summary: List API versions
responses:
'200':
description: |-
200 response
content:
application/json:
examples:
foo:
value:
{
"versions": [
{
"status": "CURRENT",
"updated": "2011-01-21T11:33:21Z",
"id": "v2.0",
"links": [
{
"href": "http://127.0.0.1:8774/v2/",
"rel": "self"
}
]
},
{
"status": "EXPERIMENTAL",
"updated": "2013-07-23T11:33:21Z",
"id": "v3.0",
"links": [
{
"href": "http://127.0.0.1:8774/v3/",
"rel": "self"
}
]
}
]
}
'300':
description: |-
300 response
content:
application/json:
examples:
foo:
value: |
{
"versions": [
{
"status": "CURRENT",
"updated": "2011-01-21T11:33:21Z",
"id": "v2.0",
"links": [
{
"href": "http://127.0.0.1:8774/v2/",
"rel": "self"
}
]
},
{
"status": "EXPERIMENTAL",
"updated": "2013-07-23T11:33:21Z",
"id": "v3.0",
"links": [
{
"href": "http://127.0.0.1:8774/v3/",
"rel": "self"
}
]
}
]
}
/v2:
get:
operationId: getVersionDetailsv2
summary: Show API version details
responses:
'200':
description: |-
200 response
content:
application/json:
examples:
foo:
value:
{
"version": {
"status": "CURRENT",
"updated": "2011-01-21T11:33:21Z",
"media-types": [
{
"base": "application/xml",
"type": "application/vnd.openstack.compute+xml;version=2"
},
{
"base": "application/json",
"type": "application/vnd.openstack.compute+json;version=2"
}
],
"id": "v2.0",
"links": [
{
"href": "http://127.0.0.1:8774/v2/",
"rel": "self"
},
{
"href": "http://docs.openstack.org/api/openstack-compute/2/os-compute-devguide-2.pdf",
"type": "application/pdf",
"rel": "describedby"
},
{
"href": "http://docs.openstack.org/api/openstack-compute/2/wadl/os-compute-2.wadl",
"type": "application/vnd.sun.wadl+xml",
"rel": "describedby"
},
{
"href": "http://docs.openstack.org/api/openstack-compute/2/wadl/os-compute-2.wadl",
"type": "application/vnd.sun.wadl+xml",
"rel": "describedby"
}
]
}
}
'203':
description: |-
203 response
content:
application/json:
examples:
foo:
value:
{
"version": {
"status": "CURRENT",
"updated": "2011-01-21T11:33:21Z",
"media-types": [
{
"base": "application/xml",
"type": "application/vnd.openstack.compute+xml;version=2"
},
{
"base": "application/json",
"type": "application/vnd.openstack.compute+json;version=2"
}
],
"id": "v2.0",
"links": [
{
"href": "http://23.253.228.211:8774/v2/",
"rel": "self"
},
{
"href": "http://docs.openstack.org/api/openstack-compute/2/os-compute-devguide-2.pdf",
"type": "application/pdf",
"rel": "describedby"
},
{
"href": "http://docs.openstack.org/api/openstack-compute/2/wadl/os-compute-2.wadl",
"type": "application/vnd.sun.wadl+xml",
"rel": "describedby"
}
]
}
}
components:
securitySchemes:
httpBasic:
type: "http"
scheme: "basic"

0 comments on commit 4928932

Please sign in to comment.