diff --git a/Jenkinsfile b/Jenkinsfile
index 688a641ff..3765128a6 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,4 +1,4 @@
buildPlugin(useAci: true, configurations: [
- [ platform: "windows", jdk: "8" ],
+ [ platform: "windows", jdk: "11" ],
[ platform: "linux", jdk: "11" ]
])
diff --git a/pom.xml b/pom.xml
index 30b43be52..783f0ea2d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
org.jenkins-ci.plugins
plugin
- 4.40
+ 4.47
@@ -16,7 +16,8 @@
https://github.com/jenkinsci/${project.artifactId}-plugin
999999-SNAPSHOT
- 2.332.1
+
+ 2.366-rc32795.df5b_49c75b_0e
jenkinsci/${project.artifactId}-plugin
@@ -50,8 +51,8 @@
io.jenkins.tools.bom
- bom-2.332.x
- 1289.v5c4b_1c43511b_
+ bom-2.361.x
+ 1607.va_c1576527071
import
pom
diff --git a/src/main/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SecureGroovyScript.java b/src/main/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SecureGroovyScript.java
index 1c28e60d3..6a7ca1e72 100644
--- a/src/main/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SecureGroovyScript.java
+++ b/src/main/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SecureGroovyScript.java
@@ -33,6 +33,7 @@
import hudson.model.AbstractDescribableImpl;
import hudson.model.Descriptor;
import hudson.model.Item;
+import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.util.FormValidation;
import io.jenkins.lib.versionnumber.JavaSpecificationVersion;
@@ -437,7 +438,16 @@ public Object evaluate(ClassLoader loader, Binding binding, @CheckForNull TaskLi
memoryProtectedLoader = new CleanGroovyClassLoader(loader);
loaderF.set(sh, memoryProtectedLoader);
}
- return sh.evaluate(ScriptApproval.get().using(script, GroovyLanguage.get()));
+ String origin = "UNKNOWN";
+ if (binding.hasVariable("build")) {
+ Run run = (Run) binding.getVariable("build");
+
+ origin = String.format("build '%s'", run.getExternalizableId());
+ } else {
+ LOGGER.log(Level.INFO, "Could not determine origin of the groovy script - missing implementation. Please open an issue for this!");
+ }
+
+ return sh.evaluate(ScriptApproval.get().using(script, GroovyLanguage.get(), origin));
}
} finally {
diff --git a/src/main/java/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval.java b/src/main/java/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval.java
index 9342ae1b4..8a0f2f1c5 100644
--- a/src/main/java/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval.java
+++ b/src/main/java/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval.java
@@ -27,6 +27,7 @@
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jenkins.model.GlobalConfiguration;
import jenkins.model.GlobalConfigurationCategory;
+import jenkins.model.ScriptListener;
import jenkins.util.SystemProperties;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
@@ -475,12 +476,27 @@ public String configuring(@NonNull String script, @NonNull Language language, @N
* @param script a possibly unapproved script
* @param language the language in which it is written
* @return {@code script}, for convenience
- * @throws UnapprovedUsageException in case it has not yet been approved
+ * @throws UnapprovedUsageException in case it has not yet been approve
+ * @deprecated Use {@link #using(String, Language, String)}.
*/
+ @Deprecated
public synchronized String using(@NonNull String script, @NonNull Language language) throws UnapprovedUsageException {
+ return using(script, language, "N/A");
+ }
+ /**
+ * Called when a script is about to be used (evaluated).
+ * @param script a possibly unapproved script
+ * @param language the language in which it is written
+ * @param origin A descriptive, trackable identifier of the entity running the script.
+ * @return {@code script}, for convenience
+ * @throws UnapprovedUsageException in case it has not yet been approved
+ */
+ public synchronized String using(@NonNull String script, @NonNull Language language, String origin) throws UnapprovedUsageException {
if (script.length() == 0) {
// As a special case, always consider the empty script preapproved, as this is usually the default for new fields,
// and in many cases there is some sensible behavior for an emoty script which we want to permit.
+ ScriptListener.fireScriptEvent(script, origin, null);
+
return script;
}
String hash = hash(script, language.getName());
@@ -488,9 +504,9 @@ public synchronized String using(@NonNull String script, @NonNull Language langu
// Probably need not add to pendingScripts, since generally that would have happened already in configuring.
throw new UnapprovedUsageException(hash);
}
+ ScriptListener.fireScriptEvent(script, origin, null);
return script;
}
-
// Only for testing
synchronized boolean isScriptHashApproved(String hash) {
return approvedScriptHashes.contains(hash);
diff --git a/src/test/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SecureGroovyScriptTest.java b/src/test/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SecureGroovyScriptTest.java
index 31c30c5f0..76dd85257 100644
--- a/src/test/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SecureGroovyScriptTest.java
+++ b/src/test/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SecureGroovyScriptTest.java
@@ -198,7 +198,7 @@ public class SecureGroovyScriptTest {
assertEquals(0, pendingScripts.size());
// Test that the script is executable. If it's not, we will get an UnapprovedUsageException
- assertEquals(groovy, ScriptApproval.get().using(groovy, GroovyLanguage.get()));
+ assertEquals(groovy, ScriptApproval.get().using(groovy, GroovyLanguage.get(), "Testing"));
}
/**
@@ -243,7 +243,7 @@ public class SecureGroovyScriptTest {
// We didn't add the approved classpath so ...
final UnapprovedUsageException e = assertThrows(UnapprovedUsageException.class,
- () -> ScriptApproval.get().using(groovy, GroovyLanguage.get()));
+ () -> ScriptApproval.get().using(groovy, GroovyLanguage.get(), "Testing"));
assertEquals("script not yet approved for use", e.getMessage());
}
diff --git a/src/test/java/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApprovalTest.java b/src/test/java/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApprovalTest.java
index 35295973c..0f189d3cb 100644
--- a/src/test/java/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApprovalTest.java
+++ b/src/test/java/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApprovalTest.java
@@ -222,7 +222,7 @@ boolean findApproved() {
@Override
Script use() {
- assertEquals(groovy, ScriptApproval.get().using(groovy, GroovyLanguage.get()));
+ assertEquals(groovy, ScriptApproval.get().using(groovy, GroovyLanguage.get(), "Testing"));
return this;
}