From 592e82add2c5d869995d5d034d6daa2425931a89 Mon Sep 17 00:00:00 2001 From: Sai Saran Vaidyanathan Date: Fri, 18 Nov 2022 16:56:56 -0800 Subject: [PATCH] fix for #161 --- pom.xml | 5 + .../com/apigee/edge/config/rest/RestUtil.java | 2 +- .../mgmtapi/sdk/client/MgmtAPIClient.java | 225 +++++------------- 3 files changed, 63 insertions(+), 169 deletions(-) diff --git a/pom.xml b/pom.xml index 77076a5..8b34101 100644 --- a/pom.xml +++ b/pom.xml @@ -165,6 +165,11 @@ google-http-client-apache 2.0.0 + + com.google.http-client + google-http-client-apache-v2 + 1.42.3 + org.apache.logging.log4j log4j-api diff --git a/src/main/java/com/apigee/edge/config/rest/RestUtil.java b/src/main/java/com/apigee/edge/config/rest/RestUtil.java index 943596c..d6526ee 100644 --- a/src/main/java/com/apigee/edge/config/rest/RestUtil.java +++ b/src/main/java/com/apigee/edge/config/rest/RestUtil.java @@ -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"); diff --git a/src/main/java/com/apigee/mgmtapi/sdk/client/MgmtAPIClient.java b/src/main/java/com/apigee/mgmtapi/sdk/client/MgmtAPIClient.java index 2ca132f..66acb84 100644 --- a/src/main/java/com/apigee/mgmtapi/sdk/client/MgmtAPIClient.java +++ b/src/main/java/com/apigee/mgmtapi/sdk/client/MgmtAPIClient.java @@ -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 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 map = new LinkedMultiValueMap(); - map.add("username", username); - map.add("password", password); - map.add("grant_type", "password"); - HttpEntity request = new HttpEntity(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 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 map = new LinkedMultiValueMap(); - map.add("refresh_token", refreshToken); - map.add("grant_type", "refresh_token"); - HttpEntity request = new HttpEntity(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();