Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ENG-1328] Make necessary generator changes for splitit java SDK to compile #309

Merged
merged 1 commit into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public class ApiClient extends ApiClientCustom {
* Basic constructor for ApiClient
*/
public ApiClient() {
this(null, null);
this((OkHttpClient) null, null);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

call can be ambiguous in some scenarios so needs a cast to compile

}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{{>licenseInfo}}

package {{invokerPackage}}.auth;

import {{invokerPackage}}.Pair;
import {{invokerPackage}}.ApiException;

import java.net.URI;
import java.util.Map;
import java.util.List;

{{>generatedAnnotation}}
public class OAuth implements Authentication {
private String accessToken;

public String getAccessToken() {
return accessToken;
}

public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}

@Override
public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams, Map<String, String> cookieParams,
String payload, String method) throws ApiException {
if (accessToken != null) {
headerParams.put("Authorization", "Bearer " + accessToken);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
{{#hasOAuthMethods}}
package {{invokerPackage}}.auth;

import {{invokerPackage}}.ApiException;
import {{invokerPackage}}.Pair;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.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.net.URI;
import java.util.Map;
import java.util.List;

public class RetryingOAuth extends OAuth implements Interceptor {
private OAuthClient oAuthClient;

private TokenRequestBuilder tokenRequestBuilder;

/**
* @param client An OkHttp client
* @param tokenRequestBuilder A token request builder
*/
public RetryingOAuth(OkHttpClient client, TokenRequestBuilder tokenRequestBuilder) {
this.oAuthClient = new OAuthClient(new OAuthOkHttpClient(client));
this.tokenRequestBuilder = tokenRequestBuilder;
}

/**
* @param tokenRequestBuilder A token request builder
*/
public RetryingOAuth(TokenRequestBuilder tokenRequestBuilder) {
this(new OkHttpClient(), tokenRequestBuilder);
}

/**
* @param tokenUrl The token URL to be used for this OAuth2 flow.
* Applicable to the following OAuth2 flows: "password", "clientCredentials" and "authorizationCode".
* The value must be an absolute URL.
* @param clientId The OAuth2 client ID for the "clientCredentials" flow.
* @param flow OAuth flow.
* @param clientSecret The OAuth2 client secret for the "clientCredentials" flow.
* @param parameters A map of string.
*/
public RetryingOAuth(
String tokenUrl,
String clientId,
OAuthFlow flow,
String clientSecret,
Map<String, String> parameters
) {
this(OAuthClientRequest.tokenLocation(tokenUrl)
.setClientId(clientId)
.setClientSecret(clientSecret));
setFlow(flow);
if (parameters != null) {
for (Map.Entry<String, String> entry : parameters.entrySet()) {
tokenRequestBuilder.setParameter(entry.getKey(), entry.getValue());
}
}
}

/**
* Set the OAuth flow
*
* @param flow The OAuth flow.
*/
public void setFlow(OAuthFlow flow) {
switch(flow) {
case ACCESS_CODE:
tokenRequestBuilder.setGrantType(GrantType.AUTHORIZATION_CODE);
break;
case IMPLICIT:
tokenRequestBuilder.setGrantType(GrantType.IMPLICIT);
break;
case PASSWORD:
tokenRequestBuilder.setGrantType(GrantType.PASSWORD);
break;
case APPLICATION:
tokenRequestBuilder.setGrantType(GrantType.CLIENT_CREDENTIALS);
break;
default:
break;
}
}

@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.url().toString()).
setAccessToken(requestAccessToken).
buildHeaderMessage();
} catch (OAuthSystemException e) {
throw new IOException(e);
}

Map<String, String> headers = oAuthRequest.getHeaders();
for (Map.Entry<String, String> entry : headers.entrySet()) {
requestBuilder.addHeader(entry.getKey(), entry.getValue());
}
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
*
* @param requestAccessToken the request access token
* @return True if the update is successful
* @throws java.io.IOException If fail to update the access token
*/
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());
}
} catch (OAuthSystemException | OAuthProblemException e) {
throw new IOException(e);
}
}
return getAccessToken() == null || !getAccessToken().equals(requestAccessToken);
}

/**
* Gets the token request builder
*
* @return A token request builder
*/
public TokenRequestBuilder getTokenRequestBuilder() {
return tokenRequestBuilder;
}

/**
* Sets the token request builder
*
* @param tokenRequestBuilder Token request builder
*/
public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) {
this.tokenRequestBuilder = tokenRequestBuilder;
}

// Applying authorization to parameters is performed in the retryingIntercept method
@Override
public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams, Map<String, String> cookieParams,
String payload, String method) throws ApiException {
// No implementation necessary
}
}
{{/hasOAuthMethods}}