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 bf4073047ea6..803716d03f79 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 @@ -22,7 +22,6 @@ import com.github.benmanes.caffeine.cache.Ticker; import com.google.common.base.CaseFormat; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; import com.samskivert.mustache.Mustache; import com.samskivert.mustache.Mustache.Compiler; import com.samskivert.mustache.Mustache.Lambda; @@ -4447,26 +4446,17 @@ public List fromSecurity(Map securitySc List codegenSecurities = new ArrayList(securitySchemeMap.size()); for (String key : securitySchemeMap.keySet()) { final SecurityScheme securityScheme = securitySchemeMap.get(key); - - CodegenSecurity cs = CodegenModelFactory.newInstance(CodegenModelType.SECURITY); - cs.name = key; - cs.type = securityScheme.getType().toString(); - cs.isCode = cs.isPassword = cs.isApplication = cs.isImplicit = false; - cs.isHttpSignature = false; - cs.isBasicBasic = cs.isBasicBearer = false; - cs.scheme = securityScheme.getScheme(); - if (securityScheme.getExtensions() != null) { - cs.vendorExtensions.putAll(securityScheme.getExtensions()); - } - if (SecurityScheme.Type.APIKEY.equals(securityScheme.getType())) { + final CodegenSecurity cs = defaultCodegenSecurity(key, securityScheme); cs.isBasic = cs.isOAuth = false; cs.isApiKey = true; cs.keyParamName = securityScheme.getName(); cs.isKeyInHeader = securityScheme.getIn() == SecurityScheme.In.HEADER; cs.isKeyInQuery = securityScheme.getIn() == SecurityScheme.In.QUERY; cs.isKeyInCookie = securityScheme.getIn() == SecurityScheme.In.COOKIE; //it assumes a validation step prior to generation. (cookie-auth supported from OpenAPI 3.0.0) + codegenSecurities.add(cs); } else if (SecurityScheme.Type.HTTP.equals(securityScheme.getType())) { + final CodegenSecurity cs = defaultCodegenSecurity(key, securityScheme); cs.isKeyInHeader = cs.isKeyInQuery = cs.isKeyInCookie = cs.isApiKey = cs.isOAuth = false; cs.isBasic = true; if ("basic".equals(securityScheme.getScheme())) { @@ -4483,35 +4473,41 @@ public List fromSecurity(Map securitySc cs.isHttpSignature = true; once(LOGGER).warn("Security scheme 'HTTP signature' is a draft IETF RFC and subject to change."); } + codegenSecurities.add(cs); } else if (SecurityScheme.Type.OAUTH2.equals(securityScheme.getType())) { - cs.isKeyInHeader = cs.isKeyInQuery = cs.isKeyInCookie = cs.isApiKey = cs.isBasic = false; - cs.isOAuth = true; final OAuthFlows flows = securityScheme.getFlows(); if (securityScheme.getFlows() == null) { - throw new RuntimeException("missing oauth flow in " + cs.name); + throw new RuntimeException("missing oauth flow in " + key); } if (flows.getPassword() != null) { + final CodegenSecurity cs = defaultOauthCodegenSecurity(key, securityScheme); setOauth2Info(cs, flows.getPassword()); cs.isPassword = true; cs.flow = "password"; - } else if (flows.getImplicit() != null) { + codegenSecurities.add(cs); + } + if (flows.getImplicit() != null) { + final CodegenSecurity cs = defaultOauthCodegenSecurity(key, securityScheme); setOauth2Info(cs, flows.getImplicit()); cs.isImplicit = true; cs.flow = "implicit"; - } else if (flows.getClientCredentials() != null) { + codegenSecurities.add(cs); + } + if (flows.getClientCredentials() != null) { + final CodegenSecurity cs = defaultOauthCodegenSecurity(key, securityScheme); setOauth2Info(cs, flows.getClientCredentials()); cs.isApplication = true; cs.flow = "application"; - } else if (flows.getAuthorizationCode() != null) { + codegenSecurities.add(cs); + } + if (flows.getAuthorizationCode() != null) { + final CodegenSecurity cs = defaultOauthCodegenSecurity(key, securityScheme); setOauth2Info(cs, flows.getAuthorizationCode()); cs.isCode = true; cs.flow = "accessCode"; - } else { - throw new RuntimeException("Could not identify any oauth2 flow in " + cs.name); + codegenSecurities.add(cs); } } - - codegenSecurities.add(cs); } // sort auth methods to maintain the same order @@ -4531,6 +4527,27 @@ public int compare(CodegenSecurity one, CodegenSecurity another) { return codegenSecurities; } + private CodegenSecurity defaultCodegenSecurity(String key, SecurityScheme securityScheme) { + final CodegenSecurity cs = CodegenModelFactory.newInstance(CodegenModelType.SECURITY); + cs.name = key; + cs.type = securityScheme.getType().toString(); + cs.isCode = cs.isPassword = cs.isApplication = cs.isImplicit = false; + cs.isHttpSignature = false; + cs.isBasicBasic = cs.isBasicBearer = false; + cs.scheme = securityScheme.getScheme(); + if (securityScheme.getExtensions() != null) { + cs.vendorExtensions.putAll(securityScheme.getExtensions()); + } + return cs; + } + + private CodegenSecurity defaultOauthCodegenSecurity(String key, SecurityScheme securityScheme) { + final CodegenSecurity cs = defaultCodegenSecurity(key, securityScheme); + cs.isKeyInHeader = cs.isKeyInQuery = cs.isKeyInCookie = cs.isApiKey = cs.isBasic = false; + cs.isOAuth = true; + return cs; + } + protected void setReservedWordsLowerCase(List words) { reservedWords = new HashSet(); for (String word : words) { diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java index 09cdd2dfc6a8..8293121970f8 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java @@ -31,6 +31,7 @@ import io.swagger.v3.oas.models.parameters.RequestBody; import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.responses.ApiResponses; +import io.swagger.v3.oas.models.security.SecurityScheme; import io.swagger.v3.parser.core.models.ParseOptions; import org.openapitools.codegen.config.CodegenConfigurator; @@ -2286,4 +2287,18 @@ public void testFreeFormSchemas() throws Exception { TestUtils.ensureDoesNotContainsFile(files, output, "src/main/java/org/openapitools/client/model/FreeForm.java"); output.deleteOnExit(); } + + @Test + public void testOauthMultipleFlows() { + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_7193.yaml"); + final DefaultCodegen codegen = new DefaultCodegen(); + codegen.setOpenAPI(openAPI); + + final Map securitySchemes = openAPI.getComponents().getSecuritySchemes(); + final List securities = codegen.fromSecurity(securitySchemes); + + assertEquals(securities.size(), 2); + final List flows = securities.stream().map(c -> c.flow).collect(Collectors.toList()); + assertTrue(flows.containsAll(Arrays.asList("password", "application"))); + } } diff --git a/modules/openapi-generator/src/test/resources/3_0/issue_7193.yaml b/modules/openapi-generator/src/test/resources/3_0/issue_7193.yaml new file mode 100644 index 000000000000..9483cb0d87db --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/issue_7193.yaml @@ -0,0 +1,45 @@ +openapi: 3.0.0 +info: + title: test api + version: 0.0.1 +paths: + /imports: + post: + summary: Creates import + operationId: createImport + responses: + 201: + description: created + security: + - oauth_auth: + - import:create + /imports/{importId}/state: + put: + summary: Changes import state + operationId: changeImportState + parameters: + - name: importId + in: path + required: true + schema: + type: string + responses: + 200: + description: State changed + security: + - oauht_auth: + - import:process +components: + securitySchemes: + oauth_auth: + type: oauth2 + flows: + password: + tokenUrl: "../auth/realms/master/protocol/openid-connect/token" + scopes: + import:create: create import + clientCredentials: + tokenUrl: "../auth/realms/master/protocol/openid-connect/token" + scopes: + import:create: create import + import:process: process import \ No newline at end of file