Skip to content

Commit

Permalink
Merge pull request #293 from jglick/Credentials.forRun
Browse files Browse the repository at this point in the history
Introduce `Credentials.forRun` to contextualize secrets
  • Loading branch information
jglick authored Mar 26, 2022
2 parents 2f4c0d5 + 4b0eba2 commit 4fe3345
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
13 changes: 13 additions & 0 deletions src/main/java/com/cloudbees/plugins/credentials/Credentials.java
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

0 comments on commit 4fe3345

Please sign in to comment.