Skip to content

Commit

Permalink
fix for #161
Browse files Browse the repository at this point in the history
  • Loading branch information
ssvaidyanathan committed Aug 22, 2023
1 parent 92fefb6 commit 87fdac7
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 173 deletions.
7 changes: 6 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@
<artifactId>google-http-client-apache</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-apache-v2</artifactId>
<version>1.43.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
Expand Down Expand Up @@ -226,7 +231,7 @@
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-oauth2-http</artifactId>
<version>0.18.0</version>
<version>1.19.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/apigee/edge/config/rest/RestUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -1098,7 +1098,7 @@ private HttpResponse executeAPI(ServerProfile profile, HttpRequest request)
else if(profile.getServiceAccountJSONFile()!=null && !profile.getServiceAccountJSONFile().equalsIgnoreCase("")) {
logger.info("Using the service account file to generate a token");
File serviceAccountJSON = new File(profile.getServiceAccountJSONFile());
accessToken = client.getGoogleAccessToken(serviceAccountJSON);
accessToken = client.getGoogleAccessToken(serviceAccountJSON, profile);
}
else {
logger.error("Service Account file or bearer token is missing");
Expand Down
222 changes: 51 additions & 171 deletions src/main/java/com/apigee/mgmtapi/sdk/client/MgmtAPIClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,205 +4,85 @@
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.Charset;

import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.routing.HttpRoutePlanner;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.ProxyAuthenticationStrategy;
import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.apigee.mgmtapi.sdk.core.AppConfig;
import com.apigee.mgmtapi.sdk.model.AccessToken;
import com.apigee.mgmtapi.sdk.service.FileService;
import com.apigee.edge.config.utils.ServerProfile;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.apache.v2.ApacheHttpTransport;
import com.google.auth.http.HttpTransportFactory;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.gson.Gson;

public class MgmtAPIClient {

private static final Logger logger = LogManager.getLogger(MgmtAPIClient.class);


/**
* To get the Access Token Management URL, client_id and client_secret needs
* to be passed through a config file whose full path is passed as system
* property like -DconfigFile.path="/to/dir/config.properties"
*
* @param username
* @param password
* @return
* @throws Exception
*/
public AccessToken getAccessToken(String username, String password) throws Exception {
Environment env = this.getConfigProperties();
if (env == null) {
logger.error("Config file missing");
throw new Exception("Config file missing");
}
return getAccessToken(env.getProperty("mgmt.login.url"), env.getProperty("mgmt.login.client.id"),
env.getProperty("mgmt.login.client.secret"), username, password);
}

/**
* To get the Access Token Management URL, client_id and client_secret needs
* to be passed through a config file whose full path is passed as system
* property like -DconfigFile.path="/to/dir/config.properties"
*
* @param username
* @param password
* @param mfa
* @param proxyHost
* @param proxyPort
* @param proxyUsername
* @param proxyPassword
* @return
* @throws Exception
*/
public AccessToken getAccessToken(String username, String password, String mfa) throws Exception {
Environment env = this.getConfigProperties();
if (env == null) {
logger.error("Config file missing");
throw new Exception("Config file missing");
}
if (mfa == null || mfa.equals("")) {
logger.error("mfa cannot be empty");
throw new Exception("mfa cannot be empty");
}
return getAccessToken(env.getProperty("mgmt.login.mfa.url")+mfa, env.getProperty("mgmt.login.client.id"),
env.getProperty("mgmt.login.client.secret"), username, password);
}
public static HttpTransportFactory getHttpTransportFactory(String proxyHost, int proxyPort, String proxyUsername, String proxyPassword) {
HttpHost proxyHostDetails = new HttpHost(proxyHost, proxyPort);
HttpRoutePlanner httpRoutePlanner = new DefaultProxyRoutePlanner(proxyHostDetails);

CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
new AuthScope(proxyHostDetails.getHostName(), proxyHostDetails.getPort()),
new UsernamePasswordCredentials(proxyUsername, proxyPassword)
);

/**
* To get Access Token
* @param url
* @param clientId
* @param client_secret
* @param username
* @param password
* @param mfa
* @return
* @throws Exception
*/
public AccessToken getAccessToken(String url, String clientId, String client_secret, String username,
String password, String mfa) throws Exception {
return getAccessToken(url+"?mfa_token="+mfa, clientId, client_secret, username, password);
}

/**
* To get the Access Token
*
* @param url
* @param clientId
* @param client_secret
* @param username
* @param password
* @return
* @throws Exception
*/
public AccessToken getAccessToken(String url, String clientId, String client_secret, String username,
String password) throws Exception {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
AccessToken token = new AccessToken();
ResponseEntity<String> result = null;
try {
headers.add("Authorization", "Basic "
+ new String(Base64.encode((clientId + ":" + client_secret).getBytes()), Charset.forName("UTF-8")));
headers.add("Content-Type", "application/x-www-form-urlencoded");
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("username", username);
map.add("password", password);
map.add("grant_type", "password");
HttpEntity<Object> request = new HttpEntity<Object>(map, headers);
result = restTemplate.postForEntity(url, request, String.class);
if (result.getStatusCode().equals(HttpStatus.OK)) {
Gson gson = new Gson();
token = gson.fromJson(result.getBody(), AccessToken.class);
HttpClient httpClient = ApacheHttpTransport.newDefaultHttpClientBuilder()
.setRoutePlanner(httpRoutePlanner)
.setProxyAuthenticationStrategy(ProxyAuthenticationStrategy.INSTANCE)
.setDefaultCredentialsProvider(credentialsProvider)
.build();

}
} catch (Exception e) {
logger.error(e.getMessage());
throw e;
}
return token;

}
final HttpTransport httpTransport = new ApacheHttpTransport(httpClient);
return new HttpTransportFactory() {
@Override
public HttpTransport create() {
return httpTransport;
}
};
}

/**
* To get the Access Token from Refresh Token
*
* @param url
* @param clientId
* @param client_secret
* @param username
* @param password
* @return
* @throws Exception
*/
public AccessToken getAccessTokenFromRefreshToken(String url, String clientId, String client_secret, String refreshToken) throws Exception {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
AccessToken token = new AccessToken();
ResponseEntity<String> result = null;
try {
headers.add("Authorization", "Basic "
+ new String(Base64.encode((clientId + ":" + client_secret).getBytes()), Charset.forName("UTF-8")));
headers.add("Content-Type", "application/x-www-form-urlencoded");
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("refresh_token", refreshToken);
map.add("grant_type", "refresh_token");
HttpEntity<Object> request = new HttpEntity<Object>(map, headers);
result = restTemplate.postForEntity(url, request, String.class);
if (result.getStatusCode().equals(HttpStatus.OK)) {
Gson gson = new Gson();
token = gson.fromJson(result.getBody(), AccessToken.class);

}
} catch (Exception e) {
logger.error("Refresh Token could be invalid or expired: "+e.getMessage());
throw e;
}
return token;

}

/**
* Fetch the properties from the property file passed as system argument (-DconfigFile.path)
* @return
*/
public Environment getConfigProperties() {
AbstractApplicationContext context;
FileService service = null;
try {
if (System.getProperty("configFile.path") != null
&& !System.getProperty("configFile.path").equalsIgnoreCase("")) {
context = new AnnotationConfigApplicationContext(AppConfig.class);
service = (FileService) context.getBean("fileService");
} else
return null;
} catch (Exception e) {
logger.error(e.getMessage());
}
return service.getEnvironment();
}

/**
* To get the Google Service Account Access Token
*
* @param serviceAccountFilePath
* @param profile
* @return
* @throws Exception
*/
public String getGoogleAccessToken(File serviceAccountJSON) throws Exception {
public String getGoogleAccessToken(File serviceAccountJSON, ServerProfile profile) throws Exception {
GoogleCredentials credentials;
try {
credentials = GoogleCredentials.fromStream(new FileInputStream(serviceAccountJSON))
.createScoped("https://www.googleapis.com/auth/cloud-platform");
if(profile.getHasProxy()) {
logger.info("Using the proxy settings to generate the token");
HttpTransportFactory httpTransportFactory = getHttpTransportFactory(
profile.getProxyServer(), profile.getProxyPort(), profile.getProxyUsername(), profile.getProxyPassword());
credentials = GoogleCredentials.fromStream(new FileInputStream(serviceAccountJSON), httpTransportFactory)
.createScoped("https://www.googleapis.com/auth/cloud-platform");
}
else {
credentials = GoogleCredentials.fromStream(new FileInputStream(serviceAccountJSON))
.createScoped("https://www.googleapis.com/auth/cloud-platform");
}
credentials.refreshIfExpired();
com.google.auth.oauth2.AccessToken token = credentials.getAccessToken();
return token.getTokenValue();
Expand Down

0 comments on commit 87fdac7

Please sign in to comment.