Skip to content

Commit 44fd744

Browse files
authored
[JENKINS-73250] The GIT_URL environmente variable contains user name after update (#921)
Revert to the behavior before the clone link feature from version 866. The remote URL must not contain the user or it may not work when using username/password authentication. This is because the username belonging to the credential provided to perform the git operation may not be the same as the URL. The clone URL comes from the links that bitbucket sends with the repository information. The link sent contains the user associated with the credentials used to call the REST APIs.
1 parent 54ecf17 commit 44fd744

File tree

4 files changed

+52
-13
lines changed

4 files changed

+52
-13
lines changed

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketGitSCMBuilder.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,8 @@ public BitbucketGitSCMBuilder withCredentials(String credentialsId, BitbucketRep
192192
public BitbucketGitSCMBuilder withBitbucketRemote() {
193193
SCMHead head = head();
194194
String headName = head.getName();
195-
if (head instanceof PullRequestSCMHead) {
196-
withPullRequestRemote((PullRequestSCMHead) head, headName);
195+
if (head instanceof PullRequestSCMHead prHead) {
196+
withPullRequestRemote(prHead, headName);
197197
} else if (head instanceof TagSCMHead) {
198198
withTagRemote(headName);
199199
} else {
@@ -322,19 +322,19 @@ private String getCloneLink(List<BitbucketHref> cloneLinks) {
322322
@Override
323323
public GitSCM build() {
324324
withBitbucketRemote();
325-
SCMHead h = head();
326-
SCMRevision r = revision();
325+
SCMHead head = head();
326+
SCMRevision rev = revision();
327327
try {
328-
if (h instanceof PullRequestSCMHead) {
329-
withHead(new SCMHead(((PullRequestSCMHead) h).getBranchName()));
330-
if (r instanceof PullRequestSCMRevision) {
331-
withRevision(((PullRequestSCMRevision) r).getPull());
328+
if (head instanceof PullRequestSCMHead prHead) {
329+
withHead(new SCMHead(prHead.getBranchName()));
330+
if (rev instanceof PullRequestSCMRevision prRev) {
331+
withRevision(prRev.getPull());
332332
}
333333
}
334334
return super.build();
335335
} finally {
336-
withHead(h);
337-
withRevision(r);
336+
withHead(head);
337+
withRevision(rev);
338338
}
339339
}
340340
}

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketGitSCMRevision.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public BitbucketGitSCMRevision(@NonNull SCMHead head, @NonNull BitbucketCommit c
6767
/**
6868
* Returns the author of this revision in GIT format.
6969
*
70-
* @return commit author in the following format &gt;name&lt; &gt;email&lt;
70+
* @return commit author in the following format &lt;name&gt; &lt;email&gt;
7171
*/
7272
public String getAuthor() {
7373
return author;

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,16 @@
6666
import hudson.model.Items;
6767
import hudson.model.TaskListener;
6868
import hudson.plugins.git.GitSCM;
69+
import hudson.plugins.git.extensions.GitSCMExtension;
6970
import hudson.scm.SCM;
7071
import hudson.security.AccessControlled;
7172
import hudson.util.FormFillFailure;
7273
import hudson.util.FormValidation;
7374
import hudson.util.ListBoxModel;
7475
import java.io.IOException;
7576
import java.io.ObjectStreamException;
77+
import java.net.MalformedURLException;
78+
import java.net.URL;
7679
import java.util.ArrayList;
7780
import java.util.Arrays;
7881
import java.util.Collection;
@@ -1002,14 +1005,29 @@ public SCM build(SCMHead head, SCMRevision revision) {
10021005
.anyMatch(SSHCheckoutTrait.class::isInstance);
10031006

10041007
BitbucketAuthenticator authenticator = authenticator();
1005-
return new BitbucketGitSCMBuilder(this, head, revision, null)
1006-
.withExtension(authenticator == null || sshAuth ? null : new GitClientAuthenticatorExtension(authenticator.getCredentialsForSCM()))
1008+
GitSCMExtension gitExtension = authenticator == null || sshAuth ? null : new GitClientAuthenticatorExtension(authenticator.getCredentialsForSCM());
1009+
return new BitbucketGitSCMBuilder(this, head, revision, gitExtension == null ? credentialsId : null)
1010+
.withExtension(gitExtension)
10071011
.withCloneLinks(primaryCloneLinks, mirrorCloneLinks)
10081012
.withTraits(traits)
10091013
.build();
10101014
}
10111015

10121016
private void setPrimaryCloneLinks(List<BitbucketHref> links) {
1017+
links.forEach(link -> {
1018+
if (StringUtils.startsWithIgnoreCase(link.getName(), "http")) {
1019+
try {
1020+
URL linkURL = new URL(link.getHref());
1021+
// Remove the username from URL because it will be set into the GIT_URL variable
1022+
// credentials used to clone or for push/pull could be different than this will cause a failure
1023+
// Restore the behaviour before mirror link feature.
1024+
URL cleanURL = new URL(linkURL.getProtocol(), linkURL.getHost(), linkURL.getPort(), linkURL.getFile());
1025+
link.setHref(cleanURL.toExternalForm());
1026+
} catch (MalformedURLException e) {
1027+
// do nothing, URL can not be parsed, leave as is
1028+
}
1029+
}
1030+
});
10131031
primaryCloneLinks = links;
10141032
}
10151033

src/test/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSourceTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package com.cloudbees.jenkins.plugins.bitbucket;
22

3+
import com.cloudbees.jenkins.plugins.bitbucket.client.BitbucketIntegrationClientFactory;
4+
import com.cloudbees.jenkins.plugins.bitbucket.client.pullrequest.BitbucketPullRequestCommit;
35
import com.cloudbees.jenkins.plugins.bitbucket.endpoints.AbstractBitbucketEndpoint;
46
import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration;
7+
import hudson.plugins.git.GitSCM;
8+
import hudson.scm.SCM;
59
import java.net.URL;
610
import java.util.Arrays;
711
import java.util.Collections;
12+
import java.util.Date;
813
import jenkins.model.Jenkins;
914
import jenkins.model.JenkinsLocationConfiguration;
1015
import jenkins.scm.api.trait.SCMSourceTrait;
@@ -25,6 +30,7 @@
2530
import static org.hamcrest.Matchers.is;
2631
import static org.hamcrest.Matchers.not;
2732
import static org.hamcrest.Matchers.nullValue;
33+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
2834
import static org.hamcrest.MatcherAssert.assertThat;
2935

3036
public class BitbucketSCMSourceTest {
@@ -423,6 +429,21 @@ public void use_agent_checkout() throws Exception {
423429
assertThat(instance.isAutoRegisterHook(), is(false));
424430
}
425431

432+
@Test
433+
public void test_that_clone_url_does_not_contains_username() {
434+
BranchSCMHead head = new BranchSCMHead("master");
435+
BitbucketPullRequestCommit commit = new BitbucketPullRequestCommit();
436+
commit.setHash("046d9a3c1532acf4cf08fe93235c00e4d673c1d2");
437+
commit.setDate(new Date());
438+
439+
BitbucketSCMSource instance = new BitbucketSCMSource("amuniz", "test-repo");
440+
BitbucketMockApiFactory.add(instance.getServerUrl(), BitbucketIntegrationClientFactory.getApiMockClient(instance.getServerUrl()));
441+
SCM scm = instance.build(head, new BitbucketGitSCMRevision(head, commit));
442+
assertInstanceOf(GitSCM.class, scm);
443+
GitSCM gitSCM = (GitSCM) scm;
444+
assertThat(gitSCM.getUserRemoteConfigs().get(0).getUrl(), is("https://bitbucket.org/amuniz/test-repos.git"));
445+
}
446+
426447
@Test
427448
public void given__instance__when__setTraits_empty__then__traitsEmpty() {
428449
BitbucketSCMSource instance = new BitbucketSCMSource("testing", "test-repo");

0 commit comments

Comments
 (0)