forked from OpenAPITools/openapi-generator
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[okhttp-gson] Add support for OAuth access token retry (OpenAPITools#…
…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
- Loading branch information
1 parent
8b479de
commit 4819e84
Showing
29 changed files
with
1,166 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
68 changes: 68 additions & 0 deletions
68
...i-generator/src/main/resources/Java/libraries/okhttp-gson/auth/OAuthOkHttpClient.mustache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} | ||
} |
147 changes: 147 additions & 0 deletions
147
...enapi-generator/src/main/resources/Java/libraries/okhttp-gson/auth/RetryingOAuth.mustache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
samples/client/petstore-security-test/java/okhttp-gson/.openapi-generator/VERSION
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
3.2.3-SNAPSHOT | ||
3.3.0-SNAPSHOT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.