Skip to content

Commit

Permalink
Restrict UserIdCause trust to those with Item.CONFIGURE #180 (com…
Browse files Browse the repository at this point in the history
  • Loading branch information
jglick committed Dec 22, 2022
1 parent 4d9ad1a commit 6e7c68f
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/main/java/jenkins/scm/api/SCMSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -975,7 +975,7 @@ public SCMRevision getTrustedRevision(@NonNull SCMRevision revision, @NonNull Ta
@NonNull
public final SCMRevision getTrustedRevisionForBuild(@NonNull SCMRevision revision, @NonNull TaskListener listener, @NonNull Run<?, ?> build)
throws IOException, InterruptedException {
if (ExtensionList.lookup(TrustworthyBuild.class).stream().anyMatch(tb -> tb.shouldBeTrusted(build))) {
if (ExtensionList.lookup(TrustworthyBuild.class).stream().anyMatch(tb -> tb.shouldBeTrusted(build, listener))) {
LOGGER.fine(() -> build + " with " + build.getCauses() + " was considered trustworthy, so using " + revision + " as is");
return revision;
} else {
Expand Down
11 changes: 3 additions & 8 deletions src/main/java/jenkins/scm/api/TrustworthyBuild.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import hudson.ExtensionPoint;
import hudson.model.Cause;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.triggers.SCMTrigger;
import hudson.triggers.TimerTrigger;

Expand All @@ -43,16 +44,10 @@ public interface TrustworthyBuild extends ExtensionPoint {
* Should this build be trusted to load sensitive source files?
* If any implementation returns true then it is trusted.
*/
boolean shouldBeTrusted(@NonNull Run<?, ?> build);
boolean shouldBeTrusted(@NonNull Run<?, ?> build, @NonNull TaskListener listener);

/**
* Convenience for the common case that a particular trigger cause indicates trust.
* Examples of causes which could be trusted include:
* <ul>
* <li>{@link Cause.UserIdCause}
* <li>{@code ReplayCause}
* <li>{@code CheckRunGHEventSubscriber.GitHubChecksRerunActionCause}
* </ul>
* Examples of causes which should <em>not</em> be registered include:
* <ul>
* <li>{@link TimerTrigger.TimerTriggerCause}
Expand All @@ -62,7 +57,7 @@ public interface TrustworthyBuild extends ExtensionPoint {
* </ul>
*/
static TrustworthyBuild byCause(Class<? extends Cause> causeType) {
return build -> build.getCause(causeType) != null;
return (build, listener) -> build.getCause(causeType) != null;
}

}
37 changes: 35 additions & 2 deletions src/main/java/jenkins/scm/impl/TrustworthyBuilds.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,53 @@

import hudson.Extension;
import hudson.model.Cause;
import hudson.model.Item;
import hudson.model.User;
import jenkins.scm.api.TrustworthyBuild;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class TrustworthyBuilds {

// Also effectively handles ReplayCause since that is only ever added in conjunction with UserIdCause. (see ReplayAction.run2)
@Extension
public static TrustworthyBuild byUserId() {
return TrustworthyBuild.byCause(Cause.UserIdCause.class);
return (build, listener) -> {
var cause = build.getCause(Cause.UserIdCause.class);
if (cause == null) {
// probably some other cause; do not print anything
return false;
}
var userId = cause.getUserId();
if (userId == null) {
listener.getLogger().println("Not trusting build since no user name was recorded");
return false;
}
var user = User.getById(userId, false);
if (user == null) {
listener.getLogger().printf("Not trusting build since no user ‘%s’ is known%n", userId);
return false;
}
try {
// TODO could also have workflow-cps offer this to anyone with only ReplayAction.REPLAY
if (build.hasPermission2(user.impersonate2(), Item.CONFIGURE)) {
listener.getLogger().printf("Trusting build since it was started by user ‘%s’%n", userId);
return true;
} else {
listener.getLogger().printf("Not trusting build since user ‘%s’ lacks Job/Configure permission%n", userId);
return false;
}
} catch (UsernameNotFoundException x) {
listener.getLogger().printf("Not trusting build since user ‘%s’ is invalid%n", userId);
return false;
}
};
}

// TODO until github-checks can declare a dep on a sufficiently new scm-api
@Extension
public static TrustworthyBuild byGitHubChecks() {
return build -> build.getCauses().stream().anyMatch(cause -> cause.getClass().getName().equals("io.jenkins.plugins.checks.github.CheckRunGHEventSubscriber$GitHubChecksRerunActionCause"));
return (build, listener) -> build.getCauses().stream().anyMatch(
cause -> cause.getClass().getName().equals("io.jenkins.plugins.checks.github.CheckRunGHEventSubscriber$GitHubChecksRerunActionCause"));
}

private TrustworthyBuilds() {}
Expand Down

0 comments on commit 6e7c68f

Please sign in to comment.