Skip to content
Open
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
Binary file modified .README/globalconfig.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Plugin is used to send actionable messages in [Outlook](http://outlook.com), [Of

#### Global configuration values used as default in jobs

![GlobalConfigurationDefault](.README/globalconfigdefault.png?raw=true)
![GlobalConfiguratio![img.png](.README/globalconfig.png)nDefault](.README/globalconfigdefault.png?raw=true)

### Microsoft Teams

Expand Down
14 changes: 12 additions & 2 deletions src/main/java/jenkins/plugins/office365connector/HttpWorker.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,20 @@ public class HttpWorker implements Runnable {

private final PrintStream logger;

private final ProxyConfiguration pluginProxy;

private final String url;
private final String data;
private final int timeout;

private static final int RETRIES = 3;

public HttpWorker(String url, String data, int timeout, PrintStream logger) {
public HttpWorker(String url, String data, int timeout, PrintStream logger, ProxyConfiguration pluginProxy) {
this.url = url;
this.data = data;
this.timeout = timeout;
this.logger = logger;
this.pluginProxy = pluginProxy;
}

/**
Expand Down Expand Up @@ -105,8 +108,15 @@ public void run() {
private HttpClient getHttpClient() {
HttpClient client = new HttpClient();
Jenkins jenkins = Jenkins.get();
if (jenkins != null) {
if (!StringUtils.isEmpty(pluginProxy.getName())) {
client.getHostConfiguration().setProxy(pluginProxy.getName(), pluginProxy.getPort());
if (StringUtils.isNotBlank(pluginProxy.getUserName())) {
client.getState().setProxyCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(pluginProxy.getUserName(), pluginProxy.getPassword()));
}
} else if (jenkins != null) {
ProxyConfiguration proxy = jenkins.proxy;
// Check job proxy first
if (proxy != null) {
List<Pattern> noHostProxyPatterns = proxy.getNoProxyHostPatterns();
if (!isNoProxyHost(this.url, noHostProxyPatterns)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import hudson.ProxyConfiguration;
import hudson.model.AbstractBuild;
import hudson.model.Job;
import hudson.model.Run;
Expand Down Expand Up @@ -112,7 +113,14 @@ private void executeWorker(Webhook webhook, Card card) {
try {
String url = run.getEnvironment(taskListener).expand(webhook.getUrl());
String data = gson.toJson(card);
HttpWorker worker = new HttpWorker(url, data, webhook.getTimeout(), taskListener.getLogger());

Integer port = 0;
if (!StringUtils.isEmpty(webhook.getDescriptor().getPort())) {
port = Integer.parseInt(webhook.getDescriptor().getPort());
}

ProxyConfiguration pluginProxy = new ProxyConfiguration(webhook.getDescriptor().getHost(), port, webhook.getDescriptor().getUsername(), webhook.getDescriptor().getPassword());
HttpWorker worker = new HttpWorker(url, data, webhook.getTimeout(), taskListener.getLogger(), pluginProxy);
worker.submit();
} catch (IOException | InterruptedException | RejectedExecutionException e) {
log(String.format("Failed to notify webhook: %s", webhook.getName()));
Expand Down
44 changes: 43 additions & 1 deletion src/main/java/jenkins/plugins/office365connector/Webhook.java
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ public static class DescriptorImpl extends Descriptor<Webhook> {
private String globalUrl;
private String globalName;

private String host;
private String port;
private String username;
private String password;

public DescriptorImpl() {
load();
}
Expand All @@ -193,6 +198,43 @@ public String getDisplayName() {
return "Webhook";
}

public String getHost() {
return Util.fixNull(host);
}

@DataBoundSetter
public void setHost(String host) {
this.host = Util.fixNull(host);
}

@Nonnull
public String getPort() {
return Util.fixNull(port);
}

@DataBoundSetter
public void setPort(String port) {
this.port = Util.fixNull(port);
}

public String getUsername() {
return Util.fixNull(username);
}

@DataBoundSetter
public void setUsername(String username) {
this.username = Util.fixNull(username);
}

public String getPassword() {
return Util.fixNull(password);
}

@DataBoundSetter
public void setPassword(String password) {
this.password = Util.fixNull(password);
}

public int getDefaultTimeout() {
return Webhook.DEFAULT_TIMEOUT;
}
Expand All @@ -201,7 +243,7 @@ public FormValidation doCheckUrl(@QueryParameter String value) {
return FormUtils.formValidateUrl(value);
}

public FormValidation doCheckGlobalUrl(@QueryParameter String value) {
public FormValidation doCheckGlobalUrl(@QueryParameter String value) {
if(StringUtils.isNotBlank(value)) {
return FormUtils.formValidateUrl(value);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,25 @@
<f:entry title="Name" field="globalName">
<f:textbox/>
</f:entry>
<f:advanced>
<f:section title="Proxy Configuration">
<f:description>
This section defines the Office365Connector proxy settings that will apply to all webhook notifications. This
proxy configuration will be prioritized over the Jenkins global proxy config
</f:description>
<f:entry title="Host" field="host">
<f:textbox/>
</f:entry>
<f:entry title="Port" field="port">
<f:textbox/>
</f:entry>
<f:entry title="Username" field="username">
<f:textbox/>
</f:entry>
<f:entry title="Password" field="password">
<f:password/>
</f:entry>
</f:section>
</f:advanced>
</f:section>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div align="help">The hostname or ip address of the proxy server</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div align="help">This field works in conjunction with the host field to specify the HTTP proxy port.</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div align="help">This field works in conjunction with the proxy server field to specify the username used to authenticate with the proxy.</div>
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ public void setUp() {
}

@Test
public void HttpWorker_getHttpClient_NoProxy() throws NoSuchMethodException {
public void HttpWorker_getHttpClient_NoJenkinsProxy() throws NoSuchMethodException {

// given
// from @Before
HttpWorker httpWorker = new HttpWorker("http://127.0.0.1", "{}", 30, System.out);
ProxyConfiguration thisPluginProxy = new ProxyConfiguration("", 0, "", "");
HttpWorker httpWorker = new HttpWorker("http://127.0.0.1", "{}", 30, System.out, thisPluginProxy);
Method method = HttpWorker.class.getDeclaredMethod("getHttpClient");
method.setAccessible(true);

Expand All @@ -50,15 +51,16 @@ public void HttpWorker_getHttpClient_NoProxy() throws NoSuchMethodException {
}

@Test
public void HttpWorker_getHttpClient_Proxy() throws NoSuchMethodException {
public void HttpWorker_getHttpClient_JenkinsProxy() throws NoSuchMethodException {

// given
// from @Before
ProxyConfiguration thisPluginProxy = new ProxyConfiguration("", 0, "", "");
Jenkins jenkins = Jenkins.get();
ProxyConfiguration proxyConfiguration = new ProxyConfiguration("name", 123, null, null, "*mockwebsite.com*");
jenkins.proxy = proxyConfiguration;

HttpWorker httpWorker = new HttpWorker("http://127.0.0.1", "{}", 30, System.out);
HttpWorker httpWorker = new HttpWorker("http://127.0.0.1", "{}", 30, System.out, thisPluginProxy);
Method method = HttpWorker.class.getDeclaredMethod("getHttpClient");
method.setAccessible(true);

Expand All @@ -71,15 +73,16 @@ public void HttpWorker_getHttpClient_Proxy() throws NoSuchMethodException {
}

@Test
public void HttpWorker_getHttpClient_Proxy_Ignored() throws NoSuchMethodException {
public void HttpWorker_getHttpClient_JenkinsProxy_Ignored() throws NoSuchMethodException {

// given
// from @Before
ProxyConfiguration thisPluginProxy = new ProxyConfiguration("", 0, "", "");
Jenkins jenkins = Jenkins.get();
ProxyConfiguration proxyConfiguration = new ProxyConfiguration("name", 123, null, null, "*mockwebsite.com*");
jenkins.proxy = proxyConfiguration;

HttpWorker httpWorker = new HttpWorker("http://mockwebsite.com", "{}", 30, System.out);
HttpWorker httpWorker = new HttpWorker("http://mockwebsite.com", "{}", 30, System.out, thisPluginProxy);
Method method = HttpWorker.class.getDeclaredMethod("getHttpClient");
method.setAccessible(true);

Expand All @@ -90,4 +93,22 @@ public void HttpWorker_getHttpClient_Proxy_Ignored() throws NoSuchMethodExceptio
assertThat(httpClient.getHostConfiguration().getProxyHost()).isNull();
assertThat(httpClient.getHostConfiguration().getProxyPort()).isEqualTo(-1);
}
}

@Test
public void HttpWorker_getHttpClient_PluginProxy() throws NoSuchMethodException {

// given
// from @Before
ProxyConfiguration thisPluginProxy = new ProxyConfiguration("10.0.0.1", 12345, "", "");
HttpWorker httpWorker = new HttpWorker("http://127.0.0.1", "{}", 30, System.out, thisPluginProxy);
Method method = HttpWorker.class.getDeclaredMethod("getHttpClient");
method.setAccessible(true);

// when
HttpClient httpClient = (HttpClient) ReflectionUtils.invokeMethod(method, httpWorker);

// then
assertThat(httpClient.getHostConfiguration().getProxyHost()).isEqualTo(thisPluginProxy.getName());
assertThat(httpClient.getHostConfiguration().getProxyPort()).isEqualTo(thisPluginProxy.getPort());
}
}
17 changes: 17 additions & 0 deletions src/test/java/jenkins/plugins/office365connector/WebhookTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@

import java.util.Arrays;
import java.util.List;

import hudson.model.AbstractBuild;
import hudson.model.Job;
import hudson.model.Result;
import jenkins.model.Jenkins;
import jenkins.plugins.office365connector.model.FactDefinition;
import jenkins.plugins.office365connector.model.Macro;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.anyObject;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;
Expand All @@ -23,6 +30,16 @@
@RunWith(PowerMockRunner.class)
@PrepareForTest(Jenkins.class)
public class WebhookTest {
@Before
public void setUp() throws Exception {

Webhook.DescriptorImpl mockDescriptor = mock(Webhook.DescriptorImpl.class);

Jenkins jenkins = mock(Jenkins.class);
mockStatic(Jenkins.class);
Mockito.when(Jenkins.get()).thenReturn(jenkins);
Mockito.when(jenkins.getDescriptorOrDie(anyObject())).thenReturn(mockDescriptor);
}

@Test
public void getUrl_ReturnsUrl() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package jenkins.plugins.office365connector.workflow;

import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;

import java.util.List;

import hudson.model.AbstractBuild;
import hudson.model.Job;
import hudson.scm.ChangeLogSet;
import jenkins.model.Jenkins;
import jenkins.plugins.office365connector.FileUtils;
import jenkins.plugins.office365connector.Office365ConnectorWebhookNotifier;
import jenkins.plugins.office365connector.Webhook;
import jenkins.plugins.office365connector.helpers.AffectedFileBuilder;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -18,21 +17,31 @@
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.powermock.api.mockito.PowerMockito.*;

/**
* @author Damian Szczepanik (damianszczepanik@github)
*/
@PowerMockIgnore("jdk.internal.reflect.*")
@RunWith(PowerMockRunner.class)
@PrepareForTest(Office365ConnectorWebhookNotifier.class)
@PrepareForTest({Office365ConnectorWebhookNotifier.class, Jenkins.class})
public class DevelopersIT extends AbstractTest {

private static final String JOB_NAME = "simple job";
private static final int BUILD_NUMBER = 1;

@Before
public void setUp() {
Webhook.DescriptorImpl mockDescriptor = mock(Webhook.DescriptorImpl.class);
when(mockDescriptor.getName()).thenReturn("testName");

mockStatic(Jenkins.class);
Jenkins jenkins = mock(Jenkins.class);
mockListener();

when(jenkins.getDescriptorOrDie(Webhook.class)).thenReturn(mockDescriptor);
when(Jenkins.get()).thenReturn(jenkins);

run = mockRun();

mockDisplayURLProvider(JOB_NAME, BUILD_NUMBER);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,17 @@ public class PullRequestIT extends AbstractTest {

@Before
public void setUp() {

Webhook.DescriptorImpl mockDescriptor = mock(Webhook.DescriptorImpl.class);
when(mockDescriptor.getName()).thenReturn("testName");

mockStatic(Jenkins.class);
Jenkins jenkins = mock(Jenkins.class);
mockListener();

when(jenkins.getDescriptorOrDie(Webhook.class)).thenReturn(mockDescriptor);
when(Jenkins.get()).thenReturn(jenkins);

run = mockRun();
mockCause("Branch indexing");
mockCommitters();
Expand All @@ -59,15 +66,7 @@ public void setUp() {
mockEnvironment();
mockHttpWorker();
mockGetChangeSets();

mockPullRequest();

when(Jenkins.get()).thenReturn(jenkins);

Webhook.DescriptorImpl mockDescriptor = mock(Webhook.DescriptorImpl.class);
when(mockDescriptor.getName()).thenReturn("testName");

when(jenkins.getDescriptorOrDie(Webhook.class)).thenReturn(mockDescriptor);
}

private AbstractBuild mockRun() {
Expand Down
Loading