[BUG][Java][Spring] Incorrect generated code when use application/x-www-form-urlencoded and oneOf
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
I am designing an API following the oauth2 protocol. In it, the encoding to use is application/x-wwww-form-urlencoded
.
Using that encoding algorithm and oneOf feature is not generating the code correctly.
openapi-generator version
6.4.0
OpenAPI declaration file content or url
Minimal sample
openapi: '3.0.0'
info:
title: AuthServer OAuth2
description: This API contains the public paths for the Auth Server
version: 0.0.6
security:
- basicOauthClientAuth: [ ]
paths:
/oauth2/token:
post:
description: Generate OAuth2/OIDC tokens
operationId: token
security:
- basicOauthClientAuth: [ ]
tags:
- OAuth2
requestBody:
description: OAuth2 RO basics grant types
required: true
content:
application/x-www-form-urlencoded:
schema:
oneOf:
- $ref: '#/components/schemas/PasswordGrantTypeForm'
- $ref: '#/components/schemas/AnonymousGrantTypeForm'
discriminator:
propertyName: grant_type
mapping:
password: '#/components/schemas/PasswordGrantTypeForm'
anonymous: '#/components/schemas/AnonymousGrantTypeForm'
responses:
'200':
description: OAuth2/OIDC standard response
content:
application/json:
schema:
$ref: '#/components/schemas/AccessTokenResponse'
components:
securitySchemes:
basicOauthClientAuth:
description: Base64 of the clientId and clientSecret, the format is clientId:clientSecret
type: http
scheme: basic
schemas:
GrantType:
type: object
required:
- grant_type
properties:
grant_type:
type: string
description: Grant type to obtain the token.
example: "password"
PasswordGrantTypeForm:
title: PasswordGrantTypeForm
description: Request body for access token with password grant type for ecommerce customers
allOf:
- $ref: '#/components/schemas/GrantType'
- type: object
properties:
scope:
description: List of scope for the token separated by an space
type: string
example: "session openid"
username:
type: string
description: Account id of the user
example: "4b4d91f2-17b9-46af-b5de-008956ee6f65"
password:
type: string
description: Password of the user
example: "dummyP4ssw0rd"
required:
- username
- password
AnonymousGrantTypeForm:
title: AnonymousGrantTypeForm
description: Request body for access token with anonymous grant type for ecommerce customers
allOf:
- $ref: '#/components/schemas/GrantType'
- type: object
properties:
scope:
description: List of scope for the token separated by an space
type: string
example: "session openid"
anonymous:parameters:account_id:
type: string
description: Account id of the user
example: "4b4d91f2-17b9-46af-b5de-008956ee6f65"
required:
- anonymous:parameters:account_id
AccessTokenResponse:
type: object
required:
- token_type
properties:
token_type:
type: string
id_token:
type: string
description: If the request includes openid scope this field contains a JWT token
Generation Details
java -jar openapi-generator-cli.jar generate -i spec.yml -g spring -o out --global-property skipFormModel=false
Steps to reproduce
- Generate classes
- See OauthApi.java.
Output
- It has been created endpoint with all parameters
- Parameters username and password are created as required --> incorrect
- Discriminator (grandType) should be required --> incorrect
/**
* POST /oauth2/token
* Generate OAuth2/OIDC tokens
*
* @param username Account id of the user (required)
* @param password Password of the user (required)
* @param grantType Grant type to obtain the token. (optional)
* @param scope List of scope for the token separated by an space (optional)
* @param anonymousColonParametersColonAccountId Account id of the user (optional)
* @return OAuth2/OIDC standard response (status code 200)
*/
@Operation(
operationId = "token",
description = "Generate OAuth2/OIDC tokens",
tags = { "OAuth2" },
responses = {
@ApiResponse(responseCode = "200", description = "OAuth2/OIDC standard response", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = AccessTokenResponse.class))
})
},
security = {
@SecurityRequirement(name = "basicOauthClientAuth")
}
)
@RequestMapping(
method = RequestMethod.POST,
value = "/oauth2/token",
produces = { "application/json" },
consumes = { "application/x-www-form-urlencoded" }
)
default ResponseEntity<AccessTokenResponse> token(
@Parameter(name = "username", description = "Account id of the user", required = true) @Valid @RequestParam(value = "username", required = true) String username,
@Parameter(name = "password", description = "Password of the user", required = true) @Valid @RequestParam(value = "password", required = true) String password,
@Parameter(name = "grant_type", description = "Grant type to obtain the token.") @Valid @RequestParam(value = "grant_type", required = false) String grantType,
@Parameter(name = "scope", description = "List of scope for the token separated by an space") @Valid @RequestParam(value = "scope", required = false) String scope,
@Parameter(name = "anonymous:parameters:account_id", description = "Account id of the user") @Valid @RequestParam(value = "anonymous:parameters:account_id", required = false) String anonymousColonParametersColonAccountId
)
Expected
I was expecting the input parameters to be like when the encoding is application/json
.
/**
* POST /oauth2/token
* Generate OAuth2/OIDC tokens
*
* @param tokenRequest OAuth2 RO basics grant types (required)
* @return OAuth2/OIDC standard response (status code 200)
*/
@Operation(
operationId = "token",
description = "Generate OAuth2/OIDC tokens",
tags = { "OAuth2" },
responses = {
@ApiResponse(responseCode = "200", description = "OAuth2/OIDC standard response", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = AccessTokenResponse.class))
})
},
security = {
@SecurityRequirement(name = "basicOauthClientAuth")
}
)
@RequestMapping(
method = RequestMethod.POST,
value = "/oauth2/token",
produces = { "application/json" },
consumes = { "application/x-www-form-urlencoded" }
)
default ResponseEntity<AccessTokenResponse> token(
@Parameter(name = "TokenRequest", description = "OAuth2 RO basics grant types", required = true) @Valid @RequestBody TokenRequest tokenRequest
)