From 1e1d95d7f6c81e58fca1e9b733242a40c876374c Mon Sep 17 00:00:00 2001 From: Javier Garcia Date: Mon, 11 Nov 2024 09:01:11 +0100 Subject: [PATCH] BEE-52312 - forceSandBox - Hide command-launcher drop down from non-administrators - Tests --- pom.xml | 5 + .../hudson/slaves/CommandLauncherTest.java | 137 ++++++++++++++++++ 2 files changed, 142 insertions(+) diff --git a/pom.xml b/pom.xml index 281675c..aa94127 100644 --- a/pom.xml +++ b/pom.xml @@ -73,5 +73,10 @@ test-harness test + + org.jenkins-ci.plugins + matrix-auth + test + diff --git a/src/test/java/hudson/slaves/CommandLauncherTest.java b/src/test/java/hudson/slaves/CommandLauncherTest.java index 23c9872..2ec76fe 100644 --- a/src/test/java/hudson/slaves/CommandLauncherTest.java +++ b/src/test/java/hudson/slaves/CommandLauncherTest.java @@ -25,6 +25,17 @@ import hudson.EnvVars; import hudson.Functions; +import hudson.model.Descriptor; +import hudson.model.User; +import hudson.security.ACL; +import hudson.security.ACLContext; +import hudson.security.GlobalMatrixAuthorizationStrategy; +import hudson.security.Permission; + +import org.htmlunit.html.HtmlForm; +import org.jenkinsci.plugins.matrixauth.AuthorizationType; +import org.jenkinsci.plugins.matrixauth.PermissionEntry; +import org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -37,6 +48,8 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import jenkins.model.Jenkins; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; @@ -156,4 +169,128 @@ public DumbSlave createAgentTimeout(String command) throws Exception { return agent; } + + @Test + public void commandLauncher_ForceSandbox() throws Exception { + DumbSlave commandLauncherAgent = new DumbSlave("commandLauncherAgent", "/",new CommandLauncher("echo unconfigured")); + DumbSlave noCommandLauncherAgent = new DumbSlave("noCommandLauncherAgent", "/", new JNLPLauncher()); + + j.jenkins.addNode(commandLauncherAgent); + j.jenkins.addNode(noCommandLauncherAgent); + + Jenkins.MANAGE.setEnabled(true); + + j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); + GlobalMatrixAuthorizationStrategy strategy = new GlobalMatrixAuthorizationStrategy(); + + PermissionEntry adminPermission = new PermissionEntry(AuthorizationType.USER, "admin"); + PermissionEntry develPermission = new PermissionEntry(AuthorizationType.USER, "devel"); + + strategy.add(Jenkins.ADMINISTER, adminPermission); + strategy.add(Jenkins.MANAGE, adminPermission); + strategy.add(Jenkins.READ, adminPermission); + strategy.add(Jenkins.MANAGE, develPermission); + strategy.add(Jenkins.READ, develPermission); + + for (Permission p : SlaveComputer.PERMISSIONS.getPermissions()) { + strategy.add(p, develPermission); + } + + j.jenkins.setAuthorizationStrategy(strategy); + + try (ACLContext ctx = ACL.as(User.getById("devel", true))) { + //With forceSandbox enabled, nonadmin users should not create agents with Launcher = CommandLauncher + ScriptApproval.get().setForceSandbox(true); + Descriptor.FormException ex = assertThrows(Descriptor.FormException.class, () -> + new DumbSlave("s", "/",new CommandLauncher("echo unconfigured")) + ); + + assertEquals("This Launch Method requires scripts executions out of the sandbox." + + " This Jenkins instance has been configured to not allow regular users to disable the sandbox", + ex.getMessage()); + + //With forceSandbox disabled, nonadmin users can create agents with Launcher = CommandLauncher + ScriptApproval.get().setForceSandbox(false); + new DumbSlave("s", "/",new CommandLauncher("echo unconfigured")); + } + + try (ACLContext ctx = ACL.as(User.getById("admin", true))) { + //admin users can create agents with Launcher = CommandLauncher independently of forceSandbox flag. + ScriptApproval.get().setForceSandbox(true); + new DumbSlave("s", "/",new CommandLauncher("echo unconfigured")); + + ScriptApproval.get().setForceSandbox(false); + new DumbSlave("s", "/",new CommandLauncher("echo unconfigured")); + } + + ScriptApproval.get().setForceSandbox(true); + { + try (JenkinsRule.WebClient wc = j.createWebClient().login("devel")) { + //Edit noCommandLauncher Agent. + //We are not admin and Sandbox is true, + //We don't have any html object for CommandLauncher + HtmlForm form = wc.getPage(noCommandLauncherAgent, "configure").getFormByName("config"); + assertTrue(form.getInputsByValue(CommandLauncher.class.getName()).isEmpty()); + + //Edit CommandLauncher Agent. + //Wwe are not admin and Sandbox is true + // As the agent is already a commandLauncher one we have some html object for CommandLauncher + form = wc.getPage(commandLauncherAgent, "configure").getFormByName("config"); + assertFalse(form.getInputsByValue(CommandLauncher.class.getName()).isEmpty()); + + //Launch CommandLauncher non Approved Script + //We are not admin and Sandbox is true, + //Error message should not show any admin approval reference + //TODO: not sure how to tackle this. + //j.jenkins.addNode(test); + + //TODO: Test the new node page + } + + try (JenkinsRule.WebClient wc = j.createWebClient().login("admin")) { + //Edit noCommandLauncher Agent. + //We areadmin and Sandbox is true, + //We have some html object for CommandLauncher + HtmlForm form = wc.getPage(noCommandLauncherAgent, "configure").getFormByName("config"); + assertFalse(form.getInputsByValue(CommandLauncher.class.getName()).isEmpty()); + + //Edit CommandLauncher Agent. + //Wwe not admin and Sandbox is true + //We have some html object for CommandLauncher + form = wc.getPage(commandLauncherAgent, "configure").getFormByName("config"); + assertFalse(form.getInputsByValue(CommandLauncher.class.getName()).isEmpty()); + } + } + + ScriptApproval.get().setForceSandbox(false); + { + try (JenkinsRule.WebClient wc = j.createWebClient().login("devel")) { + //Edit noCommandLauncher Agent. + //We are not admin and Sandbox is false, + //We have some html object for CommandLauncher + HtmlForm form = wc.getPage(noCommandLauncherAgent, "configure").getFormByName("config"); + assertFalse(form.getInputsByValue(CommandLauncher.class.getName()).isEmpty()); + + //Edit CommandLauncher Agent. + //Wwe are not admin and Sandbox is false + //We have some html object for CommandLauncher + form = wc.getPage(commandLauncherAgent, "configure").getFormByName("config"); + assertFalse(form.getInputsByValue(CommandLauncher.class.getName()).isEmpty()); + } + + try (JenkinsRule.WebClient wc = j.createWebClient().login("admin")) { + //Edit noCommandLauncher Agent. + //We areadmin and Sandbox is false, + //We have some html object for CommandLauncher + HtmlForm form = wc.getPage(noCommandLauncherAgent, "configure").getFormByName("config"); + assertFalse(form.getInputsByValue(CommandLauncher.class.getName()).isEmpty()); + + //Edit CommandLauncher Agent. + //Wwe not admin and Sandbox is false + //We have some html object for CommandLauncher + form = wc.getPage(commandLauncherAgent, "configure").getFormByName("config"); + assertFalse(form.getInputsByValue(CommandLauncher.class.getName()).isEmpty()); + } + } + } }