SwaggerValidatorUtils.java
/*
* GovWay - A customizable API Gateway
* https://govway.org
*
* Copyright (c) 2005-2024 Link.it srl (https://link.it).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3, as published by
* the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openspcoop2.utils.openapi.validator.swagger;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.regex.Pattern;
import com.atlassian.oai.validator.model.Body;
import com.atlassian.oai.validator.report.MessageResolver;
import com.atlassian.oai.validator.report.ValidationReport;
import com.atlassian.oai.validator.schema.SchemaValidator;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.CharMatcher;
import io.swagger.v3.oas.models.media.Schema;
/**
* SwaggerValidatorUtils
*
* @author $Author$
* @version $Rev$, $Date$
*
*/
public class SwaggerValidatorUtils {
public static boolean isBase64SchemaFile(Schema<?> schema) {
return "string".equals(schema.getType()) && "base64".equals(schema.getFormat());
}
public static boolean isBinarySchemaFile(Schema<?> schema) {
return "string".equals(schema.getType()) && "binary".equals(schema.getFormat());
}
// Adattata dalla com.github.fgce...jsonschema
private static final Optional<String> validateBase64String(String input) {
/*
* Regex to accurately remove _at most two_ '=' characters from the end of the
* input.
*/
final Pattern PATTERN = Pattern.compile("==?$");
/*
* Negation of the Base64 alphabet. We try and find one character, if any,
* matching this "negated" character matcher.
*
* FIXME: use .precomputed()?
*/
final CharMatcher NOT_BASE64 = CharMatcher.inRange('a', 'z').or(CharMatcher.inRange('A', 'Z'))
.or(CharMatcher.inRange('0', '9')).or(CharMatcher.anyOf("+/")).negate();
if (input.length() % 4 != 0) {
return Optional.of("err.format.base64.badLength, should be multiple of 4: " + input.length());
}
final int index = NOT_BASE64.indexIn(PATTERN.matcher(input).replaceFirst(""));
if (index == -1)
return Optional.empty();
return Optional.of(
"err.format.base64.illegalChars: character '" + Character.toString(input.charAt(index)) + "' index " + index);
}
public static final ValidationReport validateBase64Body(Body body, MessageResolver messages, boolean request) {
try {
var error = SwaggerValidatorUtils.validateBase64String(body.toString(StandardCharsets.UTF_8));
if (error.isPresent()) {
return ValidationReport.singleton(
messages.create(request ? "validation.request.body.schema": "validation.response.body.schema",
(request ? "[REQUEST] ": "[RESPONSE] ")+
error.get()));
} else {
return ValidationReport.empty();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static final ValidationReport validateJsonFormat(Body body, MessageResolver messages, boolean request) {
try {
body.toJsonNode();
} catch (final IOException e) {
return ValidationReport.singleton(
messages.create(
request ? "validation.request.body.schema.invalidJson" : "validation.response.body.schema.invalidJson",
messages.get(SchemaValidator.INVALID_JSON_KEY, e.getMessage()).getMessage()
)
);
}
return ValidationReport.empty();
}
public static final String getSchemaVersion(JsonNode node) {
if (node == null) {
return null;
}
JsonNode version = node.get("openapi");
if (version != null) {
return version.toString();
}
version = node.get("swagger");
if (version != null) {
return version.toString();
}
version = node.get("swaggerVersion");
if (version != null) {
return version.toString();
}
return null;
}
public static final boolean isSchemaV1(String version) {
return version != null && (version.startsWith("\"1") || version.startsWith("1"));
}
public static final boolean isSchemaV2(String version) {
return version != null && (version.startsWith("\"2") || version.startsWith("2"));
}
public static final boolean isSchemaV3(String version) {
return version != null && (version.startsWith("\"3") || version.startsWith("3"));
}
}