Skip to content

Commit

Permalink
[FIXED JENKINS-12080] use a hidden, encrypted field to store configur…
Browse files Browse the repository at this point in the history
…ed script when user isn't admin
  • Loading branch information
ndeloof committed Feb 8, 2012
1 parent b12fb2e commit d40a525
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 18 deletions.
48 changes: 31 additions & 17 deletions src/main/java/hudson/plugins/groovy/SystemGroovy.java
@@ -1,19 +1,18 @@
package hudson.plugins.groovy;

import com.thoughtworks.xstream.XStream;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import hudson.Extension;
import hudson.Launcher;
import hudson.model.BuildListener;
import hudson.model.Descriptor;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Hudson;
import hudson.model.*;
import hudson.security.ACL;
import hudson.tasks.Builder;

import java.io.IOException;

import hudson.util.Secret;
import hudson.util.XStream2;
import net.sf.json.JSONObject;

import org.acegisecurity.Authentication;
Expand All @@ -40,10 +39,19 @@ public SystemGroovy(ScriptSource scriptSource, String bindings,String classpath)
this.classpath = classpath;
}

private static final XStream XSTREAM = new XStream2();

/**
* @return SystemGroovy as an encrypted String
*/
public String getSecret() {
return Secret.fromString(XSTREAM.toXML(this)).getEncryptedValue();
}

@Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
//Hudson.getInstance().checkPermission(Hudson.ADMINISTER); // WTF - always pass, executed as SYSTEM

CompilerConfiguration compilerConfig = new CompilerConfiguration();
if(classpath != null) {
compilerConfig.setClasspath(classpath);
Expand All @@ -61,15 +69,15 @@ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListen
if (output != null) {
listener.getLogger().println("Script returned: " + output);
}

if (output instanceof Number) {
return ((Number) output).intValue() == 0;
}
}
//No output. Suppose success.
return true;
}

@Override
public Descriptor<Builder> getDescriptor() {
return DESCRIPTOR;
Expand All @@ -78,7 +86,7 @@ public Descriptor<Builder> getDescriptor() {
@Extension
public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl();

public static final class DescriptorImpl extends AbstractGroovyDescriptor {
public static final class DescriptorImpl extends AbstractGroovyDescriptor {

DescriptorImpl() {
super(SystemGroovy.class);
Expand All @@ -100,14 +108,20 @@ public boolean isApplicable(Class<? extends AbstractProject> jobType){
}

@Override
public Builder newInstance(StaplerRequest req, JSONObject data) throws FormException {
//don't allow unauthorized users to modify scripts
Hudson.getInstance().checkPermission(Hudson.ADMINISTER);
ScriptSource source = getScriptSource(req, data);
String binds = data.getString("bindings");
String classp = data.getString("classpath");
return new SystemGroovy(source, binds, classp);
}
public SystemGroovy newInstance(StaplerRequest req, JSONObject data) throws FormException {

//don't allow unauthorized users to modify scripts
Authentication a = Hudson.getAuthentication();
if (Hudson.getInstance().getACL().hasPermission(a,Hudson.ADMINISTER)) {
ScriptSource source = getScriptSource(req, data);
String binds = data.getString("bindings");
String classp = data.getString("classpath");
return new SystemGroovy(source, binds, classp);
} else {
String secret = data.getString("secret");
return (SystemGroovy) XSTREAM.fromXML(Secret.decrypt(secret).getPlainText());
}
}

@Override
public String getHelpFile() {
Expand Down
Expand Up @@ -4,7 +4,19 @@
<!-- <f:entry title="Groovy command">
<f:textarea name="groovy.command" value="${instance.command}"/>
</f:entry> -->


<j:if test="${not h.hasPermission(app.ADMINISTER)}">
<f:invisibleEntry>
<f:textbox name="groovy.secret" value="${instance.secret}" />
</f:invisibleEntry>
<f:entry >
<div class="warning">
Only Administrator can configure the System Groovy script to be executed.<br/>
Configuration is displayed for your information only, any change will be ignored.
</div>
</f:entry>
</j:if>

<j:set var="instanceID" value="${descriptor.nextInstanceID()}" />
<j:forEach var="d" items="${descriptor.scriptSources}" varStatus="loop">
<f:radioBlock name="${instanceID}.scriptSource" help="${d.helpFile}" value="${loop.index}"
Expand All @@ -22,5 +34,7 @@
<f:textbox name="groovy.classpath" value="${instance.classpath}" />
</f:entry>
</f:advanced>



</j:jelly>
3 changes: 3 additions & 0 deletions src/main/webapp/systemscript-projectconfig.html
Expand Up @@ -2,4 +2,7 @@
<p>
Executes a system groovy script similarly to <i>hudson_url</i>/script. The script is <b>always</b> executed on master.
</p>
<p>
You need to be Administrator to set the groovy script to be executed. In other case, changes will be ignored.
</p>
</div>

0 comments on commit d40a525

Please sign in to comment.