Skip to content

Commit 084e7f7

Browse files
committed
Merge pull request #1380 from xhh/java-global-security
Apply global security to operations when necessary
2 parents ab026fd + a1fa0b0 commit 084e7f7

File tree

7 files changed

+1132
-14
lines changed

7 files changed

+1132
-14
lines changed

modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import io.swagger.models.Model;
1313
import io.swagger.models.Operation;
1414
import io.swagger.models.Path;
15+
import io.swagger.models.SecurityRequirement;
1516
import io.swagger.models.Swagger;
1617
import io.swagger.models.auth.OAuth2Definition;
1718
import io.swagger.models.auth.SecuritySchemeDefinition;
@@ -476,16 +477,25 @@ public void processOperation(String resourcePath, String httpMethod, Operation o
476477
config.addOperationToGroup(sanitizeTag(tag), resourcePath, operation, co, operations);
477478

478479
List<Map<String, List<String>>> securities = operation.getSecurity();
479-
if (securities == null) {
480+
if (securities == null && swagger.getSecurity() != null) {
481+
securities = new ArrayList<Map<String, List<String>>>();
482+
for (SecurityRequirement sr : swagger.getSecurity()) {
483+
securities.add(sr.getRequirements());
484+
}
485+
}
486+
if (securities == null || securities.isEmpty()) {
480487
continue;
481488
}
482489
Map<String, SecuritySchemeDefinition> authMethods = new HashMap<String, SecuritySchemeDefinition>();
483-
for (Map<String, List<String>> security : securities) {
484-
if (security.size() != 1) {
485-
//Not sure what to do
486-
continue;
487-
}
488-
String securityName = security.keySet().iterator().next();
490+
// NOTE: Use only the first security requirement for now.
491+
// See the "security" field of "Swagger Object":
492+
// https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#swagger-object
493+
// "there is a logical OR between the security requirements"
494+
if (securities.size() > 1) {
495+
LOGGER.warn("More than 1 security requirements are found, using only the first one");
496+
}
497+
Map<String, List<String>> security = securities.get(0);
498+
for (String securityName : security.keySet()) {
489499
SecuritySchemeDefinition securityDefinition = fromSecurity(securityName);
490500
if (securityDefinition != null) {
491501
if(securityDefinition instanceof OAuth2Definition) {
@@ -496,7 +506,7 @@ public void processOperation(String resourcePath, String httpMethod, Operation o
496506
oauth2Operation.setFlow(oauth2Definition.getFlow());
497507
oauth2Operation.setTokenUrl(oauth2Definition.getTokenUrl());
498508
oauth2Operation.setScopes(new HashMap<String, String>());
499-
for (String scope : security.values().iterator().next()) {
509+
for (String scope : security.get(securityName)) {
500510
if (oauth2Definition.getScopes().containsKey(scope)) {
501511
oauth2Operation.addScope(scope, oauth2Definition.getScopes().get(scope));
502512
}

modules/swagger-codegen/src/test/java/io/swagger/codegen/DefaultGeneratorTest.java

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@
1717
import java.io.Writer;
1818
import java.nio.charset.StandardCharsets;
1919
import java.util.Arrays;
20+
import java.util.List;
21+
import java.util.Map;
2022

2123
import static java.nio.charset.StandardCharsets.UTF_8;
2224
import static org.junit.Assert.fail;
2325
import static org.testng.Assert.assertEquals;
2426
import static org.testng.Assert.assertTrue;
27+
import static org.testng.Assert.assertNull;
2528

2629
/**
2730
* Tests for DefaultGenerator logic
@@ -44,6 +47,102 @@ public void tearDown() throws Exception {
4447
folder.delete();
4548
}
4649

50+
@Test
51+
public void testSecurityWithoutGlobal() throws Exception {
52+
final Swagger swagger = new SwaggerParser().read("src/test/resources/2_0/petstore.json");
53+
CodegenConfig codegenConfig = new JavaClientCodegen();
54+
55+
ClientOptInput clientOptInput = new ClientOptInput().opts(new ClientOpts()).swagger(swagger).config(codegenConfig);
56+
57+
DefaultGenerator gen = new DefaultGenerator();
58+
gen.opts(clientOptInput);
59+
Map<String, List<CodegenOperation>> paths = gen.processPaths(swagger.getPaths());
60+
61+
CodegenSecurity apiKey, petstoreAuth;
62+
63+
// security of "getPetById": api_key
64+
CodegenOperation getPetById = findCodegenOperationByOperationId(paths, "getPetById");
65+
assertEquals(getPetById.authMethods.size(), 1);
66+
apiKey = getPetById.authMethods.iterator().next();
67+
assertEquals(apiKey.name, "api_key");
68+
assertEquals(apiKey.type, "apiKey");
69+
70+
// security of "updatePetWithForm": petstore_auth
71+
CodegenOperation updatePetWithForm = findCodegenOperationByOperationId(paths, "updatePetWithForm");
72+
assertEquals(updatePetWithForm.authMethods.size(), 1);
73+
petstoreAuth = updatePetWithForm.authMethods.iterator().next();
74+
assertEquals(petstoreAuth.name, "petstore_auth");
75+
assertEquals(petstoreAuth.type, "oauth2");
76+
77+
// security of "loginUser": null (no global security either)
78+
CodegenOperation loginUser = findCodegenOperationByOperationId(paths, "loginUser");
79+
assertNull(loginUser.authMethods);
80+
}
81+
82+
@Test
83+
public void testSecurityWithGlobal() throws Exception {
84+
final Swagger swagger = new SwaggerParser().read("src/test/resources/2_0/globalSecurity.json");
85+
CodegenConfig codegenConfig = new JavaClientCodegen();
86+
87+
ClientOptInput clientOptInput = new ClientOptInput().opts(new ClientOpts()).swagger(swagger).config(codegenConfig);
88+
89+
DefaultGenerator gen = new DefaultGenerator();
90+
gen.opts(clientOptInput);
91+
Map<String, List<CodegenOperation>> paths = gen.processPaths(swagger.getPaths());
92+
93+
CodegenSecurity cs, apiKey, apiKey2, petstoreAuth;
94+
95+
// security of "getPetById": api_key
96+
CodegenOperation getPetById = findCodegenOperationByOperationId(paths, "getPetById");
97+
assertEquals(getPetById.authMethods.size(), 1);
98+
apiKey = getPetById.authMethods.iterator().next();
99+
assertEquals(apiKey.name, "api_key");
100+
assertEquals(apiKey.type, "apiKey");
101+
102+
// security of "updatePetWithForm": petstore_auth
103+
CodegenOperation updatePetWithForm = findCodegenOperationByOperationId(paths, "updatePetWithForm");
104+
assertEquals(updatePetWithForm.authMethods.size(), 1);
105+
petstoreAuth = updatePetWithForm.authMethods.iterator().next();
106+
assertEquals(petstoreAuth.name, "petstore_auth");
107+
assertEquals(petstoreAuth.type, "oauth2");
108+
109+
// security of "loginUser": api_key, petstore_auth (from global security)
110+
CodegenOperation loginUser = findCodegenOperationByOperationId(paths, "loginUser");
111+
assertEquals(loginUser.authMethods.size(), 2);
112+
cs = loginUser.authMethods.get(0);
113+
if ("api_key".equals(cs.name)) {
114+
apiKey = cs;
115+
petstoreAuth = loginUser.authMethods.get(1);
116+
} else {
117+
petstoreAuth = cs;
118+
apiKey = loginUser.authMethods.get(1);
119+
}
120+
assertEquals(apiKey.name, "api_key");
121+
assertEquals(apiKey.type, "apiKey");
122+
assertEquals(petstoreAuth.name, "petstore_auth");
123+
assertEquals(petstoreAuth.type, "oauth2");
124+
125+
// security of "logoutUser": null (override global security)
126+
CodegenOperation logoutUser = findCodegenOperationByOperationId(paths, "logoutUser");
127+
assertNull(logoutUser.authMethods);
128+
129+
// security of "getUserByName": api_key, api_key2 (override global security)
130+
CodegenOperation getUserByName = findCodegenOperationByOperationId(paths, "getUserByName");
131+
assertEquals(getUserByName.authMethods.size(), 2);
132+
cs = getUserByName.authMethods.get(0);
133+
if ("api_key".equals(cs.name)) {
134+
apiKey = cs;
135+
apiKey2 = getUserByName.authMethods.get(1);
136+
} else {
137+
apiKey2 = cs;
138+
apiKey = getUserByName.authMethods.get(1);
139+
}
140+
assertEquals(apiKey.name, "api_key");
141+
assertEquals(apiKey.type, "apiKey");
142+
assertEquals(apiKey2.name, "api_key2");
143+
assertEquals(apiKey2.type, "apiKey");
144+
}
145+
47146
@Test
48147
public void testSkipOverwrite() throws Exception {
49148
final File output = folder.getRoot();
@@ -89,4 +188,15 @@ private void changeContent(File file) throws IOException {
89188
out.close();
90189
}
91190

191+
private CodegenOperation findCodegenOperationByOperationId(Map<String, List<CodegenOperation>> paths, String operationId) {
192+
for (List<CodegenOperation> ops : paths.values()) {
193+
for (CodegenOperation co : ops) {
194+
if (operationId.equals(co.operationId)) {
195+
return co;
196+
}
197+
}
198+
}
199+
return null;
200+
}
201+
92202
}

0 commit comments

Comments
 (0)