Skip to content

Commit 7119e94

Browse files
authored
[JENKINS-74965] Add support for Repository, Project and Workspace Access Token for Bitbucket Cloud (#934)
Update the bitbucket token authenticator to be used as workspace, project or repository Access Token as described in Atlassian documentation at: - https://support.atlassian.com/bitbucket-cloud/docs/using-workspace-access-tokens/ - https://support.atlassian.com/bitbucket-cloud/docs/using-project-access-tokens/ - https://support.atlassian.com/bitbucket-cloud/docs/using-access-tokens/ Convert BitbucketAuthenticatorTest to JUnit5
1 parent ff504b2 commit 7119e94

16 files changed

+381
-106
lines changed

docs/USER_GUIDE.adoc

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,27 @@ image::images/screenshot-7.png[scaledwidth=90%]
123123

124124
=== Access Token
125125

126-
The plugin can make use of a personal access token (Bitbucket Server only) instead of the standard username/password.
126+
The plugin can make use of a repository, project or workspace access token (Bitbucket Cloud only).
127+
128+
First, create a new _access token_ in Bitbucket as instructed in one of the following links:
129+
.Bulleted
130+
. https://support.atlassian.com/bitbucket-cloud/docs/create-a-repository-access-token/[Repository Access Token | Atlassian Documentation];
131+
. https://support.atlassian.com/bitbucket-cloud/docs/create-a-project-access-token/[Project Access Token | Atlassian Documentation];
132+
. https://support.atlassian.com/bitbucket-cloud/docs/create-a-workspace-access-token/[Workspace Access Token | Atlassian Documentation];
133+
134+
At least allow _read_ access for repositories. If you want the plugin to install the webhooks, allow _Read and write_ access for Webhooks.
135+
136+
image::images/screenshot-16.png[scaledwidth=90%]
137+
138+
Then create a new _Secret text_ credential in Jenkins, enter the Bitbucket token generated in the previous steps in the _Secret_ field.
139+
140+
If you want be able to perform git push operation from CLI than you have to setup _write_ access for repositories. Than configure the _Custom user name/e-mail address_ trait with the Repository Access Token email generated when you created the Repository Access Token (for example, 52c16467c5f19101ff2061cc@bots.bitbucket.org).
141+
142+
image::images/screenshot-17.png[scaledwidth=90%]
143+
144+
=== Personal Access Token
145+
146+
The plugin can make use of a personal access token (Bitbucket Datacenter only) instead of the standard username/password.
127147

128148
First, create a new _personal access token_ in Bitbucket as instructed in the link:https://confluence.atlassian.com/bitbucketserver080/http-access-tokens-1115142284.html[HTTP access tokens | Bitbucket Data Center and Server 8.0 | Atlassian Documentation].
129149
At least allow _read_ access for repositories. If you want the plugin to install the webhooks, allow _admin_ access for repositories.

docs/images/screenshot-16.png

19.7 KB
Loading

docs/images/screenshot-17.png

12.4 KB
Loading

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

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,9 @@ public PullRequestSCMHead(String name, String repoOwner, String repository, Stri
8282

8383
public PullRequestSCMHead(String name, String repoOwner, String repository, String branchName,
8484
BitbucketPullRequest pr, SCMHeadOrigin origin, ChangeRequestCheckoutStrategy strategy) {
85-
super(name);
86-
this.repoOwner = repoOwner;
87-
this.repository = repository;
88-
this.branchName = branchName;
89-
this.number = pr.getId();
90-
this.title = pr.getTitle();
91-
this.target = new BranchSCMHead(pr.getDestination().getBranch().getName());
92-
this.origin = origin;
93-
this.strategy = strategy;
85+
this(name, repoOwner, repository, branchName,
86+
pr.getId(), pr.getTitle(), new BranchSCMHead(pr.getDestination().getBranch().getName()),
87+
origin, strategy);
9488
}
9589

9690
@Deprecated

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,7 @@
3737
* @since 2.2.0
3838
*/
3939
public class PullRequestSCMRevision extends ChangeRequestSCMRevision<PullRequestSCMHead> {
40-
41-
/**
42-
* Standardize serialization.
43-
*/
44-
private static final long serialVersionUID = 1L;
40+
private static final long serialVersionUID = 6656650901355298126L;
4541

4642
/**
4743
* The pull head revision.
@@ -100,8 +96,8 @@ public int _hashCode() {
10096
*/
10197
@Override
10298
public String toString() {
103-
return getHead() instanceof PullRequestSCMHead
104-
&& ((PullRequestSCMHead) getHead()).getCheckoutStrategy() == ChangeRequestCheckoutStrategy.MERGE
99+
return getHead() instanceof PullRequestSCMHead prHead
100+
&& prHead.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.MERGE
105101
? getPull().toString() + "+" + getTarget().toString()
106102
: getPull().toString();
107103
}

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/credentials/BitbucketAccessTokenAuthenticator.java

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright (c) 2018, CloudBees, Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
125
package com.cloudbees.jenkins.plugins.bitbucket.credentials;
226

327
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator;
@@ -6,7 +30,6 @@
630
import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl;
731
import hudson.model.Descriptor.FormException;
832
import hudson.util.Secret;
9-
import org.apache.commons.lang.StringUtils;
1033
import org.apache.http.HttpHeaders;
1134
import org.apache.http.HttpRequest;
1235
import org.jenkinsci.plugins.plaincredentials.StringCredentials;
@@ -32,17 +55,25 @@ public BitbucketAccessTokenAuthenticator(StringCredentials credentials) {
3255
/**
3356
* Provides the access token as header.
3457
*
35-
* @param request the request
58+
* @param request to configure with the access token
3659
*/
3760
public void configureRequest(HttpRequest request) {
3861
request.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + token.getPlainText());
3962
}
4063

64+
/**
65+
* Provides with the Git command line interface.
66+
* <p>
67+
* As per documentation the username must be x-token-auth and the password
68+
* is the token.
69+
*
70+
* @return the UsernamePasswordCredentials credential to be used with Git
71+
* command line interface
72+
*/
4173
@Override
4274
public StandardUsernameCredentials getCredentialsForSCM() {
4375
try {
44-
return new UsernamePasswordCredentialsImpl(
45-
CredentialsScope.GLOBAL, getId(), null, StringUtils.EMPTY, token.getPlainText());
76+
return new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, getId(), null, "x-token-auth", token.getPlainText());
4677
} catch (FormException e) {
4778
throw new RuntimeException(e);
4879
}

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/credentials/BitbucketAccessTokenAuthenticatorSource.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright (c) 2018, CloudBees, Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
125
package com.cloudbees.jenkins.plugins.bitbucket.credentials;
226

327
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator;

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/credentials/BitbucketClientCertificateAuthenticator.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ public class BitbucketClientCertificateAuthenticator implements BitbucketAuthent
5050

5151
private static final Logger LOGGER = Logger.getLogger(BitbucketClientCertificateAuthenticator.class.getName());
5252

53-
/**
54-
* {@inheritDoc}
55-
*/
5653
public BitbucketClientCertificateAuthenticator(StandardCertificateCredentials credentials) {
5754
this.credentialsId = credentials.getId();
5855
keyStore = credentials.getKeyStore();

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/credentials/BitbucketOAuth.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright (c) 2018, CloudBees, Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
125
package com.cloudbees.jenkins.plugins.bitbucket.credentials;
226

327
import com.github.scribejava.core.builder.api.DefaultApi20;

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/credentials/BitbucketOAuthAuthenticator.java

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright (c) 2018, CloudBees, Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
125
package com.cloudbees.jenkins.plugins.bitbucket.credentials;
226

327
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator;
@@ -11,50 +35,58 @@
1135
import com.github.scribejava.core.model.OAuthConstants;
1236
import com.github.scribejava.core.oauth.OAuth20Service;
1337
import hudson.model.Descriptor.FormException;
38+
import hudson.util.Secret;
1439
import java.io.IOException;
1540
import java.util.concurrent.ExecutionException;
16-
import jenkins.authentication.tokens.api.AuthenticationTokenException;
1741
import jenkins.util.SetContextClassLoader;
1842
import org.apache.http.HttpRequest;
1943

2044
public class BitbucketOAuthAuthenticator implements BitbucketAuthenticator {
2145

2246
private final String credentialsId;
47+
private final String username;
48+
private final Secret password;
2349
private OAuth2AccessToken token;
2450

2551
/**
2652
* Constructor.
2753
*
2854
* @param credentials the key/pass that will be used
29-
* @throws AuthenticationTokenException
3055
*/
31-
public BitbucketOAuthAuthenticator(StandardUsernamePasswordCredentials credentials) throws AuthenticationTokenException {
56+
public BitbucketOAuthAuthenticator(StandardUsernamePasswordCredentials credentials) {
3257
this.credentialsId = credentials.getId();
58+
this.username = credentials.getUsername();
59+
this.password = credentials.getPassword();
60+
}
3361

34-
try (SetContextClassLoader cl = new SetContextClassLoader(this.getClass());
35-
OAuth20Service service = new ServiceBuilder(credentials.getUsername())
36-
.apiSecret(credentials.getPassword().getPlainText())
37-
.httpClientConfig(JDKHttpClientConfig.defaultConfig())
38-
.build(BitbucketOAuth.instance())) {
39-
token = service.getAccessTokenClientCredentialsGrant();
40-
} catch (IOException | InterruptedException | ExecutionException e) {
41-
throw new AuthenticationTokenException(e);
62+
private OAuth2AccessToken getToken() {
63+
if (token == null) {
64+
try (SetContextClassLoader cl = new SetContextClassLoader(this.getClass());
65+
OAuth20Service service = new ServiceBuilder(username)
66+
.apiSecret(Secret.toString(password))
67+
.httpClientConfig(JDKHttpClientConfig.defaultConfig())
68+
.build(BitbucketOAuth.instance())) {
69+
token = service.getAccessTokenClientCredentialsGrant();
70+
} catch (IOException | InterruptedException | ExecutionException e) {
71+
throw new RuntimeException(e);
72+
}
4273
}
74+
return token;
4375
}
4476

4577
/**
4678
* Set up request with token in header
4779
*/
4880
@Override
4981
public void configureRequest(HttpRequest request) {
50-
request.addHeader(OAuthConstants.HEADER, "Bearer " + this.token.getAccessToken());
82+
request.addHeader(OAuthConstants.HEADER, "Bearer " + getToken().getAccessToken());
5183
}
5284

5385
@Override
5486
public StandardUsernameCredentials getCredentialsForSCM() {
5587
try {
5688
return new UsernamePasswordCredentialsImpl(
57-
CredentialsScope.GLOBAL, getId(), null, "x-token-auth", token.getAccessToken());
89+
CredentialsScope.GLOBAL, getId(), null, "x-token-auth", getToken().getAccessToken());
5890
} catch (FormException e) {
5991
throw new RuntimeException(e);
6092
}

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/credentials/BitbucketOAuthAuthenticatorSource.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright (c) 2018, CloudBees, Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
125
package com.cloudbees.jenkins.plugins.bitbucket.credentials;
226

327
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator;
@@ -32,8 +56,7 @@ public BitbucketOAuthAuthenticatorSource() {
3256
*/
3357
@NonNull
3458
@Override
35-
public BitbucketOAuthAuthenticator convert(
36-
@NonNull StandardUsernamePasswordCredentials standardUsernamePasswordCredentials) throws AuthenticationTokenException {
59+
public BitbucketOAuthAuthenticator convert(@NonNull StandardUsernamePasswordCredentials standardUsernamePasswordCredentials) throws AuthenticationTokenException {
3760
return new BitbucketOAuthAuthenticator(standardUsernamePasswordCredentials);
3861
}
3962

@@ -46,8 +69,8 @@ public BitbucketOAuthAuthenticator convert(
4669
*/
4770
@Override
4871
protected boolean isFit(AuthenticationTokenContext<? super BitbucketOAuthAuthenticator> ctx) {
49-
return ctx.mustHave(BitbucketAuthenticator.SCHEME, "https") && ctx.mustHave(
50-
BitbucketAuthenticator.BITBUCKET_INSTANCE_TYPE, BitbucketAuthenticator.BITBUCKET_INSTANCE_TYPE_CLOUD);
72+
return ctx.mustHave(BitbucketAuthenticator.SCHEME, "https")
73+
&& ctx.mustHave(BitbucketAuthenticator.BITBUCKET_INSTANCE_TYPE, BitbucketAuthenticator.BITBUCKET_INSTANCE_TYPE_CLOUD);
5174
}
5275

5376
/**

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/credentials/BitbucketOAuthCredentialMatcher.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright (c) 2018, CloudBees, Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
125
package com.cloudbees.jenkins.plugins.bitbucket.credentials;
226

327
import com.cloudbees.plugins.credentials.Credentials;
@@ -18,8 +42,9 @@ public class BitbucketOAuthCredentialMatcher implements CredentialsMatcher, Cred
1842
*/
1943
@Override
2044
public boolean matches(Credentials item) {
21-
if (!(item instanceof UsernamePasswordCredentials))
45+
if (!(item instanceof UsernamePasswordCredentials)) {
2246
return false;
47+
}
2348

2449
if(item.getClass().getName().equals("com.cloudbees.jenkins.plugins.amazonecr.AmazonECSRegistryCredential")) {
2550
return false;

0 commit comments

Comments
 (0)