diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 8c0ba4b4284..624729f3cde 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -6943,6 +6943,8 @@ public class DefaultCodegen implements CodegenConfig { // https://github.com/OpenAPITools/openapi-generator/issues/10415 addProperties(properties, allRequired, schema, new HashSet<>()); + boolean isOneOfOrAnyOf = ModelUtils.isOneOf(schema) || ModelUtils.isAnyOf(schema); + if (!properties.isEmpty()) { for (Map.Entry entry : properties.entrySet()) { CodegenParameter codegenParameter; @@ -6952,8 +6954,12 @@ public class DefaultCodegen implements CodegenConfig { Schema propertySchema = entry.getValue(); codegenParameter = fromFormProperty(propertyName, propertySchema, imports); - // Set 'required' flag defined in the schema element - if (!codegenParameter.required && schema.getRequired() != null) { + if (isOneOfOrAnyOf) { + // for oneOf/anyOf, mark all the properties collected from the sub-schemas as optional + // so that users can choose which property to include in the form parameters + codegenParameter.required = false; + } else if (!codegenParameter.required && schema.getRequired() != null) { + // Set 'required' flag defined in the schema element codegenParameter.required = schema.getRequired().contains(entry.getKey()); } else if (!codegenParameter.required) { // Set 'required' flag for properties declared inside the allOf diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/swift5/Swift5ClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/swift5/Swift5ClientCodegenTest.java index a9406e0e159..52e07fa5f17 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/swift5/Swift5ClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/swift5/Swift5ClientCodegenTest.java @@ -292,4 +292,32 @@ public class Swift5ClientCodegenTest { } } + @Test(description = "optional form parameters when using oneOf schema", enabled = true) + public void oneOfFormParameterTest() { + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_15511.yaml"); + final DefaultCodegen codegen = new Swift5ClientCodegen(); + codegen.setOpenAPI(openAPI); + codegen.processOpts(); + final String path = "/as/token.oauth2"; + final Operation p = openAPI.getPaths().get(path).getPost(); + final CodegenOperation op = codegen.fromOperation(path, "post", p, null); + + Assert.assertEquals(op.formParams.size(), 6); + + Assert.assertEquals(op.formParams.get(0).baseName, "client_id"); + Assert.assertEquals(op.formParams.get(1).baseName, "grant_type"); + Assert.assertEquals(op.formParams.get(2).baseName, "password"); + Assert.assertEquals(op.formParams.get(3).baseName, "scope"); + Assert.assertEquals(op.formParams.get(4).baseName, "username"); + Assert.assertEquals(op.formParams.get(5).baseName, "refresh_token"); + + Assert.assertEquals(op.formParams.get(0).required, false); + Assert.assertEquals(op.formParams.get(1).required, false); + Assert.assertEquals(op.formParams.get(2).required, false); + Assert.assertEquals(op.formParams.get(3).required, false); + Assert.assertEquals(op.formParams.get(4).required, false); + Assert.assertEquals(op.formParams.get(5).required, false); + + } + } diff --git a/modules/openapi-generator/src/test/resources/3_0/issue_15511.yaml b/modules/openapi-generator/src/test/resources/3_0/issue_15511.yaml new file mode 100644 index 00000000000..51280fd9306 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/issue_15511.yaml @@ -0,0 +1,129 @@ + +openapi: 3.0.3 +info: + title: Auth Server Client API + description: |- + foobarbaz + version: 1.0.0 +tags: + - name: auth + description: Auth Server Client APIs for obtaining, refreshing and revoking a token +paths: + /as/token.oauth2: + post: + tags: + - auth + summary: Obtains a new token from Auth server + requestBody: + content: + application/x-www-form-urlencoded; charset=utf-8: + schema: + oneOf: + - $ref: '#/components/schemas/LoginRequestModel' + - $ref: '#/components/schemas/TokenRefreshRequestModel' + required: true + responses: + '200': + description: Successful operation + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/LoginResponseModel' + - $ref: '#/components/schemas/TokenRefreshResponseModel' + default: + description: An error occured + content: + application/json: + schema: + $ref: '#/components/schemas/AuthResponseError' +components: + schemas: + LoginResponseModel: + type: object + properties: + expires_in: + type: integer + format: int32 + access_token: + type: string + refresh_token: + type: string + token_type: + type: string + required: + [expires_in, access_token, refresh_token] + TokenRefreshResponseModel: + type: object + description: Be aware, that we may either receive a new refresh token in the response or not. In case where we do not receive a new refresh token we must use the refresh token from the old token for subsequent token refreshs. + properties: + expires_in: + type: integer + format: int32 + access_token: + type: string + refresh_token: + type: string + token_type: + type: string + required: + [expires_in, access_token] + LoginRequestModel: + type: object + properties: + client_id: + type: string + grant_type: + type: string + enum: ["refresh_token", "password"] + password: + type: string + scope: + type: string + username: + type: string + required: + [client_id, grant_type, password, scope, username] + TokenRefreshRequestModel: + type: object + properties: + grant_type: + type: string + enum: ["refresh_token", "password"] + refresh_token: + type: string + required: + [grant_type, refresh_token] + AuthResponseError: + type: object + properties: + error_description: + type: string + error: + type: string + enum: ["invalid_request", "invalid_client", "invalid_grant", "invalid_scope", "unauthorized_client", "unsupported_grant_type"] + x-enum-descriptions: + - 'Request is missing a parameter or contains an unsupported parameter of repeats parameters.' + - 'Client authentication fails due to an invalid client id or secret.' + - 'Authorization code or password is invalid or expired.' + - 'Invalid scope for the given access token.' + - 'Client is not authorized for requested grant type.' + - 'Given grant type is unsupported.' + x-enum-varnames: + - INVALID_REQUEST + - INVALID_CLIENT + - INVALID_GRANT + - INVALID_SCOPE + - UNAUTHORIZED_CLIENT + - UNSUPPORTED_GRANT_TYPE + errors: + type: array + items: + $ref: "#/components/schemas/AuthErrorDescription" + required: + [error_description, error] + AuthErrorDescription: + type: object + properties: + description: + type: string