Skip to content

Commit b4f153c

Browse files
committed
Merge pull request #826 from xhh/java-auth
[Java] Add authentication support (API key, HTTP basic)
2 parents 0d09d43 + fffc5d7 commit b4f153c

File tree

23 files changed

+657
-37
lines changed

23 files changed

+657
-37
lines changed

modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,18 @@ public void processOpts() {
106106
this.setSourceFolder((String)additionalProperties.get("sourceFolder"));
107107
}
108108

109+
final String invokerFolder = (sourceFolder + File.separator + invokerPackage).replace(".", File.separator);
109110
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
110-
supportingFiles.add(new SupportingFile("ApiClient.mustache",
111-
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiClient.java"));
112-
supportingFiles.add(new SupportingFile("Configuration.mustache",
113-
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "Configuration.java"));
114-
supportingFiles.add(new SupportingFile("JsonUtil.mustache",
115-
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "JsonUtil.java"));
116-
supportingFiles.add(new SupportingFile("apiException.mustache",
117-
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.java"));
111+
supportingFiles.add(new SupportingFile("ApiClient.mustache", invokerFolder, "ApiClient.java"));
112+
supportingFiles.add(new SupportingFile("JsonUtil.mustache", invokerFolder, "JsonUtil.java"));
113+
supportingFiles.add(new SupportingFile("apiException.mustache", invokerFolder, "ApiException.java"));
114+
supportingFiles.add(new SupportingFile("Configuration.mustache", invokerFolder, "Configuration.java"));
115+
116+
final String authFolder = (sourceFolder + File.separator + invokerPackage + ".auth").replace(".", File.separator);
117+
supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java"));
118+
supportingFiles.add(new SupportingFile("auth/HttpBasicAuth.mustache", authFolder, "HttpBasicAuth.java"));
119+
supportingFiles.add(new SupportingFile("auth/ApiKeyAuth.mustache", authFolder, "ApiKeyAuth.java"));
120+
supportingFiles.add(new SupportingFile("auth/OAuth.mustache", authFolder, "OAuth.java"));
118121
}
119122

120123

modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache

Lines changed: 102 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import javax.ws.rs.core.Response.Status.Family;
1717
import javax.ws.rs.core.MediaType;
1818

1919
import java.util.Collection;
20+
import java.util.Collections;
2021
import java.util.Map;
2122
import java.util.Map.Entry;
2223
import java.util.HashMap;
@@ -33,12 +34,19 @@ import java.text.DateFormat;
3334
import java.text.SimpleDateFormat;
3435
import java.text.ParseException;
3536

37+
import {{invokerPackage}}.auth.Authentication;
38+
import {{invokerPackage}}.auth.HttpBasicAuth;
39+
import {{invokerPackage}}.auth.ApiKeyAuth;
40+
import {{invokerPackage}}.auth.OAuth;
41+
3642
public class ApiClient {
3743
private Map<String, Client> hostMap = new HashMap<String, Client>();
3844
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
3945
private boolean debugging = false;
4046
private String basePath = "{{basePath}}";
4147
48+
private Map<String, Authentication> authentications;
49+
4250
private DateFormat dateFormat;
4351
4452
public ApiClient() {
@@ -51,6 +59,14 @@ public class ApiClient {
5159
5260
// Set default User-Agent.
5361
setUserAgent("Java-Swagger");
62+
63+
// Setup authentications (key: authentication name, value: authentication).
64+
authentications = new HashMap<String, Authentication>();{{#authMethods}}{{#isBasic}}
65+
authentications.put("{{name}}", new HttpBasicAuth());{{/isBasic}}{{#isApiKey}}
66+
authentications.put("{{name}}", new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}"));{{/isApiKey}}{{#isOAuth}}
67+
authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{/authMethods}}
68+
// Prevent the authentications from being modified.
69+
authentications = Collections.unmodifiableMap(authentications);
5470
}
5571

5672
public String getBasePath() {
@@ -62,6 +78,75 @@ public class ApiClient {
6278
return this;
6379
}
6480

81+
/**
82+
* Get authentications (key: authentication name, value: authentication).
83+
*/
84+
public Map<String, Authentication> getAuthentications() {
85+
return authentications;
86+
}
87+
88+
/**
89+
* Get authentication for the given name.
90+
*
91+
* @param authName The authentication name
92+
* @return The authentication, null if not found
93+
*/
94+
public Authentication getAuthentication(String authName) {
95+
return authentications.get(authName);
96+
}
97+
98+
/**
99+
* Helper method to set username for the first HTTP basic authentication.
100+
*/
101+
public void setUsername(String username) {
102+
for (Authentication auth : authentications.values()) {
103+
if (auth instanceof HttpBasicAuth) {
104+
((HttpBasicAuth) auth).setUsername(username);
105+
return;
106+
}
107+
}
108+
throw new RuntimeException("No HTTP basic authentication configured!");
109+
}
110+
111+
/**
112+
* Helper method to set password for the first HTTP basic authentication.
113+
*/
114+
public void setPassword(String password) {
115+
for (Authentication auth : authentications.values()) {
116+
if (auth instanceof HttpBasicAuth) {
117+
((HttpBasicAuth) auth).setPassword(password);
118+
return;
119+
}
120+
}
121+
throw new RuntimeException("No HTTP basic authentication configured!");
122+
}
123+
124+
/**
125+
* Helper method to set API key value for the first API key authentication.
126+
*/
127+
public void setApiKey(String apiKey) {
128+
for (Authentication auth : authentications.values()) {
129+
if (auth instanceof ApiKeyAuth) {
130+
((ApiKeyAuth) auth).setApiKey(apiKey);
131+
return;
132+
}
133+
}
134+
throw new RuntimeException("No API key authentication configured!");
135+
}
136+
137+
/**
138+
* Helper method to set API key prefix for the first API key authentication.
139+
*/
140+
public void setApiKeyPrefix(String apiKeyPrefix) {
141+
for (Authentication auth : authentications.values()) {
142+
if (auth instanceof ApiKeyAuth) {
143+
((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix);
144+
return;
145+
}
146+
}
147+
throw new RuntimeException("No API key authentication configured!");
148+
}
149+
65150
/**
66151
* Set the User-Agent header's value (by adding to the default header map).
67152
*/
@@ -222,13 +307,15 @@ public class ApiClient {
222307
* @param headerParams The header parameters
223308
* @param formParams The form parameters
224309
* @param contentType The request Content-Type
310+
* @param authNames The authentications to apply
225311
* @return The response body in type of string
226312
*/
227-
public String invokeAPI(String path, String method, Map<String, String> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String contentType) throws ApiException {
313+
public String invokeAPI(String path, String method, Map<String, String> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String contentType, String[] authNames) throws ApiException {
314+
updateParamsForAuth(authNames, queryParams, headerParams);
315+
228316
Client client = getClient();
229317
230318
StringBuilder b = new StringBuilder();
231-
232319
for(String key : queryParams.keySet()) {
233320
String value = queryParams.get(key);
234321
if (value != null){
@@ -329,6 +416,19 @@ public class ApiClient {
329416
}
330417
}
331418

419+
/**
420+
* Update query and header parameters based on authentication settings.
421+
*
422+
* @param authNames The authentications to apply
423+
*/
424+
private void updateParamsForAuth(String[] authNames, Map<String, String> queryParams, Map<String, String> headerParams) {
425+
for (String authName : authNames) {
426+
Authentication auth = authentications.get(authName);
427+
if (auth == null) throw new RuntimeException("Authentication undefined: " + authName);
428+
auth.applyToParams(queryParams, headerParams);
429+
}
430+
}
431+
332432
/**
333433
* Encode the given form parameters as request body.
334434
*/

modules/swagger-codegen/src/main/resources/Java/Configuration.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public class Configuration {
99
*/
1010
public static ApiClient getDefaultApiClient() {
1111
return defaultApiClient;
12-
}
12+
}
1313

1414
/**
1515
* Set the default API client, which would be used when creating API

modules/swagger-codegen/src/main/resources/Java/api.mustache

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ public class {{classname}} {
102102
}
103103

104104
try {
105-
String response = apiClient.invokeAPI(path, "{{httpMethod}}", queryParams, postBody, headerParams, formParams, contentType);
105+
String[] authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
106+
String response = apiClient.invokeAPI(path, "{{httpMethod}}", queryParams, postBody, headerParams, formParams, contentType, authNames);
106107
if(response != null){
107108
return {{#returnType}}({{{returnType}}}) apiClient.deserialize(response, "{{returnContainer}}", {{returnBaseType}}.class){{/returnType}};
108109
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package {{invokerPackage}}.auth;
2+
3+
import java.util.Map;
4+
5+
public class ApiKeyAuth implements Authentication {
6+
private final String location;
7+
private final String paramName;
8+
9+
private String apiKey;
10+
private String apiKeyPrefix;
11+
12+
public ApiKeyAuth(String location, String paramName) {
13+
this.location = location;
14+
this.paramName = paramName;
15+
}
16+
17+
public String getLocation() {
18+
return location;
19+
}
20+
21+
public String getParamName() {
22+
return paramName;
23+
}
24+
25+
public String getApiKey() {
26+
return apiKey;
27+
}
28+
29+
public void setApiKey(String apiKey) {
30+
this.apiKey = apiKey;
31+
}
32+
33+
public String getApiKeyPrefix() {
34+
return apiKeyPrefix;
35+
}
36+
37+
public void setApiKeyPrefix(String apiKeyPrefix) {
38+
this.apiKeyPrefix = apiKeyPrefix;
39+
}
40+
41+
@Override
42+
public void applyToParams(Map<String, String> queryParams, Map<String, String> headerParams) {
43+
String value;
44+
if (apiKeyPrefix != null) {
45+
value = apiKeyPrefix + " " + apiKey;
46+
} else {
47+
value = apiKey;
48+
}
49+
if (location == "query") {
50+
queryParams.put(paramName, value);
51+
} else if (location == "header") {
52+
headerParams.put(paramName, value);
53+
}
54+
}
55+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package {{invokerPackage}}.auth;
2+
3+
import java.util.Map;
4+
5+
public interface Authentication {
6+
/** Apply authentication settings to header and query params. */
7+
void applyToParams(Map<String, String> queryParams, Map<String, String> headerParams);
8+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package {{invokerPackage}}.auth;
2+
3+
import java.util.Map;
4+
5+
import java.io.UnsupportedEncodingException;
6+
import javax.xml.bind.DatatypeConverter;
7+
8+
public class HttpBasicAuth implements Authentication {
9+
private String username;
10+
private String password;
11+
12+
public String getUsername() {
13+
return username;
14+
}
15+
16+
public void setUsername(String username) {
17+
this.username = username;
18+
}
19+
20+
public String getPassword() {
21+
return password;
22+
}
23+
24+
public void setPassword(String password) {
25+
this.password = password;
26+
}
27+
28+
@Override
29+
public void applyToParams(Map<String, String> queryParams, Map<String, String> headerParams) {
30+
String str = (username == null ? "" : username) + ":" + (password == null ? "" : password);
31+
try {
32+
headerParams.put("Authorization", "Basic " + DatatypeConverter.printBase64Binary(str.getBytes("UTF-8")));
33+
} catch (UnsupportedEncodingException e) {
34+
throw new RuntimeException(e);
35+
}
36+
}
37+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package {{invokerPackage}}.auth;
2+
3+
import java.util.Map;
4+
5+
public class OAuth implements Authentication {
6+
@Override
7+
public void applyToParams(Map<String, String> queryParams, Map<String, String> headerParams) {
8+
// TODO: support oauth
9+
}
10+
}

0 commit comments

Comments
 (0)