Skip to content

Commit

Permalink
Fixes vert-x3#1066 enabling additionalProperties params both in query…
Browse files Browse the repository at this point in the history
… and cookie (vert-x3#1067)

Signed-off-by: francesco <[email protected]>
  • Loading branch information
slinkydeveloper authored Nov 19, 2018
1 parent d11935c commit 191e09c
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,21 @@ private void magicParameterExplodedObject(Parameter parameter) {
"" + "not supported for parameter " + parameter.getName());
}
}
if (parameter.getSchema().getAdditionalProperties() instanceof Schema) {
if ("query".equals(parameter.getIn())) {
this.setQueryAdditionalPropertyHandler(
this.resolveInnerSchemaPrimitiveTypeValidator((Schema)parameter.getSchema().getAdditionalProperties(), true),
parameter.getName()
);
} else if ("cookie".equals(parameter.getIn())) {
this.setCookieAdditionalPropertyHandler(
this.resolveInnerSchemaPrimitiveTypeValidator((Schema)parameter.getSchema().getAdditionalProperties(), true),
parameter.getName()
);
} else {
throw new SpecFeatureNotSupportedException("additionalProperties with exploded object fields not supports in path parameter " + parameter.getName());
}
}
}

private void magicParameterExplodedStyleSimpleTypeObject(Parameter parameter) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ public static Map<String, ObjectField> solveObjectParameters(Schema schema) {
} else {
// type object case
Map<String, ObjectField> properties = new HashMap<>();
if (schema.getProperties() == null) return new HashMap<>();
for (Map.Entry<String, ? extends Schema> entry : ((Map<String, Schema>) schema.getProperties()).entrySet()) {
properties.put(entry.getKey(), new OpenApi3Utils.ObjectField(entry.getValue(), entry.getKey(), schema));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.netty.handler.codec.http.QueryStringDecoder;
import io.vertx.core.MultiMap;
import io.vertx.core.http.CaseInsensitiveHeaders;
import io.vertx.ext.web.FileUpload;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.api.RequestParameter;
Expand All @@ -20,7 +21,11 @@ public abstract class BaseValidationHandler implements ValidationHandler {

private Map<String, ParameterValidationRule> pathParamsRules;
private Map<String, ParameterValidationRule> cookieParamsRules;
private ParameterTypeValidator cookieAdditionalPropertiesValidator;
private String cookieAdditionalPropertiesObjectPropertyName;
private Map<String, ParameterValidationRule> queryParamsRules;
private ParameterTypeValidator queryAdditionalPropertiesValidator;
private String queryAdditionalPropertiesObjectPropertyName;
private Map<String, ParameterValidationRule> formParamsRules;
private Map<String, ParameterValidationRule> headerParamsRules;
private ParameterTypeValidator entireBodyValidator;
Expand Down Expand Up @@ -128,7 +133,7 @@ private Map<String, RequestParameter> validateCookieParams(RoutingContext routin
for (ParameterValidationRule rule : cookieParamsRules.values()) {
String name = rule.getName().trim();
if (cookies.containsKey(name)) {
List<String> p = cookies.get(name);
List<String> p = cookies.remove(name);
if (p.size() != 0) {
RequestParameter parsedParam = rule.validateArrayParam(p);
if (parsedParams.containsKey(parsedParam.getName()))
Expand All @@ -148,17 +153,34 @@ private Map<String, RequestParameter> validateCookieParams(RoutingContext routin
ParameterLocation.COOKIE);
}
}
if (cookieAdditionalPropertiesValidator != null) {
for (Map.Entry<String, List<String>> e : cookies.entrySet()) {
try {
Map<String, RequestParameter> r = new HashMap<>();
r.put(e.getKey(), cookieAdditionalPropertiesValidator.isValidCollection(e.getValue()));
RequestParameter parsedParam = new RequestParameterImpl(cookieAdditionalPropertiesObjectPropertyName, r);
if (parsedParams.containsKey(cookieAdditionalPropertiesObjectPropertyName))
parsedParam = parsedParam.merge(parsedParams.get(cookieAdditionalPropertiesObjectPropertyName));
parsedParams.put(parsedParam.getName(), parsedParam);
} catch (ValidationException ex) {
ex.setParameterName(cookieAdditionalPropertiesObjectPropertyName);
e.setValue(e.getValue());
throw ex;
}
}
}
return parsedParams;
}

private Map<String, RequestParameter> validateQueryParams(RoutingContext routingContext) throws ValidationException {
// Validation process validate only params that are registered in the validation -> extra params are allowed
Map<String, RequestParameter> parsedParams = new HashMap<>();
MultiMap queryParams = routingContext.queryParams();
MultiMap queryParams = new CaseInsensitiveHeaders().addAll(routingContext.queryParams());
for (ParameterValidationRule rule : queryParamsRules.values()) {
String name = rule.getName();
if (queryParams.contains(name)) {
List<String> p = queryParams.getAll(name);
queryParams.remove(name);
if (p.size() != 0) {
RequestParameter parsedParam = rule.validateArrayParam(p);
if (parsedParams.containsKey(parsedParam.getName()))
Expand All @@ -176,6 +198,22 @@ private Map<String, RequestParameter> validateQueryParams(RoutingContext routing
throw ValidationException.ValidationExceptionFactory.generateNotFoundValidationException(name,
ParameterLocation.QUERY);
}
if (queryAdditionalPropertiesValidator != null) {
for (Map.Entry<String, String> e : queryParams.entries()) {
try {
Map<String, RequestParameter> r = new HashMap<>();
r.put(e.getKey(), queryAdditionalPropertiesValidator.isValid(e.getValue()));
RequestParameter parsedParam = new RequestParameterImpl(queryAdditionalPropertiesObjectPropertyName, r);
if (parsedParams.containsKey(queryAdditionalPropertiesObjectPropertyName))
parsedParam = parsedParam.merge(parsedParams.get(queryAdditionalPropertiesObjectPropertyName));
parsedParams.put(parsedParam.getName(), parsedParam);
} catch (ValidationException ex) {
ex.setParameterName(queryAdditionalPropertiesObjectPropertyName);
e.setValue(e.getValue());
throw ex;
}
}
}
return parsedParams;
}

Expand Down Expand Up @@ -323,4 +361,14 @@ protected void setEntireBodyValidator(ParameterTypeValidator entireBodyValidator
this.entireBodyValidator = entireBodyValidator;
bodyRequired = true;
}

protected void setCookieAdditionalPropertyHandler(ParameterTypeValidator validator, String objectParameterName) {
this.cookieAdditionalPropertiesValidator = validator;
this.cookieAdditionalPropertiesObjectPropertyName = objectParameterName;
}
protected void setQueryAdditionalPropertyHandler(ParameterTypeValidator validator, String objectParameterName) {
this.queryAdditionalPropertiesValidator = validator;
this.queryAdditionalPropertiesObjectPropertyName = objectParameterName;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.vertx.ext.web.api.contract.openapi3;

import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.QueryStringEncoder;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.parser.OpenAPIV3Parser;
Expand Down Expand Up @@ -607,4 +609,88 @@ public void testJsonBodyFailureErrorMessage() throws Exception {
new JsonObject().put("field", "body").toBuffer());
}

@Test
public void testQueryExpandedObjectTestOnlyAdditionalProperties() throws Exception {
Operation op = testSpec.getPaths().get("/queryTests/objectTests/onlyAdditionalProperties").getGet();
OpenAPI3RequestValidationHandler validationHandler = new OpenAPI3RequestValidationHandlerImpl(op, op.getParameters(), testSpec);
loadHandlers("/queryTests/objectTests/onlyAdditionalProperties",
HttpMethod.GET,
false,
validationHandler,
(routingContext) -> {
RequestParameters params = routingContext.get("parsedParameters");
assertEquals("hello", params.queryParameter("wellKnownParam").getString());
RequestParameter param = params.queryParameter("params");
assertFalse(param.getObjectKeys().contains("wellKnownParam"));
int res = param.getObjectValue("param2").getInteger() + param.getObjectValue("param1").getInteger();
routingContext.response().setStatusCode(200).setStatusMessage("Result: " + res).end();
}
);

testRequest(HttpMethod.GET, "/queryTests/objectTests/onlyAdditionalProperties?param1=2&param2=4&wellKnownParam=hello", 200, "Result: 6");
}

@Test
public void testQueryExpandedObjectTestOnlyAdditionalPropertiesFailure() throws Exception {
Operation op = testSpec.getPaths().get("/queryTests/objectTests/onlyAdditionalProperties").getGet();
OpenAPI3RequestValidationHandler validationHandler = new OpenAPI3RequestValidationHandlerImpl(op, op.getParameters(), testSpec);
loadHandlers("/queryTests/objectTests/onlyAdditionalProperties",
HttpMethod.GET,
true,
validationHandler,
(routingContext) -> {
routingContext.response().setStatusCode(200).setStatusMessage("OK").end();
}
);

testRequest(HttpMethod.GET, "/queryTests/objectTests/onlyAdditionalProperties?param1=2&param2=a&wellKnownParam=a", 400, errorMessage(ValidationException.ErrorType.NO_MATCH));
}

@Test
public void testCookieExpandedObjectTestOnlyAdditionalProperties() throws Exception {
Operation op = testSpec.getPaths().get("/cookieTests/objectTests/onlyAdditionalProperties").getGet();
OpenAPI3RequestValidationHandler validationHandler = new OpenAPI3RequestValidationHandlerImpl(op, op.getParameters(), testSpec);
loadHandlers("/cookieTests/objectTests/onlyAdditionalProperties",
HttpMethod.GET,
false,
validationHandler,
(routingContext) -> {
RequestParameters params = routingContext.get("parsedParameters");
assertEquals("hello", params.cookieParameter("wellKnownParam").toString());
RequestParameter param = params.cookieParameter("params");
assertFalse(param.getObjectKeys().contains("wellKnownParam"));
int res = param.getObjectValue("param2").getInteger() + param.getObjectValue("param1").getInteger();
routingContext.response().setStatusCode(200).setStatusMessage(Integer.toString(res)).end();
}
);

QueryStringEncoder params = new QueryStringEncoder("/");
params.addParam("param1", Integer.toString(5));
params.addParam("param2", Integer.toString(1));
params.addParam("wellKnownParam", "hello");

testRequestWithCookies(HttpMethod.GET, "/cookieTests/objectTests/onlyAdditionalProperties", params.toUri().getRawQuery(), 200, "6");
}

@Test
public void testCookieExpandedObjectTestOnlyAdditionalPropertiesFailure() throws Exception {
Operation op = testSpec.getPaths().get("/cookieTests/objectTests/onlyAdditionalProperties").getGet();
OpenAPI3RequestValidationHandler validationHandler = new OpenAPI3RequestValidationHandlerImpl(op, op.getParameters(), testSpec);
loadHandlers("/cookieTests/objectTests/onlyAdditionalProperties",
HttpMethod.GET,
true,
validationHandler,
(routingContext) -> {
routingContext.response().setStatusCode(200).setStatusMessage("OK").end();
}
);

QueryStringEncoder params = new QueryStringEncoder("/");
params.addParam("param1", Integer.toString(5));
params.addParam("param2", "a");
params.addParam("wellKnownParam", "hello");

testRequestWithCookies(HttpMethod.GET, "/cookieTests/objectTests/onlyAdditionalProperties", params.toUri().getRawQuery(), 400, errorMessage(ValidationException.ErrorType.NO_MATCH));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,25 @@ paths:
responses:
default:
description: ok
/queryTests/objectTests/onlyAdditionalProperties:
get:
operationId: objectTestOnlyAdditionalProperties
parameters:
- name: params
in: query
schema:
type: object
additionalProperties:
type: integer
style: form
explode: true
- name: wellKnownParam
in: query
schema:
type: string
responses:
default:
description: ok
/queryTests/defaultString:
get:
operationId: testDefaultString
Expand Down Expand Up @@ -337,6 +356,25 @@ paths:
responses:
default:
description: ok
/cookieTests/objectTests/onlyAdditionalProperties:
get:
operationId: cookieObjectTestOnlyAdditionalProperties
parameters:
- name: params
in: cookie
schema:
type: object
additionalProperties:
type: integer
style: form
explode: true
- name: wellKnownParam
in: cookie
schema:
type: string
responses:
default:
description: ok
/multipart/complex:
post:
operationId: complexMultipartRequest
Expand Down

0 comments on commit 191e09c

Please sign in to comment.