Skip to content

Commit f4b8340

Browse files
committed
[JENKINS-75735] Hook payload is discarded if not recognized and comes from Bitbucket Cloud and DataCenter instances
Change test cases to better reflect the header sent in the request of a webhook
1 parent 44b1a90 commit f4b8340

File tree

3 files changed

+62
-25
lines changed

3 files changed

+62
-25
lines changed

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/BitbucketServerWebhookImplementation.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
/** The different webhook implementations available for Bitbucket Server. */
2929
public enum BitbucketServerWebhookImplementation implements ModelObject {
3030
/** Plugin-based webhooks. */
31-
PLUGIN("Plugin"),
31+
PLUGIN("Plugin - Deprecated"),
3232

3333
/** Native webhooks, available since Bitbucket Server 5.4. */
3434
NATIVE("Native");

src/test/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/BitbucketSCMSourcePushHookReceiverTest.java

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,20 @@ static void init(JenkinsRule rule) {
6666
@BeforeEach
6767
void setup() throws Exception {
6868
req = mock(StaplerRequest2.class);
69+
70+
hookProcessor = mock(HookProcessor.class);
71+
sut = new BitbucketSCMSourcePushHookReceiver() {
72+
@Override
73+
HookProcessor getHookProcessor(HookEventType type) {
74+
return hookProcessor;
75+
}
76+
};
77+
78+
credentialsId = BitbucketTestUtil.registerHookCredentials("Gkvl$k$wyNpQAF42", j).getId();
79+
}
80+
81+
private void mockCloudRequest() {
6982
when(req.getRemoteHost()).thenReturn("https://bitbucket.org");
70-
when(req.getParameter("server_url")).thenReturn("https://bitbucket.org");
7183
when(req.getRemoteAddr()).thenReturn("185.166.143.48");
7284
when(req.getScheme()).thenReturn("https");
7385
when(req.getServerName()).thenReturn("jenkins.example.com");
@@ -78,16 +90,21 @@ void setup() throws Exception {
7890
when(req.getHeader("Content-Type")).thenReturn("application/json");
7991
when(req.getHeader("X-Hook-UUID")).thenReturn(UUID.randomUUID().toString());
8092
when(req.getHeader("X-Request-UUID")).thenReturn(UUID.randomUUID().toString());
93+
when(req.getHeader("traceparent")).thenReturn(UUID.randomUUID().toString());
94+
when(req.getHeader("User-Agent")).thenReturn("Bitbucket-Webhooks/2.0");
95+
}
8196

82-
hookProcessor = mock(HookProcessor.class);
83-
sut = new BitbucketSCMSourcePushHookReceiver() {
84-
@Override
85-
HookProcessor getHookProcessor(HookEventType type) {
86-
return hookProcessor;
87-
}
88-
};
89-
90-
credentialsId = BitbucketTestUtil.registerHookCredentials("Gkvl$k$wyNpQAF42", j).getId();
97+
private void mockServerRequest(String serverURL) {
98+
when(req.getRemoteHost()).thenReturn("http://localhost:7990");
99+
when(req.getParameter("server_url")).thenReturn(serverURL);
100+
when(req.getRemoteAddr()).thenReturn("127.0.0.1");
101+
when(req.getScheme()).thenReturn("https");
102+
when(req.getServerName()).thenReturn("jenkins.example.com");
103+
when(req.getLocalPort()).thenReturn(80);
104+
when(req.getRequestURI()).thenReturn("/bitbucket-scmsource-hook/notify");
105+
when(req.getHeader("Content-Type")).thenReturn("application/json; charset=utf-8");
106+
when(req.getHeader("X-Request-Id")).thenReturn(UUID.randomUUID().toString());
107+
when(req.getHeader("User-Agent")).thenReturn("Atlassian HttpClient 4.2.0 / Bitbucket-9.5.2 (9005002) / Default");
91108
}
92109

93110
@Test
@@ -98,7 +115,6 @@ void test_signature_is_missing_from_cloud_payload() throws Exception {
98115

99116
try {
100117
when(req.getHeader("X-Event-Key")).thenReturn("repo:push");
101-
when(req.getHeader("X-Bitbucket-Type")).thenReturn("cloud");
102118
when(req.getInputStream()).thenReturn(loadResource("cloud/signed_payload.json"));
103119

104120
/*HttpResponse response = */sut.doNotify(req);
@@ -111,13 +127,13 @@ void test_signature_is_missing_from_cloud_payload() throws Exception {
111127

112128
@Test
113129
void test_signature_from_cloud() throws Exception {
130+
mockCloudRequest();
114131
BitbucketCloudEndpoint endpoint = new BitbucketCloudEndpoint(false, 0, 0, false, null , true, credentialsId);
115132
endpoint.setBitbucketJenkinsRootUrl("http://jenkins.acme.com:8080/jenkins");
116133
BitbucketEndpointConfiguration.get().updateEndpoint(endpoint);
117134

118135
try {
119136
when(req.getHeader("X-Event-Key")).thenReturn("repo:push");
120-
when(req.getHeader("X-Bitbucket-Type")).thenReturn("cloud");
121137
when(req.getHeader("X-Hub-Signature")).thenReturn("sha256=f205c729821c6954aff2afe72b965c34015b4baf96ea8ddc2cc44999c014a035");
122138
when(req.getInputStream()).thenReturn(loadResource("cloud/signed_payload.json"));
123139

@@ -141,7 +157,6 @@ void test_bad_signature_from_cloud() throws Exception {
141157

142158
try {
143159
when(req.getHeader("X-Event-Key")).thenReturn("repo:push");
144-
when(req.getHeader("X-Bitbucket-Type")).thenReturn("cloud");
145160
when(req.getHeader("X-Hub-Signature")).thenReturn("sha256=f205c729821c6954aff2afe72b965c34015b4baf96ea8ddc2cc44999c014a036");
146161
when(req.getInputStream()).thenReturn(loadResource("cloud/signed_payload.json"));
147162

@@ -160,10 +175,8 @@ void test_signature_from_native_server() throws Exception {
160175
BitbucketEndpointConfiguration.get().updateEndpoint(endpoint);
161176

162177
try {
163-
when(req.getRemoteHost()).thenReturn("http://localhost:7990");
164-
when(req.getParameter("server_url")).thenReturn(endpoint.getServerUrl());
178+
mockServerRequest(endpoint.getServerUrl());
165179
when(req.getHeader("X-Event-Key")).thenReturn("repo:refs_changed");
166-
when(req.getHeader("X-Request-Id")).thenReturn("2b15f131-4d3a-436e-bc63-caa9ae92580d");
167180
when(req.getHeader("X-Hub-Signature")).thenReturn("sha256=4ffba9e7b58ea3d7e1a230446e8c92baea0aeec89b73f598932387254f0de13e");
168181
when(req.getInputStream()).thenReturn(loadResource("native/signed_payload.json"));
169182

@@ -173,7 +186,7 @@ void test_signature_from_native_server() throws Exception {
173186
eq(HookEventType.SERVER_REFS_CHANGED),
174187
anyString(),
175188
eq(BitbucketType.SERVER),
176-
eq("http://localhost:7990/185.166.143.48 ⇒ https://jenkins.example.com:80/bitbucket-scmsource-hook/notify"),
189+
eq("http://localhost:7990/127.0.0.1 ⇒ https://jenkins.example.com:80/bitbucket-scmsource-hook/notify"),
177190
eq(endpoint.getServerUrl()));
178191

179192
// verify bad signature
@@ -188,17 +201,38 @@ void test_signature_from_native_server() throws Exception {
188201
}
189202
}
190203

204+
@Test
205+
void test_ping_from_native_server() throws Exception {
206+
BitbucketServerEndpoint endpoint = new BitbucketServerEndpoint("datacenter", "http://localhost:7990/bitbucket", false, null, false, null);
207+
endpoint.setBitbucketJenkinsRootUrl("https://jenkins.example.com");
208+
BitbucketEndpointConfiguration.get().updateEndpoint(endpoint);
209+
210+
try {
211+
mockServerRequest(endpoint.getServerUrl());
212+
when(req.getHeader("X-Event-Key")).thenReturn("diagnostics:ping");
213+
when(req.getInputStream()).thenReturn(loadResource("native/ping_payload.json"));
214+
215+
sut.doNotify(req);
216+
verify(hookProcessor).process(
217+
eq(HookEventType.SERVER_PING),
218+
anyString(),
219+
eq(BitbucketType.SERVER),
220+
eq("http://localhost:7990/127.0.0.1 ⇒ https://jenkins.example.com:80/bitbucket-scmsource-hook/notify"),
221+
eq(endpoint.getServerUrl()));
222+
} finally {
223+
BitbucketEndpointConfiguration.get().removeEndpoint(endpoint.getServerUrl());
224+
}
225+
}
226+
191227
@Test
192228
void test_bad_signature_from_native_server() throws Exception {
193229
BitbucketServerEndpoint endpoint = new BitbucketServerEndpoint("datacenter", "http://localhost:7990/bitbucket", false, null, true, credentialsId);
194230
endpoint.setBitbucketJenkinsRootUrl("https://jenkins.example.com");
195231
BitbucketEndpointConfiguration.get().updateEndpoint(endpoint);
196232

197233
try {
198-
when(req.getRemoteHost()).thenReturn("http://localhost:7990");
199-
when(req.getParameter("server_url")).thenReturn(endpoint.getServerUrl());
234+
mockServerRequest(endpoint.getServerUrl());
200235
when(req.getHeader("X-Event-Key")).thenReturn("repo:refs_changed");
201-
when(req.getHeader("X-Request-Id")).thenReturn("2b15f131-4d3a-436e-bc63-caa9ae92580d");
202236
when(req.getHeader("X-Hub-Signature")).thenReturn("sha256=4ffba9e7b58ea3d7e1a230446e8c92baea0aeec89b73f598932387254f0de13f");
203237
when(req.getInputStream()).thenReturn(loadResource("native/signed_payload.json"));
204238
/*HttpResponse response = */ sut.doNotify(req);
@@ -210,9 +244,9 @@ void test_bad_signature_from_native_server() throws Exception {
210244
}
211245

212246
@Test
213-
void test_pullrequest_created() throws Exception {
247+
void test_cloud_pullrequest_created() throws Exception {
248+
mockCloudRequest();
214249
when(req.getHeader("X-Event-Key")).thenReturn("pullrequest:created");
215-
when(req.getHeader("X-Bitbucket-Type")).thenReturn("cloud");
216250
when(req.getInputStream()).thenReturn(loadResource("cloud/pullrequest_created.json"));
217251

218252
sut.doNotify(req);
@@ -226,9 +260,9 @@ void test_pullrequest_created() throws Exception {
226260
}
227261

228262
@Test
229-
void test_pullrequest_declined() throws Exception {
263+
void test_cloud_pullrequest_declined() throws Exception {
264+
mockCloudRequest();
230265
when(req.getHeader("X-Event-Key")).thenReturn("pullrequest:rejected");
231-
when(req.getHeader("X-Bitbucket-Type")).thenReturn("cloud");
232266
when(req.getInputStream()).thenReturn(loadResource("cloud/pullrequest_rejected.json"));
233267

234268
sut.doNotify(req);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"test": true
3+
}

0 commit comments

Comments
 (0)