forked from loafle/openapi-generator-original
[okhttp-gson] Add support for OAuth access token retry (#1058)
* Add support for access token retry in okhttp-gson lib * Update expected number of generated files in test * Update samples * Update security samples * Fix default user-agent and update samples
This commit is contained in:
committed by
William Cheng
parent
1b2f3fbfb6
commit
0e045bee1b
@@ -288,6 +288,8 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
supportingFiles.add(new SupportingFile("ProgressRequestBody.mustache", invokerFolder, "ProgressRequestBody.java"));
|
||||
supportingFiles.add(new SupportingFile("ProgressResponseBody.mustache", invokerFolder, "ProgressResponseBody.java"));
|
||||
supportingFiles.add(new SupportingFile("GzipRequestInterceptor.mustache", invokerFolder, "GzipRequestInterceptor.java"));
|
||||
supportingFiles.add(new SupportingFile("auth/OAuthOkHttpClient.mustache", authFolder, "OAuthOkHttpClient.java"));
|
||||
supportingFiles.add(new SupportingFile("auth/RetryingOAuth.mustache", authFolder, "RetryingOAuth.java"));
|
||||
additionalProperties.put("gson", "true");
|
||||
} else if (usesAnyRetrofitLibrary()) {
|
||||
supportingFiles.add(new SupportingFile("auth/OAuthOkHttpClient.mustache", authFolder, "OAuthOkHttpClient.java"));
|
||||
|
||||
@@ -19,6 +19,9 @@ import org.threeten.bp.OffsetDateTime;
|
||||
import org.threeten.bp.format.DateTimeFormatter;
|
||||
{{/threetenbp}}
|
||||
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
import org.apache.oltu.oauth2.common.message.types.GrantType;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -50,6 +53,7 @@ import {{invokerPackage}}.auth.Authentication;
|
||||
import {{invokerPackage}}.auth.HttpBasicAuth;
|
||||
import {{invokerPackage}}.auth.ApiKeyAuth;
|
||||
import {{invokerPackage}}.auth.OAuth;
|
||||
import {{invokerPackage}}.auth.RetryingOAuth;
|
||||
|
||||
public class ApiClient {
|
||||
|
||||
@@ -78,6 +82,38 @@ public class ApiClient {
|
||||
* Constructor for ApiClient
|
||||
*/
|
||||
public ApiClient() {
|
||||
init();
|
||||
|
||||
// Setup authentications (key: authentication name, value: authentication).{{#authMethods}}{{#isBasic}}
|
||||
authentications.put("{{name}}", new HttpBasicAuth());{{/isBasic}}{{#isApiKey}}
|
||||
authentications.put("{{name}}", new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}"));{{/isApiKey}}{{#isOAuth}}
|
||||
authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{/authMethods}}
|
||||
// Prevent the authentications from being modified.
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
}
|
||||
{{#authMethods}}{{#isOAuth}}
|
||||
/*
|
||||
* Constructor for ApiClient to support access token retry on 401/403
|
||||
*/
|
||||
public ApiClient(
|
||||
String clientId,
|
||||
String clientSecret,
|
||||
Map<String, String> parameters
|
||||
) {
|
||||
init();
|
||||
|
||||
RetryingOAuth retryingOAuth = new RetryingOAuth("{{tokenUrl}}", clientId, GrantType.valueOf("{{flow}}"), clientSecret, parameters);
|
||||
authentications.put(
|
||||
"{{name}}",
|
||||
retryingOAuth
|
||||
);
|
||||
httpClient.interceptors().add(retryingOAuth);
|
||||
|
||||
// Prevent the authentications from being modified.
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
}
|
||||
{{/isOAuth}}{{/authMethods}}
|
||||
private void init() {
|
||||
httpClient = new OkHttpClient();
|
||||
|
||||
{{#useGzipFeature}}
|
||||
@@ -92,13 +128,7 @@ public class ApiClient {
|
||||
// Set default User-Agent.
|
||||
setUserAgent("{{#httpUserAgent}}{{{.}}}{{/httpUserAgent}}{{^httpUserAgent}}OpenAPI-Generator/{{{artifactVersion}}}/java{{/httpUserAgent}}");
|
||||
|
||||
// Setup authentications (key: authentication name, value: authentication).
|
||||
authentications = new HashMap<String, Authentication>();{{#authMethods}}{{#isBasic}}
|
||||
authentications.put("{{name}}", new HttpBasicAuth());{{/isBasic}}{{#isApiKey}}
|
||||
authentications.put("{{name}}", new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}"));{{/isApiKey}}{{#isOAuth}}
|
||||
authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{/authMethods}}
|
||||
// Prevent the authentications from being modified.
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
authentications = new HashMap<String, Authentication>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -502,6 +532,20 @@ public class ApiClient {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
|
||||
* @return Token request builder
|
||||
*/
|
||||
public TokenRequestBuilder getTokenEndPoint() {
|
||||
for (Authentication apiAuth : authentications.values()) {
|
||||
if (apiAuth instanceof RetryingOAuth) {
|
||||
RetryingOAuth retryingOAuth = (RetryingOAuth) apiAuth;
|
||||
return retryingOAuth.getTokenRequestBuilder();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the given parameter object into string.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.MediaType;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.RequestBody;
|
||||
import com.squareup.okhttp.Response;
|
||||
|
||||
import org.apache.oltu.oauth2.client.HttpClient;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthClientResponse;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class OAuthOkHttpClient implements HttpClient {
|
||||
private OkHttpClient client;
|
||||
|
||||
public OAuthOkHttpClient() {
|
||||
this.client = new OkHttpClient();
|
||||
}
|
||||
|
||||
public OAuthOkHttpClient(OkHttpClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends OAuthClientResponse> T execute(OAuthClientRequest request, Map<String, String> headers,
|
||||
String requestMethod, Class<T> responseClass)
|
||||
throws OAuthSystemException, OAuthProblemException {
|
||||
|
||||
MediaType mediaType = MediaType.parse("application/json");
|
||||
Request.Builder requestBuilder = new Request.Builder().url(request.getLocationUri());
|
||||
|
||||
if(headers != null) {
|
||||
for (Entry<String, String> entry : headers.entrySet()) {
|
||||
if (entry.getKey().equalsIgnoreCase("Content-Type")) {
|
||||
mediaType = MediaType.parse(entry.getValue());
|
||||
} else {
|
||||
requestBuilder.addHeader(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RequestBody body = request.getBody() != null ? RequestBody.create(mediaType, request.getBody()) : null;
|
||||
requestBuilder.method(requestMethod, body);
|
||||
|
||||
try {
|
||||
Response response = client.newCall(requestBuilder.build()).execute();
|
||||
return OAuthClientResponseFactory.createCustomResponse(
|
||||
response.body().string(),
|
||||
response.body().contentType().toString(),
|
||||
response.code(),
|
||||
responseClass);
|
||||
} catch (IOException e) {
|
||||
throw new OAuthSystemException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
// Nothing to do here
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
import com.squareup.okhttp.Interceptor;
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.Response;
|
||||
|
||||
import org.apache.oltu.oauth2.client.OAuthClient;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
|
||||
import org.apache.oltu.oauth2.common.message.types.GrantType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.Map;
|
||||
|
||||
public class RetryingOAuth extends OAuth implements Interceptor {
|
||||
private OAuthClient oAuthClient;
|
||||
|
||||
private TokenRequestBuilder tokenRequestBuilder;
|
||||
|
||||
public RetryingOAuth(OkHttpClient client, TokenRequestBuilder tokenRequestBuilder) {
|
||||
this.oAuthClient = new OAuthClient(new OAuthOkHttpClient(client));
|
||||
this.tokenRequestBuilder = tokenRequestBuilder;
|
||||
}
|
||||
|
||||
public RetryingOAuth(TokenRequestBuilder tokenRequestBuilder) {
|
||||
this(new OkHttpClient(), tokenRequestBuilder);
|
||||
}
|
||||
|
||||
public RetryingOAuth(
|
||||
String tokenUrl,
|
||||
String clientId,
|
||||
GrantType grantType,
|
||||
String clientSecret,
|
||||
Map<String, String> parameters
|
||||
) {
|
||||
this(OAuthClientRequest.tokenLocation(tokenUrl)
|
||||
.setClientId(clientId)
|
||||
.setGrantType(grantType)
|
||||
.setClientSecret(clientSecret));
|
||||
|
||||
if (parameters != null) {
|
||||
for (String paramName : parameters.keySet()) {
|
||||
tokenRequestBuilder.setParameter(paramName, parameters.get(paramName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
return retryingIntercept(chain, true);
|
||||
}
|
||||
|
||||
private Response retryingIntercept(Chain chain, boolean updateTokenAndRetryOnAuthorizationFailure) throws IOException {
|
||||
Request request = chain.request();
|
||||
|
||||
// If the request already has an authorization (e.g. Basic auth), proceed with the request as is
|
||||
if (request.header("Authorization") != null) {
|
||||
return chain.proceed(request);
|
||||
}
|
||||
|
||||
// Get the token if it has not yet been acquired
|
||||
if (getAccessToken() == null) {
|
||||
updateAccessToken(null);
|
||||
}
|
||||
|
||||
OAuthClientRequest oAuthRequest;
|
||||
if (getAccessToken() != null) {
|
||||
// Build the request
|
||||
Request.Builder requestBuilder = request.newBuilder();
|
||||
|
||||
String requestAccessToken = getAccessToken();
|
||||
try {
|
||||
oAuthRequest =
|
||||
new OAuthBearerClientRequest(request.urlString()).
|
||||
setAccessToken(requestAccessToken).
|
||||
buildHeaderMessage();
|
||||
} catch (OAuthSystemException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
||||
Map<String, String> headers = oAuthRequest.getHeaders();
|
||||
for (String headerName : headers.keySet()) {
|
||||
requestBuilder.addHeader(headerName, headers.get(headerName));
|
||||
}
|
||||
requestBuilder.url(oAuthRequest.getLocationUri());
|
||||
|
||||
// Execute the request
|
||||
Response response = chain.proceed(requestBuilder.build());
|
||||
|
||||
// 401/403 response codes most likely indicate an expired access token, unless it happens two times in a row
|
||||
if (
|
||||
response != null &&
|
||||
( response.code() == HttpURLConnection.HTTP_UNAUTHORIZED ||
|
||||
response.code() == HttpURLConnection.HTTP_FORBIDDEN ) &&
|
||||
updateTokenAndRetryOnAuthorizationFailure
|
||||
) {
|
||||
try {
|
||||
if (updateAccessToken(requestAccessToken)) {
|
||||
response.body().close();
|
||||
return retryingIntercept(chain, false);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
response.body().close();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
else {
|
||||
return chain.proceed(chain.request());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the access token has been updated
|
||||
*/
|
||||
public synchronized boolean updateAccessToken(String requestAccessToken) throws IOException {
|
||||
if (getAccessToken() == null || getAccessToken().equals(requestAccessToken)) {
|
||||
try {
|
||||
OAuthJSONAccessTokenResponse accessTokenResponse =
|
||||
oAuthClient.accessToken(tokenRequestBuilder.buildBodyMessage());
|
||||
if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) {
|
||||
setAccessToken(accessTokenResponse.getAccessToken());
|
||||
return !getAccessToken().equals(requestAccessToken);
|
||||
}
|
||||
} catch (OAuthSystemException | OAuthProblemException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public TokenRequestBuilder getTokenRequestBuilder() {
|
||||
return tokenRequestBuilder;
|
||||
}
|
||||
|
||||
public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) {
|
||||
this.tokenRequestBuilder = tokenRequestBuilder;
|
||||
}
|
||||
}
|
||||
@@ -123,6 +123,7 @@ dependencies {
|
||||
compile 'com.squareup.okhttp:logging-interceptor:2.7.5'
|
||||
compile 'com.google.code.gson:gson:2.8.1'
|
||||
compile 'io.gsonfire:gson-fire:1.8.0'
|
||||
compile group: 'org.apache.oltu.oauth2', name: 'org.apache.oltu.oauth2.client', version: '1.0.1'
|
||||
{{#joda}}
|
||||
compile 'joda-time:joda-time:2.9.9'
|
||||
{{/joda}}
|
||||
|
||||
@@ -213,6 +213,11 @@
|
||||
<artifactId>gson-fire</artifactId>
|
||||
<version>${gson-fire-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.oltu.oauth2</groupId>
|
||||
<artifactId>org.apache.oltu.oauth2.client</artifactId>
|
||||
<version>1.0.1</version>
|
||||
</dependency>
|
||||
{{#joda}}
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
|
||||
@@ -252,7 +252,7 @@ public class JavaClientCodegenTest {
|
||||
generator.opts(clientOptInput).generate();
|
||||
|
||||
Map<String, String> generatedFiles = generator.getFiles();
|
||||
Assert.assertEquals(generatedFiles.size(), 35);
|
||||
Assert.assertEquals(generatedFiles.size(), 37);
|
||||
ensureContainsFile(generatedFiles, output, ".gitignore");
|
||||
ensureContainsFile(generatedFiles, output, ".openapi-generator-ignore");
|
||||
ensureContainsFile(generatedFiles, output, ".openapi-generator/VERSION");
|
||||
|
||||
@@ -1 +1 @@
|
||||
3.2.3-SNAPSHOT
|
||||
3.3.0-SNAPSHOT
|
||||
@@ -99,6 +99,7 @@ dependencies {
|
||||
compile 'com.squareup.okhttp:logging-interceptor:2.7.5'
|
||||
compile 'com.google.code.gson:gson:2.8.1'
|
||||
compile 'io.gsonfire:gson-fire:1.8.0'
|
||||
compile group: 'org.apache.oltu.oauth2', name: 'org.apache.oltu.oauth2.client', version: '1.0.1'
|
||||
compile 'org.threeten:threetenbp:1.3.5'
|
||||
testCompile 'junit:junit:4.12'
|
||||
}
|
||||
|
||||
@@ -212,6 +212,11 @@
|
||||
<groupId>io.gsonfire</groupId>
|
||||
<artifactId>gson-fire</artifactId>
|
||||
<version>${gson-fire-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.oltu.oauth2</groupId>
|
||||
<artifactId>org.apache.oltu.oauth2.client</artifactId>
|
||||
<version>1.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.threeten</groupId>
|
||||
|
||||
@@ -23,6 +23,9 @@ import org.threeten.bp.LocalDate;
|
||||
import org.threeten.bp.OffsetDateTime;
|
||||
import org.threeten.bp.format.DateTimeFormatter;
|
||||
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
import org.apache.oltu.oauth2.common.message.types.GrantType;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -49,6 +52,7 @@ import org.openapitools.client.auth.Authentication;
|
||||
import org.openapitools.client.auth.HttpBasicAuth;
|
||||
import org.openapitools.client.auth.ApiKeyAuth;
|
||||
import org.openapitools.client.auth.OAuth;
|
||||
import org.openapitools.client.auth.RetryingOAuth;
|
||||
|
||||
public class ApiClient {
|
||||
|
||||
@@ -77,6 +81,37 @@ public class ApiClient {
|
||||
* Constructor for ApiClient
|
||||
*/
|
||||
public ApiClient() {
|
||||
init();
|
||||
|
||||
// Setup authentications (key: authentication name, value: authentication).
|
||||
authentications.put("api_key", new ApiKeyAuth("header", "api_key */ ' " =end -- \r\n \n \r"));
|
||||
authentications.put("petstore_auth", new OAuth());
|
||||
// Prevent the authentications from being modified.
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor for ApiClient to support access token retry on 401/403
|
||||
*/
|
||||
public ApiClient(
|
||||
String clientId,
|
||||
String clientSecret,
|
||||
Map<String, String> parameters
|
||||
) {
|
||||
init();
|
||||
|
||||
RetryingOAuth retryingOAuth = new RetryingOAuth("", clientId, GrantType.valueOf("implicit"), clientSecret, parameters);
|
||||
authentications.put(
|
||||
"petstore_auth",
|
||||
retryingOAuth
|
||||
);
|
||||
httpClient.interceptors().add(retryingOAuth);
|
||||
|
||||
// Prevent the authentications from being modified.
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
httpClient = new OkHttpClient();
|
||||
|
||||
|
||||
@@ -87,12 +122,7 @@ public class ApiClient {
|
||||
// Set default User-Agent.
|
||||
setUserAgent("OpenAPI-Generator/1.0.0/java");
|
||||
|
||||
// Setup authentications (key: authentication name, value: authentication).
|
||||
authentications = new HashMap<String, Authentication>();
|
||||
authentications.put("api_key", new ApiKeyAuth("header", "api_key */ ' " =end -- \r\n \n \r"));
|
||||
authentications.put("petstore_auth", new OAuth());
|
||||
// Prevent the authentications from being modified.
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -482,6 +512,20 @@ public class ApiClient {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
|
||||
* @return Token request builder
|
||||
*/
|
||||
public TokenRequestBuilder getTokenEndPoint() {
|
||||
for (Authentication apiAuth : authentications.values()) {
|
||||
if (apiAuth instanceof RetryingOAuth) {
|
||||
RetryingOAuth retryingOAuth = (RetryingOAuth) apiAuth;
|
||||
return retryingOAuth.getTokenRequestBuilder();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the given parameter object into string.
|
||||
*
|
||||
@@ -497,7 +541,7 @@ public class ApiClient {
|
||||
return jsonStr.substring(1, jsonStr.length() - 1);
|
||||
} else if (param instanceof Collection) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (Object o : (Collection)param) {
|
||||
for (Object o : (Collection) param) {
|
||||
if (b.length() > 0) {
|
||||
b.append(",");
|
||||
}
|
||||
@@ -522,7 +566,9 @@ public class ApiClient {
|
||||
List<Pair> params = new ArrayList<Pair>();
|
||||
|
||||
// preconditions
|
||||
if (name == null || name.isEmpty() || value == null || value instanceof Collection) return params;
|
||||
if (name == null || name.isEmpty() || value == null || value instanceof Collection) {
|
||||
return params;
|
||||
}
|
||||
|
||||
params.add(new Pair(name, parameterToString(value)));
|
||||
return params;
|
||||
@@ -567,7 +613,7 @@ public class ApiClient {
|
||||
delimiter = escapeString("|");
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder() ;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Object item : value) {
|
||||
sb.append(delimiter);
|
||||
sb.append(escapeString(parameterToString(item)));
|
||||
@@ -637,7 +683,7 @@ public class ApiClient {
|
||||
*/
|
||||
public String selectHeaderContentType(String[] contentTypes) {
|
||||
if (contentTypes.length == 0 || contentTypes[0].equals("*/*")) {
|
||||
return "application/json";
|
||||
return "application/json";
|
||||
}
|
||||
for (String contentType : contentTypes) {
|
||||
if (isJsonMime(contentType)) {
|
||||
@@ -961,7 +1007,7 @@ public class ApiClient {
|
||||
* @param formParams The form parameters
|
||||
* @param authNames The authentications to apply
|
||||
* @param progressRequestListener Progress request listener
|
||||
* @return The HTTP request
|
||||
* @return The HTTP request
|
||||
* @throws ApiException If fail to serialize the request body object
|
||||
*/
|
||||
public Request buildRequest(String path, String method, List<Pair> queryParams, List<Pair> collectionQueryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String[] authNames, ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
|
||||
@@ -1078,13 +1124,15 @@ public class ApiClient {
|
||||
* Update query and header parameters based on authentication settings.
|
||||
*
|
||||
* @param authNames The authentications to apply
|
||||
* @param queryParams List of query parameters
|
||||
* @param headerParams Map of header parameters
|
||||
* @param queryParams List of query parameters
|
||||
* @param headerParams Map of header parameters
|
||||
*/
|
||||
public void updateParamsForAuth(String[] authNames, List<Pair> queryParams, Map<String, String> headerParams) {
|
||||
for (String authName : authNames) {
|
||||
Authentication auth = authentications.get(authName);
|
||||
if (auth == null) throw new RuntimeException("Authentication undefined: " + authName);
|
||||
if (auth == null) {
|
||||
throw new RuntimeException("Authentication undefined: " + authName);
|
||||
}
|
||||
auth.applyToParams(queryParams, headerParams);
|
||||
}
|
||||
}
|
||||
@@ -1096,7 +1144,7 @@ public class ApiClient {
|
||||
* @return RequestBody
|
||||
*/
|
||||
public RequestBody buildRequestBodyFormEncoding(Map<String, Object> formParams) {
|
||||
FormEncodingBuilder formBuilder = new FormEncodingBuilder();
|
||||
FormEncodingBuilder formBuilder = new FormEncodingBuilder();
|
||||
for (Entry<String, Object> param : formParams.entrySet()) {
|
||||
formBuilder.add(param.getKey(), parameterToString(param.getValue()));
|
||||
}
|
||||
@@ -1159,10 +1207,12 @@ public class ApiClient {
|
||||
public X509Certificate[] getAcceptedIssuers() { return null; }
|
||||
};
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
trustManagers = new TrustManager[]{ trustAll };
|
||||
trustManagers = new TrustManager[] {trustAll};
|
||||
hostnameVerifier = new HostnameVerifier() {
|
||||
@Override
|
||||
public boolean verify(String hostname, SSLSession session) { return true; }
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
} else if (sslCaCert != null) {
|
||||
char[] password = null; // Any password will work.
|
||||
|
||||
@@ -27,7 +27,8 @@ import java.io.IOException;
|
||||
* Taken from https://github.com/square/okhttp/issues/350
|
||||
*/
|
||||
class GzipRequestInterceptor implements Interceptor {
|
||||
@Override public Response intercept(Chain chain) throws IOException {
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
Request originalRequest = chain.request();
|
||||
if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
|
||||
return chain.proceed(originalRequest);
|
||||
@@ -63,19 +64,22 @@ class GzipRequestInterceptor implements Interceptor {
|
||||
|
||||
private RequestBody gzip(final RequestBody body) {
|
||||
return new RequestBody() {
|
||||
@Override public MediaType contentType() {
|
||||
@Override
|
||||
public MediaType contentType() {
|
||||
return body.contentType();
|
||||
}
|
||||
|
||||
@Override public long contentLength() {
|
||||
@Override
|
||||
public long contentLength() {
|
||||
return -1; // We don't know the compressed length in advance!
|
||||
}
|
||||
|
||||
@Override public void writeTo(BufferedSink sink) throws IOException {
|
||||
@Override
|
||||
public void writeTo(BufferedSink sink) throws IOException {
|
||||
BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
|
||||
body.writeTo(gzipSink);
|
||||
gzipSink.close();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r
|
||||
* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end --
|
||||
* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end --
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r
|
||||
* Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r
|
||||
@@ -15,19 +15,21 @@ package org.openapitools.client;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.internal.bind.util.ISO8601Utils;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import com.google.gson.JsonElement;
|
||||
import io.gsonfire.GsonFireBuilder;
|
||||
import okio.ByteString;
|
||||
import org.openapitools.client.model.*;
|
||||
import io.gsonfire.TypeSelector;
|
||||
import org.threeten.bp.LocalDate;
|
||||
import org.threeten.bp.OffsetDateTime;
|
||||
import org.threeten.bp.format.DateTimeFormatter;
|
||||
|
||||
import org.openapitools.client.model.*;
|
||||
import okio.ByteString;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.lang.reflect.Type;
|
||||
@@ -37,6 +39,7 @@ import java.text.ParsePosition;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class JSON {
|
||||
private Gson gson;
|
||||
@@ -49,7 +52,6 @@ public class JSON {
|
||||
|
||||
public static GsonBuilder createGson() {
|
||||
GsonFireBuilder fireBuilder = new GsonFireBuilder()
|
||||
|
||||
;
|
||||
GsonBuilder builder = fireBuilder.createGsonBuilder();
|
||||
return builder;
|
||||
@@ -57,7 +59,7 @@ public class JSON {
|
||||
|
||||
private static String getDiscriminatorValue(JsonElement readElement, String discriminatorField) {
|
||||
JsonElement element = readElement.getAsJsonObject().get(discriminatorField);
|
||||
if(null == element) {
|
||||
if (null == element) {
|
||||
throw new IllegalArgumentException("missing discriminator field: <" + discriminatorField + ">");
|
||||
}
|
||||
return element.getAsString();
|
||||
@@ -65,7 +67,7 @@ public class JSON {
|
||||
|
||||
private static Class getClassByDiscriminator(Map classByDiscriminatorValue, String discriminatorValue) {
|
||||
Class clazz = (Class) classByDiscriminatorValue.get(discriminatorValue.toUpperCase(Locale.ROOT));
|
||||
if(null == clazz) {
|
||||
if (null == clazz) {
|
||||
throw new IllegalArgumentException("cannot determine model class of name: <" + discriminatorValue + ">");
|
||||
}
|
||||
return clazz;
|
||||
@@ -138,9 +140,11 @@ public class JSON {
|
||||
} catch (JsonParseException e) {
|
||||
// Fallback processing when failed to parse JSON form response body:
|
||||
// return the response body string directly for the String return type;
|
||||
if (returnType.equals(String.class))
|
||||
if (returnType.equals(String.class)) {
|
||||
return (T) body;
|
||||
else throw (e);
|
||||
} else {
|
||||
throw (e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,8 +280,7 @@ public class JSON {
|
||||
|
||||
private DateFormat dateFormat;
|
||||
|
||||
public SqlDateTypeAdapter() {
|
||||
}
|
||||
public SqlDateTypeAdapter() {}
|
||||
|
||||
public SqlDateTypeAdapter(DateFormat dateFormat) {
|
||||
this.dateFormat = dateFormat;
|
||||
@@ -330,8 +333,7 @@ public class JSON {
|
||||
|
||||
private DateFormat dateFormat;
|
||||
|
||||
public DateTypeAdapter() {
|
||||
}
|
||||
public DateTypeAdapter() {}
|
||||
|
||||
public DateTypeAdapter(DateFormat dateFormat) {
|
||||
this.dateFormat = dateFormat;
|
||||
|
||||
@@ -24,13 +24,17 @@ public class Pair {
|
||||
}
|
||||
|
||||
private void setName(String name) {
|
||||
if (!isValidString(name)) return;
|
||||
if (!isValidString(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
private void setValue(String value) {
|
||||
if (!isValidString(value)) return;
|
||||
if (!isValidString(value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.value = value;
|
||||
}
|
||||
@@ -44,8 +48,13 @@ public class Pair {
|
||||
}
|
||||
|
||||
private boolean isValidString(String arg) {
|
||||
if (arg == null) return false;
|
||||
if (arg.trim().isEmpty()) return false;
|
||||
if (arg == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (arg.trim().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -24,8 +24,12 @@ public class StringUtil {
|
||||
*/
|
||||
public static boolean containsIgnoreCase(String[] array, String value) {
|
||||
for (String str : array) {
|
||||
if (value == null && str == null) return true;
|
||||
if (value != null && value.equalsIgnoreCase(str)) return true;
|
||||
if (value == null && str == null) {
|
||||
return true;
|
||||
}
|
||||
if (value != null && value.equalsIgnoreCase(str)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -43,7 +47,9 @@ public class StringUtil {
|
||||
*/
|
||||
public static String join(String[] array, String separator) {
|
||||
int len = array.length;
|
||||
if (len == 0) return "";
|
||||
if (len == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
StringBuilder out = new StringBuilder();
|
||||
out.append(array[0]);
|
||||
|
||||
@@ -70,16 +70,15 @@ public class FakeApi {
|
||||
|
||||
List<Pair> localVarQueryParams = new ArrayList<Pair>();
|
||||
List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
|
||||
|
||||
Map<String, String> localVarHeaderParams = new HashMap<String, String>();
|
||||
|
||||
Map<String, Object> localVarFormParams = new HashMap<String, Object>();
|
||||
|
||||
final String[] localVarAccepts = {
|
||||
|
||||
};
|
||||
final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
|
||||
if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
|
||||
if (localVarAccept != null) {
|
||||
localVarHeaderParams.put("Accept", localVarAccept);
|
||||
}
|
||||
|
||||
final String[] localVarContentTypes = {
|
||||
"application/json", "*_/ ' =end -- "
|
||||
@@ -87,7 +86,7 @@ public class FakeApi {
|
||||
final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
|
||||
localVarHeaderParams.put("Content-Type", localVarContentType);
|
||||
|
||||
if(progressListener != null) {
|
||||
if (progressListener != null) {
|
||||
apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
|
||||
@Override
|
||||
public com.squareup.okhttp.Response intercept(com.squareup.okhttp.Interceptor.Chain chain) throws IOException {
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.MediaType;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.RequestBody;
|
||||
import com.squareup.okhttp.Response;
|
||||
|
||||
import org.apache.oltu.oauth2.client.HttpClient;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthClientResponse;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class OAuthOkHttpClient implements HttpClient {
|
||||
private OkHttpClient client;
|
||||
|
||||
public OAuthOkHttpClient() {
|
||||
this.client = new OkHttpClient();
|
||||
}
|
||||
|
||||
public OAuthOkHttpClient(OkHttpClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends OAuthClientResponse> T execute(OAuthClientRequest request, Map<String, String> headers,
|
||||
String requestMethod, Class<T> responseClass)
|
||||
throws OAuthSystemException, OAuthProblemException {
|
||||
|
||||
MediaType mediaType = MediaType.parse("application/json");
|
||||
Request.Builder requestBuilder = new Request.Builder().url(request.getLocationUri());
|
||||
|
||||
if(headers != null) {
|
||||
for (Entry<String, String> entry : headers.entrySet()) {
|
||||
if (entry.getKey().equalsIgnoreCase("Content-Type")) {
|
||||
mediaType = MediaType.parse(entry.getValue());
|
||||
} else {
|
||||
requestBuilder.addHeader(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RequestBody body = request.getBody() != null ? RequestBody.create(mediaType, request.getBody()) : null;
|
||||
requestBuilder.method(requestMethod, body);
|
||||
|
||||
try {
|
||||
Response response = client.newCall(requestBuilder.build()).execute();
|
||||
return OAuthClientResponseFactory.createCustomResponse(
|
||||
response.body().string(),
|
||||
response.body().contentType().toString(),
|
||||
response.code(),
|
||||
responseClass);
|
||||
} catch (IOException e) {
|
||||
throw new OAuthSystemException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
// Nothing to do here
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
import com.squareup.okhttp.Interceptor;
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.Response;
|
||||
|
||||
import org.apache.oltu.oauth2.client.OAuthClient;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
|
||||
import org.apache.oltu.oauth2.common.message.types.GrantType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.Map;
|
||||
|
||||
public class RetryingOAuth extends OAuth implements Interceptor {
|
||||
private OAuthClient oAuthClient;
|
||||
|
||||
private TokenRequestBuilder tokenRequestBuilder;
|
||||
|
||||
public RetryingOAuth(OkHttpClient client, TokenRequestBuilder tokenRequestBuilder) {
|
||||
this.oAuthClient = new OAuthClient(new OAuthOkHttpClient(client));
|
||||
this.tokenRequestBuilder = tokenRequestBuilder;
|
||||
}
|
||||
|
||||
public RetryingOAuth(TokenRequestBuilder tokenRequestBuilder) {
|
||||
this(new OkHttpClient(), tokenRequestBuilder);
|
||||
}
|
||||
|
||||
public RetryingOAuth(
|
||||
String tokenUrl,
|
||||
String clientId,
|
||||
GrantType grantType,
|
||||
String clientSecret,
|
||||
Map<String, String> parameters
|
||||
) {
|
||||
this(OAuthClientRequest.tokenLocation(tokenUrl)
|
||||
.setClientId(clientId)
|
||||
.setGrantType(grantType)
|
||||
.setClientSecret(clientSecret));
|
||||
|
||||
if (parameters != null) {
|
||||
for (String paramName : parameters.keySet()) {
|
||||
tokenRequestBuilder.setParameter(paramName, parameters.get(paramName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
return retryingIntercept(chain, true);
|
||||
}
|
||||
|
||||
private Response retryingIntercept(Chain chain, boolean updateTokenAndRetryOnAuthorizationFailure) throws IOException {
|
||||
Request request = chain.request();
|
||||
|
||||
// If the request already has an authorization (e.g. Basic auth), proceed with the request as is
|
||||
if (request.header("Authorization") != null) {
|
||||
return chain.proceed(request);
|
||||
}
|
||||
|
||||
// Get the token if it has not yet been acquired
|
||||
if (getAccessToken() == null) {
|
||||
updateAccessToken(null);
|
||||
}
|
||||
|
||||
OAuthClientRequest oAuthRequest;
|
||||
if (getAccessToken() != null) {
|
||||
// Build the request
|
||||
Request.Builder requestBuilder = request.newBuilder();
|
||||
|
||||
String requestAccessToken = getAccessToken();
|
||||
try {
|
||||
oAuthRequest =
|
||||
new OAuthBearerClientRequest(request.urlString()).
|
||||
setAccessToken(requestAccessToken).
|
||||
buildHeaderMessage();
|
||||
} catch (OAuthSystemException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
||||
Map<String, String> headers = oAuthRequest.getHeaders();
|
||||
for (String headerName : headers.keySet()) {
|
||||
requestBuilder.addHeader(headerName, headers.get(headerName));
|
||||
}
|
||||
requestBuilder.url(oAuthRequest.getLocationUri());
|
||||
|
||||
// Execute the request
|
||||
Response response = chain.proceed(requestBuilder.build());
|
||||
|
||||
// 401/403 response codes most likely indicate an expired access token, unless it happens two times in a row
|
||||
if (
|
||||
response != null &&
|
||||
( response.code() == HttpURLConnection.HTTP_UNAUTHORIZED ||
|
||||
response.code() == HttpURLConnection.HTTP_FORBIDDEN ) &&
|
||||
updateTokenAndRetryOnAuthorizationFailure
|
||||
) {
|
||||
try {
|
||||
if (updateAccessToken(requestAccessToken)) {
|
||||
response.body().close();
|
||||
return retryingIntercept(chain, false);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
response.body().close();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
else {
|
||||
return chain.proceed(chain.request());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the access token has been updated
|
||||
*/
|
||||
public synchronized boolean updateAccessToken(String requestAccessToken) throws IOException {
|
||||
if (getAccessToken() == null || getAccessToken().equals(requestAccessToken)) {
|
||||
try {
|
||||
OAuthJSONAccessTokenResponse accessTokenResponse =
|
||||
oAuthClient.accessToken(tokenRequestBuilder.buildBodyMessage());
|
||||
if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) {
|
||||
setAccessToken(accessTokenResponse.getAccessToken());
|
||||
return !getAccessToken().equals(requestAccessToken);
|
||||
}
|
||||
} catch (OAuthSystemException | OAuthProblemException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public TokenRequestBuilder getTokenRequestBuilder() {
|
||||
return tokenRequestBuilder;
|
||||
}
|
||||
|
||||
public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) {
|
||||
this.tokenRequestBuilder = tokenRequestBuilder;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r
|
||||
* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end --
|
||||
* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end --
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r
|
||||
* Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r
|
||||
@@ -13,11 +13,16 @@
|
||||
|
||||
package org.openapitools.client.model;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Arrays;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.annotations.JsonAdapter;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r
|
||||
@@ -70,7 +75,7 @@ public class ModelReturn {
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("class ModelReturn {\n");
|
||||
|
||||
|
||||
sb.append(" _return: ").append(toIndentedString(_return)).append("\n");
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
|
||||
@@ -99,6 +99,7 @@ dependencies {
|
||||
compile 'com.squareup.okhttp:logging-interceptor:2.7.5'
|
||||
compile 'com.google.code.gson:gson:2.8.1'
|
||||
compile 'io.gsonfire:gson-fire:1.8.0'
|
||||
compile group: 'org.apache.oltu.oauth2', name: 'org.apache.oltu.oauth2.client', version: '1.0.1'
|
||||
compile 'org.threeten:threetenbp:1.3.5'
|
||||
testCompile 'junit:junit:4.12'
|
||||
}
|
||||
|
||||
@@ -212,6 +212,11 @@
|
||||
<groupId>io.gsonfire</groupId>
|
||||
<artifactId>gson-fire</artifactId>
|
||||
<version>${gson-fire-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.oltu.oauth2</groupId>
|
||||
<artifactId>org.apache.oltu.oauth2.client</artifactId>
|
||||
<version>1.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.threeten</groupId>
|
||||
|
||||
@@ -23,6 +23,9 @@ import org.threeten.bp.LocalDate;
|
||||
import org.threeten.bp.OffsetDateTime;
|
||||
import org.threeten.bp.format.DateTimeFormatter;
|
||||
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
import org.apache.oltu.oauth2.common.message.types.GrantType;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -49,6 +52,7 @@ import org.openapitools.client.auth.Authentication;
|
||||
import org.openapitools.client.auth.HttpBasicAuth;
|
||||
import org.openapitools.client.auth.ApiKeyAuth;
|
||||
import org.openapitools.client.auth.OAuth;
|
||||
import org.openapitools.client.auth.RetryingOAuth;
|
||||
|
||||
public class ApiClient {
|
||||
|
||||
@@ -77,6 +81,39 @@ public class ApiClient {
|
||||
* Constructor for ApiClient
|
||||
*/
|
||||
public ApiClient() {
|
||||
init();
|
||||
|
||||
// Setup authentications (key: authentication name, value: authentication).
|
||||
authentications.put("api_key", new ApiKeyAuth("header", "api_key"));
|
||||
authentications.put("api_key_query", new ApiKeyAuth("query", "api_key_query"));
|
||||
authentications.put("http_basic_test", new HttpBasicAuth());
|
||||
authentications.put("petstore_auth", new OAuth());
|
||||
// Prevent the authentications from being modified.
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor for ApiClient to support access token retry on 401/403
|
||||
*/
|
||||
public ApiClient(
|
||||
String clientId,
|
||||
String clientSecret,
|
||||
Map<String, String> parameters
|
||||
) {
|
||||
init();
|
||||
|
||||
RetryingOAuth retryingOAuth = new RetryingOAuth("", clientId, GrantType.valueOf("implicit"), clientSecret, parameters);
|
||||
authentications.put(
|
||||
"petstore_auth",
|
||||
retryingOAuth
|
||||
);
|
||||
httpClient.interceptors().add(retryingOAuth);
|
||||
|
||||
// Prevent the authentications from being modified.
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
httpClient = new OkHttpClient();
|
||||
|
||||
|
||||
@@ -87,14 +124,7 @@ public class ApiClient {
|
||||
// Set default User-Agent.
|
||||
setUserAgent("OpenAPI-Generator/1.0.0/java");
|
||||
|
||||
// Setup authentications (key: authentication name, value: authentication).
|
||||
authentications = new HashMap<String, Authentication>();
|
||||
authentications.put("api_key", new ApiKeyAuth("header", "api_key"));
|
||||
authentications.put("api_key_query", new ApiKeyAuth("query", "api_key_query"));
|
||||
authentications.put("http_basic_test", new HttpBasicAuth());
|
||||
authentications.put("petstore_auth", new OAuth());
|
||||
// Prevent the authentications from being modified.
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -484,6 +514,20 @@ public class ApiClient {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
|
||||
* @return Token request builder
|
||||
*/
|
||||
public TokenRequestBuilder getTokenEndPoint() {
|
||||
for (Authentication apiAuth : authentications.values()) {
|
||||
if (apiAuth instanceof RetryingOAuth) {
|
||||
RetryingOAuth retryingOAuth = (RetryingOAuth) apiAuth;
|
||||
return retryingOAuth.getTokenRequestBuilder();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the given parameter object into string.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.MediaType;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.RequestBody;
|
||||
import com.squareup.okhttp.Response;
|
||||
|
||||
import org.apache.oltu.oauth2.client.HttpClient;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthClientResponse;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class OAuthOkHttpClient implements HttpClient {
|
||||
private OkHttpClient client;
|
||||
|
||||
public OAuthOkHttpClient() {
|
||||
this.client = new OkHttpClient();
|
||||
}
|
||||
|
||||
public OAuthOkHttpClient(OkHttpClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends OAuthClientResponse> T execute(OAuthClientRequest request, Map<String, String> headers,
|
||||
String requestMethod, Class<T> responseClass)
|
||||
throws OAuthSystemException, OAuthProblemException {
|
||||
|
||||
MediaType mediaType = MediaType.parse("application/json");
|
||||
Request.Builder requestBuilder = new Request.Builder().url(request.getLocationUri());
|
||||
|
||||
if(headers != null) {
|
||||
for (Entry<String, String> entry : headers.entrySet()) {
|
||||
if (entry.getKey().equalsIgnoreCase("Content-Type")) {
|
||||
mediaType = MediaType.parse(entry.getValue());
|
||||
} else {
|
||||
requestBuilder.addHeader(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RequestBody body = request.getBody() != null ? RequestBody.create(mediaType, request.getBody()) : null;
|
||||
requestBuilder.method(requestMethod, body);
|
||||
|
||||
try {
|
||||
Response response = client.newCall(requestBuilder.build()).execute();
|
||||
return OAuthClientResponseFactory.createCustomResponse(
|
||||
response.body().string(),
|
||||
response.body().contentType().toString(),
|
||||
response.code(),
|
||||
responseClass);
|
||||
} catch (IOException e) {
|
||||
throw new OAuthSystemException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
// Nothing to do here
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
import com.squareup.okhttp.Interceptor;
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.Response;
|
||||
|
||||
import org.apache.oltu.oauth2.client.OAuthClient;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
|
||||
import org.apache.oltu.oauth2.common.message.types.GrantType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.Map;
|
||||
|
||||
public class RetryingOAuth extends OAuth implements Interceptor {
|
||||
private OAuthClient oAuthClient;
|
||||
|
||||
private TokenRequestBuilder tokenRequestBuilder;
|
||||
|
||||
public RetryingOAuth(OkHttpClient client, TokenRequestBuilder tokenRequestBuilder) {
|
||||
this.oAuthClient = new OAuthClient(new OAuthOkHttpClient(client));
|
||||
this.tokenRequestBuilder = tokenRequestBuilder;
|
||||
}
|
||||
|
||||
public RetryingOAuth(TokenRequestBuilder tokenRequestBuilder) {
|
||||
this(new OkHttpClient(), tokenRequestBuilder);
|
||||
}
|
||||
|
||||
public RetryingOAuth(
|
||||
String tokenUrl,
|
||||
String clientId,
|
||||
GrantType grantType,
|
||||
String clientSecret,
|
||||
Map<String, String> parameters
|
||||
) {
|
||||
this(OAuthClientRequest.tokenLocation(tokenUrl)
|
||||
.setClientId(clientId)
|
||||
.setGrantType(grantType)
|
||||
.setClientSecret(clientSecret));
|
||||
|
||||
if (parameters != null) {
|
||||
for (String paramName : parameters.keySet()) {
|
||||
tokenRequestBuilder.setParameter(paramName, parameters.get(paramName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
return retryingIntercept(chain, true);
|
||||
}
|
||||
|
||||
private Response retryingIntercept(Chain chain, boolean updateTokenAndRetryOnAuthorizationFailure) throws IOException {
|
||||
Request request = chain.request();
|
||||
|
||||
// If the request already has an authorization (e.g. Basic auth), proceed with the request as is
|
||||
if (request.header("Authorization") != null) {
|
||||
return chain.proceed(request);
|
||||
}
|
||||
|
||||
// Get the token if it has not yet been acquired
|
||||
if (getAccessToken() == null) {
|
||||
updateAccessToken(null);
|
||||
}
|
||||
|
||||
OAuthClientRequest oAuthRequest;
|
||||
if (getAccessToken() != null) {
|
||||
// Build the request
|
||||
Request.Builder requestBuilder = request.newBuilder();
|
||||
|
||||
String requestAccessToken = getAccessToken();
|
||||
try {
|
||||
oAuthRequest =
|
||||
new OAuthBearerClientRequest(request.urlString()).
|
||||
setAccessToken(requestAccessToken).
|
||||
buildHeaderMessage();
|
||||
} catch (OAuthSystemException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
||||
Map<String, String> headers = oAuthRequest.getHeaders();
|
||||
for (String headerName : headers.keySet()) {
|
||||
requestBuilder.addHeader(headerName, headers.get(headerName));
|
||||
}
|
||||
requestBuilder.url(oAuthRequest.getLocationUri());
|
||||
|
||||
// Execute the request
|
||||
Response response = chain.proceed(requestBuilder.build());
|
||||
|
||||
// 401/403 response codes most likely indicate an expired access token, unless it happens two times in a row
|
||||
if (
|
||||
response != null &&
|
||||
( response.code() == HttpURLConnection.HTTP_UNAUTHORIZED ||
|
||||
response.code() == HttpURLConnection.HTTP_FORBIDDEN ) &&
|
||||
updateTokenAndRetryOnAuthorizationFailure
|
||||
) {
|
||||
try {
|
||||
if (updateAccessToken(requestAccessToken)) {
|
||||
response.body().close();
|
||||
return retryingIntercept(chain, false);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
response.body().close();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
else {
|
||||
return chain.proceed(chain.request());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the access token has been updated
|
||||
*/
|
||||
public synchronized boolean updateAccessToken(String requestAccessToken) throws IOException {
|
||||
if (getAccessToken() == null || getAccessToken().equals(requestAccessToken)) {
|
||||
try {
|
||||
OAuthJSONAccessTokenResponse accessTokenResponse =
|
||||
oAuthClient.accessToken(tokenRequestBuilder.buildBodyMessage());
|
||||
if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) {
|
||||
setAccessToken(accessTokenResponse.getAccessToken());
|
||||
return !getAccessToken().equals(requestAccessToken);
|
||||
}
|
||||
} catch (OAuthSystemException | OAuthProblemException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public TokenRequestBuilder getTokenRequestBuilder() {
|
||||
return tokenRequestBuilder;
|
||||
}
|
||||
|
||||
public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) {
|
||||
this.tokenRequestBuilder = tokenRequestBuilder;
|
||||
}
|
||||
}
|
||||
@@ -99,6 +99,7 @@ dependencies {
|
||||
compile 'com.squareup.okhttp:logging-interceptor:2.7.5'
|
||||
compile 'com.google.code.gson:gson:2.8.1'
|
||||
compile 'io.gsonfire:gson-fire:1.8.0'
|
||||
compile group: 'org.apache.oltu.oauth2', name: 'org.apache.oltu.oauth2.client', version: '1.0.1'
|
||||
compile 'org.threeten:threetenbp:1.3.5'
|
||||
testCompile 'junit:junit:4.12'
|
||||
}
|
||||
|
||||
@@ -212,6 +212,11 @@
|
||||
<groupId>io.gsonfire</groupId>
|
||||
<artifactId>gson-fire</artifactId>
|
||||
<version>${gson-fire-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.oltu.oauth2</groupId>
|
||||
<artifactId>org.apache.oltu.oauth2.client</artifactId>
|
||||
<version>1.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.threeten</groupId>
|
||||
|
||||
@@ -23,6 +23,9 @@ import org.threeten.bp.LocalDate;
|
||||
import org.threeten.bp.OffsetDateTime;
|
||||
import org.threeten.bp.format.DateTimeFormatter;
|
||||
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
import org.apache.oltu.oauth2.common.message.types.GrantType;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -49,6 +52,7 @@ import org.openapitools.client.auth.Authentication;
|
||||
import org.openapitools.client.auth.HttpBasicAuth;
|
||||
import org.openapitools.client.auth.ApiKeyAuth;
|
||||
import org.openapitools.client.auth.OAuth;
|
||||
import org.openapitools.client.auth.RetryingOAuth;
|
||||
|
||||
public class ApiClient {
|
||||
|
||||
@@ -77,6 +81,39 @@ public class ApiClient {
|
||||
* Constructor for ApiClient
|
||||
*/
|
||||
public ApiClient() {
|
||||
init();
|
||||
|
||||
// Setup authentications (key: authentication name, value: authentication).
|
||||
authentications.put("api_key", new ApiKeyAuth("header", "api_key"));
|
||||
authentications.put("api_key_query", new ApiKeyAuth("query", "api_key_query"));
|
||||
authentications.put("http_basic_test", new HttpBasicAuth());
|
||||
authentications.put("petstore_auth", new OAuth());
|
||||
// Prevent the authentications from being modified.
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor for ApiClient to support access token retry on 401/403
|
||||
*/
|
||||
public ApiClient(
|
||||
String clientId,
|
||||
String clientSecret,
|
||||
Map<String, String> parameters
|
||||
) {
|
||||
init();
|
||||
|
||||
RetryingOAuth retryingOAuth = new RetryingOAuth("", clientId, GrantType.valueOf("implicit"), clientSecret, parameters);
|
||||
authentications.put(
|
||||
"petstore_auth",
|
||||
retryingOAuth
|
||||
);
|
||||
httpClient.interceptors().add(retryingOAuth);
|
||||
|
||||
// Prevent the authentications from being modified.
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
httpClient = new OkHttpClient();
|
||||
|
||||
|
||||
@@ -87,14 +124,7 @@ public class ApiClient {
|
||||
// Set default User-Agent.
|
||||
setUserAgent("OpenAPI-Generator/1.0.0/java");
|
||||
|
||||
// Setup authentications (key: authentication name, value: authentication).
|
||||
authentications = new HashMap<String, Authentication>();
|
||||
authentications.put("api_key", new ApiKeyAuth("header", "api_key"));
|
||||
authentications.put("api_key_query", new ApiKeyAuth("query", "api_key_query"));
|
||||
authentications.put("http_basic_test", new HttpBasicAuth());
|
||||
authentications.put("petstore_auth", new OAuth());
|
||||
// Prevent the authentications from being modified.
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -484,6 +514,20 @@ public class ApiClient {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
|
||||
* @return Token request builder
|
||||
*/
|
||||
public TokenRequestBuilder getTokenEndPoint() {
|
||||
for (Authentication apiAuth : authentications.values()) {
|
||||
if (apiAuth instanceof RetryingOAuth) {
|
||||
RetryingOAuth retryingOAuth = (RetryingOAuth) apiAuth;
|
||||
return retryingOAuth.getTokenRequestBuilder();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the given parameter object into string.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.MediaType;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.RequestBody;
|
||||
import com.squareup.okhttp.Response;
|
||||
|
||||
import org.apache.oltu.oauth2.client.HttpClient;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthClientResponse;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class OAuthOkHttpClient implements HttpClient {
|
||||
private OkHttpClient client;
|
||||
|
||||
public OAuthOkHttpClient() {
|
||||
this.client = new OkHttpClient();
|
||||
}
|
||||
|
||||
public OAuthOkHttpClient(OkHttpClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends OAuthClientResponse> T execute(OAuthClientRequest request, Map<String, String> headers,
|
||||
String requestMethod, Class<T> responseClass)
|
||||
throws OAuthSystemException, OAuthProblemException {
|
||||
|
||||
MediaType mediaType = MediaType.parse("application/json");
|
||||
Request.Builder requestBuilder = new Request.Builder().url(request.getLocationUri());
|
||||
|
||||
if(headers != null) {
|
||||
for (Entry<String, String> entry : headers.entrySet()) {
|
||||
if (entry.getKey().equalsIgnoreCase("Content-Type")) {
|
||||
mediaType = MediaType.parse(entry.getValue());
|
||||
} else {
|
||||
requestBuilder.addHeader(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RequestBody body = request.getBody() != null ? RequestBody.create(mediaType, request.getBody()) : null;
|
||||
requestBuilder.method(requestMethod, body);
|
||||
|
||||
try {
|
||||
Response response = client.newCall(requestBuilder.build()).execute();
|
||||
return OAuthClientResponseFactory.createCustomResponse(
|
||||
response.body().string(),
|
||||
response.body().contentType().toString(),
|
||||
response.code(),
|
||||
responseClass);
|
||||
} catch (IOException e) {
|
||||
throw new OAuthSystemException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
// Nothing to do here
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package org.openapitools.client.auth;
|
||||
|
||||
import com.squareup.okhttp.Interceptor;
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.Response;
|
||||
|
||||
import org.apache.oltu.oauth2.client.OAuthClient;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
|
||||
import org.apache.oltu.oauth2.common.message.types.GrantType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.Map;
|
||||
|
||||
public class RetryingOAuth extends OAuth implements Interceptor {
|
||||
private OAuthClient oAuthClient;
|
||||
|
||||
private TokenRequestBuilder tokenRequestBuilder;
|
||||
|
||||
public RetryingOAuth(OkHttpClient client, TokenRequestBuilder tokenRequestBuilder) {
|
||||
this.oAuthClient = new OAuthClient(new OAuthOkHttpClient(client));
|
||||
this.tokenRequestBuilder = tokenRequestBuilder;
|
||||
}
|
||||
|
||||
public RetryingOAuth(TokenRequestBuilder tokenRequestBuilder) {
|
||||
this(new OkHttpClient(), tokenRequestBuilder);
|
||||
}
|
||||
|
||||
public RetryingOAuth(
|
||||
String tokenUrl,
|
||||
String clientId,
|
||||
GrantType grantType,
|
||||
String clientSecret,
|
||||
Map<String, String> parameters
|
||||
) {
|
||||
this(OAuthClientRequest.tokenLocation(tokenUrl)
|
||||
.setClientId(clientId)
|
||||
.setGrantType(grantType)
|
||||
.setClientSecret(clientSecret));
|
||||
|
||||
if (parameters != null) {
|
||||
for (String paramName : parameters.keySet()) {
|
||||
tokenRequestBuilder.setParameter(paramName, parameters.get(paramName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
return retryingIntercept(chain, true);
|
||||
}
|
||||
|
||||
private Response retryingIntercept(Chain chain, boolean updateTokenAndRetryOnAuthorizationFailure) throws IOException {
|
||||
Request request = chain.request();
|
||||
|
||||
// If the request already has an authorization (e.g. Basic auth), proceed with the request as is
|
||||
if (request.header("Authorization") != null) {
|
||||
return chain.proceed(request);
|
||||
}
|
||||
|
||||
// Get the token if it has not yet been acquired
|
||||
if (getAccessToken() == null) {
|
||||
updateAccessToken(null);
|
||||
}
|
||||
|
||||
OAuthClientRequest oAuthRequest;
|
||||
if (getAccessToken() != null) {
|
||||
// Build the request
|
||||
Request.Builder requestBuilder = request.newBuilder();
|
||||
|
||||
String requestAccessToken = getAccessToken();
|
||||
try {
|
||||
oAuthRequest =
|
||||
new OAuthBearerClientRequest(request.urlString()).
|
||||
setAccessToken(requestAccessToken).
|
||||
buildHeaderMessage();
|
||||
} catch (OAuthSystemException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
||||
Map<String, String> headers = oAuthRequest.getHeaders();
|
||||
for (String headerName : headers.keySet()) {
|
||||
requestBuilder.addHeader(headerName, headers.get(headerName));
|
||||
}
|
||||
requestBuilder.url(oAuthRequest.getLocationUri());
|
||||
|
||||
// Execute the request
|
||||
Response response = chain.proceed(requestBuilder.build());
|
||||
|
||||
// 401/403 response codes most likely indicate an expired access token, unless it happens two times in a row
|
||||
if (
|
||||
response != null &&
|
||||
( response.code() == HttpURLConnection.HTTP_UNAUTHORIZED ||
|
||||
response.code() == HttpURLConnection.HTTP_FORBIDDEN ) &&
|
||||
updateTokenAndRetryOnAuthorizationFailure
|
||||
) {
|
||||
try {
|
||||
if (updateAccessToken(requestAccessToken)) {
|
||||
response.body().close();
|
||||
return retryingIntercept(chain, false);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
response.body().close();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
else {
|
||||
return chain.proceed(chain.request());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the access token has been updated
|
||||
*/
|
||||
public synchronized boolean updateAccessToken(String requestAccessToken) throws IOException {
|
||||
if (getAccessToken() == null || getAccessToken().equals(requestAccessToken)) {
|
||||
try {
|
||||
OAuthJSONAccessTokenResponse accessTokenResponse =
|
||||
oAuthClient.accessToken(tokenRequestBuilder.buildBodyMessage());
|
||||
if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) {
|
||||
setAccessToken(accessTokenResponse.getAccessToken());
|
||||
return !getAccessToken().equals(requestAccessToken);
|
||||
}
|
||||
} catch (OAuthSystemException | OAuthProblemException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public TokenRequestBuilder getTokenRequestBuilder() {
|
||||
return tokenRequestBuilder;
|
||||
}
|
||||
|
||||
public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) {
|
||||
this.tokenRequestBuilder = tokenRequestBuilder;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user