Skip to content

Commit

Permalink
Merge branch 'master' into fix/ensure-valid-classpath-paths
Browse files Browse the repository at this point in the history
  • Loading branch information
gracekarina authored Feb 28, 2023
2 parents 44777b8 + 092438d commit 90a54c5
Show file tree
Hide file tree
Showing 30 changed files with 316 additions and 98 deletions.
18 changes: 18 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: 2
updates:
- package-ecosystem: "maven"
target-branch: "master"
directory: "/"
schedule:
interval: "daily"
allow:
- dependency-name: "io.swagger.core.v3:*"
- dependency-name: "io.swagger:*"
- package-ecosystem: "maven"
target-branch: "v1"
directory: "/"
schedule:
interval: "daily"
allow:
- dependency-name: "io.swagger.core.v3:*"
- dependency-name: "io.swagger:*"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ You can include this library from Sonatype OSS for SNAPSHOTS, or Maven central f
<dependency>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser</artifactId>
<version>2.1.11</version>
<version>2.1.12</version>
</dependency>
```

Expand Down
4 changes: 2 additions & 2 deletions modules/swagger-parser-cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>swagger-parser-project</artifactId>
<groupId>io.swagger.parser.v3</groupId>
<version>2.1.12-SNAPSHOT</version>
<version>2.1.13-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
Expand Down Expand Up @@ -69,7 +69,7 @@
<dependency>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser-v3</artifactId>
<version>2.1.12-SNAPSHOT</version>
<version>2.1.13-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
Expand Down
2 changes: 1 addition & 1 deletion modules/swagger-parser-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<parent>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser-project</artifactId>
<version>2.1.12-SNAPSHOT</version>
<version>2.1.13-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
Expand Down
2 changes: 1 addition & 1 deletion modules/swagger-parser-v2-converter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<parent>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser-project</artifactId>
<version>2.1.12-SNAPSHOT</version>
<version>2.1.13-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
Expand Down
2 changes: 1 addition & 1 deletion modules/swagger-parser-v3/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<parent>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser-project</artifactId>
<version>2.1.12-SNAPSHOT</version>
<version>2.1.13-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ public String processRefToExternalSchema(String $ref, RefFormat refFormat) {
for(Schema item : composedSchema.getAllOf()){
if (item.get$ref() != null){
processRefSchema(item,file);
} else if (item.getProperties() != null) {
processProperties(item.getProperties(), file);
} else{
processSchema(item, file);
}
}

Expand All @@ -159,6 +159,8 @@ public String processRefToExternalSchema(String $ref, RefFormat refFormat) {
if (item.get$ref() != null){
if (item.get$ref() != null){
processRefSchema(item,file);
}else{
processSchema(item, file);
}
}
}
Expand All @@ -167,10 +169,11 @@ public String processRefToExternalSchema(String $ref, RefFormat refFormat) {
if (item.get$ref() != null){
if (item.get$ref() != null){
processRefSchema(item,file);
}else{
processSchema(item, file);
}
}
}

}
}
//Loop the properties and recursively call this method;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public List<OpenAPIDereferencer> getDereferencers() {
if (ext == null) {
LOGGER.error("failed to load extension {}", ext);
} else {
instance.addDereferencer(ext);
getInstance().addDereferencer(ext);
LOGGER.debug("adding OpenAPIDereferencer: {}", ext);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
package io.swagger.v3.parser.reference;

import com.fasterxml.jackson.databind.JsonNode;
import io.swagger.v3.core.util.Json31;
import io.swagger.v3.core.util.Yaml31;
import io.swagger.v3.parser.core.models.AuthorizationValue;
import io.swagger.v3.parser.util.ClasspathHelper;
import io.swagger.v3.parser.util.RemoteUrl;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.util.List;
import java.util.regex.Pattern;

import static java.nio.charset.StandardCharsets.UTF_8;

public class ReferenceUtils {

public static String toBaseURI(String uri) throws Exception
Expand Down Expand Up @@ -68,52 +57,6 @@ public static boolean isAnchor(String ref) {
return false;
}

public static String readURI(String absoluteUri, List<AuthorizationValue> auths) throws Exception {
URI resolved = new URI(absoluteUri);
if (StringUtils.isNotBlank(resolved.getScheme())) {
if (resolved.getScheme().startsWith("http")) {
return readHttp(absoluteUri, auths);
} else if (resolved.getScheme().startsWith("file")) {
return readFile(absoluteUri);
} else if (resolved.getScheme().startsWith("classpath")) {
return readClasspath(absoluteUri);
}
}
// If no matches exists, try file
String content = null;
try {
content = readFile(absoluteUri);
} catch (Exception e) {
//
}
if (StringUtils.isBlank(content)) {
content = readClasspath(absoluteUri);
}
return content;
}

public static JsonNode deserializeIntoTree(String content) throws Exception {
boolean isJson = content.trim().startsWith("{");
return isJson ? Json31.mapper().readTree(content) : Yaml31.mapper().readTree(content);
}

public static JsonNode parse(String absoluteUri, List<AuthorizationValue> auths) throws Exception {
return deserializeIntoTree(readURI(absoluteUri, auths));
}

public static String readFile(String uri) throws Exception {
try (InputStream inputStream = new FileInputStream(uri)) {
return IOUtils.toString(inputStream, UTF_8);
}
}

public static String readClasspath(String uri) throws Exception {
return ClasspathHelper.loadFileFromClasspath(uri);
}
public static String readHttp(String uri, List<AuthorizationValue> auths) throws Exception {
return RemoteUrl.urlToString(uri, auths);
}

public static String unescapePointer(String jsonPathElement) {
// URL decode the fragment
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import io.swagger.v3.core.util.Json31;
import io.swagger.v3.core.util.Yaml31;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.examples.Example;
import io.swagger.v3.oas.models.headers.Header;
Expand All @@ -11,6 +13,7 @@
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.parser.core.models.AuthorizationValue;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -50,7 +53,7 @@ public Reference toReference(String uri) throws Exception{
if (referenceSet.containsKey(baseUri)) {
return referenceSet.get(baseUri);
}
JsonNode node = ReferenceUtils.parse(baseUri, this.reference.getAuths());
JsonNode node = parse(baseUri, this.reference.getAuths());

Reference ref = new Reference()
.auths(this.reference.getAuths())
Expand Down Expand Up @@ -205,11 +208,11 @@ public Schema resolveSchemaRef(Schema visiting, String ref, List<String> inherit
else {
JsonNode node = null;
try {
node = ReferenceUtils.parse(baseURI, this.reference.getAuths());
node = parse(baseURI, this.reference.getAuths());
} catch (Exception e) {
// we can not parse, try ref
baseURI = toBaseURI(ref);
node = ReferenceUtils.parse(baseURI, this.reference.getAuths());
node = parse(baseURI, this.reference.getAuths());
}
reference = toSchemaReference(baseURI, node);
}
Expand Down Expand Up @@ -266,4 +269,13 @@ public JsonNode findAnchor(JsonNode root, String anchor) {

return null;
}

public JsonNode deserializeIntoTree(String content) throws Exception {
boolean isJson = content.trim().startsWith("{");
return isJson ? Json31.mapper().readTree(content) : Yaml31.mapper().readTree(content);
}

public JsonNode parse(String absoluteUri, List<AuthorizationValue> auths) throws Exception {
return deserializeIntoTree(readURI(absoluteUri, auths));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,19 @@
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
import io.swagger.v3.oas.models.security.SecurityScheme;

import io.swagger.v3.parser.core.models.AuthorizationValue;
import io.swagger.v3.parser.util.ClasspathHelper;
import io.swagger.v3.parser.util.RemoteUrl;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URI;
import java.util.List;

import static java.nio.charset.StandardCharsets.UTF_8;

public interface Visitor {
OpenAPI visitOpenApi(OpenAPI openAPI);

Expand Down Expand Up @@ -52,4 +62,41 @@ public interface Visitor {

Example visitExample(Example example);

default String readFile(String uri) throws Exception {
try (InputStream inputStream = new FileInputStream(uri)) {
return IOUtils.toString(inputStream, UTF_8);
}
}

default String readClasspath(String uri) throws Exception {
return ClasspathHelper.loadFileFromClasspath(uri);
}
default String readHttp(String uri, List<AuthorizationValue> auths) throws Exception {
return RemoteUrl.urlToString(uri, auths);
}

default String readURI(String absoluteUri, List<AuthorizationValue> auths) throws Exception {
URI resolved = new URI(absoluteUri);
if (StringUtils.isNotBlank(resolved.getScheme())) {
if (resolved.getScheme().startsWith("http")) {
return readHttp(absoluteUri, auths);
} else if (resolved.getScheme().startsWith("file")) {
return readFile(absoluteUri);
} else if (resolved.getScheme().startsWith("classpath")) {
return readClasspath(absoluteUri);
}
}
// If no matches exists, try file
String content = null;
try {
content = readFile(absoluteUri);
} catch (Exception e) {
//
}
if (StringUtils.isBlank(content)) {
content = readClasspath(absoluteUri);
}
return content;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

Expand Down Expand Up @@ -47,10 +48,13 @@ public static String computeDefinitionName(String ref) {
plausibleName = filePathElements[filePathElements.length - 1];

final String[] split = plausibleName.split("\\.");
// Fix for issue-1621
plausibleName = split[0];
for (int i = 1; i < split.length - 1; i++) {
plausibleName += "." + split[i];
// Fix for issue-1621 and issue-1865
//validate number of dots
if(split.length > 2) {
//Remove dot so ref can be interpreted as internal and relative in Swagger-Core schema class 'set$ref'
plausibleName = String.join("", Arrays.copyOf(split, split.length - 1));
}else{
plausibleName = split[0];
}
}

Expand Down Expand Up @@ -225,4 +229,4 @@ private static String readAll(Path path) throws IOException {
return IOUtils.toString(inputStream, UTF_8);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package io.swagger.v3.parser.test;

import io.swagger.v3.parser.core.models.AuthorizationValue;
import io.swagger.v3.parser.reference.DereferencerContext;
import io.swagger.v3.parser.reference.OpenAPI31Traverser;
import io.swagger.v3.parser.reference.OpenAPIDereferencer31;
import io.swagger.v3.parser.reference.Reference;
import io.swagger.v3.parser.reference.ReferenceVisitor;
import io.swagger.v3.parser.reference.Traverser;
import io.swagger.v3.parser.reference.Visitor;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

public class CustomOpenAPIDereferencer extends OpenAPIDereferencer31 {
@Override
public Visitor buildReferenceVisitor(DereferencerContext context, Reference reference, Traverser traverser) {
return new CustomVisitor(reference, (OpenAPI31Traverser)traverser, new HashSet<>(), new HashMap<>());
}

static public class CustomVisitor extends ReferenceVisitor {

public CustomVisitor(Reference reference, OpenAPI31Traverser openAPITraverser, HashSet<Object> visited,
HashMap<Object, Object> visitedMap) {
super(reference, openAPITraverser, visited, visitedMap);
}

@Override
public String readHttp(String uri, List<AuthorizationValue> auths) throws Exception {

if (uri.startsWith("http://example.com/custom")) {
return "openapi: 3.1.0\n" +
"info:\n" +
" title: Domain\n" +
" version: '1.0'\n" +
"components:\n" +
" pathItems:\n" +
" ExternalRef:\n" +
" get:\n" +
" description: ExternalRef domain\n" +
" operationId: ExternalRef PathItem\n" +
" responses:\n" +
" '200':\n" +
" description: OK";
} else {
return super.readHttp(uri, auths);
}
}
}
}
Loading

0 comments on commit 90a54c5

Please sign in to comment.