Skip to content

Commit 67b7169

Browse files
authored
Add support for StringCredentials in credentials configuration (#326)
* Add support for StringCredentials * Move out GitLabCredentialMatcher to new package
1 parent f7df455 commit 67b7169

File tree

7 files changed

+85
-45
lines changed

7 files changed

+85
-45
lines changed

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ After installing the plugin on your Jenkins instance, you need configure your Gi
199199
200200
ii. `Server URL` - Contains the URL to your GitLab Server. By default it is set to "https://gitlab.com". User can modify it to enter their GitLab Server URL e.g. https://gitlab.gnome.org/, http://gitlab.example.com:7990. etc.
201201
202-
iii. `Credentials` - Contains a list of credentials entries that are of type GitLab Personal Access Token. When no credential has been added it shows "-none-". User can add a credential by clicking "Add" button.
202+
iii. `Credentials` - Contains a list of credentials entries that are of type GitLab Personal Access Token or any String Credentials. When no credential has been added it shows "-none-". User can add a credential by clicking "Add" button.
203203
204204
iv. `Mange Web Hook` - If you want the plugin to setup web hook on your GitLab project(s) to get push/mr/tag/note events then check this box.
205205
@@ -213,8 +213,7 @@ After installing the plugin on your Jenkins instance, you need configure your Gi
213213
214214
This is a manual setup. To automatically generate Personal Access Token see [next section](#creating-personal-access-token-within-jenkins).
215215
216-
i. User is required to add a `GitLab Personal Access Token` type credentials entry to securely persist the token
217-
inside Jenkins.
216+
i. User is required to add a `GitLab Personal Access Token` or any `String Credential` type credentials entry to securely persist the token inside Jenkins.
218217
219218
ii. Generate a `Personal Access Token` on your GitLab Server
220219

src/main/java/io/jenkins/plugins/gitlabbranchsource/GitLabHookCreator.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package io.jenkins.plugins.gitlabbranchsource;
22

3+
import static io.jenkins.plugins.gitlabbranchsource.helpers.GitLabHelper.getPrivateTokenAsPlainText;
34
import static io.jenkins.plugins.gitlabbranchsource.helpers.GitLabHelper.getProxyConfig;
45

6+
import com.cloudbees.plugins.credentials.common.StandardCredentials;
57
import com.damnhandy.uri.template.UriTemplate;
68
import com.damnhandy.uri.template.UriTemplateBuilder;
7-
import io.jenkins.plugins.gitlabserverconfig.credentials.PersonalAccessToken;
89
import io.jenkins.plugins.gitlabserverconfig.servers.GitLabServer;
910
import io.jenkins.plugins.gitlabserverconfig.servers.GitLabServers;
1011
import java.net.MalformedURLException;
@@ -25,7 +26,7 @@ public class GitLabHookCreator {
2526

2627
public static void register(
2728
SCMNavigatorOwner owner, GitLabSCMNavigator navigator, GitLabHookRegistration systemhookMode) {
28-
PersonalAccessToken credentials;
29+
StandardCredentials credentials;
2930
GitLabServer server = GitLabServers.get().findServer(navigator.getServerName());
3031
if (server == null) {
3132
return;
@@ -59,7 +60,7 @@ public static void register(
5960

6061
public static void register(
6162
GitLabSCMSource source, GitLabHookRegistration webhookMode, GitLabHookRegistration systemhookMode) {
62-
PersonalAccessToken credentials = null;
63+
StandardCredentials credentials = null;
6364
GitLabServer server = GitLabServers.get().findServer(source.getServerName());
6465
if (server == null) {
6566
return;
@@ -98,7 +99,7 @@ public static void register(
9899
try {
99100
GitLabApi gitLabApi = new GitLabApi(
100101
server.getServerUrl(),
101-
credentials.getToken().getPlainText(),
102+
getPrivateTokenAsPlainText(credentials),
102103
null,
103104
getProxyConfig(server.getServerUrl()));
104105
createWebHookWhenMissing(gitLabApi, source.getProjectPath(), hookUrl, secretToken);
@@ -137,12 +138,12 @@ public static void register(
137138
}
138139
}
139140

140-
public static void createSystemHookWhenMissing(GitLabServer server, PersonalAccessToken credentials) {
141+
public static void createSystemHookWhenMissing(GitLabServer server, StandardCredentials credentials) {
141142
String systemHookUrl = getHookUrl(server, false);
142143
try {
143144
GitLabApi gitLabApi = new GitLabApi(
144145
server.getServerUrl(),
145-
credentials.getToken().getPlainText(),
146+
getPrivateTokenAsPlainText(credentials),
146147
null,
147148
getProxyConfig(server.getServerUrl()));
148149
SystemHook systemHook = gitLabApi

src/main/java/io/jenkins/plugins/gitlabbranchsource/GitLabSCMNavigator.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials;
44
import static com.cloudbees.plugins.credentials.domains.URIRequirementBuilder.fromUri;
55
import static io.jenkins.plugins.gitlabbranchsource.helpers.GitLabHelper.apiBuilder;
6+
import static io.jenkins.plugins.gitlabbranchsource.helpers.GitLabHelper.getPrivateTokenAsPlainText;
67
import static io.jenkins.plugins.gitlabbranchsource.helpers.GitLabHelper.getProxyConfig;
78
import static io.jenkins.plugins.gitlabbranchsource.helpers.GitLabHelper.getServerUrl;
89
import static io.jenkins.plugins.gitlabbranchsource.helpers.GitLabHelper.getServerUrlFromName;
@@ -11,6 +12,7 @@
1112

1213
import com.cloudbees.plugins.credentials.CredentialsMatchers;
1314
import com.cloudbees.plugins.credentials.CredentialsProvider;
15+
import com.cloudbees.plugins.credentials.common.StandardCredentials;
1416
import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
1517
import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials;
1618
import edu.umd.cs.findbugs.annotations.CheckForNull;
@@ -30,7 +32,7 @@
3032
import io.jenkins.plugins.gitlabbranchsource.helpers.GitLabLink;
3133
import io.jenkins.plugins.gitlabbranchsource.helpers.GitLabOwner;
3234
import io.jenkins.plugins.gitlabbranchsource.helpers.GitLabUser;
33-
import io.jenkins.plugins.gitlabserverconfig.credentials.PersonalAccessToken;
35+
import io.jenkins.plugins.gitlabserverconfig.credentials.helpers.GitLabCredentialMatcher;
3436
import io.jenkins.plugins.gitlabserverconfig.servers.GitLabServer;
3537
import io.jenkins.plugins.gitlabserverconfig.servers.GitLabServers;
3638
import java.io.IOException;
@@ -247,14 +249,14 @@ public void visitSources(@NonNull final SCMSourceObserver observer) throws IOExc
247249
}
248250
int count = 0;
249251
observer.getListener().getLogger().format("%nChecking projects...%n");
250-
PersonalAccessToken webHookCredentials = getWebHookCredentials(observer.getContext());
252+
StandardCredentials webHookCredentials = getWebHookCredentials(observer.getContext());
251253
GitLabApi webhookGitLabApi = null;
252254
String webHookUrl = null;
253255
if (webHookCredentials != null) {
254256
GitLabServer server = GitLabServers.get().findServer(serverName);
255257
String serverUrl = getServerUrl(server);
256258
webhookGitLabApi = new GitLabApi(
257-
serverUrl, webHookCredentials.getToken().getPlainText(), null, getProxyConfig(serverUrl));
259+
serverUrl, getPrivateTokenAsPlainText(webHookCredentials), null, getProxyConfig(serverUrl));
258260
webHookUrl = GitLabHookCreator.getHookUrl(server, true);
259261
}
260262
for (Project p : projects) {
@@ -361,8 +363,8 @@ private String getProjectName(GitLabApi gitLabApi, int projectNamingStrategy, Pr
361363
return projectName;
362364
}
363365

364-
private PersonalAccessToken getWebHookCredentials(SCMSourceOwner owner) {
365-
PersonalAccessToken credentials = null;
366+
private StandardCredentials getWebHookCredentials(SCMSourceOwner owner) {
367+
StandardCredentials credentials = null;
366368
GitLabServer server = GitLabServers.get().findServer(getServerName());
367369
if (server == null) {
368370
return null;
@@ -435,14 +437,14 @@ public void afterSave(@NonNull SCMNavigatorOwner owner) {
435437
GitLabHookCreator.register(owner, this, systemhookMode);
436438
}
437439

438-
public PersonalAccessToken credentials(SCMSourceOwner owner) {
440+
public StandardCredentials credentials(SCMSourceOwner owner) {
439441
return CredentialsMatchers.firstOrNull(
440442
lookupCredentials(
441-
PersonalAccessToken.class,
443+
StandardCredentials.class,
442444
owner,
443445
Jenkins.getAuthentication(),
444446
fromUri(getServerUrlFromName(serverName)).build()),
445-
credentials -> credentials instanceof PersonalAccessToken);
447+
new GitLabCredentialMatcher());
446448
}
447449

448450
@Symbol("gitlab")

src/main/java/io/jenkins/plugins/gitlabbranchsource/helpers/GitLabHelper.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.jenkins.plugins.gitlabbranchsource.helpers;
22

3+
import com.cloudbees.plugins.credentials.common.StandardCredentials;
34
import com.damnhandy.uri.template.UriTemplate;
45
import com.damnhandy.uri.template.UriTemplateBuilder;
56
import com.damnhandy.uri.template.impl.Operator;
@@ -17,18 +18,21 @@
1718
import org.eclipse.jgit.annotations.NonNull;
1819
import org.gitlab4j.api.GitLabApi;
1920
import org.gitlab4j.api.ProxyClientConfig;
21+
import org.jenkinsci.plugins.plaincredentials.StringCredentials;
2022

2123
public class GitLabHelper {
2224

2325
public static GitLabApi apiBuilder(AccessControlled context, String serverName) {
2426
GitLabServer server = GitLabServers.get().findServer(serverName);
2527
if (server != null) {
26-
PersonalAccessToken credentials = server.getCredentials(context);
28+
StandardCredentials credentials = server.getCredentials(context);
2729
String serverUrl = server.getServerUrl();
28-
if (credentials != null) {
29-
return new GitLabApi(serverUrl, credentials.getToken().getPlainText(), null, getProxyConfig(serverUrl));
30+
String privateToken = getPrivateTokenAsPlainText(credentials);
31+
if (privateToken.equals(GitLabServer.EMPTY_TOKEN)) {
32+
return new GitLabApi(serverUrl, GitLabServer.EMPTY_TOKEN, null, getProxyConfig(serverUrl));
33+
} else {
34+
return new GitLabApi(serverUrl, privateToken, null, getProxyConfig(serverUrl));
3035
}
31-
return new GitLabApi(serverUrl, GitLabServer.EMPTY_TOKEN, null, getProxyConfig(serverUrl));
3236
}
3337
throw new IllegalStateException(String.format("No server found with the name: %s", serverName));
3438
}
@@ -96,6 +100,19 @@ private static String sanitizeUrlValue(String url) {
96100
return url;
97101
}
98102

103+
public static String getPrivateTokenAsPlainText(StandardCredentials credentials) {
104+
String privateToken = "";
105+
if (credentials != null) {
106+
if (credentials instanceof PersonalAccessToken) {
107+
privateToken = ((PersonalAccessToken) credentials).getToken().getPlainText();
108+
}
109+
if (credentials instanceof StringCredentials) {
110+
privateToken = ((StringCredentials) credentials).getSecret().getPlainText();
111+
}
112+
}
113+
return privateToken;
114+
}
115+
99116
public static UriTemplateBuilder getUriTemplateFromServer(String server) {
100117
return UriTemplate.buildFromTemplate(getServerUrl(server));
101118
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package io.jenkins.plugins.gitlabserverconfig.credentials.helpers;
2+
3+
import com.cloudbees.plugins.credentials.Credentials;
4+
import com.cloudbees.plugins.credentials.CredentialsMatcher;
5+
import edu.umd.cs.findbugs.annotations.NonNull;
6+
import io.jenkins.plugins.gitlabserverconfig.credentials.PersonalAccessToken;
7+
import org.jenkinsci.plugins.plaincredentials.StringCredentials;
8+
9+
public class GitLabCredentialMatcher implements CredentialsMatcher {
10+
11+
private static final long serialVersionUID = 1;
12+
13+
@Override
14+
public boolean matches(@NonNull Credentials credentials) {
15+
try {
16+
return credentials instanceof PersonalAccessToken || credentials instanceof StringCredentials;
17+
} catch (Exception e) {
18+
return false;
19+
}
20+
}
21+
}

src/main/java/io/jenkins/plugins/gitlabserverconfig/servers/GitLabServer.java

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static com.cloudbees.plugins.credentials.CredentialsMatchers.withId;
44
import static com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials;
55
import static com.cloudbees.plugins.credentials.domains.URIRequirementBuilder.fromUri;
6+
import static io.jenkins.plugins.gitlabbranchsource.helpers.GitLabHelper.getPrivateTokenAsPlainText;
67
import static io.jenkins.plugins.gitlabbranchsource.helpers.GitLabHelper.getProxyConfig;
78
import static org.apache.commons.lang.StringUtils.defaultIfBlank;
89

@@ -27,7 +28,7 @@
2728
import hudson.util.FormValidation;
2829
import hudson.util.ListBoxModel;
2930
import hudson.util.Secret;
30-
import io.jenkins.plugins.gitlabserverconfig.credentials.PersonalAccessToken;
31+
import io.jenkins.plugins.gitlabserverconfig.credentials.helpers.GitLabCredentialMatcher;
3132
import java.net.MalformedURLException;
3233
import java.net.URL;
3334
import java.security.SecureRandom;
@@ -59,10 +60,9 @@
5960
public class GitLabServer extends AbstractDescribableImpl<GitLabServer> {
6061

6162
/**
62-
* The credentials matcher for GitLab Personal Access Token
63+
* The credentials matcher for PersonalAccessToken and StringCredentials
6364
*/
64-
public static final CredentialsMatcher CREDENTIALS_MATCHER =
65-
CredentialsMatchers.instanceOf(PersonalAccessToken.class);
65+
public static final CredentialsMatcher CREDENTIALS_MATCHER = new GitLabCredentialMatcher();
6666
/**
6767
* Default name for community SaaS version server
6868
*/
@@ -115,7 +115,7 @@ public class GitLabServer extends AbstractDescribableImpl<GitLabServer> {
115115
private boolean manageSystemHooks;
116116

117117
/**
118-
* The {@link PersonalAccessToken#getId()} of the credentials to use for
118+
* The {@link StandardCredentials#getId()} of the credentials to use for
119119
* auto-management of
120120
* hooks.
121121
*/
@@ -165,7 +165,7 @@ public class GitLabServer extends AbstractDescribableImpl<GitLabServer> {
165165
* @param name A unique name to use to describe the end-point, if empty
166166
* replaced with a random
167167
* name
168-
* @param credentialsId The {@link PersonalAccessToken#getId()} of the
168+
* @param credentialsId The {@link StandardCredentials#getId()} of the
169169
* credentials to use for
170170
* GitLab Server Authentication to access GitLab APIs
171171
*/
@@ -252,11 +252,11 @@ public void setManageSystemHooks(boolean manageSystemHooks) {
252252
}
253253

254254
/**
255-
* Returns The {@link PersonalAccessToken#getId()} of the credentials to use for
255+
* Returns The {@link StandardCredentials#getId()} of the credentials to use for
256256
* GitLab Server
257257
* Authentication to access GitLab APIs.
258258
*
259-
* @return The {@link PersonalAccessToken#getId()} of the credentials to use for
259+
* @return The {@link StandardCredentials#getId()} of the credentials to use for
260260
* GitLab Server
261261
* Authentication to access GitLab APIs.
262262
*/
@@ -266,11 +266,11 @@ public String getCredentialsId() {
266266
}
267267

268268
/**
269-
* Looks up for Personal Access Token
269+
* Looks up for PersonalAccessToken and StringCredentials
270270
*
271-
* @return {@link PersonalAccessToken}
271+
* @return {@link StandardCredentials}
272272
*/
273-
public PersonalAccessToken getCredentials(AccessControlled context) {
273+
public StandardCredentials getCredentials(AccessControlled context) {
274274
Jenkins jenkins = Jenkins.get();
275275
if (context == null) {
276276
jenkins.checkPermission(CredentialsProvider.USE_OWN);
@@ -281,7 +281,7 @@ public PersonalAccessToken getCredentials(AccessControlled context) {
281281
? null
282282
: CredentialsMatchers.firstOrNull(
283283
lookupCredentials(
284-
PersonalAccessToken.class,
284+
StandardCredentials.class,
285285
jenkins,
286286
ACL.SYSTEM,
287287
fromUri(defaultIfBlank(serverUrl, GITLAB_SERVER_URL))
@@ -576,11 +576,8 @@ public String getDisplayName() {
576576
@Restricted(DoNotUse.class)
577577
@SuppressWarnings("unused")
578578
public FormValidation doTestConnection(@QueryParameter String serverUrl, @QueryParameter String credentialsId) {
579-
PersonalAccessToken credentials = getCredentials(serverUrl, credentialsId);
580-
String privateToken = "";
581-
if (credentials != null) {
582-
privateToken = credentials.getToken().getPlainText();
583-
}
579+
StandardCredentials credentials = getCredentials(serverUrl, credentialsId);
580+
String privateToken = getPrivateTokenAsPlainText(credentials);
584581
if (privateToken.equals(EMPTY_TOKEN)) {
585582
GitLabApi gitLabApi = new GitLabApi(serverUrl, EMPTY_TOKEN, null, getProxyConfig(serverUrl));
586583
try {
@@ -598,7 +595,6 @@ public FormValidation doTestConnection(@QueryParameter String serverUrl, @QueryP
598595
Messages.GitLabServer_credentialsNotResolved(Util.escape(credentialsId)));
599596
}
600597
} else {
601-
602598
GitLabApi gitLabApi = new GitLabApi(serverUrl, privateToken, null, getProxyConfig(serverUrl));
603599
try {
604600
User user = gitLabApi.getUserApi().getCurrentUser();
@@ -662,14 +658,14 @@ public ListBoxModel doFillWebhookSecretCredentialsIdItems(
662658
WEBHOOK_SECRET_CREDENTIALS_MATCHER);
663659
}
664660

665-
private PersonalAccessToken getCredentials(String serverUrl, String credentialsId) {
661+
private StandardCredentials getCredentials(String serverUrl, String credentialsId) {
666662
Jenkins jenkins = Jenkins.get();
667663
jenkins.checkPermission(Jenkins.ADMINISTER);
668664
return StringUtils.isBlank(credentialsId)
669665
? null
670666
: CredentialsMatchers.firstOrNull(
671667
lookupCredentials(
672-
PersonalAccessToken.class,
668+
StandardCredentials.class,
673669
jenkins,
674670
ACL.SYSTEM,
675671
fromUri(defaultIfBlank(serverUrl, GITLAB_SERVER_URL))

src/main/resources/io/jenkins/plugins/gitlabserverconfig/servers/GitLabServer/help-credentialsId.html

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,17 @@
1212
</li>
1313
</ul>
1414

15-
In Jenkins, create a token credential as «<b>GitLab Personal Access Token</b>». Human readable id
16-
and description is recommended.
15+
In Jenkins, create a token credential as «<b>GitLab Personal Access Token</b>» or any
16+
«<b>StringCredentials</b>» type credential (e.g. «<b>"Secret text"</b>» provided by
17+
<a href="https://plugins.jenkins.io/plain-credentials">Plain Credentials plugin</a> or
18+
«<b>"Vault Secret Text Credential"</b>» provided by
19+
<a href="https://plugins.jenkins.io/hashicorp-vault-plugin">HashiCorp Vault plugin</a>).
20+
Human-readable id and description is recommended.
1721
<br/>
1822

1923
<p>
2024
If you have an existing GitLab login and password you can convert it to a token automatically
21-
with the help of <br>
22-
«<b>Manage additional GitLab actions</b>» in Advanced section of GitLab Servers.
25+
with the help of «<b>Manage additional GitLab actions</b>» in Advanced section of
26+
GitLab Servers.
2327
</p>
2428
</div>

0 commit comments

Comments
 (0)