Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.ExtensionPoint;
import hudson.model.Describable;
import hudson.model.Run;
import java.io.Serializable;

/**
Expand Down Expand Up @@ -54,4 +55,16 @@ public interface Credentials extends Describable<Credentials>, Serializable, Ext
@NonNull
@SuppressWarnings("unchecked")
CredentialsDescriptor getDescriptor();

/**
* Optionally produce a special value when used in the context of a particular build.
* @param context a build wishing to consume these credentials
* @return contextualized credentials, preferably implementing the same interfaces (if not of the same concrete type); by default, {@code this}
* @see CredentialsProvider#findCredentialById(java.lang.String, java.lang.Class, hudson.model.Run, com.cloudbees.plugins.credentials.domains.DomainRequirement...)
*/
@NonNull
default Credentials forRun(@NonNull Run<?, ?> context) {
return this;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,8 @@ public static <C extends IdCredentials> C findCredentialById(@NonNull String id,
CredentialsProvider.lookupCredentials(type, run.getParent(), ACL.SYSTEM, domainRequirements)
);
}
return CredentialsMatchers.firstOrNull(candidates, CredentialsMatchers.withId(id));
// TODO should this be calling track?
return contextualize(type, CredentialsMatchers.firstOrNull(candidates, CredentialsMatchers.withId(id)), run);
}
// this is a parameter and not the default value, we need to determine who triggered the build
final Map.Entry<User, Run<?, ?>> triggeredBy = triggeredBy(run);
Expand Down Expand Up @@ -957,7 +958,23 @@ public static <C extends IdCredentials> C findCredentialById(@NonNull String id,
C result = CredentialsMatchers.firstOrNull(candidates, CredentialsMatchers.withId(id));
// if the run has not completed yet then we can safely assume that the credential is being used for this run
// so we will track it's usage. We use isLogUpdated() as it could be used during post production
return run.isLogUpdated() ? track(run, result) : result;
if (run.isLogUpdated()) {
track(run, result);
}
return contextualize(type, result, run);
}

@CheckForNull
private static <C extends Credentials> C contextualize(@NonNull Class<C> type, @CheckForNull C credentials, @NonNull Run<?, ?> run) {
if (credentials != null) {
Credentials contextualized = credentials.forRun(run);
if (type.isInstance(contextualized)) {
return type.cast(contextualized);
} else {
LOGGER.warning(() -> "Ignoring " + contextualized.getClass().getName() + " return value of " + credentials.getClass().getName() + ".forRun since it is not assignable to " + type.getName());
}
}
return credentials;
}

/**
Expand Down