Skip to content

Commit e1fd221

Browse files
authored
[core] Enable multiple oauth2 flows (#7570)
1 parent 626481b commit e1fd221

File tree

3 files changed

+100
-23
lines changed

3 files changed

+100
-23
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import com.github.benmanes.caffeine.cache.Ticker;
2323
import com.google.common.base.CaseFormat;
2424
import com.google.common.collect.ImmutableMap;
25-
import com.google.common.collect.Maps;
2625
import com.samskivert.mustache.Mustache;
2726
import com.samskivert.mustache.Mustache.Compiler;
2827
import com.samskivert.mustache.Mustache.Lambda;
@@ -4447,26 +4446,17 @@ public List<CodegenSecurity> fromSecurity(Map<String, SecurityScheme> securitySc
44474446
List<CodegenSecurity> codegenSecurities = new ArrayList<CodegenSecurity>(securitySchemeMap.size());
44484447
for (String key : securitySchemeMap.keySet()) {
44494448
final SecurityScheme securityScheme = securitySchemeMap.get(key);
4450-
4451-
CodegenSecurity cs = CodegenModelFactory.newInstance(CodegenModelType.SECURITY);
4452-
cs.name = key;
4453-
cs.type = securityScheme.getType().toString();
4454-
cs.isCode = cs.isPassword = cs.isApplication = cs.isImplicit = false;
4455-
cs.isHttpSignature = false;
4456-
cs.isBasicBasic = cs.isBasicBearer = false;
4457-
cs.scheme = securityScheme.getScheme();
4458-
if (securityScheme.getExtensions() != null) {
4459-
cs.vendorExtensions.putAll(securityScheme.getExtensions());
4460-
}
4461-
44624449
if (SecurityScheme.Type.APIKEY.equals(securityScheme.getType())) {
4450+
final CodegenSecurity cs = defaultCodegenSecurity(key, securityScheme);
44634451
cs.isBasic = cs.isOAuth = false;
44644452
cs.isApiKey = true;
44654453
cs.keyParamName = securityScheme.getName();
44664454
cs.isKeyInHeader = securityScheme.getIn() == SecurityScheme.In.HEADER;
44674455
cs.isKeyInQuery = securityScheme.getIn() == SecurityScheme.In.QUERY;
44684456
cs.isKeyInCookie = securityScheme.getIn() == SecurityScheme.In.COOKIE; //it assumes a validation step prior to generation. (cookie-auth supported from OpenAPI 3.0.0)
4457+
codegenSecurities.add(cs);
44694458
} else if (SecurityScheme.Type.HTTP.equals(securityScheme.getType())) {
4459+
final CodegenSecurity cs = defaultCodegenSecurity(key, securityScheme);
44704460
cs.isKeyInHeader = cs.isKeyInQuery = cs.isKeyInCookie = cs.isApiKey = cs.isOAuth = false;
44714461
cs.isBasic = true;
44724462
if ("basic".equals(securityScheme.getScheme())) {
@@ -4483,35 +4473,41 @@ public List<CodegenSecurity> fromSecurity(Map<String, SecurityScheme> securitySc
44834473
cs.isHttpSignature = true;
44844474
once(LOGGER).warn("Security scheme 'HTTP signature' is a draft IETF RFC and subject to change.");
44854475
}
4476+
codegenSecurities.add(cs);
44864477
} else if (SecurityScheme.Type.OAUTH2.equals(securityScheme.getType())) {
4487-
cs.isKeyInHeader = cs.isKeyInQuery = cs.isKeyInCookie = cs.isApiKey = cs.isBasic = false;
4488-
cs.isOAuth = true;
44894478
final OAuthFlows flows = securityScheme.getFlows();
44904479
if (securityScheme.getFlows() == null) {
4491-
throw new RuntimeException("missing oauth flow in " + cs.name);
4480+
throw new RuntimeException("missing oauth flow in " + key);
44924481
}
44934482
if (flows.getPassword() != null) {
4483+
final CodegenSecurity cs = defaultOauthCodegenSecurity(key, securityScheme);
44944484
setOauth2Info(cs, flows.getPassword());
44954485
cs.isPassword = true;
44964486
cs.flow = "password";
4497-
} else if (flows.getImplicit() != null) {
4487+
codegenSecurities.add(cs);
4488+
}
4489+
if (flows.getImplicit() != null) {
4490+
final CodegenSecurity cs = defaultOauthCodegenSecurity(key, securityScheme);
44984491
setOauth2Info(cs, flows.getImplicit());
44994492
cs.isImplicit = true;
45004493
cs.flow = "implicit";
4501-
} else if (flows.getClientCredentials() != null) {
4494+
codegenSecurities.add(cs);
4495+
}
4496+
if (flows.getClientCredentials() != null) {
4497+
final CodegenSecurity cs = defaultOauthCodegenSecurity(key, securityScheme);
45024498
setOauth2Info(cs, flows.getClientCredentials());
45034499
cs.isApplication = true;
45044500
cs.flow = "application";
4505-
} else if (flows.getAuthorizationCode() != null) {
4501+
codegenSecurities.add(cs);
4502+
}
4503+
if (flows.getAuthorizationCode() != null) {
4504+
final CodegenSecurity cs = defaultOauthCodegenSecurity(key, securityScheme);
45064505
setOauth2Info(cs, flows.getAuthorizationCode());
45074506
cs.isCode = true;
45084507
cs.flow = "accessCode";
4509-
} else {
4510-
throw new RuntimeException("Could not identify any oauth2 flow in " + cs.name);
4508+
codegenSecurities.add(cs);
45114509
}
45124510
}
4513-
4514-
codegenSecurities.add(cs);
45154511
}
45164512

45174513
// sort auth methods to maintain the same order
@@ -4531,6 +4527,27 @@ public int compare(CodegenSecurity one, CodegenSecurity another) {
45314527
return codegenSecurities;
45324528
}
45334529

4530+
private CodegenSecurity defaultCodegenSecurity(String key, SecurityScheme securityScheme) {
4531+
final CodegenSecurity cs = CodegenModelFactory.newInstance(CodegenModelType.SECURITY);
4532+
cs.name = key;
4533+
cs.type = securityScheme.getType().toString();
4534+
cs.isCode = cs.isPassword = cs.isApplication = cs.isImplicit = false;
4535+
cs.isHttpSignature = false;
4536+
cs.isBasicBasic = cs.isBasicBearer = false;
4537+
cs.scheme = securityScheme.getScheme();
4538+
if (securityScheme.getExtensions() != null) {
4539+
cs.vendorExtensions.putAll(securityScheme.getExtensions());
4540+
}
4541+
return cs;
4542+
}
4543+
4544+
private CodegenSecurity defaultOauthCodegenSecurity(String key, SecurityScheme securityScheme) {
4545+
final CodegenSecurity cs = defaultCodegenSecurity(key, securityScheme);
4546+
cs.isKeyInHeader = cs.isKeyInQuery = cs.isKeyInCookie = cs.isApiKey = cs.isBasic = false;
4547+
cs.isOAuth = true;
4548+
return cs;
4549+
}
4550+
45344551
protected void setReservedWordsLowerCase(List<String> words) {
45354552
reservedWords = new HashSet<String>();
45364553
for (String word : words) {

modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import io.swagger.v3.oas.models.parameters.RequestBody;
3232
import io.swagger.v3.oas.models.responses.ApiResponse;
3333
import io.swagger.v3.oas.models.responses.ApiResponses;
34+
import io.swagger.v3.oas.models.security.SecurityScheme;
3435
import io.swagger.v3.parser.core.models.ParseOptions;
3536

3637
import org.openapitools.codegen.config.CodegenConfigurator;
@@ -2286,4 +2287,18 @@ public void testFreeFormSchemas() throws Exception {
22862287
TestUtils.ensureDoesNotContainsFile(files, output, "src/main/java/org/openapitools/client/model/FreeForm.java");
22872288
output.deleteOnExit();
22882289
}
2290+
2291+
@Test
2292+
public void testOauthMultipleFlows() {
2293+
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_7193.yaml");
2294+
final DefaultCodegen codegen = new DefaultCodegen();
2295+
codegen.setOpenAPI(openAPI);
2296+
2297+
final Map<String, SecurityScheme> securitySchemes = openAPI.getComponents().getSecuritySchemes();
2298+
final List<CodegenSecurity> securities = codegen.fromSecurity(securitySchemes);
2299+
2300+
assertEquals(securities.size(), 2);
2301+
final List<String> flows = securities.stream().map(c -> c.flow).collect(Collectors.toList());
2302+
assertTrue(flows.containsAll(Arrays.asList("password", "application")));
2303+
}
22892304
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
openapi: 3.0.0
2+
info:
3+
title: test api
4+
version: 0.0.1
5+
paths:
6+
/imports:
7+
post:
8+
summary: Creates import
9+
operationId: createImport
10+
responses:
11+
201:
12+
description: created
13+
security:
14+
- oauth_auth:
15+
- import:create
16+
/imports/{importId}/state:
17+
put:
18+
summary: Changes import state
19+
operationId: changeImportState
20+
parameters:
21+
- name: importId
22+
in: path
23+
required: true
24+
schema:
25+
type: string
26+
responses:
27+
200:
28+
description: State changed
29+
security:
30+
- oauht_auth:
31+
- import:process
32+
components:
33+
securitySchemes:
34+
oauth_auth:
35+
type: oauth2
36+
flows:
37+
password:
38+
tokenUrl: "../auth/realms/master/protocol/openid-connect/token"
39+
scopes:
40+
import:create: create import
41+
clientCredentials:
42+
tokenUrl: "../auth/realms/master/protocol/openid-connect/token"
43+
scopes:
44+
import:create: create import
45+
import:process: process import

0 commit comments

Comments
 (0)