Skip to content

Commit

Permalink
Track credential usage within BitbucketCredentials#lookupCredentials
Browse files Browse the repository at this point in the history
The previous implementation actually missed out on a couple of usages, for example within `BitbucketSCMNavigator`.
  • Loading branch information
Thomas Salzinger committed Mar 28, 2024
1 parent d4babb5 commit 0c3b6ee
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
package com.cloudbees.jenkins.plugins.bitbucket;

import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator;
import com.cloudbees.plugins.credentials.Credentials;
import com.cloudbees.plugins.credentials.CredentialsMatchers;
import com.cloudbees.plugins.credentials.CredentialsProvider;
import com.cloudbees.plugins.credentials.common.StandardCertificateCredentials;
Expand All @@ -32,6 +33,7 @@
import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder;
import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.model.Item;
import hudson.model.Queue;
import hudson.model.queue.Tasks;
import hudson.security.ACL;
Expand All @@ -53,26 +55,34 @@ private BitbucketCredentials() {
throw new IllegalAccessError("Utility class");
}

/**
* Performs a lookup of credentials for the given context. Additionally, usage of the credentials is tracked for the
* given {@link SCMSourceOwner} via {@link CredentialsProvider#track(Item, Credentials)}
*/
@CheckForNull
static <T extends StandardCredentials> T lookupCredentials(@CheckForNull String serverUrl,
@CheckForNull SCMSourceOwner context,
@CheckForNull String id,
@NonNull Class<T> type) {
if (StringUtils.isNotBlank(id) && context != null) {
return CredentialsMatchers.firstOrNull(
CredentialsProvider.lookupCredentials(
type,
context,
context instanceof Queue.Task
? Tasks.getDefaultAuthenticationOf((Queue.Task) context)
: ACL.SYSTEM,
URIRequirementBuilder.fromUri(serverUrl).build()
),
CredentialsMatchers.allOf(
CredentialsMatchers.withId(id),
CredentialsMatchers.anyOf(CredentialsMatchers.instanceOf(type))
)
final T credentials = CredentialsMatchers.firstOrNull(
CredentialsProvider.lookupCredentials(
type,
context,
context instanceof Queue.Task
? Tasks.getDefaultAuthenticationOf((Queue.Task) context)

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note

Invoking
Tasks.getDefaultAuthenticationOf
should be avoided because it has been deprecated.
: ACL.SYSTEM,
URIRequirementBuilder.fromUri(serverUrl).build()
),

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note

Invoking
CredentialsProvider.lookupCredentials
should be avoided because it has been deprecated.
CredentialsMatchers.allOf(
CredentialsMatchers.withId(id),
CredentialsMatchers.anyOf(CredentialsMatchers.instanceOf(type))
)
);

CredentialsProvider.track(context, credentials);

return credentials;
}
return null;
}
Expand All @@ -87,13 +97,13 @@ static ListBoxModel fillCredentialsIdItems(
return result;
}
result.includeMatchingAs(
context instanceof Queue.Task
? Tasks.getDefaultAuthenticationOf((Queue.Task) context)
: ACL.SYSTEM,
context,
StandardCredentials.class,
URIRequirementBuilder.fromUri(serverUrl).build(),
AuthenticationTokens.matcher(BitbucketAuthenticator.authenticationContext(serverUrl))
context instanceof Queue.Task
? Tasks.getDefaultAuthenticationOf((Queue.Task) context)

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note

Invoking
Tasks.getDefaultAuthenticationOf
should be avoided because it has been deprecated.
: ACL.SYSTEM,
context,
StandardCredentials.class,
URIRequirementBuilder.fromUri(serverUrl).build(),
AuthenticationTokens.matcher(BitbucketAuthenticator.authenticationContext(serverUrl))
);
return result;
}
Expand All @@ -106,15 +116,15 @@ static FormValidation checkCredentialsId(
AccessControlled contextToCheck = context == null ? Jenkins.get() : context;
contextToCheck.checkPermission(CredentialsProvider.VIEW);
if (CredentialsMatchers.firstOrNull(
CredentialsProvider.lookupCredentials(
StandardCertificateCredentials.class,
context,
context instanceof Queue.Task ? Tasks.getDefaultAuthenticationOf((Queue.Task) context) : ACL.SYSTEM,
URIRequirementBuilder.fromUri(serverUrl).build()),
CredentialsMatchers.allOf(
CredentialsMatchers.withId(value),
AuthenticationTokens.matcher(BitbucketAuthenticator.authenticationContext(serverUrl))
)
CredentialsProvider.lookupCredentials(
StandardCertificateCredentials.class,
context,
context instanceof Queue.Task ? Tasks.getDefaultAuthenticationOf((Queue.Task) context) : ACL.SYSTEM,

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note

Invoking
Tasks.getDefaultAuthenticationOf
should be avoided because it has been deprecated.
URIRequirementBuilder.fromUri(serverUrl).build()),

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note

Invoking
CredentialsProvider.lookupCredentials
should be avoided because it has been deprecated.
CredentialsMatchers.allOf(
CredentialsMatchers.withId(value),
AuthenticationTokens.matcher(BitbucketAuthenticator.authenticationContext(serverUrl))
)
) != null) {
return FormValidation.warning("A certificate was selected. You will likely need to configure Checkout over SSH.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
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 Down Expand Up @@ -571,8 +570,6 @@ 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 @@ -827,19 +824,9 @@ 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 @@ -1241,7 +1228,7 @@ public static void setEventDelaySeconds(int eventDelaySeconds) {

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

private void initCloneLinks() {
Expand Down

0 comments on commit 0c3b6ee

Please sign in to comment.