Skip to content

Commit 53d0c23

Browse files
committed
partial: proxy from env vars
1 parent d7f9772 commit 53d0c23

14 files changed

+310
-89
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ hs_err_pid*
2222
.project
2323
.settings/
2424
/bin/
25+
.vscode/
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.browserstack.automate.ci.common.clienthandler;
2+
3+
import com.browserstack.appautomate.AppAutomateClient;
4+
import com.browserstack.automate.AutomateClient;
5+
import com.browserstack.automate.ci.common.enums.ProjectType;
6+
import com.browserstack.automate.ci.common.proxysettings.JenkinsProxySettings;
7+
import com.browserstack.client.BrowserStackClient;
8+
9+
import javax.annotation.Nonnull;
10+
import javax.annotation.Nullable;
11+
import java.io.PrintStream;
12+
13+
public class ClientHandler {
14+
15+
public static BrowserStackClient getBrowserStackClient(@Nonnull final ProjectType project, @Nonnull final String username,
16+
@Nonnull final String accessKey, @Nullable final String customProxy,
17+
@Nullable final PrintStream logger) {
18+
BrowserStackClient client = decideAndGetClient(project, username, accessKey);
19+
20+
JenkinsProxySettings proxy;
21+
if (customProxy != null) {
22+
proxy = new JenkinsProxySettings(customProxy, logger);
23+
} else {
24+
proxy = new JenkinsProxySettings(logger);
25+
}
26+
27+
if (proxy.hasProxy()) {
28+
client.setProxy(proxy.getHost(), proxy.getPort(), proxy.getUsername(), proxy.getPassword());
29+
}
30+
31+
return client;
32+
}
33+
34+
private static BrowserStackClient decideAndGetClient(@Nonnull final ProjectType project, @Nonnull final String username, @Nonnull final String accessKey) {
35+
if (project == ProjectType.APP_AUTOMATE) {
36+
return new AppAutomateClient(username, accessKey);
37+
}
38+
39+
return new AutomateClient(username, accessKey);
40+
}
41+
}
Lines changed: 183 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,218 @@
11
package com.browserstack.automate.ci.common.proxysettings;
22

3+
import com.browserstack.automate.ci.common.Tools;
34
import hudson.ProxyConfiguration;
5+
import hudson.Util;
46
import jenkins.model.Jenkins;
57

8+
import javax.annotation.Nonnull;
9+
import javax.annotation.Nullable;
10+
import java.io.PrintStream;
611
import java.net.InetSocketAddress;
712
import java.net.Proxy;
13+
import java.net.URL;
14+
15+
import static com.browserstack.automate.ci.common.logger.PluginLogger.log;
16+
import static com.browserstack.automate.ci.common.logger.PluginLogger.logError;
817

918
public class JenkinsProxySettings {
1019

1120
private static final ProxyConfiguration jenkinsProxy = Jenkins.getInstanceOrNull() != null ? Jenkins.getInstanceOrNull().proxy : null;
12-
private static final String protocol = "https";
13-
private static final String systemProxyHost = System.getProperty(protocol + ".proxyHost");
14-
private static final int systemProxyPort = Integer.parseInt(System.getProperty(protocol + ".proxyPort", "0"));
15-
private static final String systemProxyUser = System.getProperty(protocol + ".proxyUser");
16-
private static final String systemProxyPassword = System.getProperty(protocol + ".proxyPassword");
17-
18-
public static Proxy getJenkinsProxy() {
19-
if (hasSystemProxy()) {
20-
return new Proxy(Proxy.Type.HTTP, new InetSocketAddress(systemProxyHost, systemProxyPort));
21-
}
2221

23-
if (jenkinsProxy == null) return null;
24-
final String proxyHost = jenkinsProxy.name;
25-
final int proxyPort = jenkinsProxy.port;
26-
return (proxyHost != null && proxyPort != 0) ? new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)) : null;
22+
private static final String jarProxyHost = System.getProperty("https.proxyHost");
23+
private static final int jarProxyPort = Integer.parseInt(System.getProperty("https.proxyPort", "443"));
24+
private static final String jarProxyUser = System.getProperty("https.proxyUser");
25+
private static final String jarProxyPassword = System.getProperty("https.proxyPassword");
26+
27+
private static final String systemHttpProxyEnv = System.getenv("http_proxy");
28+
private static final String systemHttpsProxyEnv = System.getenv("https_proxy");
29+
30+
private String finalProxyHost;
31+
private int finalProxyPort;
32+
private String finalProxyUsername;
33+
private String finalProxyPassword;
34+
35+
private boolean hasProxy;
36+
37+
private transient PrintStream logger;
38+
39+
/**
40+
* Constructor for JenkinsProxySettings with Priority for Custom Proxy
41+
*
42+
* @param customProxy Custom Proxy String
43+
* @param logger Logger
44+
*/
45+
public JenkinsProxySettings(@Nonnull final String customProxy, @Nullable PrintStream logger) {
46+
this.logger = logger;
47+
decideJenkinsProxy(customProxy);
2748
}
2849

29-
public static String getHost() {
30-
if (hasSystemProxy()) {
31-
return systemProxyHost;
32-
}
50+
/**
51+
* Constructor for JenkinsProxySettings
52+
*
53+
* @param logger Logger
54+
*/
55+
public JenkinsProxySettings(@Nullable PrintStream logger) {
56+
this.logger = logger;
57+
decideJenkinsProxy(null);
58+
}
3359

34-
if (jenkinsProxy == null) return null;
35-
return jenkinsProxy.name;
60+
/**
61+
* Verifies the format of the Proxy String
62+
*
63+
* @param proxyString String
64+
* @param proxyType Type/Source of Proxy
65+
* @return
66+
*/
67+
private URL verifyAndGetProxyURL(final String proxyString, final String proxyType) {
68+
try {
69+
final URL proxyUrl = new URL(proxyString);
70+
if (proxyUrl.getHost() != null && proxyUrl.getHost().length() == 0)
71+
throw new Error("Empty host in proxy");
72+
73+
String userInfo = proxyUrl.getUserInfo();
74+
if (userInfo != null) {
75+
if (userInfo.split(":").length != 2) {
76+
throw new Error("Invalid authentication params in proxy");
77+
}
78+
}
79+
80+
return proxyUrl;
81+
} catch (Exception e) {
82+
// TODO: Change to logDebug
83+
if (logger != null)
84+
logError(logger, String.format("Invalid Proxy String: %s, Proxy Type: %s. Error: %s", proxyString, proxyType, e.toString()));
85+
return null;
86+
}
3687
}
3788

38-
public static int getPort() {
39-
if (hasSystemProxy()) {
40-
return systemProxyPort;
89+
/**
90+
* Decides Proxy for the Plugin. Priority:
91+
* 0. Custom Proxy passed as input
92+
* 1. `https_proxy` Environment Variable
93+
* 2. `http_proxy` Environment Variable
94+
* 3. Jenkins Proxy Configuration
95+
* 4. JAR Proxy arguments, i.e. `https.proxyHost` etc.
96+
*
97+
* @param customProxyString Custom Proxy String
98+
*/
99+
private void decideJenkinsProxy(final String customProxyString) {
100+
URL proxyUrl = null;
101+
102+
// Verifies the custom proxy string
103+
if (customProxyString != null) {
104+
proxyUrl = verifyAndGetProxyURL(customProxyString, "ENV_VAR");
41105
}
42106

43-
if (jenkinsProxy == null) return 0;
44-
return jenkinsProxy.port;
45-
}
107+
// Looks for System level `https_proxy`. If not, looks for `http_proxy`
108+
if (proxyUrl == null && getSystemProxyString() != null) {
109+
proxyUrl = verifyAndGetProxyURL(getSystemProxyString(), "SYSTEM_ENV_VAR");
110+
}
46111

47-
public static String getUsername() {
48-
if (hasSystemProxy() && systemProxyUser != null && systemProxyPassword != null) {
49-
return systemProxyUser;
112+
// Looks for Jenkins Proxy
113+
if (proxyUrl == null && jenkinsProxy != null) {
114+
this.finalProxyHost = jenkinsProxy.name;
115+
this.finalProxyPort = jenkinsProxy.port;
116+
117+
if (Util.fixEmpty(jenkinsProxy.getUserName()) != null && Util.fixEmpty(jenkinsProxy.getPassword()) != null) {
118+
this.finalProxyUsername = jenkinsProxy.getUserName();
119+
this.finalProxyPassword = jenkinsProxy.getPassword();
120+
}
50121
}
51122

52-
if (jenkinsProxy == null) return null;
53-
return jenkinsProxy.getUserName();
123+
// Looks for JAR Proxy Arguments
124+
if (proxyUrl == null && this.finalProxyHost == null && jarProxyHost != null) {
125+
this.finalProxyHost = jarProxyHost;
126+
this.finalProxyPort = jarProxyPort;
127+
128+
if (Util.fixEmpty(jarProxyUser) != null && Util.fixEmpty(jarProxyPassword) != null) {
129+
this.finalProxyUsername = jarProxyUser;
130+
this.finalProxyPassword = jarProxyPassword;
131+
}
132+
133+
if (this.finalProxyUsername == null)
134+
System.out.println("Username is null in case of JAR proxy...");
135+
}
136+
137+
// Utilises the proxyUrl set by Env Vars if Jenkins & Jar Proxy are absent
138+
if (proxyUrl != null) {
139+
this.finalProxyHost = proxyUrl.getHost();
140+
this.finalProxyPort = proxyUrl.getPort() == -1 ? proxyUrl.getDefaultPort() : proxyUrl.getPort();
141+
142+
final String userInfo = proxyUrl.getUserInfo();
143+
144+
if (userInfo != null) {
145+
String[] userInfoArray = userInfo.split(":");
146+
this.finalProxyUsername = userInfoArray[0];
147+
this.finalProxyPassword = userInfoArray[1];
148+
}
149+
}
150+
151+
// Logging and final boolean set
152+
if (this.finalProxyHost != null && this.finalProxyPort != 0) {
153+
this.hasProxy = true;
154+
155+
String proxyDataToLog = "\nHost: " + this.getHost() + "\nPort: " + this.getPort();
156+
if (this.hasAuth()) {
157+
proxyDataToLog += "\nUsername: " + this.getUsername() + "\nPassword: " + Tools.maskString(this.getPassword());
158+
}
159+
160+
if (logger != null) log(logger, "Proxy Selected for BrowserStack Plugin: " + proxyDataToLog);
161+
} else {
162+
this.hasProxy = false;
163+
164+
if (logger != null) log(logger, "No Proxy Selected for BrowserStack Plugin");
165+
}
54166
}
55167

56-
public static String getPassword() {
57-
if (hasSystemProxy() && systemProxyUser != null && systemProxyPassword != null) {
58-
return systemProxyPassword;
168+
169+
/**
170+
* Returns the proxy string from System level env vars. Priority:
171+
* 1. `https_proxy`
172+
* 2. `http_proxy`
173+
* If no value exists, returns null
174+
*
175+
* @return String/null
176+
*/
177+
private String getSystemProxyString() {
178+
return systemHttpsProxyEnv == null ? systemHttpProxyEnv : systemHttpsProxyEnv;
179+
}
180+
181+
public Proxy getJenkinsProxy() {
182+
if (this.hasProxy()) {
183+
return new Proxy(Proxy.Type.HTTP, new InetSocketAddress(this.finalProxyHost, this.finalProxyPort));
59184
}
60185

61-
if (jenkinsProxy == null) return null;
62-
return jenkinsProxy.getPassword();
186+
return Proxy.NO_PROXY;
187+
}
188+
189+
public String getHost() {
190+
return this.finalProxyHost;
191+
}
192+
193+
public int getPort() {
194+
return this.finalProxyPort;
63195
}
64196

65-
public static ProxyConfiguration getProxyConfig() {
66-
return jenkinsProxy;
197+
public String getUsername() {
198+
if (this.finalProxyUsername != null && this.finalProxyUsername.length() != 0)
199+
return this.finalProxyUsername;
200+
201+
return null;
67202
}
68203

69-
public static boolean hasProxy() {
70-
return getHost() != null && getPort() != 0;
204+
public String getPassword() {
205+
if (this.finalProxyPassword != null && this.finalProxyPassword.length() != 0)
206+
return this.finalProxyPassword;
207+
208+
return null;
71209
}
72210

73-
public static boolean hasSystemProxy() {
74-
return systemProxyHost != null && systemProxyPort != 0;
211+
public boolean hasAuth() {
212+
return ((this.getUsername() != null) && (this.getPassword() != null));
75213
}
76214

215+
public boolean hasProxy() {
216+
return this.hasProxy;
217+
}
77218
}

src/main/java/com/browserstack/automate/ci/common/tracking/PluginsTracker.java

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import okhttp3.Route;
1717
import org.json.JSONObject;
1818

19+
import javax.annotation.Nullable;
1920
import java.io.IOException;
2021
import java.net.Proxy;
2122
import java.time.Instant;
@@ -28,17 +29,24 @@ public class PluginsTracker {
2829
private final String trackingId;
2930
private String username;
3031
private String accessKey;
32+
private String customProxy;
3133

32-
public PluginsTracker(final String username, final String accessKey) {
34+
public PluginsTracker(final String username, final String accessKey, @Nullable final String customProxy) {
3335
this.username = username;
3436
this.accessKey = accessKey;
37+
this.customProxy = customProxy;
3538
this.trackingId = Tools.getUniqueString(true, true);
3639
initializeClient();
3740
}
3841

3942
public PluginsTracker() {
43+
this(null);
44+
}
45+
46+
public PluginsTracker(@Nullable final String customProxy) {
4047
this.username = null;
4148
this.accessKey = null;
49+
this.customProxy = customProxy;
4250
this.trackingId = Tools.getUniqueString(true, true);
4351
initializeClient();
4452
}
@@ -67,11 +75,21 @@ public void onResponse(Call call, Response response) throws IOException {
6775

6876
private void initializeClient() {
6977

70-
final Proxy proxy = JenkinsProxySettings.getJenkinsProxy() != null ? JenkinsProxySettings.getJenkinsProxy() : Proxy.NO_PROXY;
78+
JenkinsProxySettings jenkinsProxy;
79+
if (customProxy != null) {
80+
System.out.println("Custom Proxy In Plugins Tracker: " + customProxy);
81+
jenkinsProxy = new JenkinsProxySettings(customProxy, null);
82+
} else {
83+
System.out.println("Without Custom Proxy In Plugins Tracker");
84+
jenkinsProxy = new JenkinsProxySettings(null);
85+
}
86+
87+
final Proxy proxy = jenkinsProxy.getJenkinsProxy();
7188
if (proxy != Proxy.NO_PROXY) {
72-
final String username = JenkinsProxySettings.getUsername();
73-
final String password = JenkinsProxySettings.getPassword();
74-
if (username != null && password != null) {
89+
System.out.println("Selected some proxy for plugins tracker. " + proxy.toString());
90+
if (jenkinsProxy.hasAuth()) {
91+
final String username = jenkinsProxy.getUsername();
92+
final String password = jenkinsProxy.getPassword();
7593
Authenticator proxyAuthenticator = new Authenticator() {
7694
@Override
7795
public Request authenticate(Route route, Response response) throws IOException {

0 commit comments

Comments
 (0)