package com.cloudbees.plugins.credentials; import com.cloudbees.plugins.credentials.common.IdCredentials; import com.cloudbees.plugins.credentials.common.StandardCredentials; import com.cloudbees.plugins.credentials.domains.Domain; import com.cloudbees.plugins.credentials.domains.DomainRequirement; import edu.umd.cs.findbugs.annotations.NonNull; import hudson.EnvVars; import hudson.Util; import hudson.model.AbstractBuild; import hudson.model.Executor; import hudson.model.ParameterValue; import hudson.model.Run; import hudson.model.User; import hudson.model.queue.WorkUnit; import hudson.security.ACL; import hudson.util.VariableResolver; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import jenkins.model.Jenkins; import org.acegisecurity.Authentication; import org.acegisecurity.context.SecurityContext; import org.acegisecurity.context.SecurityContextHolder; import org.apache.commons.lang.StringUtils; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.Stapler; /** * A {@link ParameterValue} produced from a {@link CredentialsParameterDefinition}. */ public class CredentialsParameterValue extends ParameterValue { /** * The {@link StandardCredentials#getId()} of the selected credentials. */ private final String value; /** * {@code true} if and only if the {@link #value} corresponds to * {@link CredentialsParameterDefinition#getDefaultValue()} (as this affects the authentication that is * used to resolve the actual credential. */ private final boolean isDefaultValue; @DataBoundConstructor public CredentialsParameterValue(String name, String value, String description) { this(name, value, description, false); } public CredentialsParameterValue(String name, String value, String description, boolean isDefaultValue) { super(name, description); this.value = value; this.isDefaultValue = isDefaultValue; } public String getValue() { return value; } /** * {@inheritDoc} */ @Override public void buildEnvironment(Run<?, ?> build, EnvVars env) { CredentialsProvider.track(build, lookupCredentials(StandardCredentials.class, build)); env.put(name, value); } /** * {@inheritDoc} */ @Override public VariableResolver<String> createVariableResolver(AbstractBuild<?, ?> build) { CredentialsProvider.track(build, lookupCredentials(StandardCredentials.class, build)); return new VariableResolver<String>() { public String resolve(String name) { return CredentialsParameterValue.this.name.equals(name) ? value : null; } }; } /** * {@inheritDoc} */ @Override public boolean isSensitive() { return true; } public <C extends IdCredentials> C lookupCredentials(@NonNull Class<C> type, @NonNull Run run, DomainRequirement... domainRequirements) { return lookupCredentials(type, run, Arrays.asList(domainRequirements)); } public <C extends IdCredentials> C lookupCredentials(@NonNull Class<C> type, @NonNull Run run, List<DomainRequirement> domainRequirements) { Authentication authentication = Jenkins.getAuthentication(); final Executor executor = run.getExecutor(); if (executor != null) { final WorkUnit workUnit = executor.getCurrentWorkUnit(); if (workUnit != null) { authentication = workUnit.context.item.authenticate(); } } List<C> candidates = new ArrayList<C>(); final boolean isSystem = ACL.SYSTEM.equals(authentication); if (!isSystem && run.getParent().getACL() .hasPermission(CredentialsProvider.USE_OWN)) { candidates.addAll(CredentialsProvider .lookupCredentials(type, run.getParent(), authentication, domainRequirements)); } if (run.getParent().getACL().hasPermission(CredentialsProvider.USE_ITEM) || isSystem || isDefaultValue) { candidates.addAll( CredentialsProvider.lookupCredentials(type, run.getParent(), ACL.SYSTEM, domainRequirements)); } return CredentialsMatchers.firstOrNull(candidates, CredentialsMatchers.withId(value)); } public String describe() { if (StringUtils.isBlank(value)) { return ""; } final Run run = Stapler.getCurrentRequest().findAncestorObject(Run.class); if (run == null) { throw new IllegalStateException("Should only be called from value.jelly"); } StandardCredentials c = CredentialsMatchers.firstOrNull( CredentialsProvider.lookupCredentials(StandardCredentials.class, run.getParent(), ACL.SYSTEM, Collections.<DomainRequirement>emptyList()), CredentialsMatchers.withId(value)); if (c != null) { return CredentialsNameProvider.name(c); } c = CredentialsMatchers.firstOrNull( CredentialsProvider.lookupCredentials(StandardCredentials.class, run.getParent(), Jenkins.getAuthentication(), Collections.<DomainRequirement>emptyList()), CredentialsMatchers.withId(value)); if (c != null) { return CredentialsNameProvider.name(c); } return Messages.CredentialsParameterValue_NotAvailableToCurrentUser(); } public String iconClassName() { if (StringUtils.isBlank(value)) { return ""; } final Run run = Stapler.getCurrentRequest().findAncestorObject(Run.class); if (run == null) { throw new IllegalStateException("Should only be called from value.jelly"); } StandardCredentials c = CredentialsMatchers.firstOrNull( CredentialsProvider.lookupCredentials(StandardCredentials.class, run.getParent(), ACL.SYSTEM, Collections.<DomainRequirement>emptyList()), CredentialsMatchers.withId(value)); if (c != null) { return c.getDescriptor().getIconClassName(); } c = CredentialsMatchers.firstOrNull( CredentialsProvider.lookupCredentials(StandardCredentials.class, run.getParent(), Jenkins.getAuthentication(), Collections.<DomainRequirement>emptyList()), CredentialsMatchers.withId(value)); if (c != null) { return c.getDescriptor().getIconClassName(); } return "icon-credentials-credential"; } public String url() { if (StringUtils.isBlank(value)) { return null; } final Run run = Stapler.getCurrentRequest().findAncestorObject(Run.class); if (run == null) { throw new IllegalStateException("Should only be called from value.jelly"); } SecurityContext oldContext = ACL.impersonate(ACL.SYSTEM); try { for (CredentialsStore store : CredentialsProvider.lookupStores(run.getParent())) { String url = url(store); if (url != null) { return url; } } } finally { SecurityContextHolder.setContext(oldContext); } for (CredentialsStore store: CredentialsProvider.lookupStores(User.current())) { String url = url(store); if (url != null) { return url; } } return null; } private String url(CredentialsStore store) { for (Domain d: store.getDomains()) { for (Credentials c: store.getCredentials(d)) { if (c instanceof IdCredentials && value.equals(((IdCredentials) c).getId())) { String link = store.getRelativeLinkToAction(); return link == null ? null : link + d.getUrl() + "credential/"+ Util.rawEncode(value); } } } return null; } public boolean isDefaultValue() { return isDefaultValue; } }