OpenAPITools / OpenAPITools/openapi-generator
[BUG] [Pistache] Validation is incomplete on model structs which have a child model struct
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
Bug Report Checklist
- Have you provided a full/minimal spec to reproduce the issue?
- Have you validated the input using an OpenAPI validator (example)?
- Have you tested with the latest master to confirm the issue still exists?
- Have you searched for related issues/PRs?
- What's the actual output vs expected output?
- [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
When an object contains another object, the generated validation method doesn't call the generated validation method of the child object.
openapi-generator version
Release 7.0.1
OpenAPI declaration file content or url
Extract of YAML description of the API :
card_desc:
type: object
properties:
vip_level:
type: integer
minimum: 0
comments:
description: Additionnal comments
type: string
maxLength: 100
required:
- vip_level
card:
type: object
properties:
id:
description: Unique id = RFID tag id
type: string
minLength: 1
maxLength: 36
desc:
description: Description
$ref: "#/components/schemas/card_desc"
required:
- id
- desc
Generation Details
Generated code for card_desc:
bool Card_desc::validate(std::stringstream& msg, const std::string& pathPrefix) const
{
bool success = true;
const std::string _pathPrefix = pathPrefix.empty() ? "Card_desc" : pathPrefix;
/* vip_level */ {
const int32_t& value = vip_level;
const std::string currentValuePath = _pathPrefix + ".vipLevel";
if (value < 0)
{
success = false;
msg << currentValuePath << ": must be greater than or equal to 0;";
}
}
if (comments.has_value())
{
const std::string& value = comments.value();
const std::string currentValuePath = _pathPrefix + ".comments";
if (value.length() > 100)
{
success = false;
msg << currentValuePath << ": must be at most 100 characters long;";
}
}
return success;
}
=> Ok, all fields are checked
Generated code for card:
bool Card::validate(std::stringstream& msg, const std::string& pathPrefix) const
{
bool success = true;
const std::string _pathPrefix = pathPrefix.empty() ? "Card" : pathPrefix;
/* id */ {
const std::string& value = id;
const std::string currentValuePath = _pathPrefix + ".id";
if (value.length() < 1)
{
success = false;
msg << currentValuePath << ": must be at least 1 characters long;";
}
if (value.length() > 36)
{
success = false;
msg << currentValuePath << ": must be at most 36 characters long;";
}
}
return success;
}
=> Ko, the desc member is not validated!
Suggest a fix
Here is a suggestion which fixes the issue :
diff --git a/modules/openapi-generator/src/main/resources/cpp-pistache-server/model-struct-source.mustache b/modules/openapi-generator/src/main/resources/cpp-pistache-server/model-struct-source.mustache
index 4d7dbfe0a90..666d4599d3f 100644
--- a/modules/openapi-generator/src/main/resources/cpp-pistache-server/model-struct-source.mustache
+++ b/modules/openapi-generator/src/main/resources/cpp-pistache-server/model-struct-source.mustache
@@ -56,18 +56,34 @@ bool {{classname}}::validate(std::stringstream& msg, const std::string& pathPref
const std::string currentValuePath = _pathPrefix + ".{{nameInCamelCase}}";
{{> model-validation-body }}
}
- {{/isArray}}{{^isArray}}{{#hasValidation}} {{! Only generate validation if necessary }}
+ {{/isArray}}
+ {{^isArray}}
+ {{#hasValidation}} {{! Only generate validation if necessary }}
{{^required}}if ({{name}}.has_value()){{/required}}
{{#required}}/* {{name}} */ {{/required}}{
const {{{dataType}}}& value = {{name}}{{^required}}.value(){{/required}};
const std::string currentValuePath = _pathPrefix + ".{{nameInCamelCase}}";
{{> model-validation-body }}
}
- {{/hasValidation}}{{/isArray}}{{/vars}}{{/isEnum}}{{#vendorExtensions.x-is-string-enum-container}}{{#anyOf}}{{#-first}}
+ {{/hasValidation}}
+ {{#isModel}}
+ {{^required}}if ({{name}}.has_value()){{/required}}
+ {{#required}}/* {{name}} */ {{/required}}{
+ const {{{dataType}}}& value = {{name}}{{^required}}.value(){{/required}};
+ const std::string currentValuePath = _pathPrefix + ".{{nameInCamelCase}}";
+ if (!value.validate(msg, currentValuePath))
+ {
+ success = false;
+ }
+ }
+ {{/isModel}}
+ {{/isArray}}{{/vars}}
+ {{/isEnum}}{{#vendorExtensions.x-is-string-enum-container}}{{#anyOf}}{{#-first}}
if (!m_value.validate(msg))
{
success = false;
}{{/-first}}{{/anyOf}}{{/vendorExtensions.x-is-string-enum-container}}
+
return success;
}
Which leads to the following code for card :
bool Card::validate(std::stringstream& msg, const std::string& pathPrefix) const
{
bool success = true;
const std::string _pathPrefix = pathPrefix.empty() ? "Card" : pathPrefix;
/* id */ {
const std::string& value = id;
const std::string currentValuePath = _pathPrefix + ".id";
if (value.length() < 1)
{
success = false;
msg << currentValuePath << ": must be at least 1 characters long;";
}
if (value.length() > 36)
{
success = false;
msg << currentValuePath << ": must be at most 36 characters long;";
}
}
/* desc */ {
const org::openapitools::server::model::Card_desc& value = desc;
const std::string currentValuePath = _pathPrefix + ".desc";
if (!value.validate(msg, currentValuePath))
{
success = false;
}
}
return success;
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with modules/openapi-generator/src/main/resources/cpp-pistache-server/model-struct-source.mustache and generate the C++ Pistache models from the supplied YAML declaration. Check that a parent model's validate method invokes validation for its child model, including the child path prefix; done means nested constraints such as vip_level and comments are reported.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100