package hudson.plugins.emailext; import hudson.ExtensionList; import hudson.FilePath; import hudson.Plugin; import hudson.model.AbstractBuild; import hudson.model.AbstractProject; import hudson.model.Action; import hudson.plugins.emailext.plugins.content.AbstractEvalContent; import hudson.plugins.emailext.plugins.content.JellyScriptContent; import hudson.plugins.emailext.plugins.content.ScriptContent; import hudson.util.FormValidation; import hudson.util.StreamTaskListener; import jenkins.model.Jenkins; import org.apache.commons.lang.StringUtils; import org.jenkinsci.lib.configprovider.ConfigProvider; import org.jenkinsci.lib.configprovider.model.Config; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.bind.JavaScriptMethod; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; /** * * @author acearl */ public class EmailExtTemplateAction implements Action { private final AbstractProject<?,?> project; public EmailExtTemplateAction(AbstractProject<?,?> project) { this.project = project; } public String getIconFileName() { // returning null allows us to have our own action.jelly return null; } public String getDisplayName() { return Messages.EmailExtTemplateAction_DisplayName(); } public String getUrlName() { return "templateTest"; } private String renderError(Exception ex) { StringBuilder builder = new StringBuilder(); builder.append("<h3>An error occured trying to render the template:</h3><br/><span style=\"color:red; font-weight:bold\">") .append(ex.toString().replace("\n", "<br/>")).append("</span>"); return builder.toString(); } public FormValidation doTemplateFileCheck(@QueryParameter final String value) { if(!StringUtils.isEmpty(value)) { if(value.startsWith("managed:")) { return checkForManagedFile(value); } else { // first check in the default resources area... InputStream inputStream = Thread.currentThread().getContextClassLoader() .getResourceAsStream("hudson/plugins/emailext/templates/" + value); if(inputStream == null) { final File scriptsFolder = new File(Jenkins.getActiveInstance().getRootDir(), "email-templates"); final File scriptFile = new File(scriptsFolder, value); try { if(!scriptFile.exists() || !AbstractEvalContent.isChildOf(new FilePath(scriptFile), new FilePath(scriptsFolder))) { return FormValidation.error("The file '" + value + "' does not exist"); } } catch (IOException | InterruptedException e) { //Don't want to expose too much info to a potential file fishing attempt return FormValidation.error("I/O Error."); } } } } return FormValidation.ok(); } private FormValidation checkForManagedFile(final String value) { Plugin plugin = Jenkins.getActiveInstance().getPlugin("config-file-provider"); if(plugin != null) { Config config = null; Collection<ConfigProvider> providers = getTemplateConfigProviders(); for(ConfigProvider provider : providers) { for(Config c : provider.getAllConfigs()) { if(c.name.equalsIgnoreCase(value)) { return FormValidation.ok(); } } } } else { return FormValidation.error(Messages.EmailExtTemplateAction_ConfigFileProviderNotAvailable()); } return FormValidation.error(Messages.EmailExtTemplateAction_ManagedTemplateNotFound()); } private static Collection<ConfigProvider> getTemplateConfigProviders() { Collection<ConfigProvider> providers = new ArrayList<>(); ExtensionList<ConfigProvider> all = ConfigProvider.all(); ConfigProvider p = all.get(GroovyTemplateConfig.GroovyTemplateConfigProvider.class); if(p != null) { providers.add(p); } p = all.get(JellyTemplateConfig.JellyTemplateConfigProvider.class); if(p != null) { providers.add(p); } return providers; } @JavaScriptMethod public String[] renderTemplate(String templateFile, String buildId) { String[] result = new String[2]; result[0] = StringUtils.EMPTY; result[1] = StringUtils.EMPTY; try { AbstractBuild<?,?> build = project.getBuild(buildId); ByteArrayOutputStream stream = new ByteArrayOutputStream(); StreamTaskListener listener = new StreamTaskListener(stream); if(templateFile.endsWith(".jelly")) { JellyScriptContent jellyContent = new JellyScriptContent(); jellyContent.template = templateFile; result[0] = jellyContent.evaluate(build, listener, "JELLY_SCRIPT"); } else { ScriptContent scriptContent = new ScriptContent(); scriptContent.template = templateFile; result[0] = scriptContent.evaluate(build, listener, "SCRIPT"); } result[1] = stream.toString(ExtendedEmailPublisher.descriptor().getCharset()); } catch (Exception ex) { result[0] = renderError(ex); } return result; } public AbstractProject<?, ?> getProject() { return project; } }