From 50a5d05156527a3a45219b21fbf38db02e3dc925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20NO=C3=8BL?= Date: Fri, 27 Mar 2020 15:34:50 +0100 Subject: [PATCH] feat: add more accuracy on list checking for minimum size. --- .../parser/validation/ValidatorBase.java | 23 +++++++++++-------- .../validation/v3/OpenApiValidator.java | 6 ++--- .../validation/v3/OperationValidator.java | 6 ++--- .../parser/validation/v3/PathValidator.java | 4 ++-- .../parser/validation/v3/SchemaValidator.java | 10 ++++---- .../v3/ServerVariableValidator.java | 2 +- 6 files changed, 28 insertions(+), 23 deletions(-) diff --git a/openapi-parser/src/main/java/org/openapi4j/parser/validation/ValidatorBase.java b/openapi-parser/src/main/java/org/openapi4j/parser/validation/ValidatorBase.java index bdd45de9..efc83d5f 100644 --- a/openapi-parser/src/main/java/org/openapi4j/parser/validation/ValidatorBase.java +++ b/openapi-parser/src/main/java/org/openapi4j/parser/validation/ValidatorBase.java @@ -22,15 +22,16 @@ * @param The Open API sub-object. */ public abstract class ValidatorBase implements Validator { - private static final ValidationResult MALFORMED_SPEC = new ValidationResult(ERROR, 100, "Malformed spec around '%s'"); - private static final ValidationResult DUPLICATED_VALUES = new ValidationResult(ERROR, 101, "Duplicated values in '%s'"); - private static final ValidationResult INVALID_PATTERN = new ValidationResult(ERROR, 102, "Pattern '%s' is not valid"); - private static final ValidationResult POSITIVE_STRICT_VALUE = new ValidationResult(ERROR, 103, "Value '%s' must be strictly positive"); - private static final ValidationResult POSITIVE_VALUE = new ValidationResult(ERROR, 104, "Value '%s' must be positive or 0"); - private static final ValidationResult MISSING_REQUIRED_FIELD = new ValidationResult(ERROR, 105, "Required field is missing '%s'"); - private static final ValidationResult PATTERN_NOT_MATCHED = new ValidationResult(ERROR, 106, "String value '%s' does not match required pattern '%s'"); - private static final ValidationResult INVALID_KEY = new ValidationResult(ERROR, 107, "Invalid key '%s' in map '%s'"); - private static final ValidationResult INVALID_URI = new ValidationResult(ERROR, 144, "Invalid (or not absolute) URI '%s'"); + private static final ValidationResult MALFORMED_SPEC = new ValidationResult(ERROR, 100, "Malformed spec around '%s'."); + private static final ValidationResult DUPLICATED_VALUES = new ValidationResult(ERROR, 101, "Duplicated values in '%s'."); + private static final ValidationResult MIN_SIZE_LIST = new ValidationResult(ERROR, 146, "List should have at least '%s' element(s) in '%s'."); + private static final ValidationResult INVALID_PATTERN = new ValidationResult(ERROR, 102, "Pattern '%s' is not valid."); + private static final ValidationResult POSITIVE_STRICT_VALUE = new ValidationResult(ERROR, 103, "Value '%s' must be strictly positive."); + private static final ValidationResult POSITIVE_VALUE = new ValidationResult(ERROR, 104, "Value '%s' must be positive or 0."); + private static final ValidationResult MISSING_REQUIRED_FIELD = new ValidationResult(ERROR, 105, "Required field is missing '%s'."); + private static final ValidationResult PATTERN_NOT_MATCHED = new ValidationResult(ERROR, 106, "String value '%s' does not match required pattern '%s'."); + private static final ValidationResult INVALID_KEY = new ValidationResult(ERROR, 107, "Invalid key '%s' in map '%s'."); + private static final ValidationResult INVALID_URI = new ValidationResult(ERROR, 144, "Invalid (or not absolute) URI '%s'."); protected static final Pattern EMAIL_REGEX = Pattern.compile("(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9]" + "(?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:" + @@ -73,6 +74,7 @@ protected void validateList(final ValidationContext context, final Collection value, final ValidationResults results, final boolean required, + final int minSize, final ValidationResults.CrumbInfo crumbInfo, final Validator validator) { @@ -82,6 +84,9 @@ protected void validateList(final ValidationContext context, if (set.size() != value.size()) { results.add(crumbInfo, DUPLICATED_VALUES, crumbInfo.crumb()); } + if (value.size() < minSize) { + results.add(crumbInfo, MIN_SIZE_LIST, minSize, crumbInfo.crumb()); + } if (validator != null) { for (V element : value) { diff --git a/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/OpenApiValidator.java b/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/OpenApiValidator.java index 6e1a99cd..901afb6b 100644 --- a/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/OpenApiValidator.java +++ b/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/OpenApiValidator.java @@ -41,11 +41,11 @@ public static Validator instance() { public void validate(ValidationContext context, OpenApi3 root, OpenApi3 api, ValidationResults results) { validateString(api.getOpenapi(), results, true, PATTERN_OAI3, CRUMB_OPENAPI); validateField(context, api, api.getInfo(), results, true, CRUMB_INFO, InfoValidator.instance()); - validateList(context, api, api.getServers(), results, false, CRUMB_SERVERS, ServerValidator.instance()); + validateList(context, api, api.getServers(), results, false, 0, CRUMB_SERVERS, ServerValidator.instance()); validateMap(context, api, api.getPaths(), results, true, CRUMB_PATHS, Regexes.PATH_REGEX, PathValidator.instance()); validateField(context, api, api.getComponents(), results, false, CRUMB_COMPONENTS, ComponentsValidator.instance()); - validateList(context, api, api.getSecurityRequirements(), results, false, CRUMB_SECURITY, SecurityRequirementValidator.instance()); - validateList(context, api, api.getTags(), results, false, CRUMB_TAGS, TagValidator.instance()); + validateList(context, api, api.getSecurityRequirements(), results, false, 0, CRUMB_SECURITY, SecurityRequirementValidator.instance()); + validateList(context, api, api.getTags(), results, false, 0, CRUMB_TAGS, TagValidator.instance()); validateField(context, api, api.getExternalDocs(), results, false, CRUMB_EXTERNALDOCS, ExternalDocsValidator.instance()); validateMap(context, api, api.getExtensions(), results, false, CRUMB_EXTENSIONS, Regexes.EXT_REGEX, null); diff --git a/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/OperationValidator.java b/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/OperationValidator.java index 374b01d3..f50a58f3 100644 --- a/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/OperationValidator.java +++ b/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/OperationValidator.java @@ -25,12 +25,12 @@ public void validate(ValidationContext context, OpenApi3 api, Operatio // summary, description, deprecated, tags validateField(context, api, operation.getExternalDocs(), results, false, CRUMB_EXTERNALDOCS, ExternalDocsValidator.instance()); validateString(operation.getOperationId(), results, false, CRUMB_OPERATIONID); - validateList(context, api, operation.getParameters(), results, false, CRUMB_PARAMETERS, ParameterValidator.instance()); + validateList(context, api, operation.getParameters(), results, false, 0, CRUMB_PARAMETERS, ParameterValidator.instance()); validateField(context, api, operation.getRequestBody(), results, false, CRUMB_REQUESTBODY, RequestBodyValidator.instance()); validateMap(context, api, operation.getResponses(), results, true, CRUMB_RESPONSES, Regexes.RESPONSE_REGEX, ResponseValidator.instance()); validateMap(context, api, operation.getCallbacks(), results, false, CRUMB_CALLBACKS, Regexes.NOEXT_REGEX, CallbackValidator.instance()); - validateList(context, api, operation.getSecurityRequirements(), results, false, CRUMB_SECURITY, SecurityRequirementValidator.instance()); - validateList(context, api, operation.getServers(), results, false, CRUMB_SERVERS, ServerValidator.instance()); + validateList(context, api, operation.getSecurityRequirements(), results, false, 0, CRUMB_SECURITY, SecurityRequirementValidator.instance()); + validateList(context, api, operation.getServers(), results, false, 0, CRUMB_SERVERS, ServerValidator.instance()); validateMap(context, api, operation.getExtensions(), results, false, CRUMB_EXTENSIONS, Regexes.EXT_REGEX, null); validateCallbacks(api, operation, results); diff --git a/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/PathValidator.java b/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/PathValidator.java index 94c2642c..9c1d6284 100644 --- a/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/PathValidator.java +++ b/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/PathValidator.java @@ -27,8 +27,8 @@ public void validate(ValidationContext context, OpenApi3 api, Path pat // description, summary validateMap(context, api, path.getExtensions(), results, false, CRUMB_EXTENSIONS, Regexes.EXT_REGEX, null); validateMap(context, api, path.getOperations(), results, false, null, Regexes.METHOD_REGEX, OperationValidator.instance()); - validateList(context, api, path.getParameters(), results, false, CRUMB_PARAMETERS, ParameterValidator.instance()); - validateList(context, api, path.getServers(), results, false, CRUMB_SERVERS, ServerValidator.instance()); + validateList(context, api, path.getParameters(), results, false, 0, CRUMB_PARAMETERS, ParameterValidator.instance()); + validateList(context, api, path.getServers(), results, false, 0, CRUMB_SERVERS, ServerValidator.instance()); } } } diff --git a/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/SchemaValidator.java b/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/SchemaValidator.java index 108c6f46..5ec42514 100644 --- a/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/SchemaValidator.java +++ b/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/SchemaValidator.java @@ -68,7 +68,7 @@ public void validate(ValidationContext context, OpenApi3 api, Schema s validateField(context, api, schema.getDiscriminator(), results, false, CRUMB_DISCRIMINATOR, DiscriminatorValidator.instance()); checkDiscriminator(api, schema, results); validateDefaultType(schema.getDefault(), schema.getType(), results); - validateList(context, api, schema.getEnums(), results, false, CRUMB_ENUM, null); + validateList(context, api, schema.getEnums(), results, false, 1, CRUMB_ENUM, null); validateMap(context, api, schema.getExtensions(), results, false, CRUMB_EXTENSIONS, Regexes.EXT_REGEX, null); validateField(context, api, schema.getExternalDocs(), results, false, CRUMB_EXTERNALDOCS, ExternalDocsValidator.instance()); validateFormat(schema.getFormat(), schema.getType(), results); @@ -87,10 +87,10 @@ public void validate(ValidationContext context, OpenApi3 api, Schema s } validatePattern(schema.getPattern(), results, false, CRUMB_PATTERN); validateMap(context, api, schema.getProperties(), results, false, CRUMB_PROPERTIES, null, this); - validateList(context, api, schema.getRequiredFields(), results, false, CRUMB_REQUIRED, null); - validateList(context, api, schema.getAllOfSchemas(), results, false, CRUMB_ALLOF, this); - validateList(context, api, schema.getAnyOfSchemas(), results, false, CRUMB_ANYOF, this); - validateList(context, api, schema.getOneOfSchemas(), results, false, CRUMB_ONEOF, this); + validateList(context, api, schema.getRequiredFields(), results, false, 1, CRUMB_REQUIRED, null); + validateList(context, api, schema.getAllOfSchemas(), results, false, 1, CRUMB_ALLOF, this); + validateList(context, api, schema.getAnyOfSchemas(), results, false, 1, CRUMB_ANYOF, this); + validateList(context, api, schema.getOneOfSchemas(), results, false, 1, CRUMB_ONEOF, this); checkReadWrite(schema, results); validateString(schema.getType(), results, false, TYPE_REGEX, CRUMB_TYPE); validateField(context, api, schema.getXml(), results, false, CRUMB_XML, XmlValidator.instance()); diff --git a/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/ServerVariableValidator.java b/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/ServerVariableValidator.java index aea68e06..908d38e3 100644 --- a/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/ServerVariableValidator.java +++ b/openapi-parser/src/main/java/org/openapi4j/parser/validation/v3/ServerVariableValidator.java @@ -20,7 +20,7 @@ public static Validator instance() { @Override public void validate(ValidationContext context, OpenApi3 api, final ServerVariable variable, final ValidationResults results) { - validateList(context, api, variable.getEnums(), results, false, CRUMB_ENUM, null); + validateList(context, api, variable.getEnums(), results, false, 1, CRUMB_ENUM, null); validateString(variable.getDefault(), results, true, CRUMB_DEFAULT); validateString(variable.getDescription(), results, false, CRUMB_DESCRIPTION); }