- changed status to open
oneOf and anyOf validations violate additionalProperties constraints due to over application of additionalProperties
I believe I have identified an issue that causes anyOf and oneOf cases to fail due to the application of additonalProperties: false in the schema checks. In the below description I focus on the oneOf case, however, the findings apply the same to anyOf. I am fully aware of the documented limitations of additionalProperties checking with composite models, however, I believe this specific issues falls outside that concern.
OpenAPI Schema – for one of testing:
openapi: 3.0.0
info:
title: Enum Validation
description: >-
version: 1.0.0
servers:
- url: 'http://test.com'
description: stage
paths:
/test:
get:
summary: placeholder summary
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/test'
components:
schemas:
test:
oneOf:
- $ref: '#/components/schemas/typeA'
- $ref: '#/components/schemas/typeB'
typeA:
type: object
properties:
typeAValueA:
type: string
typeB:
type: object
properties:
typeBValueB:
type: number
Test response – we would expect this to pass when evaluated against the above schema:
{
"typeAValueA": "good"
}
Configuration of the swagger validator:
ParseOptions parseOptions = new ParseOptions();
parseOptions.setResolveFully(true);
parseOptions.setResolveCombinators(true);
OpenApiInteractionValidator validator = OpenApiInteractionValidator.createFor(schemaResourcePath).withParseOptions(parseOptions).build();
ValidationReport validationReport = validator.validateResponse(schemaPath, requestMethod, response);
Documentation of the issue:
When the com.atlassian.oai.validator.schema.SchemaValidator converts the yaml to JSON schema at line 145 the resulting jsonSchema.schema.baseNode shown below has additionalProperties: false applied to non JSON object types (shown below). This doesn’t make sense for any type other than a JSON object where properties are defined.
When the validation runs on this JSON schema, we end up with a the com.github.fge.jsonschema.keyword.validator.common.AdditionalPropertiesValidator getting initialized, along with the oneOf validator, with an object without any properties or patternProperties. This would make sense given the schema root is a one of that also has additionalProperties: false, however, the additonalProperties has no relevance at this level in the parsed schema.
The subsequence call to AdditionalPropertiesValidator with the test response (above) causes a validation failure, because, the fields contain ‘typeValueA’ but there aren’t any properties in the additionalProperties validator so typeValueA isn’t removed and thus fails the validation check. I suspect if the conversion from OpenAPI yaml to JSON schema didn’t over apply additionalProperties then we wouldn’t have this issue.
{
"exampleSetFlag": false,
"oneOf": [
{
"type": "object",
"properties": {
"typeAValueA": {
"type": "string",
"exampleSetFlag": false,
"additionalProperties": false
}
},
"exampleSetFlag": false,
"additionalProperties": false
},
{
"type": "object",
"properties": {
"typeBValueB": {
"type": "number",
"exampleSetFlag": false,
"additionalProperties": false
}
},
"exampleSetFlag": false,
"additionalProperties": false
}
],
"components": {
"schemas": {
"test": {
"exampleSetFlag": false,
"oneOf": [
{
"type": "object",
"properties": {
"typeAValueA": {
"type": "string",
"exampleSetFlag": false,
"additionalProperties": false
}
},
"exampleSetFlag": false,
"additionalProperties": false
},
{
"type": "object",
"properties": {
"typeBValueB": {
"type": "number",
"exampleSetFlag": false,
"additionalProperties": false
}
},
"exampleSetFlag": false,
"additionalProperties": false
}
],
"additionalProperties": false
},
"typeA": {
"type": "object",
"properties": {
"typeAValueA": {
"type": "string",
"exampleSetFlag": false,
"additionalProperties": false
}
},
"exampleSetFlag": false,
"additionalProperties": false
},
"typeB": {
"type": "object",
"properties": {
"typeBValueB": {
"type": "number",
"exampleSetFlag": false,
"additionalProperties": false
}
},
"exampleSetFlag": false,
"additionalProperties": false
}
}
},
"$schema": "https://openapis.org/specification/versions/2.0#",
"additionalProperties": false
}
Proposed Solution:
Updating the AdditionalPropertiesInjectionTransformer.java to apply additionalProperties: false only when properties are defined for the current model will ensure additionalProperties is only applied where relevant. This will eliminate the additionalProperties validation failures due to additionalProperties checks being applied to the wrong models when validating.
Comments (8)
-
reporter -
reporter - changed status to resolved
PR submitted to apply additionalProperties only when properties are present. Also corrected 'object' type field assignment for non applicable cases.
-
Was this fixed? I dont see any merge request..Thanks! Facing the same issue.
-
reporter Here is the PR: https://bitbucket.org/atlassian/swagger-request-validator/pull-requests/238/fix-for-issue-336 Sounds like this wont get merged until sometime in August, at the earliest.
-
Thanks for raising the PR Ben. I have returned from leave this week - will take a look at it by end of week.
Cheers.
-
+1 To this. Without this we are having issues with properly validating one ofs and others.
-
Available in 2.19.3
-
This still won’t work if the allOf has properties:
DatiRiferimentoMixed: type: object allOf: - $ref: '#/components/schemas/Dati' - type: object required: - allegati properties: allegati: type: array items: $ref: '#/components/schemas/AllegatoRiferimentoMixed'
[ERROR][REQUEST][POST http://petstore.swagger.io/api/documenti/mixed/send @body] Instance failed to match all required schemas (matched only 0 out of 2) * /allOf/0: Object instance has properties which are not allowed by the schema: ["allegati"] * /allOf/1: Object instance has properties which are not allowed by the schema: ["destinatario","mittente","procedimento"]
The validation of the first allOf element doesn’t pass because of the additionalProperties injected by the trasformer.
- Log in to comment
Implementing fix for this issue.