Skip to content

Commit 85cf3a4

Browse files
mymarchejetersen
andauthored
Allow users without global Job/Build permission configure multibranch jobs (#156)
Co-authored-by: Joseph Petersen <josephp90@gmail.com>
1 parent 3013db8 commit 85cf3a4

File tree

9 files changed

+67
-40
lines changed

9 files changed

+67
-40
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ target
88
.settings
99
bin
1010
.DS_Store
11+
.vscode/

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public static void register(SCMNavigatorOwner owner, GitLabSCMNavigator navigato
3737
if (!server.isManageSystemHooks()) {
3838
return;
3939
}
40-
credentials = server.getCredentials();
40+
credentials = server.getCredentials(owner);
4141
if (credentials == null) {
4242
LOGGER.log(Level.WARNING, "No System credentials added, cannot create system hook");
4343
}
@@ -71,7 +71,7 @@ public static void register(GitLabSCMSource source,
7171
if (!server.isManageWebHooks()) {
7272
break;
7373
}
74-
credentials = server.getCredentials();
74+
credentials = server.getCredentials(source.getOwner());
7575
if (credentials == null) {
7676
LOGGER.log(Level.WARNING, "No System credentials added, cannot create web hook");
7777
}
@@ -108,7 +108,7 @@ public static void register(GitLabSCMSource source,
108108
if (!server.isManageSystemHooks()) {
109109
return;
110110
}
111-
credentials = server.getCredentials();
111+
credentials = server.getCredentials(source.getOwner());
112112
if (credentials == null) {
113113
LOGGER.log(Level.WARNING, "No System credentials added, cannot create system hook");
114114
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public SCMFileSystem build(@NonNull SCMSource source, @NonNull SCMHead head,
9797
@CheckForNull SCMRevision rev)
9898
throws IOException, InterruptedException {
9999
GitLabSCMSource gitlabScmSource = (GitLabSCMSource) source;
100-
GitLabApi gitLabApi = apiBuilder(gitlabScmSource.getServerName());
100+
GitLabApi gitLabApi = apiBuilder(source.getOwner(), gitlabScmSource.getServerName());
101101
String projectPath = gitlabScmSource.getProjectPath();
102102
return build(head, rev, gitLabApi, projectPath);
103103
}

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

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,9 @@ public void setTraits(@CheckForNull SCMTrait[] traits) {
189189
}
190190
}
191191

192-
private GitLabOwner getGitlabOwner() {
192+
private GitLabOwner getGitlabOwner(SCMNavigatorOwner owner) {
193193
if (gitlabOwner == null) {
194-
getGitlabOwner(apiBuilder(serverName));
194+
getGitlabOwner(apiBuilder(owner, serverName));
195195
}
196196
return gitlabOwner;
197197
}
@@ -229,7 +229,7 @@ public void visitSources(@NonNull final SCMSourceObserver observer)
229229
GitLabSCMNavigatorContext context = new GitLabSCMNavigatorContext()
230230
.withTraits(traits);
231231
try (GitLabSCMNavigatorRequest request = context.newRequest(this, observer)) {
232-
GitLabApi gitLabApi = apiBuilder(serverName);
232+
GitLabApi gitLabApi = apiBuilder(observer.getContext(), serverName);
233233
getGitlabOwner(gitLabApi);
234234
List<Project> projects;
235235
if (gitlabOwner instanceof GitLabUser) {
@@ -260,7 +260,7 @@ public void visitSources(@NonNull final SCMSourceObserver observer)
260260
count++;
261261
String projectPathWithNamespace = p.getPathWithNamespace();
262262
String projectOwner = getProjectOwnerFromNamespace(projectPathWithNamespace);
263-
String projectName = getProjectName(request.withProjectNamingStrategy(), p);
263+
String projectName = getProjectName(gitLabApi, request.withProjectNamingStrategy(), p);
264264
getNavigatorProjects().add(projectPathWithNamespace);
265265
if (StringUtils.isEmpty(p.getDefaultBranch())) {
266266
observer.getListener().getLogger()
@@ -319,7 +319,7 @@ public void visitSources(@NonNull final SCMSourceObserver observer)
319319
}
320320

321321
@NonNull
322-
private String getProjectName(int projectNamingStrategy, Project project) throws URISyntaxException {
322+
private String getProjectName(GitLabApi gitLabApi, int projectNamingStrategy, Project project) throws URISyntaxException {
323323
String fullPath = project.getPathWithNamespace();
324324
String projectName;
325325
switch (projectNamingStrategy) {
@@ -331,7 +331,7 @@ private String getProjectName(int projectNamingStrategy, Project project) throws
331331
case 2:
332332
// Project name
333333
projectName = project.getNameWithNamespace()
334-
.replace(String.format("%s / ", getGitlabOwner().getFullName()), "");
334+
.replace(String.format("%s / ", getGitlabOwner(gitLabApi).getFullName()), "");
335335
break;
336336
case 3:
337337
// Contextual project path
@@ -365,7 +365,7 @@ private PersonalAccessToken getWebHookCredentials(SCMSourceOwner owner) {
365365
if (!server.isManageWebHooks()) {
366366
break;
367367
}
368-
credentials = server.getCredentials();
368+
credentials = server.getCredentials(owner);
369369
if (credentials == null) {
370370
LOGGER.log(Level.WARNING, "No System credentials added, cannot create web hook");
371371
}
@@ -387,7 +387,7 @@ private PersonalAccessToken getWebHookCredentials(SCMSourceOwner owner) {
387387
protected List<Action> retrieveActions(@NonNull SCMNavigatorOwner owner,
388388
SCMNavigatorEvent event,
389389
@NonNull TaskListener listener) throws IOException, InterruptedException {
390-
getGitlabOwner();
390+
getGitlabOwner(owner);
391391
String fullName = gitlabOwner.getFullName();
392392
String webUrl = gitlabOwner.getWebUrl();
393393
String avatarUrl = gitlabOwner.getAvatarUrl();
@@ -443,14 +443,15 @@ public static class DescriptorImpl extends SCMNavigatorDescriptor implements Ico
443443
@Inject
444444
private GitLabSCMSource.DescriptorImpl delegate;
445445

446-
public static FormValidation doCheckProjectOwner(@QueryParameter String projectOwner,
446+
public static FormValidation doCheckProjectOwner(@AncestorInPath SCMSourceOwner context,
447+
@QueryParameter String projectOwner,
447448
@QueryParameter String serverName) {
448449
if (projectOwner.equals("")) {
449450
return FormValidation.ok();
450451
}
451452
GitLabApi gitLabApi = null;
452453
try {
453-
gitLabApi = apiBuilder(serverName);
454+
gitLabApi = apiBuilder(context, serverName);
454455
GitLabOwner gitLabOwner = GitLabOwner.fetchOwner(gitLabApi, projectOwner);
455456
return FormValidation.ok(projectOwner + " is a valid " + gitLabOwner.getWord());
456457
} catch (IllegalStateException e) {

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ public String getRemote() {
193193

194194
protected Project getGitlabProject() {
195195
if (gitlabProject == null) {
196-
getGitlabProject(apiBuilder(serverName));
196+
getGitlabProject(apiBuilder(this.getOwner(), serverName));
197197
}
198198
return gitlabProject;
199199
}
@@ -216,7 +216,7 @@ protected Project getGitlabProject(GitLabApi gitLabApi) {
216216
public HashMap<String, AccessLevel> getMembers() {
217217
HashMap<String, AccessLevel> members = new HashMap<>();
218218
try {
219-
GitLabApi gitLabApi = apiBuilder(serverName);
219+
GitLabApi gitLabApi = apiBuilder(this.getOwner(), serverName);
220220
for (Member m : gitLabApi.getProjectApi().getAllMembers(projectPath)) {
221221
members.put(m.getUsername(), m.getAccessLevel());
222222
}
@@ -251,7 +251,7 @@ public void setTraits(List<SCMSourceTrait> traits) {
251251
protected SCMRevision retrieve(@NonNull SCMHead head, @NonNull TaskListener listener)
252252
throws IOException, InterruptedException {
253253
try {
254-
GitLabApi gitLabApi = apiBuilder(serverName);
254+
GitLabApi gitLabApi = apiBuilder(this.getOwner(), serverName);
255255
getGitlabProject(gitLabApi);
256256
if (head instanceof BranchSCMHead) {
257257
listener.getLogger().format("Querying the current revision of branch %s...%n", head.getName());
@@ -304,7 +304,7 @@ protected void retrieve(SCMSourceCriteria criteria, @NonNull SCMHeadObserver obs
304304
SCMHeadEvent<?> event,
305305
@NonNull TaskListener listener) throws IOException, InterruptedException {
306306
try {
307-
GitLabApi gitLabApi = apiBuilder(serverName);
307+
GitLabApi gitLabApi = apiBuilder(this.getOwner(), serverName);
308308
getGitlabProject(gitLabApi);
309309
setProjectId(gitlabProject.getId());
310310
sshRemote = gitlabProject.getSshUrlToRepo();
@@ -675,7 +675,7 @@ protected SCMProbe createProbe(@NonNull final SCMHead head, SCMRevision revision
675675
if (builder == null) {
676676
throw new AssertionError();
677677
}
678-
GitLabApi gitLabApi = apiBuilder(serverName);
678+
GitLabApi gitLabApi = apiBuilder(this.getOwner(), serverName);
679679
getGitlabProject(gitLabApi);
680680
final SCMFileSystem fs = builder.build(head, revision, gitLabApi, projectPath);
681681
return new SCMProbe() {
@@ -807,17 +807,17 @@ context, StandardUsernameCredentials.class, fromUri(getServerUrlFromName(serverN
807807
return result;
808808
}
809809

810-
public long getProjectId(@QueryParameter String projectPath, @QueryParameter String serverName) {
810+
public long getProjectId(@AncestorInPath SCMSourceOwner context, @QueryParameter String projectPath, @QueryParameter String serverName) {
811811
List<GitLabServer> gitLabServers = GitLabServers.get().getServers();
812812
if (gitLabServers.size() == 0) {
813813
return -1;
814814
}
815815
try {
816816
GitLabApi gitLabApi;
817817
if (StringUtils.isBlank(serverName)) {
818-
gitLabApi = apiBuilder(gitLabServers.get(0).getName());
818+
gitLabApi = apiBuilder(context, gitLabServers.get(0).getName());
819819
} else {
820-
gitLabApi = apiBuilder(serverName);
820+
gitLabApi = apiBuilder(context, serverName);
821821
}
822822
if (StringUtils.isNotBlank(projectPath)) {
823823
return gitLabApi.getProjectApi().getProject(projectPath).getId();
@@ -838,9 +838,9 @@ public ListBoxModel doFillProjectPathItems(@AncestorInPath SCMSourceOwner contex
838838
try {
839839
GitLabApi gitLabApi;
840840
if (serverName.equals("")) {
841-
gitLabApi = apiBuilder(gitLabServers.get(0).getName());
841+
gitLabApi = apiBuilder(context, gitLabServers.get(0).getName());
842842
} else {
843-
gitLabApi = apiBuilder(serverName);
843+
gitLabApi = apiBuilder(context, serverName);
844844
}
845845

846846
if (projectOwner.equals("")) {

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.damnhandy.uri.template.UriTemplateBuilder;
55
import com.damnhandy.uri.template.impl.Operator;
66
import hudson.ProxyConfiguration;
7+
import hudson.security.AccessControlled;
78
import io.jenkins.plugins.gitlabserverconfig.credentials.PersonalAccessToken;
89
import io.jenkins.plugins.gitlabserverconfig.servers.GitLabServer;
910
import io.jenkins.plugins.gitlabserverconfig.servers.GitLabServers;
@@ -19,10 +20,10 @@
1920

2021
public class GitLabHelper {
2122

22-
public static GitLabApi apiBuilder(String serverName) {
23+
public static GitLabApi apiBuilder(AccessControlled context, String serverName) {
2324
GitLabServer server = GitLabServers.get().findServer(serverName);
2425
if (server != null) {
25-
PersonalAccessToken credentials = server.getCredentials();
26+
PersonalAccessToken credentials = server.getCredentials(context);
2627
String serverUrl = server.getServerUrl();
2728
if (credentials != null) {
2829
return new GitLabApi(serverUrl, credentials.getToken().getPlainText(), null, getProxyConfig(serverUrl));

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ private static void logComment(Run<?, ?> build, TaskListener listener) {
174174
String suffix = " - [Details](" + url + ")";
175175
SCMRevision revision = SCMRevisionAction.getRevision(source, build);
176176
try {
177-
GitLabApi gitLabApi = GitLabHelper.apiBuilder(source.getServerName());
177+
GitLabApi gitLabApi = GitLabHelper.apiBuilder(build.getParent(), source.getServerName());
178178
String sudoUsername = sourceContext.getSudoUser();
179179
if (!sudoUsername.isEmpty()) {
180180
gitLabApi.sudo(sudoUsername);
@@ -319,7 +319,7 @@ private static void sendNotifications(Run<?, ?> build, TaskListener listener) {
319319
}
320320
}
321321
try {
322-
GitLabApi gitLabApi = GitLabHelper.apiBuilder(source.getServerName());
322+
GitLabApi gitLabApi = GitLabHelper.apiBuilder(build.getParent(), source.getServerName());
323323
LOGGER.log(Level.FINE, String.format("Notifiying commit: %s", hash));
324324

325325
if (revision instanceof MergeRequestSCMRevision) {
@@ -419,7 +419,7 @@ public void onEnterWaiting(final Queue.WaitingItem wi) {
419419

420420
Constants.CommitBuildState state = Constants.CommitBuildState.PENDING;
421421
try {
422-
GitLabApi gitLabApi = GitLabHelper.apiBuilder(source.getServerName());
422+
GitLabApi gitLabApi = GitLabHelper.apiBuilder(job, source.getServerName());
423423
// check are we still the task to set pending
424424
synchronized (resolving) {
425425
if (!nonce.equals(resolving.get(job))) {

src/main/java/io/jenkins/plugins/gitlabserverconfig/action/GitlabAction.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.util.logging.Level;
1010
import java.util.logging.Logger;
1111
import jenkins.model.Jenkins;
12+
import jenkins.scm.api.SCMSourceOwner;
1213
import net.sf.json.JSONArray;
1314
import net.sf.json.JSONObject;
1415
import org.apache.commons.lang.StringUtils;
@@ -18,6 +19,7 @@
1819
import org.gitlab4j.api.models.ProjectFilter;
1920
import org.kohsuke.accmod.Restricted;
2021
import org.kohsuke.accmod.restrictions.NoExternalUse;
22+
import org.kohsuke.stapler.AncestorInPath;
2123
import org.kohsuke.stapler.HttpResponse;
2224
import org.kohsuke.stapler.QueryParameter;
2325
import org.kohsuke.stapler.interceptor.RequirePOST;
@@ -48,7 +50,8 @@ public HttpResponse doServerList() {
4850
}
4951

5052
@RequirePOST
51-
public HttpResponse doProjectList(@QueryParameter String server,
53+
public HttpResponse doProjectList(@AncestorInPath SCMSourceOwner context,
54+
@QueryParameter String server,
5255
@QueryParameter String owner) {
5356
if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER)) {
5457
return HttpResponses.errorJSON("no permission to get Gitlab server list");
@@ -60,7 +63,7 @@ public HttpResponse doProjectList(@QueryParameter String server,
6063

6164
JSONArray servers = new JSONArray();
6265

63-
GitLabApi gitLabApi = GitLabHelper.apiBuilder(server);
66+
GitLabApi gitLabApi = GitLabHelper.apiBuilder(context, server);
6467
try {
6568
for (Project project : gitLabApi.getProjectApi().getUserProjects(owner,
6669
new ProjectFilter().withOwned(true))) {

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

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111
import hudson.Util;
1212
import hudson.model.AbstractDescribableImpl;
1313
import hudson.model.Descriptor;
14+
import hudson.model.Item;
15+
import hudson.model.ItemGroup;
1416
import hudson.security.ACL;
17+
import hudson.security.AccessControlled;
1518
import hudson.util.FormValidation;
1619
import hudson.util.ListBoxModel;
1720
import hudson.util.Secret;
@@ -230,16 +233,34 @@ public String getCredentialsId() {
230233
*
231234
* @return {@link PersonalAccessToken}
232235
*/
233-
public PersonalAccessToken getCredentials() {
236+
public PersonalAccessToken getCredentials(AccessControlled context) {
234237
Jenkins jenkins = Jenkins.get();
235-
jenkins.checkPermission(CredentialsProvider.USE_OWN);
236-
return StringUtils.isBlank(credentialsId) ? null : CredentialsMatchers.firstOrNull(
237-
lookupCredentials(
238-
PersonalAccessToken.class,
239-
jenkins,
240-
ACL.SYSTEM,
241-
fromUri(defaultIfBlank(serverUrl, GITLAB_SERVER_URL)).build()
242-
), withId(credentialsId));
238+
if (context == null) {
239+
jenkins.checkPermission(CredentialsProvider.USE_OWN);
240+
return StringUtils.isBlank(credentialsId) ? null : CredentialsMatchers.firstOrNull( lookupCredentials(
241+
PersonalAccessToken.class,
242+
jenkins,
243+
ACL.SYSTEM,
244+
fromUri(defaultIfBlank(serverUrl, GITLAB_SERVER_URL)).build()
245+
), withId(credentialsId));
246+
} else {
247+
context.checkPermission(CredentialsProvider.USE_OWN);
248+
if (context instanceof ItemGroup) {
249+
return StringUtils.isBlank(credentialsId) ? null : CredentialsMatchers.firstOrNull( lookupCredentials(
250+
PersonalAccessToken.class,
251+
(ItemGroup) context,
252+
ACL.SYSTEM,
253+
fromUri(defaultIfBlank(serverUrl, GITLAB_SERVER_URL)).build()
254+
), withId(credentialsId));
255+
} else {
256+
return StringUtils.isBlank(credentialsId) ? null : CredentialsMatchers.firstOrNull( lookupCredentials(
257+
PersonalAccessToken.class,
258+
(Item) context,
259+
ACL.SYSTEM,
260+
fromUri(defaultIfBlank(serverUrl, GITLAB_SERVER_URL)).build()
261+
), withId(credentialsId));
262+
}
263+
}
243264
}
244265

245266
/**

0 commit comments

Comments
 (0)