Skip to content

Commit

Permalink
Merge pull request #60 from pascal-hofmann/configurable-minimum-permi…
Browse files Browse the repository at this point in the history
…ssions

Add configurable minimum permissions for triggers
  • Loading branch information
bluesliverx committed Apr 17, 2023
2 parents 4f61f93 + 00d64c4 commit e96c665
Show file tree
Hide file tree
Showing 13 changed files with 112 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import jenkins.scm.api.SCMSource;
import org.jenkinsci.plugins.github_branch_source.Connector;
import org.jenkinsci.plugins.github_branch_source.GitHubSCMSource;
import org.kohsuke.github.GHPermissionType;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
import org.slf4j.LoggerFactory;
Expand All @@ -23,10 +24,28 @@ private GithubHelper() {
// private
}

public static boolean isAuthorized(final Job<?, ?> job, final String author) {
public static boolean isAuthorized(final Job<?, ?> job, final String author, String minimumPermissions) {
try {
GHRepository ghRepository = getGHRepository(job);
boolean authorized = ghRepository.getCollaboratorNames().contains(author);
GHPermissionType authorPermissions = ghRepository.getPermission(author);

Check warning on line 30 in src/main/java/com/adobe/jenkins/github_pr_comment_build/GithubHelper.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 30 is not covered by tests
boolean authorized = false;

Check warning on line 31 in src/main/java/com/adobe/jenkins/github_pr_comment_build/GithubHelper.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 31 is not covered by tests
switch (GHPermissionType.valueOf(minimumPermissions)) {

Check warning on line 32 in src/main/java/com/adobe/jenkins/github_pr_comment_build/GithubHelper.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 32 is only partially covered, 3 branches are missing
case NONE:
authorized = true;

Check warning on line 34 in src/main/java/com/adobe/jenkins/github_pr_comment_build/GithubHelper.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 34 is not covered by tests
break;

Check warning on line 35 in src/main/java/com/adobe/jenkins/github_pr_comment_build/GithubHelper.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 35 is not covered by tests
default: // break intentionally omitted
case WRITE:
if(authorPermissions == GHPermissionType.WRITE || authorPermissions == GHPermissionType.ADMIN) {

Check warning on line 38 in src/main/java/com/adobe/jenkins/github_pr_comment_build/GithubHelper.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 38 is only partially covered, 4 branches are missing
authorized = true;

Check warning on line 39 in src/main/java/com/adobe/jenkins/github_pr_comment_build/GithubHelper.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 39 is not covered by tests
}
break;
case ADMIN:
if(authorPermissions == GHPermissionType.ADMIN) {

Check warning on line 43 in src/main/java/com/adobe/jenkins/github_pr_comment_build/GithubHelper.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 43 is only partially covered, 2 branches are missing
authorized = true;

Check warning on line 44 in src/main/java/com/adobe/jenkins/github_pr_comment_build/GithubHelper.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 44 is not covered by tests
}
break;
}

LOG.debug("User {} authorized: {}", author, authorized);
return authorized;
} catch (final IOException | IllegalArgumentException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ protected void onEvent(GHEvent event, String payload) {
propFound = true;
TriggerPRCommentBranchProperty branchProp = (TriggerPRCommentBranchProperty)prop;
String expectedCommentBody = branchProp.getCommentBody();
if (!branchProp.isAllowUntrusted() && !GithubHelper.isAuthorized(job, commentAuthor)) {
if (!GithubHelper.isAuthorized(job, commentAuthor, branchProp.getMinimumPermissions())) {

Check warning on line 152 in src/main/java/com/adobe/jenkins/github_pr_comment_build/IssueCommentGHEventSubscriber.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 152 is only partially covered, 2 branches are missing
continue;
}
Pattern pattern = Pattern.compile(expectedCommentBody,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ protected void onEvent(GHEvent event, String payload) {
continue;
}
TriggerPRReviewBranchProperty branchProp = (TriggerPRReviewBranchProperty)prop;
if (!branchProp.isAllowUntrusted() && !GithubHelper.isAuthorized(job, author)) {
if (!GithubHelper.isAuthorized(job, author, branchProp.getMinimumPermissions())) {

Check warning on line 123 in src/main/java/com/adobe/jenkins/github_pr_comment_build/PRReviewGHEventSubscriber.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 123 is only partially covered, 2 branches are missing
continue;
}
propFound = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ protected void onEvent(GHEvent event, String payload) {
continue;
}
TriggerPRUpdateBranchProperty branchProp = (TriggerPRUpdateBranchProperty)prop;
if (!branchProp.isAllowUntrusted() && !GithubHelper.isAuthorized(job, author)) {
if (!GithubHelper.isAuthorized(job, author, branchProp.getMinimumPermissions())) {

Check warning on line 138 in src/main/java/com/adobe/jenkins/github_pr_comment_build/PRUpdateGHEventSubscriber.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 138 is only partially covered, 2 branches are missing
continue;
}
propFound = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.adobe.jenkins.github_pr_comment_build;

import hudson.model.Job;
import hudson.model.Run;
import jenkins.branch.BranchProperty;
import jenkins.branch.JobDecorator;
import org.kohsuke.stapler.DataBoundSetter;

/**
* Common parts of TriggerPR*BranchProperty classes
*/
abstract public class TriggerBranchProperty extends BranchProperty {

Check warning on line 12 in src/main/java/com/adobe/jenkins/github_pr_comment_build/TriggerBranchProperty.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 12 is not covered by tests
protected boolean allowUntrusted;
protected String minimumPermissions;

@Deprecated
public boolean isAllowUntrusted() {
return allowUntrusted;

Check warning on line 18 in src/main/java/com/adobe/jenkins/github_pr_comment_build/TriggerBranchProperty.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 18 is not covered by tests
}

@DataBoundSetter
@Deprecated
public void setAllowUntrusted(boolean allowUntrusted) {
this.allowUntrusted = allowUntrusted;

Check warning on line 24 in src/main/java/com/adobe/jenkins/github_pr_comment_build/TriggerBranchProperty.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 24 is not covered by tests
}

Check warning on line 25 in src/main/java/com/adobe/jenkins/github_pr_comment_build/TriggerBranchProperty.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 25 is not covered by tests

@DataBoundSetter
public void setMinimumPermissions(String minimumPermissions) {
this.minimumPermissions = minimumPermissions;

Check warning on line 29 in src/main/java/com/adobe/jenkins/github_pr_comment_build/TriggerBranchProperty.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 29 is not covered by tests
}

Check warning on line 30 in src/main/java/com/adobe/jenkins/github_pr_comment_build/TriggerBranchProperty.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 30 is not covered by tests

public String getMinimumPermissions() {
if (minimumPermissions == null || minimumPermissions.isEmpty()) {

Check warning on line 33 in src/main/java/com/adobe/jenkins/github_pr_comment_build/TriggerBranchProperty.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 33 is only partially covered, 4 branches are missing
return this.allowUntrusted ? "NONE" : "WRITE";

Check warning on line 34 in src/main/java/com/adobe/jenkins/github_pr_comment_build/TriggerBranchProperty.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 34 is only partially covered, 2 branches are missing
}
return minimumPermissions;

Check warning on line 36 in src/main/java/com/adobe/jenkins/github_pr_comment_build/TriggerBranchProperty.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 36 is not covered by tests
}

@Override
public <P extends Job<P, B>, B extends Run<P, B>> JobDecorator<P, B> jobDecorator(Class<P> clazz) {
return null;

Check warning on line 41 in src/main/java/com/adobe/jenkins/github_pr_comment_build/TriggerBranchProperty.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 41 is not covered by tests
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.adobe.jenkins.github_pr_comment_build;

import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.util.ListBoxModel;
import jenkins.branch.BranchPropertyDescriptor;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.github.GHPermissionType;

abstract public class TriggerBranchPropertyDescriptorImpl extends BranchPropertyDescriptor {

/**
* Populates the minimum permissions options.
*
* @return the minimum permissions options.
*/
@NonNull
@Restricted(NoExternalUse.class)
@SuppressWarnings("unused") // stapler
public ListBoxModel doFillMinimumPermissionsItems() {
ListBoxModel result = new ListBoxModel();

Check warning on line 21 in src/main/java/com/adobe/jenkins/github_pr_comment_build/TriggerBranchPropertyDescriptorImpl.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 21 is not covered by tests
result.add("Only users with admin permission", String.valueOf(GHPermissionType.ADMIN));

Check warning on line 22 in src/main/java/com/adobe/jenkins/github_pr_comment_build/TriggerBranchPropertyDescriptorImpl.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 22 is not covered by tests
result.add("Only users that can push to the repository", String.valueOf(GHPermissionType.WRITE));

Check warning on line 23 in src/main/java/com/adobe/jenkins/github_pr_comment_build/TriggerBranchPropertyDescriptorImpl.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 23 is not covered by tests
result.add("Allow untrusted users to trigger the build", String.valueOf(GHPermissionType.NONE));

Check warning on line 24 in src/main/java/com/adobe/jenkins/github_pr_comment_build/TriggerBranchPropertyDescriptorImpl.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 24 is not covered by tests
return result;

Check warning on line 25 in src/main/java/com/adobe/jenkins/github_pr_comment_build/TriggerBranchPropertyDescriptorImpl.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 25 is not covered by tests
}

}
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
package com.adobe.jenkins.github_pr_comment_build;

import hudson.Extension;
import hudson.model.Job;
import hudson.model.Run;
import jenkins.branch.BranchProperty;
import jenkins.branch.BranchPropertyDescriptor;
import jenkins.branch.JobDecorator;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

/**
* Allows a GitHub pull request comment to trigger an immediate build based on a comment string.
*/
public class TriggerPRCommentBranchProperty extends BranchProperty {
public class TriggerPRCommentBranchProperty extends TriggerBranchProperty {
/**
* The comment body to trigger a new build on.
*/
private final String commentBody;
private boolean allowUntrusted;

/**
* Constructor.
Expand All @@ -39,27 +32,12 @@ public String getCommentBody() {
return commentBody;
}

public boolean isAllowUntrusted() {
return allowUntrusted;
}

@DataBoundSetter
public void setAllowUntrusted(boolean allowUntrusted) {
this.allowUntrusted = allowUntrusted;
}

@Override
public <P extends Job<P, B>, B extends Run<P, B>> JobDecorator<P, B> jobDecorator(Class<P> clazz) {
return null;
}

@Extension
public static class DescriptorImpl extends BranchPropertyDescriptor {
public static class DescriptorImpl extends TriggerBranchPropertyDescriptorImpl {

@Override
public String getDisplayName() {
return Messages.TriggerPRCommentBranchProperty_trigger_on_pull_request_comment();
}

}
}
Original file line number Diff line number Diff line change
@@ -1,47 +1,25 @@
package com.adobe.jenkins.github_pr_comment_build;

import hudson.Extension;
import hudson.model.Job;
import hudson.model.Run;
import jenkins.branch.BranchProperty;
import jenkins.branch.BranchPropertyDescriptor;
import jenkins.branch.JobDecorator;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

/**
* Allows a GitHub pull request update to trigger an immediate build.
*/
public class TriggerPRReviewBranchProperty extends BranchProperty {
private boolean allowUntrusted;
public class TriggerPRReviewBranchProperty extends TriggerBranchProperty {

/**
* Constructor.
*/
@DataBoundConstructor
public TriggerPRReviewBranchProperty() { }

public boolean isAllowUntrusted() {
return allowUntrusted;
}

@DataBoundSetter
public void setAllowUntrusted(boolean allowUntrusted) {
this.allowUntrusted = allowUntrusted;
}

@Override
public <P extends Job<P, B>, B extends Run<P, B>> JobDecorator<P, B> jobDecorator(Class<P> clazz) {
return null;
}
public TriggerPRReviewBranchProperty() {}

@Extension
public static class DescriptorImpl extends BranchPropertyDescriptor {
public static class DescriptorImpl extends TriggerBranchPropertyDescriptorImpl {

@Override
public String getDisplayName() {
return Messages.TriggerPRReviewBranchProperty_trigger_on_pull_request_review();
}

}
}
}
Original file line number Diff line number Diff line change
@@ -1,47 +1,25 @@
package com.adobe.jenkins.github_pr_comment_build;

import hudson.Extension;
import hudson.model.Job;
import hudson.model.Run;
import jenkins.branch.BranchProperty;
import jenkins.branch.BranchPropertyDescriptor;
import jenkins.branch.JobDecorator;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

/**
* Allows a GitHub pull request update to trigger an immediate build.
*/
public class TriggerPRUpdateBranchProperty extends BranchProperty {
private boolean allowUntrusted;
public class TriggerPRUpdateBranchProperty extends TriggerBranchProperty {

/**
* Constructor.
*/
@DataBoundConstructor
public TriggerPRUpdateBranchProperty() { }

public boolean isAllowUntrusted() {
return allowUntrusted;
}

@DataBoundSetter
public void setAllowUntrusted(boolean allowUntrusted) {
this.allowUntrusted = allowUntrusted;
}

@Override
public <P extends Job<P, B>, B extends Run<P, B>> JobDecorator<P, B> jobDecorator(Class<P> clazz) {
return null;
}
public TriggerPRUpdateBranchProperty() {}

@Extension
public static class DescriptorImpl extends BranchPropertyDescriptor {
public static class DescriptorImpl extends TriggerBranchPropertyDescriptorImpl {

@Override
public String getDisplayName() {
return Messages.TriggerPRUpdateBranchProperty_trigger_on_pull_request_update();
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<f:entry title="Comment Body" field="commentBody">
<f:textbox />
</f:entry>
<f:entry title="Allow untrusted users to trigger the build" field="allowUntrusted">
<f:checkbox default="false"/>
<f:entry field="minimumPermissions" title="Minimum Permissions on repository to trigger the build">
<f:select default="WRITE" />
</f:entry>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div>
The comment body to trigger a new build for a PR job when it is received. This is compiled as a
case insensitive regular expression, so use ".*" to trigger a build on any comment whatsoever.
case-insensitive regular expression, so use ".*" to trigger a build on any comment whatsoever.
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<f:entry title="Allow untrusted users to trigger the build" field="allowUntrusted">
<f:checkbox default="false"/>
<f:entry field="minimumPermissions" title="Minimum Permissions on repository to trigger the build">
<f:select default="WRITE" />
</f:entry>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<f:entry title="Allow untrusted users to trigger the build" field="allowUntrusted">
<f:checkbox default="false"/>
<f:entry field="minimumPermissions" title="Minimum Permissions on repository to trigger the build">
<f:select default="WRITE" />
</f:entry>
</j:jelly>

0 comments on commit e96c665

Please sign in to comment.