diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java index 6fd22fd149d7ad54c14d95ee11556de64c5403f7..b2efe0caa51aa2d8c287298f2d2e96f2712118f0 100755 --- a/core/src/main/java/jenkins/model/Jenkins.java +++ b/core/src/main/java/jenkins/model/Jenkins.java @@ -3398,7 +3398,7 @@ public class Jenkins extends AbstractCIBase implements ModifiableTopLevelItemGro */ @RequirePOST public void doEval(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - checkPermission(ADMINISTER); + checkPermission(RUN_SCRIPTS); try { MetaClass mc = WebApp.getCurrent().getMetaClass(getClass()); diff --git a/test/src/test/java/jenkins/model/JenkinsTest.java b/test/src/test/java/jenkins/model/JenkinsTest.java index 6859e83b5826e0e79277502090879277929fa294..250d9591f540731e20763ac4dbfb0c435a9213ec 100644 --- a/test/src/test/java/jenkins/model/JenkinsTest.java +++ b/test/src/test/java/jenkins/model/JenkinsTest.java @@ -23,6 +23,7 @@ */ package jenkins.model; +import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; import com.gargoylesoftware.htmlunit.HttpMethod; import com.gargoylesoftware.htmlunit.WebRequestSettings; import com.gargoylesoftware.htmlunit.html.HtmlForm; @@ -273,6 +274,45 @@ public class JenkinsTest extends HudsonTestCase { wc.assertFails("script", HttpURLConnection.HTTP_FORBIDDEN); } + public void testDoEval() throws Exception { + jenkins.setSecurityRealm(new LegacySecurityRealm()); + GlobalMatrixAuthorizationStrategy gmas = new GlobalMatrixAuthorizationStrategy() { + @Override public boolean hasPermission(String sid, Permission p) { + return p == Jenkins.RUN_SCRIPTS ? hasExplicitPermission(sid, p) : super.hasPermission(sid, p); + } + }; + gmas.add(Jenkins.ADMINISTER, "alice"); + gmas.add(Jenkins.RUN_SCRIPTS, "alice"); + gmas.add(Jenkins.READ, "bob"); + gmas.add(Jenkins.ADMINISTER, "charlie"); + jenkins.setAuthorizationStrategy(gmas); + // Otherwise get "RuntimeException: Trying to set the request parameters, but the request body has already been specified;the two are mutually exclusive!" from WebRequestSettings.setRequestParameters when POSTing content: + jenkins.setCrumbIssuer(null); + WebClient wc = createWebClient(); + wc.login("alice"); + wc.assertFails("eval", HttpURLConnection.HTTP_INTERNAL_ERROR); + assertEquals("3", eval(wc)); + wc.login("bob"); + try { + eval(wc); + fail("bob has only READ"); + } catch (FailingHttpStatusCodeException e) { + assertEquals(HttpURLConnection.HTTP_FORBIDDEN, e.getStatusCode()); + } + wc.login("charlie"); + try { + eval(wc); + fail("charlie has ADMINISTER but not RUN_SCRIPTS"); + } catch (FailingHttpStatusCodeException e) { + assertEquals(HttpURLConnection.HTTP_FORBIDDEN, e.getStatusCode()); + } + } + private String eval(WebClient wc) throws Exception { + WebRequestSettings req = new WebRequestSettings(new URL(wc.getContextPath() + "eval"), HttpMethod.POST); + req.setRequestBody("${1+2}"); + return wc.getPage(/*wc.addCrumb(*/req/*)*/).getWebResponse().getContentAsString(); + } + @TestExtension("testUnprotectedRootAction") public static class RootActionImpl implements UnprotectedRootAction { private int count;