Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix and test for issue 1758 #1760

Merged
merged 5 commits into from
Jul 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,9 @@ public PathItem getPathItem(ObjectNode obj, String location, ParseResult result)
} else {
pathItem.set$ref(ref.textValue());
}
if(ref.textValue().startsWith("#/components") && !(ref.textValue().startsWith("#/components/pathItems"))) {
result.warning(location, "$ref target "+ref.textValue() +" is not of expected type PathItem");
}
if(result.isOpenapi31()){
String value = getString("summary", obj, false, location, result);
if (StringUtils.isNotBlank(value)) {
Expand Down Expand Up @@ -1568,6 +1571,9 @@ public Link getLink(ObjectNode linkNode, String location, ParseResult result) {
} else {
link.set$ref(ref.textValue());
}
if(ref.textValue().startsWith("#/components") && !(ref.textValue().startsWith("#/components/links"))) {
result.warning(location, "$ref target "+ref.textValue() +" is not of expected type Link");
}
if (result.isOpenapi31()) {
String desc = getString("description", linkNode, false, location, result);
if (StringUtils.isNotBlank(desc)) {
Expand Down Expand Up @@ -1692,6 +1698,9 @@ public Callback getCallback(ObjectNode node, String location, ParseResult result
} else {
callback.set$ref(ref.textValue());
}
if(ref.textValue().startsWith("#/components") && !(ref.textValue().startsWith("#/components/callbacks"))) {
result.warning(location, "$ref target "+ref.textValue() +" is not of expected type Callback");
}
return callback;
} else {
result.invalidType(location, "$ref", "string", node);
Expand Down Expand Up @@ -1938,10 +1947,13 @@ public Parameter getParameter(ObjectNode obj, String location, ParseResult resul
parameter = new Parameter();
String mungedRef = mungedRef(ref.textValue());
if (mungedRef != null) {
parameter.set$ref(mungedRef);
} else {
parameter.set$ref(ref.textValue());
}
parameter.set$ref(mungedRef);
}else {
parameter.set$ref(ref.textValue());
}
if(ref.textValue().startsWith("#/components") && !(ref.textValue().startsWith("#/components/parameters") || ref.textValue().startsWith("#/components/headers"))) {
result.warning(location, "$ref target "+ref.textValue() +" is not of expected type Parameter/Header");
}
if (result.isOpenapi31()) {
String desc = getString("description", obj, false, location, result);
if (StringUtils.isNotBlank(desc)) {
Expand Down Expand Up @@ -2148,6 +2160,10 @@ public Header getHeader(ObjectNode headerNode, String location, ParseResult resu
} else {
header.set$ref(ref.textValue());
}
if(ref.textValue().startsWith("#/components") && !(ref.textValue().startsWith("#/components/parameters") || ref.textValue().startsWith("#/components/headers"))) {
result.warning(location, "$ref target "+ref.textValue() +" is not of expected type Header/Parameter");
}

if (result.isOpenapi31()) {
String desc = getString("description", headerNode, false, location, result);
if (StringUtils.isNotBlank(desc)) {
Expand Down Expand Up @@ -2310,6 +2326,9 @@ public SecurityScheme getSecurityScheme(ObjectNode node, String location, ParseR
} else {
securityScheme.set$ref(ref.textValue());
}
if(ref.textValue().startsWith("#/components") && !(ref.textValue().startsWith("#/components/securitySchemes"))) {
result.warning(location, "$ref target "+ref.textValue() +" is not of expected type securitySchemes");
}
if (result.isOpenapi31()) {
String desc = getString("description", node, false, location, result);
if (StringUtils.isNotBlank(desc)) {
Expand Down Expand Up @@ -2743,6 +2762,9 @@ at the moment path passed as string (basePath) from upper components can be both
if(schema.get$ref().startsWith("#/components/schemas")){// it's internal
String refName = schema.get$ref().substring(schema.get$ref().lastIndexOf("/")+1);
localSchemaRefs.put(refName,location);
}
if(ref.textValue().startsWith("#/components") && !(ref.textValue().startsWith("#/components/schemas"))) {
result.warning(location, "$ref target "+ref.textValue() +" is not of expected type Schema");
}
return schema;
} else {
Expand Down Expand Up @@ -3216,6 +3238,9 @@ public Example getExample(ObjectNode node, String location, ParseResult result)
} else {
example.set$ref(ref.textValue());
}
if(ref.textValue().startsWith("#/components") && !(ref.textValue().startsWith("#/components/examples"))) {
result.warning(location, "$ref target "+ref.textValue() +" is not of expected type Examples");
}
if(result.isOpenapi31()){
String value = getString("summary", node, false, location, result);
if (StringUtils.isNotBlank(value)) {
Expand Down Expand Up @@ -3355,6 +3380,9 @@ public ApiResponse getResponse(ObjectNode node, String location, ParseResult res
} else {
apiResponse.set$ref(ref.textValue());
}
if(ref.textValue().startsWith("#/components") && !(ref.textValue().startsWith("#/components/responses"))) {
result.warning(location, "$ref target "+ref.textValue() +" is not of expected type Response");
}
if(result.isOpenapi31()){
String value = getString("description", node, false, location, result);
if (StringUtils.isNotBlank(value)) {
Expand All @@ -3376,15 +3404,15 @@ public ApiResponse getResponse(ObjectNode node, String location, ParseResult res

ObjectNode headerObject = getObject("headers", node, false, location, result);
if (headerObject != null) {
Map<String, Header> headers = getHeaders(headerObject, location, result, false);
Map<String, Header> headers = getHeaders(headerObject, String.format("%s.%s", location, "headers"), result, false);
if (headers != null && headers.size() > 0) {
apiResponse.setHeaders(headers);
}
}

ObjectNode linksObj = getObject("links", node, false, location, result);
if (linksObj != null) {
Map<String, Link> links = getLinks(linksObj, location, result, false);
Map<String, Link> links = getLinks(linksObj, String.format("%s.%s", location, "links"), result, false);
if (links != null && links.size() > 0) {
apiResponse.setLinks(links);
}
Expand Down Expand Up @@ -3605,6 +3633,9 @@ public RequestBody getRequestBody(ObjectNode node, String location, ParseResult
} else {
body.set$ref(ref.textValue());
}
if(ref.textValue().startsWith("#/components") && !(ref.textValue().startsWith("#/components/requestBodies"))) {
result.warning(location, "$ref target "+ref.textValue() +" is not of expected type RequestBody");
}
if (result.isOpenapi31()) {
String desc = getString("description", node, false, location, result);
if (StringUtils.isNotBlank(desc)) {
Expand Down Expand Up @@ -3823,6 +3854,9 @@ public Schema getJsonSchema(JsonNode jsonNode, String location, ParseResult resu
} else {
schema.set$ref(ref.asText());
}
if(ref.textValue().startsWith("#/components") && !(ref.textValue().startsWith("#/components/schemas"))) {
result.warning(location, "$ref target "+ref.textValue() +" is not of expected type Schema");
}
} else {
result.invalidType(location, "$ref", "string", node);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,26 @@ public class OpenAPIV3ParserTest {
protected int serverPort = getDynamicPort();
protected WireMockServer wireMockServer;

@Test
public void testIssue1758() throws Exception{
ParseOptions options = new ParseOptions();
SwaggerParseResult result = new OpenAPIV3Parser().readLocation("src/test/resources/issue1758.yaml", null, options);

Assert.assertNotNull(result);
Assert.assertNotNull(result.getOpenAPI());
assertEquals(result.getMessages().size(),9);
assertTrue(result.getMessages().contains("paths.'/path1'.$ref target #/components/schemas/xFoo is not of expected type PathItem"));
assertTrue(result.getMessages().contains("paths.'/foo'(get).parameters.$ref target #/components/schemas/xFoo is not of expected type Parameter/Header"));
assertTrue(result.getMessages().contains("paths.'/foo'(get).responses.default.headers.three.$ref target #/components/schemas/xFoo is not of expected type Header/Parameter"));
assertTrue(result.getMessages().contains("paths.'/foo'(get).requestBody.$ref target #/components/schemas/xFoo is not of expected type RequestBody"));
assertTrue(result.getMessages().contains("paths.'/foo'(get).responses.200.links.user.$ref target #/components/schemas/xFoo is not of expected type Link"));
assertTrue(result.getMessages().contains("paths.'/foo'(get).responses.200.content.'application/json'.schema.$ref target #/components/parameters/pet is not of expected type Schema"));
assertTrue(result.getMessages().contains("paths.'/foo'(get).responses.200.content.'application/json'.examples.one.$ref target #/components/schemas/xFoo is not of expected type Examples"));
assertTrue(result.getMessages().contains("paths.'/foo'(get).responses.400.$ref target #/components/schemas/xFoo is not of expected type Response"));
assertTrue(result.getMessages().contains("paths.'/foo'(get).callbacks.$ref target #/components/schemas/xFoo is not of expected type Callback"));

}

@Test(description = "Test for not setting the schema type as default")
public void testNotDefaultSchemaType() {
ParseOptions options = new ParseOptions();
Expand Down Expand Up @@ -514,7 +534,6 @@ public void testIssueSameRefsDifferentModelValid() {
options.setResolveFully(true);

final SwaggerParseResult openAPI = parser.readLocation("src/test/resources/same-refs-different-model-valid.yaml", null, options);
Yaml.prettyPrint(openAPI);
assertEquals(openAPI.getMessages().size(), 0);
}

Expand Down
55 changes: 55 additions & 0 deletions modules/swagger-parser-v3/src/test/resources/issue1758.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
openapi: 3.0.3
info:
title: Missing validation rule for schemas in Headers.
version: 1.0.0
servers:
- url: /
paths:
/path1:
$ref: '#/components/schemas/xFoo'
/foo:
get:
description: ok
parameters:
- $ref: '#/components/schemas/xFoo'
requestBody:
$ref: '#/components/schemas/xFoo'
responses:
default:
description: ok
headers:
three:
$ref: '#/components/schemas/xFoo'
'200':
description: successful operation
content:
application/json:
schema:
type: array
items:
$ref: '#/components/parameters/pet'
examples:
one:
$ref: '#/components/schemas/xFoo'
links:
user:
$ref: '#/components/schemas/xFoo'
'400':
$ref: '#/components/schemas/xFoo'
callbacks:
mainHook:
$ref: "#/components/schemas/xFoo"
components:
schemas:
xFoo:
type: string
description: This isn't validated correctly
parameters:
pet:
name: X-pet
in: header
required: false
schema:
type: string
format: uuid