package hudson.model;
import hudson.Launcher;
import hudson.tasks.Builder;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.recipes.LocalData;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class ParametersAction2Test {
@Rule
public JenkinsRule j = new JenkinsRule();
@Test
@Issue("SECURITY-170")
public void undefinedParameters() throws Exception {
FreeStyleProject p = j.createFreeStyleProject();
p.addProperty(new ParametersDefinitionProperty(Arrays.asList(new ParameterDefinition[]{
new StringParameterDefinition("foo", "foo"),
new StringParameterDefinition("bar", "bar")
})));
ParametersCheckBuilder b = new ParametersCheckBuilder(false);
p.getBuildersList().add(b);
p.save();
j.assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause(), new ParametersAction(
new StringParameterValue("foo", "baz"),
new StringParameterValue("undef", "undef")
)));
}
@Test
@Issue("SECURITY-170")
public void undefinedParametersOverride() throws Exception {
FreeStyleProject p = j.createFreeStyleProject();
p.addProperty(new ParametersDefinitionProperty(Arrays.asList(new ParameterDefinition[]{
new StringParameterDefinition("foo", "foo"),
new StringParameterDefinition("bar", "bar")
})));
ParametersCheckBuilder b = new ParametersCheckBuilder(true);
p.getBuildersList().add(b);
p.save();
try {
System.setProperty(ParametersAction.KEEP_UNDEFINED_PARAMETERS_SYSTEM_PROPERTY_NAME, "true");
j.assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause(), new ParametersAction(
new StringParameterValue("foo", "baz"),
new StringParameterValue("undef", "undef")
)));
} finally {
System.clearProperty(ParametersAction.KEEP_UNDEFINED_PARAMETERS_SYSTEM_PROPERTY_NAME);
}
}
@Test
@Issue("SECURITY-170")
@LocalData
public void backwardCompatibility() throws Exception {
// Local data contains a parameterized job with two parameters (FOO and BAR) and one build
// with pre-fix format (generated with 1.609.3) with FOO, BAR and UNDEF.
FreeStyleProject p = j.jenkins.getItemByFullName("parameterized", FreeStyleProject.class);
FreeStyleBuild b1 = p.getBuildByNumber(1);
ParametersAction pa = b1.getAction(ParametersAction.class);
hasParameterWithName(pa, "FOO");
hasParameterWithName(pa, "BAR");
// legacy behaviour expected (UNDEF returned by getParameters())
hasParameterWithName(pa, "UNDEF");
// A new build should work as expected (undef is not published to env)
ParametersCheckBuilder b = new ParametersCheckBuilder(false);
p.getBuildersList().add(b);
p.save();
j.assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause(), new ParametersAction(
new StringParameterValue("foo", "baz"),
new StringParameterValue("undef", "undef")
)));
}
@Test
@Issue("SECURITY-170")
public void parametersDefinitionChange() throws Exception {
FreeStyleProject p = j.createFreeStyleProject();
p.addProperty(new ParametersDefinitionProperty(Arrays.<ParameterDefinition>asList(
new StringParameterDefinition("foo", "foo"),
new StringParameterDefinition("bar", "bar"))));
FreeStyleBuild build = j.assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause(), new ParametersAction(
new StringParameterValue("foo", "baz"),
new StringParameterValue("bar", "bar"),
new StringParameterValue("undef", "undef")
)));
assertTrue("undef parameter is not listed in getParameters",
!hasParameterWithName(build.getAction(ParametersAction.class), "undef"));
p.removeProperty(ParametersDefinitionProperty.class);
p.addProperty(new ParametersDefinitionProperty(Arrays.<ParameterDefinition>asList(
new StringParameterDefinition("foo", "foo"),
new StringParameterDefinition("bar", "bar"),
new StringParameterDefinition("undef", "undef"))));
// undef is still not listed even after being added to the job parameters definition
assertTrue("undef parameter is not listed in getParameters",
!hasParameterWithName(build.getAction(ParametersAction.class), "undef"));
// remove bar and undef from parameters definition
p.removeProperty(ParametersDefinitionProperty.class);
p.addProperty(new ParametersDefinitionProperty(Arrays.<ParameterDefinition>asList(
new StringParameterDefinition("foo", "foo"))));
assertTrue("the build still have 2 parameters", build.getAction(ParametersAction.class).getParameters().size() == 2);
p.removeProperty(ParametersDefinitionProperty.class);
assertTrue("the build still have 2 parameters", build.getAction(ParametersAction.class).getParameters().size() == 2);
}
@Test
@Issue("SECURITY-170")
public void whitelistedParameter() throws Exception {
FreeStyleProject p = j.createFreeStyleProject();
p.addProperty(new ParametersDefinitionProperty(Arrays.<ParameterDefinition>asList(
new StringParameterDefinition("foo", "foo"),
new StringParameterDefinition("bar", "bar"))));
try {
System.setProperty(ParametersAction.SAFE_PARAMETERS_SYSTEM_PROPERTY_NAME, "whitelisted1,whitelisted2");
FreeStyleBuild build = j.assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause(), new ParametersAction(
new StringParameterValue("foo", "baz"),
new StringParameterValue("bar", "bar"),
new StringParameterValue("whitelisted1", "x"),
new StringParameterValue("whitelisted2", "y")
)));
assertTrue("whitelisted1 parameter is listed in getParameters",
hasParameterWithName(build.getAction(ParametersAction.class), "whitelisted1"));
assertTrue("whitelisted2 parameter is listed in getParameters",
hasParameterWithName(build.getAction(ParametersAction.class), "whitelisted2"));
} finally {
System.clearProperty(ParametersAction.SAFE_PARAMETERS_SYSTEM_PROPERTY_NAME);
}
}
@Test
@Issue("SECURITY-170")
public void whitelistedParameterByOverride() throws Exception {
FreeStyleProject p = j.createFreeStyleProject();
String name = p.getFullName();
p.addProperty(new ParametersDefinitionProperty(Arrays.<ParameterDefinition>asList(
new StringParameterDefinition("foo", "foo"),
new StringParameterDefinition("bar", "bar"))));
try {
ParametersAction action = new ParametersAction(
Arrays.<ParameterValue>asList(
new StringParameterValue("foo", "baz"),
new StringParameterValue("bar", "bar"),
new StringParameterValue("whitelisted1", "x"),
new StringParameterValue("whitelisted2", "y"),
new StringParameterValue("whitelisted3", "y")
),
Arrays.asList("whitelisted1", "whitelisted2"));
FreeStyleBuild build = j.assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause(), action));
assertTrue("whitelisted1 parameter is listed in getParameters",
hasParameterWithName(build.getAction(ParametersAction.class), "whitelisted1"));
assertTrue("whitelisted2 parameter is listed in getParameters",
hasParameterWithName(build.getAction(ParametersAction.class), "whitelisted2"));
assertFalse("whitelisted3 parameter is listed in getParameters",
hasParameterWithName(build.getAction(ParametersAction.class), "whitelisted3"));
p = null;
build = null;
j.jenkins.reload();
//Test again after reload
p = j.jenkins.getItemByFullName(name, FreeStyleProject.class);
build = p.getLastBuild();
assertTrue("whitelisted1 parameter is listed in getParameters",
hasParameterWithName(build.getAction(ParametersAction.class), "whitelisted1"));
assertTrue("whitelisted2 parameter is listed in getParameters",
hasParameterWithName(build.getAction(ParametersAction.class), "whitelisted2"));
assertFalse("whitelisted3 parameter is listed in getParameters",
hasParameterWithName(build.getAction(ParametersAction.class), "whitelisted3"));
} finally {
System.clearProperty(ParametersAction.SAFE_PARAMETERS_SYSTEM_PROPERTY_NAME);
}
}
@Test
@Issue("SECURITY-170")
public void whitelistedParameterSameAfterChange() throws Exception {
FreeStyleProject p = j.createFreeStyleProject();
String name = p.getFullName();
p.addProperty(new ParametersDefinitionProperty(Arrays.<ParameterDefinition>asList(
new StringParameterDefinition("foo", "foo"),
new StringParameterDefinition("bar", "bar"))));
try {
System.setProperty(ParametersAction.SAFE_PARAMETERS_SYSTEM_PROPERTY_NAME, "whitelisted1,whitelisted2");
FreeStyleBuild build = j.assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause(), new ParametersAction(
new StringParameterValue("foo", "baz"),
new StringParameterValue("bar", "bar"),
new StringParameterValue("whitelisted1", "x"),
new StringParameterValue("whitelisted2", "y"),
new StringParameterValue("whitelisted3", "z"),
new StringParameterValue("whitelisted4", "w")
)));
assertTrue("whitelisted1 parameter is listed in getParameters",
hasParameterWithName(build.getAction(ParametersAction.class), "whitelisted1"));
assertTrue("whitelisted2 parameter is listed in getParameters",
hasParameterWithName(build.getAction(ParametersAction.class), "whitelisted2"));
assertFalse("whitelisted3 parameter is listed in getParameters",
hasParameterWithName(build.getAction(ParametersAction.class), "whitelisted3"));
assertFalse("whitelisted4 parameter is listed in getParameters",
hasParameterWithName(build.getAction(ParametersAction.class), "whitelisted4"));
System.setProperty(ParametersAction.SAFE_PARAMETERS_SYSTEM_PROPERTY_NAME, "whitelisted3,whitelisted4");
p = null;
build = null;
j.jenkins.reload();
p = j.jenkins.getItemByFullName(name, FreeStyleProject.class);
build = p.getLastBuild();
assertTrue("whitelisted1 parameter is listed in getParameters",
hasParameterWithName(build.getAction(ParametersAction.class), "whitelisted1"));
assertTrue("whitelisted2 parameter is listed in getParameters",
hasParameterWithName(build.getAction(ParametersAction.class), "whitelisted2"));
assertFalse("whitelisted3 parameter is listed in getParameters",
hasParameterWithName(build.getAction(ParametersAction.class), "whitelisted3"));
assertFalse("whitelisted4 parameter is listed in getParameters",
hasParameterWithName(build.getAction(ParametersAction.class), "whitelisted4"));
} finally {
System.clearProperty(ParametersAction.SAFE_PARAMETERS_SYSTEM_PROPERTY_NAME);
}
}
@Test
@Issue("SECURITY-170")
public void nonParameterizedJob() throws Exception {
FreeStyleProject p = j.createFreeStyleProject();
FreeStyleBuild build = j.assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause(), new ParametersAction(
new StringParameterValue("foo", "baz"),
new StringParameterValue("bar", "bar")
)));
assertTrue("foo parameter is not listed in getParameters",
!hasParameterWithName(build.getAction(ParametersAction.class), "foo"));
assertTrue("bar parameter is not listed in getParameters",
!hasParameterWithName(build.getAction(ParametersAction.class), "bar"));
}
@Test
@Issue("SECURITY-170")
public void nonParameterizedJobButWhitelisted() throws Exception {
FreeStyleProject p = j.createFreeStyleProject();
try {
System.setProperty(ParametersAction.SAFE_PARAMETERS_SYSTEM_PROPERTY_NAME, "foo,bar");
FreeStyleBuild build2 = j.assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause(), new ParametersAction(
new StringParameterValue("foo", "baz"),
new StringParameterValue("bar", "bar")
)));
assertTrue("foo parameter is listed in getParameters",
hasParameterWithName(build2.getAction(ParametersAction.class), "foo"));
assertTrue("bar parameter is listed in getParameters",
hasParameterWithName(build2.getAction(ParametersAction.class), "bar"));
} finally {
System.clearProperty(ParametersAction.SAFE_PARAMETERS_SYSTEM_PROPERTY_NAME);
}
}
public static boolean hasParameterWithName(Iterable<ParameterValue> values, String name) {
for (ParameterValue v : values) {
if (v.getName().equals(name)) {
return true;
}
}
return false;
}
public static class ParametersCheckBuilder extends Builder {
private final boolean expectLegacyBehavior;
public ParametersCheckBuilder(boolean expectLegacyBehavior) {
this.expectLegacyBehavior = expectLegacyBehavior;
}
@Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener)
throws InterruptedException, IOException {
ParametersAction pa = build.getAction(ParametersAction.class);
assertEquals("foo value expected changed", "baz", pa.getParameter("foo").getValue());
if (expectLegacyBehavior) {
assertTrue("undef parameter is listed in getParameters", hasParameterWithName(pa.getParameters(), "undef"));
assertTrue("undef parameter is listed in iterator", hasParameterWithName(pa, "undef"));
assertTrue("undef in environment", build.getEnvironment(listener).keySet().contains("undef"));
assertTrue("UNDEF in environment", build.getEnvironment(listener).keySet().contains("UNDEF"));
} else {
assertFalse("undef parameter is not listed in getParameters", hasParameterWithName(pa.getParameters(), "undef"));
assertFalse("undef parameter is not listed in iterator", hasParameterWithName(pa, "undef"));
assertFalse("undef not in environment", build.getEnvironment(listener).keySet().contains("undef"));
assertFalse("UNDEF not in environment", build.getEnvironment(listener).keySet().contains("UNDEF"));
}
assertTrue("undef parameter is listed in getAllParameters", hasParameterWithName(pa.getAllParameters(), "undef"));
assertEquals("undef parameter direct access expected to work", "undef", pa.getParameter("undef").getValue());
return true;
}
}
}