Skip to content

Commit

Permalink
fix for #161
Browse files Browse the repository at this point in the history
  • Loading branch information
ssvaidyanathan committed Nov 19, 2022
1 parent 76de62c commit 592e82a
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 169 deletions.
5 changes: 5 additions & 0 deletions 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.42.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
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
225 changes: 57 additions & 168 deletions src/main/java/com/apigee/mgmtapi/sdk/client/MgmtAPIClient.java
Original file line number Diff line number Diff line change
@@ -1,208 +1,97 @@
package com.apigee.mgmtapi.sdk.client;

import static org.apache.commons.lang3.StringUtils.isNotBlank;

import java.io.File;
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.HttpClientBuilder;
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);

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 host
* @param port
* @param username
* @param password
* @param mfa
* @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);
}


/**
* To get Access Token
* @param url
* @param clientId
* @param client_secret
* @param username
* @param password
* @param mfa
* @param serviceAccountJSON
* @return
* @throws Exception
* @throws IOException
*/
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);
public GoogleCredentials getCredentials(String host, int port, String username, String password, File serviceAccountJSON) throws IOException {
HttpTransportFactory httpTransportFactory = getHttpTransportFactory(
host, port, username, password
);
return GoogleCredentials.fromStream(new FileInputStream(serviceAccountJSON), httpTransportFactory)
.createScoped("https://www.googleapis.com/auth/cloud-platform");
}

/**
* 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);
public HttpTransportFactory getHttpTransportFactory(String proxyHost, int proxyPort, String proxyUsername, String proxyPassword) {
HttpClientBuilder builder = HttpClientBuilder.create();
HttpHost proxyHostDetails = new HttpHost(proxyHost, proxyPort);
HttpRoutePlanner httpRoutePlanner = new DefaultProxyRoutePlanner(proxyHostDetails);
builder.setRoutePlanner(httpRoutePlanner);
builder.setProxyAuthenticationStrategy(ProxyAuthenticationStrategy.INSTANCE);
if (isNotBlank(proxyUsername) && isNotBlank(proxyPassword)) {
logger.debug("setting proxy credentials");

}
} catch (Exception e) {
logger.error(e.getMessage());
throw e;
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(proxyHost, proxyPort),
new UsernamePasswordCredentials(proxyUsername, proxyPassword));
builder.setDefaultCredentialsProvider(credsProvider);
}
return token;
HttpClient httpClient = builder.build();

}

/**
* 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);
final HttpTransport httpTransport = new ApacheHttpTransport(httpClient);
return new HttpTransportFactory() {
@Override
public HttpTransport create() {
return httpTransport;
}
};
}

}
} 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("proxy is set to generate access token - " + profile.getProxyServer() + ":" + profile.getProxyPort());
credentials = getCredentials(profile.getProxyServer(), profile.getProxyPort(), profile.getProxyUsername(), profile.getProxyPassword(), serviceAccountJSON);
}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 592e82a

Please sign in to comment.