Skip to content

Commit

Permalink
[JENKINS-22834] Added tests for classpath identity.
Browse files Browse the repository at this point in the history
  • Loading branch information
ikedam committed Aug 2, 2014
1 parent 2cf0f0e commit e78155e
Show file tree
Hide file tree
Showing 3 changed files with 303 additions and 1 deletion.
Expand Up @@ -27,6 +27,8 @@
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlTextArea;
import com.gargoylesoftware.htmlunit.html.Util;

import hudson.model.FreeStyleProject;
import hudson.model.FreeStyleBuild;
import hudson.model.Item;
Expand All @@ -35,25 +37,36 @@
import hudson.security.Permission;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.Publisher;

import java.io.File;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import jenkins.model.Jenkins;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.taskdefs.Expand;
import org.apache.tools.ant.taskdefs.Touch;
import org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval;
import org.jenkinsci.plugins.scriptsecurity.scripts.UnapprovedUsageException;

import static org.junit.Assert.*;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.jvnet.hudson.test.JenkinsRule;

public class SecureGroovyScriptTest {

@Rule public JenkinsRule r = new JenkinsRule();

@Rule public TemporaryFolder tmpFolderRule = new TemporaryFolder();

@Test public void basicApproval() throws Exception {
r.jenkins.setSecurityRealm(r.createDummySecurityRealm());
GlobalMatrixAuthorizationStrategy gmas = new GlobalMatrixAuthorizationStrategy();
Expand Down Expand Up @@ -110,7 +123,7 @@ private List<File> getAllJarFiles() throws URISyntaxException {

DirectoryScanner ds = new DirectoryScanner();
ds.setBasedir(testClassDir);
ds.setIncludes(new String[]{ "**/*.jar" });
ds.setIncludes(new String[]{ "*.jar" });
ds.scan();

List<File> ret = new ArrayList<File>();
Expand All @@ -122,6 +135,26 @@ private List<File> getAllJarFiles() throws URISyntaxException {
return ret;
}

private List<File> getAllUpdatedJarFiles() throws URISyntaxException {
String testClassPath = String.format(StringUtils.join(getClass().getName().split("\\."), "/"));
File testClassDir = new File(ClassLoader.getSystemResource(testClassPath).toURI()).getAbsoluteFile();

File updatedDir = new File(testClassDir, "updated");

DirectoryScanner ds = new DirectoryScanner();
ds.setBasedir(updatedDir);
ds.setIncludes(new String[]{ "*.jar" });
ds.scan();

List<File> ret = new ArrayList<File>();

for (String relpath: ds.getIncludedFiles()) {
ret.add(new File(updatedDir, relpath));
}

return ret;
}

@Test public void testClasspathConfiguration() throws Exception {
List<AdditionalClasspath> classpathList = new ArrayList<AdditionalClasspath>();
for (File jarfile: getAllJarFiles()) {
Expand Down Expand Up @@ -303,4 +336,273 @@ private List<File> getAllJarFiles() throws URISyntaxException {
r.assertBuildStatusSuccess(p.scheduleBuild2(0));
}
}

@Test public void testUpdatedClasspath() throws Exception {
r.jenkins.setSecurityRealm(r.createDummySecurityRealm());
GlobalMatrixAuthorizationStrategy gmas = new GlobalMatrixAuthorizationStrategy();
gmas.add(Jenkins.READ, "devel");
for (Permission p : Item.PERMISSIONS.getPermissions()) {
gmas.add(p, "devel");
}
r.jenkins.setAuthorizationStrategy(gmas);

// Copy jar files to temporary directory, then overwrite them with updated jar files.
File tmpDir = tmpFolderRule.newFolder();

for (File jarfile: getAllJarFiles()) {
FileUtils.copyFileToDirectory(jarfile, tmpDir);
}

List<AdditionalClasspath> classpathList = new ArrayList<AdditionalClasspath>();
for (File jarfile: tmpDir.listFiles()) {
classpathList.add(new AdditionalClasspath(jarfile.getAbsolutePath()));
}

String SCRIPT_TO_RUN = "\"Script is run\";";

// approve script
{
FreeStyleProject p = r.createFreeStyleProject();
p.getPublishersList().add(new TestGroovyRecorder(new SecureGroovyScript(SCRIPT_TO_RUN, false)));

Set<ScriptApproval.PendingScript> pss = ScriptApproval.get().getPendingScripts();
assertNotEquals(0, pss.size());
for(ScriptApproval.PendingScript ps: pss) {
ScriptApproval.get().approveScript(ps.getHash());
}
}

// Success without classpaths
{
FreeStyleProject p = r.createFreeStyleProject();
p.getPublishersList().add(new TestGroovyRecorder(new SecureGroovyScript(SCRIPT_TO_RUN, false)));

r.assertBuildStatusSuccess(p.scheduleBuild2(0).get());
}

FreeStyleProject p = r.createFreeStyleProject();
p.getPublishersList().add(new TestGroovyRecorder(new SecureGroovyScript(SCRIPT_TO_RUN, false, classpathList)));

// Fail as the classpath is not approved.
r.assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0).get());

// Approve classpath.
{
List<ScriptApproval.PendingClasspath> pcps = ScriptApproval.get().getPendingClasspaths();
assertNotEquals(0, pcps.size());
for(ScriptApproval.PendingClasspath pcp: pcps) {
ScriptApproval.get().approveClasspath(pcp.getHash(), pcp.getPath());
}
}

// Success as approved.
r.assertBuildStatusSuccess(p.scheduleBuild2(0));

// overwrite jar files.
for (File jarfile: getAllUpdatedJarFiles()) {
FileUtils.copyFileToDirectory(jarfile, tmpDir);
}

// Fail as the updated jar files are not approved.
r.assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0).get());

// Approve classpath.
{
List<ScriptApproval.PendingClasspath> pcps = ScriptApproval.get().getPendingClasspaths();
assertNotEquals(0, pcps.size());
for(ScriptApproval.PendingClasspath pcp: pcps) {
ScriptApproval.get().approveClasspath(pcp.getHash(), pcp.getPath());
}
}

// Success as approved.
r.assertBuildStatusSuccess(p.scheduleBuild2(0));
}

@Test public void testClasspathWithClassDirectory() throws Exception {
r.jenkins.setSecurityRealm(r.createDummySecurityRealm());
GlobalMatrixAuthorizationStrategy gmas = new GlobalMatrixAuthorizationStrategy();
gmas.add(Jenkins.READ, "devel");
for (Permission p : Item.PERMISSIONS.getPermissions()) {
gmas.add(p, "devel");
}
r.jenkins.setAuthorizationStrategy(gmas);

// Copy jar files to temporary directory, then overwrite them with updated jar files.
File tmpDir = tmpFolderRule.newFolder();

for (File jarfile: getAllJarFiles()) {
Expand e = new Expand();
e.setSrc(jarfile);
e.setDest(tmpDir);
e.execute();
}

List<AdditionalClasspath> classpathList = new ArrayList<AdditionalClasspath>();
classpathList.add(new AdditionalClasspath(tmpDir.getAbsolutePath()));

final String testingDisplayName = "TESTDISPLAYNAME";

FreeStyleProject p = r.createFreeStyleProject();
p.getPublishersList().add(new TestGroovyRecorder(new SecureGroovyScript(
String.format(
"import org.jenkinsci.plugins.scriptsecurity.testjar.BuildUtil;"
+ "BuildUtil.setDisplayNameWhitelisted(build, \"%s\");"
+ "\"\"", testingDisplayName),
true,
classpathList
)));

// Fail as the classpath is not approved.
{
FreeStyleBuild b = p.scheduleBuild2(0).get();
r.assertBuildStatus(Result.FAILURE, b);
assertNotEquals(testingDisplayName, b.getDisplayName());
}

// Approve classpath.
{
List<ScriptApproval.PendingClasspath> pcps = ScriptApproval.get().getPendingClasspaths();
assertNotEquals(0, pcps.size());
for(ScriptApproval.PendingClasspath pcp: pcps) {
ScriptApproval.get().approveClasspath(pcp.getHash(), pcp.getPath());
}
}

// Success as approved.
{
FreeStyleBuild b = p.scheduleBuild2(0).get();
r.assertBuildStatusSuccess(b);
assertEquals(testingDisplayName, b.getDisplayName());
}

// add new file in tmpDir.
{
File f = tmpFolderRule.newFile();
FileUtils.copyFileToDirectory(f, tmpDir);
}

// Fail as the class directory is updated.
{
FreeStyleBuild b = p.scheduleBuild2(0).get();
r.assertBuildStatus(Result.FAILURE, b);
assertNotEquals(testingDisplayName, b.getDisplayName());
}

// Approve classpath.
{
List<ScriptApproval.PendingClasspath> pcps = ScriptApproval.get().getPendingClasspaths();
assertNotEquals(0, pcps.size());
for(ScriptApproval.PendingClasspath pcp: pcps) {
ScriptApproval.get().approveClasspath(pcp.getHash(), pcp.getPath());
}
}

// Success as approved.
{
FreeStyleBuild b = p.scheduleBuild2(0).get();
r.assertBuildStatusSuccess(b);
assertEquals(testingDisplayName, b.getDisplayName());
}
}

@Test public void testDifferentClasspathButSameContent() throws Exception {
r.jenkins.setSecurityRealm(r.createDummySecurityRealm());
GlobalMatrixAuthorizationStrategy gmas = new GlobalMatrixAuthorizationStrategy();
gmas.add(Jenkins.READ, "devel");
for (Permission p : Item.PERMISSIONS.getPermissions()) {
gmas.add(p, "devel");
}
r.jenkins.setAuthorizationStrategy(gmas);

final String testingDisplayName = "TESTDISPLAYNAME";

File tmpDir1 = tmpFolderRule.newFolder();

for (File jarfile: getAllJarFiles()) {
Expand e = new Expand();
e.setSrc(jarfile);
e.setDest(tmpDir1);
e.execute();
}

List<AdditionalClasspath> classpathList1 = new ArrayList<AdditionalClasspath>();
classpathList1.add(new AdditionalClasspath(tmpDir1.getAbsolutePath()));

FreeStyleProject p1 = r.createFreeStyleProject();
p1.getPublishersList().add(new TestGroovyRecorder(new SecureGroovyScript(
String.format(
"import org.jenkinsci.plugins.scriptsecurity.testjar.BuildUtil;"
+ "BuildUtil.setDisplayNameWhitelisted(build, \"%s\");"
+ "\"\"", testingDisplayName),
true,
classpathList1
)));

// Fail as the classpath is not approved.
{
FreeStyleBuild b = p1.scheduleBuild2(0).get();
r.assertBuildStatus(Result.FAILURE, b);
assertNotEquals(testingDisplayName, b.getDisplayName());
}

// Approve classpath.
{
List<ScriptApproval.PendingClasspath> pcps = ScriptApproval.get().getPendingClasspaths();
assertNotEquals(0, pcps.size());
for(ScriptApproval.PendingClasspath pcp: pcps) {
ScriptApproval.get().approveClasspath(pcp.getHash(), pcp.getPath());
}
}

// Success as approved.
{
FreeStyleBuild b = p1.scheduleBuild2(0).get();
r.assertBuildStatusSuccess(b);
assertEquals(testingDisplayName, b.getDisplayName());
}

File tmpDir2 = tmpFolderRule.newFolder();

for (File jarfile: getAllJarFiles()) {
Expand e = new Expand();
e.setSrc(jarfile);
e.setDest(tmpDir2);
e.execute();
}

// touch all files.
{
DirectoryScanner ds = new DirectoryScanner();
ds.setBasedir(tmpDir2);
ds.setIncludes(new String[]{ "**" });
ds.scan();

for (String relpath: ds.getIncludedFiles()) {
Touch t = new Touch();
t.setFile(new File(tmpDir2, relpath));
t.execute();
}
}

List<AdditionalClasspath> classpathList2 = new ArrayList<AdditionalClasspath>();
classpathList2.add(new AdditionalClasspath(tmpDir2.getAbsolutePath()));

FreeStyleProject p2 = r.createFreeStyleProject();
p2.getPublishersList().add(new TestGroovyRecorder(new SecureGroovyScript(
String.format(
"import org.jenkinsci.plugins.scriptsecurity.testjar.BuildUtil;"
+ "BuildUtil.setDisplayNameWhitelisted(build, \"%s\");"
+ "\"\"", testingDisplayName),
true,
classpathList2
)));

// Success as approved.
{
FreeStyleBuild b = p2.scheduleBuild2(0).get();
r.assertBuildStatusSuccess(b);
assertEquals(testingDisplayName, b.getDisplayName());
}
}
}
Binary file not shown.
Binary file not shown.

0 comments on commit e78155e

Please sign in to comment.