Skip to content

Commit

Permalink
Implement credentials tracking
Browse files Browse the repository at this point in the history
This allows to see jobs which execute repository / branch scanning as users of credentials, allowing to figure out which jobs actually reference these credentials more easily.
  • Loading branch information
Thomas Salzinger committed Mar 27, 2024
1 parent 4733e8c commit d4babb5
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,6 @@ private static void createStatus(@NonNull Run<?, ?> build, @NonNull TaskListener
}
}

private static @CheckForNull BitbucketSCMSource findBitbucketSCMSource(Run<?, ?> build) {
SCMSource s = SCMSource.SourceByItem.findSource(build.getParent());
return s instanceof BitbucketSCMSource ? (BitbucketSCMSource) s : null;
}

private static void sendNotifications(BitbucketSCMSource source, Run<?, ?> build, TaskListener listener)
throws IOException, InterruptedException {
BitbucketSCMSourceContext sourceContext = new BitbucketSCMSourceContext(null,
Expand Down Expand Up @@ -244,7 +239,7 @@ public static class JobCheckOutListener extends SCMListener {
@Override
public void onCheckout(Run<?, ?> build, SCM scm, FilePath workspace, TaskListener listener, File changelogFile,
SCMRevisionState pollingBaseline) throws Exception {
BitbucketSCMSource source = findBitbucketSCMSource(build);
BitbucketSCMSource source = BitbucketSCMSource.findForRun(build);
if (source == null) {
return;
}
Expand Down Expand Up @@ -277,7 +272,7 @@ public static class JobCompletedListener extends RunListener<Run<?, ?>> {

@Override
public void onCompleted(Run<?, ?> build, TaskListener listener) {
BitbucketSCMSource source = findBitbucketSCMSource(build);
BitbucketSCMSource source = BitbucketSCMSource.findForRun(build);
if (source == null) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import com.cloudbees.jenkins.plugins.bitbucket.server.client.BitbucketServerAPIClient;
import com.cloudbees.jenkins.plugins.bitbucket.server.client.repository.BitbucketServerRepository;
import com.cloudbees.plugins.credentials.CredentialsNameProvider;
import com.cloudbees.plugins.credentials.CredentialsProvider;
import com.cloudbees.plugins.credentials.common.StandardCredentials;
import com.damnhandy.uri.template.UriTemplate;
import com.fasterxml.jackson.databind.util.StdDateFormat;
Expand All @@ -62,6 +63,7 @@
import hudson.model.Action;
import hudson.model.Actionable;
import hudson.model.Item;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.plugins.git.GitSCM;
import hudson.scm.SCM;
Expand Down Expand Up @@ -569,6 +571,8 @@ public void afterSave() {
protected void retrieve(@CheckForNull SCMSourceCriteria criteria, @NonNull SCMHeadObserver observer,
@CheckForNull SCMHeadEvent<?> event, @NonNull TaskListener listener)
throws IOException, InterruptedException {

trackCredentialsUsage();
try (BitbucketSCMSourceRequest request = new BitbucketSCMSourceContext(criteria, observer)
.withTraits(traits)
.newRequest(this, listener)) {
Expand Down Expand Up @@ -823,9 +827,19 @@ private void retrieveTags(final BitbucketSCMSourceRequest request) throws IOExce
request.listener().getLogger().format("%n %d tags were processed%n", count);
}

private void trackCredentialsUsage() {
final SCMSourceOwner owner = getOwner();
if (owner != null) {
CredentialsProvider.track(owner, credentials());
}
}

@Override
protected SCMRevision retrieve(SCMHead head, TaskListener listener) throws IOException, InterruptedException {
final BitbucketApi bitbucket = buildBitbucketClient();

trackCredentialsUsage();

try {
if (head instanceof PullRequestSCMHead) {
PullRequestSCMHead h = (PullRequestSCMHead) head;
Expand Down Expand Up @@ -1225,6 +1239,11 @@ public static void setEventDelaySeconds(int eventDelaySeconds) {
BitbucketSCMSource.eventDelaySeconds = Math.min(300, Math.max(0, eventDelaySeconds));
}

public static BitbucketSCMSource findForRun(Run<?, ?> run) {
SCMSource s = SCMSource.SourceByItem.findSource(run.getParent());
return s instanceof BitbucketSCMSource ? (BitbucketSCMSource) s : null;
}

private void initCloneLinks() {
if (primaryCloneLinks == null) {
BitbucketApi bitbucket = buildBitbucketClient();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.cloudbees.jenkins.plugins.bitbucket;

import com.cloudbees.plugins.credentials.CredentialsProvider;
import hudson.Extension;
import hudson.model.Run;
import hudson.model.listeners.RunListener;

/**
* Tracks the usage of credentials
*/
@Extension
public class CredentialTrackingRunListener extends RunListener<Run<?, ?>> {
@Override
public void onInitialize(Run<?, ?> run) {
final BitbucketSCMSource source = BitbucketSCMSource.findForRun(run);

if (source == null) {
return;
}

final boolean usesSshCheckout = source.getTraits().stream().anyMatch(scmSourceTrait -> scmSourceTrait instanceof SSHCheckoutTrait);

if (!usesSshCheckout) {

Check warning on line 23 in src/main/java/com/cloudbees/jenkins/plugins/bitbucket/CredentialTrackingRunListener.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 23 is only partially covered, one branch is missing
CredentialsProvider.track(run, source.credentials());
}
}
}

0 comments on commit d4babb5

Please sign in to comment.