From ae34b386ceb2edd6527c90863910e5560bd85c84 Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Tue, 21 Jan 2025 13:19:45 -0800 Subject: [PATCH 01/34] Remove `robust-http-client` --- bom/pom.xml | 5 ----- core/pom.xml | 4 ---- core/src/main/java/hudson/ProxyConfiguration.java | 5 ++--- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/bom/pom.xml b/bom/pom.xml index 6c6e5bed54..a93cfdca2e 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -297,11 +297,6 @@ THE SOFTWARE. localizer 1.31 - - org.jvnet.robust-http-client - robust-http-client - 1.2 - org.jvnet.winp winp diff --git a/core/pom.xml b/core/pom.xml index 5314c25f50..4104311504 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -333,10 +333,6 @@ THE SOFTWARE. org.jvnet.localizer localizer - - org.jvnet.robust-http-client - robust-http-client - org.jvnet.winp winp diff --git a/core/src/main/java/hudson/ProxyConfiguration.java b/core/src/main/java/hudson/ProxyConfiguration.java index cc5b30d956..885b68dec4 100644 --- a/core/src/main/java/hudson/ProxyConfiguration.java +++ b/core/src/main/java/hudson/ProxyConfiguration.java @@ -70,7 +70,6 @@ import jenkins.security.stapler.StaplerAccessibleType; import jenkins.util.JenkinsJVM; import jenkins.util.SystemProperties; import org.jenkinsci.Symbol; -import org.jvnet.robust_http_client.RetryableHttpStream; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.DataBoundConstructor; @@ -346,10 +345,10 @@ public final class ProxyConfiguration extends AbstractDescribableImpl Date: Thu, 30 Jan 2025 21:23:26 +0100 Subject: [PATCH 02/34] removed obsolete exclusion --- core/src/spotbugs/excludesFilter.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/core/src/spotbugs/excludesFilter.xml b/core/src/spotbugs/excludesFilter.xml index 9bf8e5afa3..b361005cb8 100644 --- a/core/src/spotbugs/excludesFilter.xml +++ b/core/src/spotbugs/excludesFilter.xml @@ -239,13 +239,6 @@ - - - - - - - From 0ca321172937d073b7c744f27b1dfd7fca009f35 Mon Sep 17 00:00:00 2001 From: Vincent Latombe Date: Fri, 31 Jan 2025 09:30:58 +0100 Subject: [PATCH 03/34] Reapply "[JENKINS-75174] Move existing `web.xml` to `web-fragment.xml` under core (#10185)" (#10225) This reverts commit 6109053fa281b59b3752b36341d692deb08cc25b. --- .../main/resources/META-INF/web-fragment.xml | 279 ++++++++++++++++++ war/src/main/webapp/WEB-INF/web.xml | 251 +--------------- 2 files changed, 280 insertions(+), 250 deletions(-) create mode 100644 core/src/main/resources/META-INF/web-fragment.xml diff --git a/core/src/main/resources/META-INF/web-fragment.xml b/core/src/main/resources/META-INF/web-fragment.xml new file mode 100644 index 0000000000..c9acb6e151 --- /dev/null +++ b/core/src/main/resources/META-INF/web-fragment.xml @@ -0,0 +1,279 @@ + + + + + jenkins + + + Stapler + org.kohsuke.stapler.Stapler + + default-encodings + text/html=UTF-8 + + + diagnosticThreadName + false + + true + + + + Stapler + /* + + + + suspicious-request-filter + jenkins.security.SuspiciousRequestFilter + true + + + diagnostic-name-filter + org.kohsuke.stapler.DiagnosticThreadNameFilter + true + + + encoding-filter + hudson.util.CharacterEncodingFilter + true + + + uncaught-exception-filter + org.kohsuke.stapler.UncaughtExceptionFilter + true + + + authentication-filter + hudson.security.HudsonFilter + true + + + csrf-filter + hudson.security.csrf.CrumbFilter + true + + + error-attribute-filter + jenkins.ErrorAttributeFilter + true + + + plugins-filter + hudson.util.PluginServletFilter + true + + + + + + suspicious-request-filter + /* + + + diagnostic-name-filter + /* + + + encoding-filter + /* + + + uncaught-exception-filter + /* + + + authentication-filter + /* + + + csrf-filter + /* + + + error-attribute-filter + /* + + + plugins-filter + /* + + + + + jenkins.util.SystemProperties$Listener + + + hudson.WebAppMain + + + jenkins.JenkinsHttpSessionListener + + + + + admin + + + user + + + hudson + + + + + Hudson + /loginEntry + + + + ** + + + + + + + Disable TRACE + /* + TRACE + + + + + + + other + /* + + + + + + FORM + + /login + /loginError + + + + + + xml + application/xml + + + + log + text/plain + + + war + application/octet-stream + + + ear + application/octet-stream + + + rar + application/octet-stream + + + webm + video/webm + + + + java.lang.Throwable + /oops + + + 404 + /404 + + + + + + true + + + + diff --git a/war/src/main/webapp/WEB-INF/web.xml b/war/src/main/webapp/WEB-INF/web.xml index 4ef6db9e3f..5e86c73a22 100644 --- a/war/src/main/webapp/WEB-INF/web.xml +++ b/war/src/main/webapp/WEB-INF/web.xml @@ -26,256 +26,7 @@ THE SOFTWARE. + version="3.1"> Jenkins v${project.version} Build management system - - - Stapler - org.kohsuke.stapler.Stapler - - default-encodings - text/html=UTF-8 - - - diagnosticThreadName - false - - true - - - - Stapler - /* - - - - suspicious-request-filter - jenkins.security.SuspiciousRequestFilter - true - - - diagnostic-name-filter - org.kohsuke.stapler.DiagnosticThreadNameFilter - true - - - encoding-filter - hudson.util.CharacterEncodingFilter - true - - - uncaught-exception-filter - org.kohsuke.stapler.UncaughtExceptionFilter - true - - - authentication-filter - hudson.security.HudsonFilter - true - - - csrf-filter - hudson.security.csrf.CrumbFilter - true - - - error-attribute-filter - jenkins.ErrorAttributeFilter - true - - - plugins-filter - hudson.util.PluginServletFilter - true - - - - - - suspicious-request-filter - /* - - - diagnostic-name-filter - /* - - - encoding-filter - /* - - - uncaught-exception-filter - /* - - - authentication-filter - /* - - - csrf-filter - /* - - - error-attribute-filter - /* - - - plugins-filter - /* - - - - - jenkins.util.SystemProperties$Listener - - - hudson.WebAppMain - - - jenkins.JenkinsHttpSessionListener - - - - - admin - - - user - - - hudson - - - - - Hudson - /loginEntry - - - - ** - - - - - - - Disable TRACE - /* - TRACE - - - - - - - other - /* - - - - - - FORM - - /login - /loginError - - - - - - xml - application/xml - - - - log - text/plain - - - war - application/octet-stream - - - ear - application/octet-stream - - - rar - application/octet-stream - - - webm - video/webm - - - - java.lang.Throwable - /oops - - - 404 - /404 - - - - - - true - - - From 25a6a84d8796d4f132f9e9fbed760bb71b618eab Mon Sep 17 00:00:00 2001 From: Vincent Latombe Date: Fri, 31 Jan 2025 10:56:13 +0100 Subject: [PATCH 04/34] Update jetty plugin configuration for configuration discovery * Remove core classes from extra classpath, as when running `mvn -pl war jetty:run` it automatically gets added. --- war/pom.xml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/war/pom.xml b/war/pom.xml index 91cd5225ab..1e78b07c4a 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -691,12 +691,9 @@ THE SOFTWARE. com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl - - ${project.basedir}/../core/src/main/resources,${project.basedir}/../core/target/classes,${project.build.directory}/support-log-formatter.jar + + ${project.build.directory}/support-log-formatter.jar ${contextPath} - false - - NONE From 796a5579979fcb27e5ef7a4927d81a8f43179c06 Mon Sep 17 00:00:00 2001 From: Vincent Latombe Date: Fri, 31 Jan 2025 11:46:34 +0100 Subject: [PATCH 05/34] Only need to scan core jar --- war/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/war/pom.xml b/war/pom.xml index 1e78b07c4a..3d6705835e 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -694,6 +694,7 @@ THE SOFTWARE. ${project.build.directory}/support-log-formatter.jar ${contextPath} + .*(jenkins-core|target/classes).* From 326da6bd4f25d711ad44456f91e72c860592caff Mon Sep 17 00:00:00 2001 From: Markus Winter Date: Fri, 24 Jan 2025 19:23:24 +0100 Subject: [PATCH 06/34] remove commons-codec usage from core Since Java 17 we have HexFormat so use it instead of commons-codec or the self-written implementation --- core/src/main/java/hudson/Util.java | 29 +++++++++---------- .../security/seed/UserSeedProperty.java | 4 +-- .../java/jenkins/telemetry/Telemetry.java | 4 +-- .../jenkins/util/JSONSignatureValidator.java | 9 +++--- .../java/jenkins/telemetry/TelemetryTest.java | 4 +-- 5 files changed, 23 insertions(+), 27 deletions(-) diff --git a/core/src/main/java/hudson/Util.java b/core/src/main/java/hudson/Util.java index 07d00a44d0..8e9f1002f3 100644 --- a/core/src/main/java/hudson/Util.java +++ b/core/src/main/java/hudson/Util.java @@ -92,6 +92,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.EnumSet; +import java.util.HexFormat; import java.util.List; import java.util.Locale; import java.util.Map; @@ -115,7 +116,6 @@ import jenkins.model.Jenkins; import jenkins.util.MemoryReductionUtil; import jenkins.util.SystemProperties; import jenkins.util.io.PathRemover; -import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.time.FastDateFormat; import org.apache.tools.ant.BuildException; @@ -635,7 +635,6 @@ public class Util { * The stream will be closed by this method at the end of this method. * @return * 32-char wide string - * @see DigestUtils#md5Hex(InputStream) */ @NonNull public static String getDigestOf(@NonNull InputStream source) throws IOException { @@ -710,13 +709,7 @@ public class Util { @NonNull public static String toHexString(@NonNull byte[] data, int start, int len) { - StringBuilder buf = new StringBuilder(); - for (int i = 0; i < len; i++) { - int b = data[start + i] & 0xFF; - if (b < 16) buf.append('0'); - buf.append(Integer.toHexString(b)); - } - return buf.toString(); + return HexFormat.of().formatHex(data, start, len); } @NonNull @@ -726,12 +719,7 @@ public class Util { @NonNull public static byte[] fromHexString(@NonNull String data) { - if (data.length() % 2 != 0) - throw new IllegalArgumentException("data must have an even number of hexadecimal digits"); - byte[] r = new byte[data.length() / 2]; - for (int i = 0; i < data.length(); i += 2) - r[i / 2] = (byte) Integer.parseInt(data.substring(i, i + 2), 16); - return r; + return HexFormat.of().parseHex(data); } /** @@ -1992,9 +1980,18 @@ public class Util { * Returns Hex string of SHA-256 Digest of passed input */ @Restricted(NoExternalUse.class) - public static String getHexOfSHA256DigestOf(byte[] input) throws IOException { + public static String getHexOfSHA256DigestOf(byte[] input) { //get hex string of sha 256 of payload byte[] payloadDigest = Util.getSHA256DigestOf(input); return (payloadDigest != null) ? Util.toHexString(payloadDigest) : null; } + + + /** + * Returns Hex string of SHA-256 Digest of passed string + */ + @Restricted(NoExternalUse.class) + public static String getHexOfSHA256DigestOf(String input) { + return getHexOfSHA256DigestOf(input.getBytes(StandardCharsets.UTF_8)); + } } diff --git a/core/src/main/java/jenkins/security/seed/UserSeedProperty.java b/core/src/main/java/jenkins/security/seed/UserSeedProperty.java index 968ee9320f..17d9dd4335 100644 --- a/core/src/main/java/jenkins/security/seed/UserSeedProperty.java +++ b/core/src/main/java/jenkins/security/seed/UserSeedProperty.java @@ -28,6 +28,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.BulkChange; import hudson.Extension; +import hudson.Util; import hudson.model.User; import hudson.model.UserProperty; import hudson.model.UserPropertyDescriptor; @@ -39,7 +40,6 @@ import java.util.Objects; import jenkins.model.Jenkins; import jenkins.security.LastGrantedAuthoritiesProperty; import jenkins.util.SystemProperties; -import org.apache.commons.codec.binary.Hex; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; @@ -103,7 +103,7 @@ public class UserSeedProperty extends UserProperty { byte[] bytes = new byte[SEED_NUM_BYTES]; while (Objects.equals(newSeed, currentSeed)) { RANDOM.nextBytes(bytes); - newSeed = new String(Hex.encodeHex(bytes)); + newSeed = Util.toHexString(bytes); } this.seed = newSeed; } diff --git a/core/src/main/java/jenkins/telemetry/Telemetry.java b/core/src/main/java/jenkins/telemetry/Telemetry.java index de081c1695..968ca0f08d 100644 --- a/core/src/main/java/jenkins/telemetry/Telemetry.java +++ b/core/src/main/java/jenkins/telemetry/Telemetry.java @@ -32,6 +32,7 @@ import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.PluginWrapper; import hudson.ProxyConfiguration; +import hudson.Util; import hudson.model.AsyncPeriodicWork; import hudson.model.TaskListener; import hudson.model.UsageStatistics; @@ -51,7 +52,6 @@ import java.util.logging.Logger; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import net.sf.json.JSONObject; -import org.apache.commons.codec.digest.DigestUtils; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -221,7 +221,7 @@ public abstract class Telemetry implements ExtensionPoint { wrappedData.put("type", telemetry.getId()); wrappedData.put("payload", data); String correlationId = ExtensionList.lookupSingleton(Correlator.class).getCorrelationId(); - wrappedData.put("correlator", DigestUtils.sha256Hex(correlationId + telemetry.getId())); + wrappedData.put("correlator", Util.getHexOfSHA256DigestOf(correlationId + telemetry.getId())); String body = wrappedData.toString(); if (LOGGER.isLoggable(Level.FINEST)) { diff --git a/core/src/main/java/jenkins/util/JSONSignatureValidator.java b/core/src/main/java/jenkins/util/JSONSignatureValidator.java index e6f5429f43..d3f416a91f 100644 --- a/core/src/main/java/jenkins/util/JSONSignatureValidator.java +++ b/core/src/main/java/jenkins/util/JSONSignatureValidator.java @@ -1,6 +1,7 @@ package jenkins.util; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.Util; import hudson.util.FormValidation; import java.io.ByteArrayInputStream; import java.io.File; @@ -33,8 +34,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import jenkins.model.Jenkins; import net.sf.json.JSONObject; -import org.apache.commons.codec.DecoderException; -import org.apache.commons.codec.binary.Hex; import org.apache.commons.io.output.TeeOutputStream; import org.jvnet.hudson.crypto.CertificateUtil; import org.jvnet.hudson.crypto.SignatureOutputStream; @@ -221,10 +220,10 @@ public class JSONSignatureValidator { // This approach might look unnecessarily clever, but short of having redundant Signature instances, // there doesn't seem to be a better approach for this. try { - if (signature.verify(Hex.decodeHex(providedSignature.toCharArray()))) { + if (signature.verify(Util.fromHexString(providedSignature))) { return true; } - } catch (SignatureException | DecoderException ignore) { + } catch (SignatureException | IllegalArgumentException ignore) { // ignore } @@ -242,7 +241,7 @@ public class JSONSignatureValidator { * Utility method supporting both possible digest formats: Base64 and Hex */ private boolean digestMatches(byte[] digest, String providedDigest) { - return providedDigest.equalsIgnoreCase(Hex.encodeHexString(digest)) || providedDigest.equalsIgnoreCase(Base64.getEncoder().encodeToString(digest)); + return providedDigest.equalsIgnoreCase(Util.toHexString(digest)) || providedDigest.equalsIgnoreCase(Base64.getEncoder().encodeToString(digest)); } diff --git a/test/src/test/java/jenkins/telemetry/TelemetryTest.java b/test/src/test/java/jenkins/telemetry/TelemetryTest.java index 701ffa7e4d..d5606a4842 100644 --- a/test/src/test/java/jenkins/telemetry/TelemetryTest.java +++ b/test/src/test/java/jenkins/telemetry/TelemetryTest.java @@ -13,6 +13,7 @@ import static org.junit.Assert.assertTrue; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; import hudson.ExtensionList; +import hudson.Util; import hudson.model.UnprotectedRootAction; import hudson.security.csrf.CrumbExclusion; import jakarta.servlet.FilterChain; @@ -31,7 +32,6 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.regex.Pattern; import net.sf.json.JSONObject; -import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.IOUtils; import org.junit.Before; import org.junit.Rule; @@ -99,7 +99,7 @@ public class TelemetryTest { .atMost(10, TimeUnit.SECONDS) .until(() -> types, hasItem("test-data")); //90ecf3ce1cd5ba1e5ad3cde7ad08a941e884f2e4d9bd463361715abab8efedc5 - assertThat(correlators, hasItem(DigestUtils.sha256Hex(correlationId + "test-data"))); + assertThat(correlators, hasItem(Util.getHexOfSHA256DigestOf(correlationId + "test-data"))); } @Test From 349b6cc7e8f5995af3b4f1ab8399e87bf6e907df Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 08:31:16 -0800 Subject: [PATCH 07/34] Update dependency io.jenkins.plugins:design-library to v355 (#10229) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/pom.xml b/test/pom.xml index 4d0f4685cf..005b151c19 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -344,7 +344,7 @@ THE SOFTWARE. io.jenkins.plugins design-library - 354.v87d9d5804b_c1 + 355.v0f007356e15d hpi ${project.build.outputDirectory}/plugins design-library.jpi From 417812769b8db52996eb2de36e87b4b440c8e97b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 11:13:49 -0800 Subject: [PATCH 08/34] Update dependency io.jenkins.plugins:gson-api to v2.12.1-113.v347686d6729f (#10231) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- war/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/war/pom.xml b/war/pom.xml index 91cd5225ab..46bca903ad 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -525,7 +525,7 @@ THE SOFTWARE. io.jenkins.plugins gson-api - 2.11.0-109.v1ef91dd0829a_ + 2.12.1-113.v347686d6729f hpi From 7a7f056e5d885fec90d65270acb5f22e23250ef6 Mon Sep 17 00:00:00 2001 From: Vincent Latombe Date: Fri, 31 Jan 2025 09:28:19 +0100 Subject: [PATCH 09/34] [JENKINS-58743] Allow to provide a custom path for master key --- .../security/DefaultConfidentialStore.java | 37 ++++++++++-- .../DefaultConfidentialStoreTest.java | 59 +++++++++++++++---- 2 files changed, 77 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/jenkins/security/DefaultConfidentialStore.java b/core/src/main/java/jenkins/security/DefaultConfidentialStore.java index 9c97c9ae3b..f8cc528575 100644 --- a/core/src/main/java/jenkins/security/DefaultConfidentialStore.java +++ b/core/src/main/java/jenkins/security/DefaultConfidentialStore.java @@ -1,5 +1,6 @@ package jenkins.security; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.FilePath; import hudson.Util; import hudson.util.Secret; @@ -19,19 +20,35 @@ import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.SecretKey; import jenkins.model.Jenkins; +import jenkins.util.SystemProperties; /** * Default portable implementation of {@link ConfidentialStore} that uses * a directory inside $JENKINS_HOME. - * - * The master key is also stored in this same directory. + *

+ * The master key is stored by default in $JENKINS_HOME/secrets/master.key but another location can be provided using the system property master.key.file. + *

+ * It is also possible to prevent the generation of the master key file using the system property -Dmaster.key.readOnly. In this case, the master key file must be provided or startup will fail. * * @author Kohsuke Kawaguchi */ // @MetaInfServices --- not annotated because this is the fallback implementation public class DefaultConfidentialStore extends ConfidentialStore { + static final String MASTER_KEY_FILE_SYSTEM_PROPERTY = "master.key.file"; + static final String MASTER_KEY_READONLY_SYSTEM_PROPERTY_NAME = "master.key.readOnly"; + private final SecureRandom sr = new SecureRandom(); + @NonNull + private static File getMasterKeyFile(File rootDir) { + var jenkinsMasterKey = SystemProperties.getString(MASTER_KEY_FILE_SYSTEM_PROPERTY); + if (jenkinsMasterKey != null) { + return new File(jenkinsMasterKey); + } else { + return new File(rootDir, "master.key"); + } + } + /** * Directory that stores individual keys. */ @@ -51,6 +68,10 @@ public class DefaultConfidentialStore extends ConfidentialStore { } public DefaultConfidentialStore(File rootDir) throws IOException, InterruptedException { + this(rootDir, getMasterKeyFile(rootDir)); + } + + protected DefaultConfidentialStore(File rootDir, File keyFile) throws IOException, InterruptedException { this.rootDir = rootDir; if (rootDir.mkdirs()) { // protect this directory. but don't change the permission of the existing directory @@ -58,11 +79,15 @@ public class DefaultConfidentialStore extends ConfidentialStore { new FilePath(rootDir).chmod(0700); } - TextFile masterSecret = new TextFile(new File(rootDir, "master.key")); + TextFile masterSecret = new TextFile(keyFile); if (!masterSecret.exists()) { - // we are only going to use small number of bits (since export control limits AES key length) - // but let's generate a long enough key anyway - masterSecret.write(Util.toHexString(randomBytes(128))); + if (SystemProperties.getBoolean(MASTER_KEY_READONLY_SYSTEM_PROPERTY_NAME)) { + throw new IOException(masterSecret + " does not exist and system property " + MASTER_KEY_READONLY_SYSTEM_PROPERTY_NAME + " is set. You must provide a valid master key file."); + } else { + // we are only going to use small number of bits (since export control limits AES key length) + // but let's generate a long enough key anyway + masterSecret.write(Util.toHexString(randomBytes(128))); + } } this.masterKey = Util.toAes128Key(masterSecret.readTrim()); } diff --git a/core/src/test/java/jenkins/security/DefaultConfidentialStoreTest.java b/core/src/test/java/jenkins/security/DefaultConfidentialStoreTest.java index 117e1d5b18..bab1f7b1a8 100644 --- a/core/src/test/java/jenkins/security/DefaultConfidentialStoreTest.java +++ b/core/src/test/java/jenkins/security/DefaultConfidentialStoreTest.java @@ -7,10 +7,15 @@ import static org.junit.Assert.assertTrue; import hudson.FilePath; import hudson.Functions; +import hudson.Util; +import hudson.util.TextFile; import java.io.File; +import java.io.IOException; import java.nio.charset.MalformedInputException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.security.SecureRandom; +import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -20,6 +25,8 @@ public class DefaultConfidentialStoreTest { @Rule public TemporaryFolder tmpRule = new TemporaryFolder(); + private final SecureRandom sr = new SecureRandom(); + @Test public void roundtrip() throws Exception { File tmp = new File(tmpRule.getRoot(), "tmp"); // let ConfidentialStore create a directory @@ -27,20 +34,8 @@ public class DefaultConfidentialStoreTest { DefaultConfidentialStore store = new DefaultConfidentialStore(tmp); ConfidentialKey key = new ConfidentialKey("test") {}; - // basic roundtrip - String str = "Hello world!"; - store.store(key, str.getBytes(StandardCharsets.UTF_8)); - assertEquals(str, new String(store.load(key), StandardCharsets.UTF_8)); - - // data storage should have some stuff - assertTrue(new File(tmp, "test").exists()); assertTrue(new File(tmp, "master.key").exists()); - - assertThrows(MalformedInputException.class, () -> Files.readString(tmp.toPath().resolve("test"), StandardCharsets.UTF_8)); // the data shouldn't be a plain text, obviously - - if (!Functions.isWindows()) { - assertEquals(0700, new FilePath(tmp).mode() & 0777); // should be read only - } + roundTrip(store, key, tmp); // if the master key changes, we should gracefully fail to load the store new File(tmp, "master.key").delete(); @@ -49,4 +44,42 @@ public class DefaultConfidentialStoreTest { assertNull(store2.load(key)); } + private static void roundTrip(DefaultConfidentialStore store, ConfidentialKey key, File tmp) throws IOException, InterruptedException { + // basic roundtrip + String str = "Hello world!"; + store.store(key, str.getBytes(StandardCharsets.UTF_8)); + assertEquals(str, new String(store.load(key), StandardCharsets.UTF_8)); + + // data storage should have some stuff + assertTrue(new File(tmp, "test").exists()); + + assertThrows(MalformedInputException.class, () -> Files.readString(tmp.toPath().resolve("test"), StandardCharsets.UTF_8)); // the data shouldn't be a plain text, obviously + + if (!Functions.isWindows()) { + assertEquals(0700, new FilePath(tmp).mode() & 0777); // should be read only + } + } + + @Test + public void masterKeyGeneratedBeforehand() throws IOException, InterruptedException { + File external = new File(tmpRule.getRoot(), "external"); + File tmp = new File(tmpRule.getRoot(), "tmp"); + var masterKeyFile = new File(external, "master.key"); + new TextFile(masterKeyFile).write(Util.toHexString(randomBytes(128))); + System.setProperty(DefaultConfidentialStore.MASTER_KEY_FILE_SYSTEM_PROPERTY, masterKeyFile.getAbsolutePath()); + System.setProperty(DefaultConfidentialStore.MASTER_KEY_READONLY_SYSTEM_PROPERTY_NAME, "true"); + DefaultConfidentialStore store = new DefaultConfidentialStore(tmp); + ConfidentialKey key = new ConfidentialKey("test") {}; + roundTrip(store, key, tmp); + // With this configuration, the master key file deletion is fatal + masterKeyFile.delete(); + assertThrows(IOException.class, () -> new DefaultConfidentialStore(tmp)); + } + + private byte[] randomBytes(int size) { + byte[] random = new byte[size]; + sr.nextBytes(random); + return random; + } + } From 5748d3105e5e0949489776ee700a73c61ebb28a7 Mon Sep 17 00:00:00 2001 From: Vincent Latombe Date: Tue, 4 Feb 2025 10:33:23 +0100 Subject: [PATCH 10/34] Spotless --- .../java/jenkins/security/DefaultConfidentialStore.java | 8 ++++---- .../jenkins/security/DefaultConfidentialStoreTest.java | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/jenkins/security/DefaultConfidentialStore.java b/core/src/main/java/jenkins/security/DefaultConfidentialStore.java index f8cc528575..3fdae97486 100644 --- a/core/src/main/java/jenkins/security/DefaultConfidentialStore.java +++ b/core/src/main/java/jenkins/security/DefaultConfidentialStore.java @@ -26,16 +26,16 @@ import jenkins.util.SystemProperties; * Default portable implementation of {@link ConfidentialStore} that uses * a directory inside $JENKINS_HOME. *

- * The master key is stored by default in $JENKINS_HOME/secrets/master.key but another location can be provided using the system property master.key.file. + * The master key is stored by default in $JENKINS_HOME/secrets/master.key but another location can be provided using the system property jenkins.master.key.file. *

- * It is also possible to prevent the generation of the master key file using the system property -Dmaster.key.readOnly. In this case, the master key file must be provided or startup will fail. + * It is also possible to prevent the generation of the master key file using the system property -Djenkins.master.key.readOnly. In this case, the master key file must be provided or startup will fail. * * @author Kohsuke Kawaguchi */ // @MetaInfServices --- not annotated because this is the fallback implementation public class DefaultConfidentialStore extends ConfidentialStore { - static final String MASTER_KEY_FILE_SYSTEM_PROPERTY = "master.key.file"; - static final String MASTER_KEY_READONLY_SYSTEM_PROPERTY_NAME = "master.key.readOnly"; + static final String MASTER_KEY_FILE_SYSTEM_PROPERTY = "jenkins.master.key.file"; + static final String MASTER_KEY_READONLY_SYSTEM_PROPERTY_NAME = "jenkins.master.key.readOnly"; private final SecureRandom sr = new SecureRandom(); diff --git a/core/src/test/java/jenkins/security/DefaultConfidentialStoreTest.java b/core/src/test/java/jenkins/security/DefaultConfidentialStoreTest.java index bab1f7b1a8..eb6cc8c993 100644 --- a/core/src/test/java/jenkins/security/DefaultConfidentialStoreTest.java +++ b/core/src/test/java/jenkins/security/DefaultConfidentialStoreTest.java @@ -15,7 +15,6 @@ import java.nio.charset.MalformedInputException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.security.SecureRandom; -import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; From 11d1fa7b98e2a13952519e6e0b8a4346fbee672d Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Tue, 4 Feb 2025 13:21:12 +0100 Subject: [PATCH 11/34] Better document lib.hudson.widget-refresh --- core/src/main/resources/lib/hudson/widget-refresh.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core/src/main/resources/lib/hudson/widget-refresh.js b/core/src/main/resources/lib/hudson/widget-refresh.js index 8d406488a0..e38709f744 100644 --- a/core/src/main/resources/lib/hudson/widget-refresh.js +++ b/core/src/main/resources/lib/hudson/widget-refresh.js @@ -1,10 +1,17 @@ +/* global Behaviour, refreshPart */ +/** + * Use the `widget-refresh-reference` class on an element with `data-id` and `data-url` attributes. + * The content from the URL will be used to replace the element with the specified ID. + * Usually the URL content is an element with the same ID as specified here, to allow continuous updates. + * This is primarily used for sidepanel widgets, but not exclusively. + */ Behaviour.specify( ".widget-refresh-reference", "widget-refresh", 0, function (e) { - var id = e.getAttribute("data-id"); - var url = e.getAttribute("data-url"); + let id = e.getAttribute("data-id"); + let url = e.getAttribute("data-url"); refreshPart(id, url); }, ); From 484a617ea9837fd3bb0b5178ad1b7aa4ae40c54b Mon Sep 17 00:00:00 2001 From: Jenkins Release Bot <66998184+jenkins-release-bot@users.noreply.github.com> Date: Tue, 4 Feb 2025 13:38:06 +0000 Subject: [PATCH 12/34] [maven-release-plugin] prepare release jenkins-2.496 --- bom/pom.xml | 2 +- cli/pom.xml | 2 +- core/pom.xml | 2 +- coverage/pom.xml | 2 +- pom.xml | 6 +++--- test/pom.xml | 2 +- war/pom.xml | 2 +- websocket/jetty12-ee9/pom.xml | 2 +- websocket/spi/pom.xml | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/bom/pom.xml b/bom/pom.xml index bf3390eed5..8181b0ec7e 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.496 jenkins-bom diff --git a/cli/pom.xml b/cli/pom.xml index 2473629d23..b27e6290e6 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -5,7 +5,7 @@ org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.496 cli diff --git a/core/pom.xml b/core/pom.xml index 0c9b072e0b..368ce9faa2 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -29,7 +29,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.496 jenkins-core diff --git a/coverage/pom.xml b/coverage/pom.xml index fe1e89a120..32f600f2a6 100644 --- a/coverage/pom.xml +++ b/coverage/pom.xml @@ -5,7 +5,7 @@ org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.496 jenkins-coverage diff --git a/pom.xml b/pom.xml index ba0bb25bd4..17b5948915 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.496 pom Jenkins main module @@ -63,7 +63,7 @@ THE SOFTWARE. scm:git:https://github.com/jenkinsci/jenkins.git scm:git:git@github.com:jenkinsci/jenkins.git - ${scmTag} + jenkins-2.496 https://github.com/jenkinsci/jenkins @@ -75,7 +75,7 @@ THE SOFTWARE. 2.496 -SNAPSHOT - 2025-01-28T13:58:52Z + 2025-02-04T10:33:32Z github diff --git a/test/pom.xml b/test/pom.xml index 005b151c19..5d6c73112c 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.496 jenkins-test diff --git a/war/pom.xml b/war/pom.xml index 46bca903ad..e2b455249f 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.496 jenkins-war diff --git a/websocket/jetty12-ee9/pom.xml b/websocket/jetty12-ee9/pom.xml index 2253163b3c..8f734089e2 100644 --- a/websocket/jetty12-ee9/pom.xml +++ b/websocket/jetty12-ee9/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.496 ../.. diff --git a/websocket/spi/pom.xml b/websocket/spi/pom.xml index 178413f92c..305227e5b5 100644 --- a/websocket/spi/pom.xml +++ b/websocket/spi/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.496 ../.. From 630b6b63abcf30959c7b1457a19e155e5f18a436 Mon Sep 17 00:00:00 2001 From: Jenkins Release Bot <66998184+jenkins-release-bot@users.noreply.github.com> Date: Tue, 4 Feb 2025 13:38:22 +0000 Subject: [PATCH 13/34] [maven-release-plugin] prepare for next development iteration --- bom/pom.xml | 2 +- cli/pom.xml | 2 +- core/pom.xml | 2 +- coverage/pom.xml | 2 +- pom.xml | 8 ++++---- test/pom.xml | 2 +- war/pom.xml | 2 +- websocket/jetty12-ee9/pom.xml | 2 +- websocket/spi/pom.xml | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/bom/pom.xml b/bom/pom.xml index 8181b0ec7e..bf3390eed5 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.496 + ${revision}${changelist} jenkins-bom diff --git a/cli/pom.xml b/cli/pom.xml index b27e6290e6..2473629d23 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -5,7 +5,7 @@ org.jenkins-ci.main jenkins-parent - 2.496 + ${revision}${changelist} cli diff --git a/core/pom.xml b/core/pom.xml index 368ce9faa2..0c9b072e0b 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -29,7 +29,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.496 + ${revision}${changelist} jenkins-core diff --git a/coverage/pom.xml b/coverage/pom.xml index 32f600f2a6..fe1e89a120 100644 --- a/coverage/pom.xml +++ b/coverage/pom.xml @@ -5,7 +5,7 @@ org.jenkins-ci.main jenkins-parent - 2.496 + ${revision}${changelist} jenkins-coverage diff --git a/pom.xml b/pom.xml index 17b5948915..f53f0578ea 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.496 + ${revision}${changelist} pom Jenkins main module @@ -63,7 +63,7 @@ THE SOFTWARE. scm:git:https://github.com/jenkinsci/jenkins.git scm:git:git@github.com:jenkinsci/jenkins.git - jenkins-2.496 + ${scmTag} https://github.com/jenkinsci/jenkins @@ -73,9 +73,9 @@ THE SOFTWARE. - 2.496 + 2.497 -SNAPSHOT - 2025-02-04T10:33:32Z + 2025-02-04T13:38:06Z github diff --git a/test/pom.xml b/test/pom.xml index 5d6c73112c..005b151c19 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.496 + ${revision}${changelist} jenkins-test diff --git a/war/pom.xml b/war/pom.xml index e2b455249f..46bca903ad 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.496 + ${revision}${changelist} jenkins-war diff --git a/websocket/jetty12-ee9/pom.xml b/websocket/jetty12-ee9/pom.xml index 8f734089e2..2253163b3c 100644 --- a/websocket/jetty12-ee9/pom.xml +++ b/websocket/jetty12-ee9/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.496 + ${revision}${changelist} ../.. diff --git a/websocket/spi/pom.xml b/websocket/spi/pom.xml index 305227e5b5..178413f92c 100644 --- a/websocket/spi/pom.xml +++ b/websocket/spi/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.496 + ${revision}${changelist} ../.. From 14c6a25786721979e209dfd4c9d193c62c39a46e Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Tue, 4 Feb 2025 14:54:03 -0500 Subject: [PATCH 14/34] `CronTab.floor` / `.ceil` should return times at minute granularity --- .../main/java/hudson/scheduler/CronTab.java | 7 +++++++ .../java/hudson/scheduler/CronTabTest.java | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/core/src/main/java/hudson/scheduler/CronTab.java b/core/src/main/java/hudson/scheduler/CronTab.java index 2c4b188a0d..86e5d28758 100644 --- a/core/src/main/java/hudson/scheduler/CronTab.java +++ b/core/src/main/java/hudson/scheduler/CronTab.java @@ -371,6 +371,11 @@ public final class CronTab { * (e.g. Jun 31) date, or at least a date too rare to be useful. This addresses JENKINS-41864 and was added in 2.49 */ public Calendar ceil(Calendar cal) { + if (cal.get(Calendar.SECOND) > 0 || cal.get(Calendar.MILLISECOND) > 0) { + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + cal.add(Calendar.MINUTE, 1); + } Calendar twoYearsFuture = (Calendar) cal.clone(); twoYearsFuture.add(Calendar.YEAR, 2); OUTER: @@ -440,6 +445,8 @@ public final class CronTab { * (e.g. Jun 31) date, or at least a date too rare to be useful. This addresses JENKINS-41864 and was added in 2.49 */ public Calendar floor(Calendar cal) { + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); Calendar twoYearsAgo = (Calendar) cal.clone(); twoYearsAgo.add(Calendar.YEAR, -2); diff --git a/core/src/test/java/hudson/scheduler/CronTabTest.java b/core/src/test/java/hudson/scheduler/CronTabTest.java index 0ae6ae0f22..352e72f3a5 100644 --- a/core/src/test/java/hudson/scheduler/CronTabTest.java +++ b/core/src/test/java/hudson/scheduler/CronTabTest.java @@ -27,6 +27,7 @@ package hudson.scheduler; import static java.util.Calendar.MONDAY; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; @@ -340,6 +341,24 @@ public class CronTabTest { assertEquals("[35, 56]", times.toString()); } + @Test public void floorCeilMinuteGranularity() throws Exception { + var tab = new CronTab("*/5 * * * *"); + assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 15, 23), "Mar 4, 2025, 2:15:00 PM", "Mar 4, 2025, 2:20:00 PM"); + assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 19, 23), "Mar 4, 2025, 2:15:00 PM", "Mar 4, 2025, 2:20:00 PM"); + assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 16, 0), "Mar 4, 2025, 2:15:00 PM", "Mar 4, 2025, 2:20:00 PM"); + assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 19, 0), "Mar 4, 2025, 2:15:00 PM", "Mar 4, 2025, 2:20:00 PM"); + assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 15, 0), "Mar 4, 2025, 2:15:00 PM", "Mar 4, 2025, 2:15:00 PM"); + } + + private static void assertFloorCeil(CronTab tab, Calendar now, String expectedFloor, String expectedCeil) { + var fmt = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM); + var nowFormatted = fmt.format(now.getTime()); + var nowClone = (Calendar) now.clone(); + assertThat("floor of " + nowFormatted, fmt.format(tab.floor(nowClone).getTime()), is(expectedFloor)); + nowClone = (Calendar) now.clone(); + assertThat("ceil of " + nowFormatted, fmt.format(tab.ceil(nowClone).getTime()), is(expectedCeil)); + } + @Issue("SECURITY-790") @Test(timeout = 1000L) public void testLongMonths() throws Exception { Calendar cal = Calendar.getInstance(); From 6c16c347f3ae1aaa2f171c7b5cf04fdf05b467dd Mon Sep 17 00:00:00 2001 From: Vincent Latombe Date: Wed, 5 Feb 2025 12:26:53 +0100 Subject: [PATCH 15/34] Rename system properties --- .../main/java/jenkins/security/DefaultConfidentialStore.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/jenkins/security/DefaultConfidentialStore.java b/core/src/main/java/jenkins/security/DefaultConfidentialStore.java index 3fdae97486..2a2b602c22 100644 --- a/core/src/main/java/jenkins/security/DefaultConfidentialStore.java +++ b/core/src/main/java/jenkins/security/DefaultConfidentialStore.java @@ -34,8 +34,8 @@ import jenkins.util.SystemProperties; */ // @MetaInfServices --- not annotated because this is the fallback implementation public class DefaultConfidentialStore extends ConfidentialStore { - static final String MASTER_KEY_FILE_SYSTEM_PROPERTY = "jenkins.master.key.file"; - static final String MASTER_KEY_READONLY_SYSTEM_PROPERTY_NAME = "jenkins.master.key.readOnly"; + static final String MASTER_KEY_FILE_SYSTEM_PROPERTY = DefaultConfidentialStore.class.getName() + ".file"; + static final String MASTER_KEY_READONLY_SYSTEM_PROPERTY_NAME = DefaultConfidentialStore.class.getName() + ".readOnly"; private final SecureRandom sr = new SecureRandom(); From 047e875d029c1f0f876ac5a229082ff9cc690e6f Mon Sep 17 00:00:00 2001 From: Vincent Latombe Date: Wed, 5 Feb 2025 12:27:17 +0100 Subject: [PATCH 16/34] Fail fast if the confidential store can't be loaded --- core/src/main/java/jenkins/model/Jenkins.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java index 802681c939..b294017239 100644 --- a/core/src/main/java/jenkins/model/Jenkins.java +++ b/core/src/main/java/jenkins/model/Jenkins.java @@ -974,6 +974,9 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve ClassFilterImpl.register(); LOGGER.info("Starting version " + getVersion()); + // Sanity check that we can load the confidential store. Fail fast if we can't. + ConfidentialStore.get(); + // initialization consists of ... executeReactor(is, pluginManager.initTasks(is), // loading and preparing plugins From 092756b83ba50652c23945ad4d2b43761da0c6bd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 5 Feb 2025 11:18:58 -0800 Subject: [PATCH 17/34] Update dependency io.jenkins.plugins:checks-api to v2.2.2 (#10241) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- war/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/war/pom.xml b/war/pom.xml index 46bca903ad..31e457d5ce 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -344,7 +344,7 @@ THE SOFTWARE. io.jenkins.plugins checks-api - 2.2.1 + 2.2.2 hpi From 832ba1d6c69607c36e5e4360915798dec4d6b4d8 Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Wed, 5 Feb 2025 18:25:02 -0500 Subject: [PATCH 18/34] More stable date formatting https://github.com/jenkinsci/jenkins/pull/10239#discussion_r1943013763 --- .../java/hudson/scheduler/CronTabTest.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/core/src/test/java/hudson/scheduler/CronTabTest.java b/core/src/test/java/hudson/scheduler/CronTabTest.java index 352e72f3a5..a75c7d7f31 100644 --- a/core/src/test/java/hudson/scheduler/CronTabTest.java +++ b/core/src/test/java/hudson/scheduler/CronTabTest.java @@ -34,12 +34,15 @@ import static org.junit.Assert.assertThrows; import antlr.ANTLRException; import java.text.DateFormat; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.List; import java.util.Locale; import java.util.TimeZone; +import java.util.function.Function; import org.junit.Test; import org.jvnet.hudson.test.Issue; @@ -343,20 +346,20 @@ public class CronTabTest { @Test public void floorCeilMinuteGranularity() throws Exception { var tab = new CronTab("*/5 * * * *"); - assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 15, 23), "Mar 4, 2025, 2:15:00 PM", "Mar 4, 2025, 2:20:00 PM"); - assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 19, 23), "Mar 4, 2025, 2:15:00 PM", "Mar 4, 2025, 2:20:00 PM"); - assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 16, 0), "Mar 4, 2025, 2:15:00 PM", "Mar 4, 2025, 2:20:00 PM"); - assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 19, 0), "Mar 4, 2025, 2:15:00 PM", "Mar 4, 2025, 2:20:00 PM"); - assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 15, 0), "Mar 4, 2025, 2:15:00 PM", "Mar 4, 2025, 2:15:00 PM"); + assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 15, 23), "2025-03-04T14:15:00", "2025-03-04T14:20:00"); + assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 19, 23), "2025-03-04T14:15:00", "2025-03-04T14:20:00"); + assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 16, 0), "2025-03-04T14:15:00", "2025-03-04T14:20:00"); + assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 19, 0), "2025-03-04T14:15:00", "2025-03-04T14:20:00"); + assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 15, 0), "2025-03-04T14:15:00", "2025-03-04T14:15:00"); } private static void assertFloorCeil(CronTab tab, Calendar now, String expectedFloor, String expectedCeil) { - var fmt = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM); - var nowFormatted = fmt.format(now.getTime()); + Function fmt = c -> ZonedDateTime.ofInstant(c.toInstant(), c.getTimeZone().toZoneId()).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); + var nowFormatted = fmt.apply(now); var nowClone = (Calendar) now.clone(); - assertThat("floor of " + nowFormatted, fmt.format(tab.floor(nowClone).getTime()), is(expectedFloor)); + assertThat("floor of " + nowFormatted, fmt.apply(tab.floor(nowClone)), is(expectedFloor)); nowClone = (Calendar) now.clone(); - assertThat("ceil of " + nowFormatted, fmt.format(tab.ceil(nowClone).getTime()), is(expectedCeil)); + assertThat("ceil of " + nowFormatted, fmt.apply(tab.ceil(nowClone)), is(expectedCeil)); } @Issue("SECURITY-790") From 9e8794c3f9b8e3d69d56a3a158b85a6c3debbabe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 11:04:59 -0800 Subject: [PATCH 19/34] Update dependency org.jenkins-ci.plugins:credentials to v1408 (#10244) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/pom.xml b/test/pom.xml index 005b151c19..41d5bcefc0 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -224,7 +224,7 @@ THE SOFTWARE. org.jenkins-ci.plugins credentials - 1405.vb_cda_74a_f8974 + 1408.va_622a_b_f5b_1b_1 test From bad86cc6e4f0fb52a322e4392b6cb4b396e963a6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 11:05:50 -0800 Subject: [PATCH 20/34] Update dependency org.jenkins-ci.modules:sshd to v3.350.v1080103a_10fd (#10242) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- war/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/war/pom.xml b/war/pom.xml index a58c6e2797..aafcfab57a 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -462,7 +462,7 @@ THE SOFTWARE. org.jenkins-ci.modules sshd - 3.330.vc866a_8389b_58 + 3.350.v1080103a_10fd hpi From 4f185213d2153c262471448d64d3139913115f31 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Fri, 7 Feb 2025 09:57:22 +0100 Subject: [PATCH 21/34] Update Plugin count (#10246) Signed-off-by: Alexander Brandes --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e69e309272..5a4524d6ec 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ [![Gitter](https://img.shields.io/gitter/room/jenkinsci/jenkins)](https://app.gitter.im/#/room/#jenkinsci_jenkins:gitter.im) In a nutshell, Jenkins is the leading open-source automation server. -Built with Java, it provides over 1,800 [plugins](https://plugins.jenkins.io/) to support automating virtually anything, +Built with Java, it provides over 2,000 [plugins](https://plugins.jenkins.io/) to support automating virtually anything, so that humans can spend their time doing things machines cannot. # What to Use Jenkins for and When to Use It From 3b3c41c6677ec3471150d9cc4c2f2969ccac00ba Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Fri, 7 Feb 2025 16:24:02 +0100 Subject: [PATCH 22/34] Remove comment due to duplicate declaration warning --- core/src/main/resources/lib/hudson/widget-refresh.js | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/resources/lib/hudson/widget-refresh.js b/core/src/main/resources/lib/hudson/widget-refresh.js index e38709f744..68f2202b8f 100644 --- a/core/src/main/resources/lib/hudson/widget-refresh.js +++ b/core/src/main/resources/lib/hudson/widget-refresh.js @@ -1,4 +1,3 @@ -/* global Behaviour, refreshPart */ /** * Use the `widget-refresh-reference` class on an element with `data-id` and `data-url` attributes. * The content from the URL will be used to replace the element with the specified ID. From 6fd9121623b9f297f5752a2492c6434d9ac688e7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 8 Feb 2025 07:35:13 -0700 Subject: [PATCH 23/34] Update dependency org.jenkins-ci.plugins.workflow:workflow-support to v946 (#10243) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- test/pom.xml | 2 +- war/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/pom.xml b/test/pom.xml index 41d5bcefc0..5f7064f31b 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -134,7 +134,7 @@ THE SOFTWARE. org.jenkins-ci.plugins.workflow workflow-support - 944.v5a_859593b_98a_ + 946.v2a_79d8a_4b_e14 diff --git a/war/pom.xml b/war/pom.xml index aafcfab57a..0a8335f526 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -352,7 +352,7 @@ THE SOFTWARE. org.jenkins-ci.plugins.workflow workflow-support - 944.v5a_859593b_98a_ + 946.v2a_79d8a_4b_e14 hpi From f8c9f3753ca2df1d795673d5c7f625ae685c165b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 8 Feb 2025 07:35:23 -0700 Subject: [PATCH 24/34] Update dependency org.jenkins-ci.plugins:apache-httpcomponents-client-4-api to v4.5.14-269.vfa_2321039a_83 (#10247) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- war/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/war/pom.xml b/war/pom.xml index 0a8335f526..13efe46422 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -497,7 +497,7 @@ THE SOFTWARE. org.jenkins-ci.plugins apache-httpcomponents-client-4-api - 4.5.14-208.v438351942757 + 4.5.14-269.vfa_2321039a_83 hpi From e61ecca4fcd9c13b9c07e18555b0dc4159d6d69d Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Sat, 8 Feb 2025 06:37:48 -0800 Subject: [PATCH 25/34] Migrate from deprecated EE 8 methods to non-deprecated equivalents (#10233) * Migrate from deprecated EE 8 methods to non-deprecated equivalents * Clean up `GlobalComputerRetentionCheckIntervalConfiguration` as well --- core/src/main/java/hudson/Functions.java | 2 +- .../java/jenkins/console/ConsoleUrlProvider.java | 2 +- ...omputerRetentionCheckIntervalConfiguration.java | 4 ++-- .../java/jenkins/model/GlobalConfiguration.java | 2 +- .../resources/hudson/PluginManager/available.jelly | 2 +- .../resources/hudson/PluginManager/installed.jelly | 2 +- .../resources/hudson/PluginManager/updates.jelly | 2 +- .../diagnosis/MemoryUsageMonitor/index.jelly | 2 +- .../AbstractModelObject/descriptionForm.jelly | 4 ++-- .../hudson/model/AbstractProject/changes.jelly | 4 ++-- .../resources/hudson/model/AllView/noJob.groovy | 2 +- .../resources/hudson/model/ComputerSet/_new.jelly | 4 ++-- .../hudson/model/ParametersAction/index.jelly | 2 +- .../model/ParametersDefinitionProperty/index.jelly | 2 +- .../resources/hudson/model/Run/delete-retry.jelly | 2 +- .../main/resources/hudson/model/View/index.jelly | 2 +- .../hudson/search/Search/search-failed.jelly | 4 ++-- .../GlobalSecurityConfiguration/index.groovy | 2 +- .../HudsonPrivateSecurityRealm/signup.jelly | 4 ++-- .../resources/hudson/security/WhoAmI/index.jelly | 2 +- .../hudson/util/HudsonIsLoading/index.jelly | 2 +- .../hudson/util/HudsonIsRestarting/index.jelly | 2 +- .../resources/jenkins/agents/CloudSet/_new.jelly | 2 +- .../SetupWizard/authenticate-security-token.jelly | 2 +- .../resources/jenkins/model/Jenkins/_404.jelly | 6 +++--- .../jenkins/model/Jenkins/_404_simple.jelly | 2 +- .../resources/jenkins/model/Jenkins/login.jelly | 8 ++++---- .../resources/jenkins/model/Jenkins/oops.jelly | 6 +++--- .../model/Jenkins/projectRelationship.jelly | 14 +++++++------- .../security/seed/UserSeedProperty/config.jelly | 2 +- .../main/resources/lib/form/editableComboBox.jelly | 4 ++-- .../main/resources/lib/hudson/scriptConsole.jelly | 2 +- .../main/resources/lib/layout/breadcrumbBar.jelly | 2 +- core/src/main/resources/lib/layout/layout.jelly | 4 ++-- ...terRetentionCheckIntervalConfigurationTest.java | 4 ++-- 35 files changed, 57 insertions(+), 57 deletions(-) diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index 3ae81031b0..6c2d0b7a0e 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -1989,7 +1989,7 @@ public class Functions { */ public static @CheckForNull String getConsoleUrl(WithConsoleUrl withConsoleUrl) { String consoleUrl = withConsoleUrl.getConsoleUrl(); - return consoleUrl != null ? Stapler.getCurrentRequest().getContextPath() + '/' + consoleUrl : null; + return consoleUrl != null ? Stapler.getCurrentRequest2().getContextPath() + '/' + consoleUrl : null; } /** diff --git a/core/src/main/java/jenkins/console/ConsoleUrlProvider.java b/core/src/main/java/jenkins/console/ConsoleUrlProvider.java index 9c6080ac02..f779c07e62 100644 --- a/core/src/main/java/jenkins/console/ConsoleUrlProvider.java +++ b/core/src/main/java/jenkins/console/ConsoleUrlProvider.java @@ -80,7 +80,7 @@ public interface ConsoleUrlProvider extends Describable { * @return the URL for the console for the specified build, relative to the web server root */ static @NonNull String getRedirectUrl(Run run) { - return Stapler.getCurrentRequest().getContextPath() + '/' + run.getConsoleUrl(); + return Stapler.getCurrentRequest2().getContextPath() + '/' + run.getConsoleUrl(); } static List all() { diff --git a/core/src/main/java/jenkins/model/GlobalComputerRetentionCheckIntervalConfiguration.java b/core/src/main/java/jenkins/model/GlobalComputerRetentionCheckIntervalConfiguration.java index 46d760fe8e..9766cd9772 100644 --- a/core/src/main/java/jenkins/model/GlobalComputerRetentionCheckIntervalConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalComputerRetentionCheckIntervalConfiguration.java @@ -6,7 +6,7 @@ import java.util.logging.Logger; import net.sf.json.JSONException; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Configures check interval for computer retention. @@ -56,7 +56,7 @@ public class GlobalComputerRetentionCheckIntervalConfiguration extends GlobalCon } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { try { final int interval = json.getInt("computerRetentionCheckInterval"); setComputerRetentionCheckInterval(interval); diff --git a/core/src/main/java/jenkins/model/GlobalConfiguration.java b/core/src/main/java/jenkins/model/GlobalConfiguration.java index af788945b2..bc0d700403 100644 --- a/core/src/main/java/jenkins/model/GlobalConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalConfiguration.java @@ -67,7 +67,7 @@ public abstract class GlobalConfiguration extends Descriptor + value="${request2.getParameter('filter')}" />

diff --git a/core/src/main/resources/hudson/PluginManager/installed.jelly b/core/src/main/resources/hudson/PluginManager/installed.jelly index c9b7dd93f2..81b175b955 100644 --- a/core/src/main/resources/hudson/PluginManager/installed.jelly +++ b/core/src/main/resources/hudson/PluginManager/installed.jelly @@ -43,7 +43,7 @@ THE SOFTWARE. placeholder="${%Search installed plugins}" id="filter-box" autofocus="true" - value="${request.getParameter('filter')}" + value="${request2.getParameter('filter')}" enabled="${!noPlugins}" />
diff --git a/core/src/main/resources/hudson/PluginManager/updates.jelly b/core/src/main/resources/hudson/PluginManager/updates.jelly index d4163fb7cf..5ce8a810ff 100644 --- a/core/src/main/resources/hudson/PluginManager/updates.jelly +++ b/core/src/main/resources/hudson/PluginManager/updates.jelly @@ -41,7 +41,7 @@ THE SOFTWARE. placeholder="${%Search plugin updates}" id="filter-box" autofocus="true" - value="${request.getParameter('filter')}" + value="${request2.getParameter('filter')}" enabled="${!empty(list)}" />
diff --git a/core/src/main/resources/hudson/diagnosis/MemoryUsageMonitor/index.jelly b/core/src/main/resources/hudson/diagnosis/MemoryUsageMonitor/index.jelly index bb0efd378e..43c579130a 100644 --- a/core/src/main/resources/hudson/diagnosis/MemoryUsageMonitor/index.jelly +++ b/core/src/main/resources/hudson/diagnosis/MemoryUsageMonitor/index.jelly @@ -31,7 +31,7 @@ THE SOFTWARE.

${%JVM Memory Usage}

- +
${%Timespan}: diff --git a/core/src/main/resources/hudson/model/AbstractModelObject/descriptionForm.jelly b/core/src/main/resources/hudson/model/AbstractModelObject/descriptionForm.jelly index 633e67f356..b1754861c0 100644 --- a/core/src/main/resources/hudson/model/AbstractModelObject/descriptionForm.jelly +++ b/core/src/main/resources/hudson/model/AbstractModelObject/descriptionForm.jelly @@ -30,14 +30,14 @@ THE SOFTWARE. - + - +
diff --git a/core/src/main/resources/hudson/model/AbstractProject/changes.jelly b/core/src/main/resources/hudson/model/AbstractProject/changes.jelly index bc2ad59d22..dd6ec243a7 100644 --- a/core/src/main/resources/hudson/model/AbstractProject/changes.jelly +++ b/core/src/main/resources/hudson/model/AbstractProject/changes.jelly @@ -31,8 +31,8 @@ THE SOFTWARE. - - + +

diff --git a/core/src/main/resources/hudson/model/AllView/noJob.groovy b/core/src/main/resources/hudson/model/AllView/noJob.groovy index f62125fed9..6a9e355d30 100644 --- a/core/src/main/resources/hudson/model/AllView/noJob.groovy +++ b/core/src/main/resources/hudson/model/AllView/noJob.groovy @@ -111,7 +111,7 @@ div { section(class: "empty-state-section") { ul(class: "empty-state-section-list") { li(class: "content-block") { - a(href: "${rootURL}/${app.securityRealm.loginUrl}?from=${request.requestURI}", + a(href: "${rootURL}/${app.securityRealm.loginUrl}?from=${request2.requestURI}", class: "content-block__link") { span(_("Log in to Jenkins")) span(class: "trailing-icon") { diff --git a/core/src/main/resources/hudson/model/ComputerSet/_new.jelly b/core/src/main/resources/hudson/model/ComputerSet/_new.jelly index 36e2f23fd7..5d3a79782e 100644 --- a/core/src/main/resources/hudson/model/ComputerSet/_new.jelly +++ b/core/src/main/resources/hudson/model/ComputerSet/_new.jelly @@ -32,7 +32,7 @@ THE SOFTWARE. - + @@ -40,7 +40,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/model/ParametersAction/index.jelly b/core/src/main/resources/hudson/model/ParametersAction/index.jelly index a035793cfa..c8e8bf3aaf 100644 --- a/core/src/main/resources/hudson/model/ParametersAction/index.jelly +++ b/core/src/main/resources/hudson/model/ParametersAction/index.jelly @@ -30,7 +30,7 @@ THE SOFTWARE. - + ${title} diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/index.jelly b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/index.jelly index 1302960c1a..0bea62baf0 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/index.jelly +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/index.jelly @@ -40,7 +40,7 @@ THE SOFTWARE.

${it.job.pronoun} ${it.job.displayName}

${%description}

- + diff --git a/core/src/main/resources/hudson/model/Run/delete-retry.jelly b/core/src/main/resources/hudson/model/Run/delete-retry.jelly index 79dfa6beed..5e405e5284 100644 --- a/core/src/main/resources/hudson/model/Run/delete-retry.jelly +++ b/core/src/main/resources/hudson/model/Run/delete-retry.jelly @@ -20,7 +20,7 @@

diff --git a/core/src/main/resources/hudson/model/View/index.jelly b/core/src/main/resources/hudson/model/View/index.jelly index 14632b8e60..661e2e22ce 100644 --- a/core/src/main/resources/hudson/model/View/index.jelly +++ b/core/src/main/resources/hudson/model/View/index.jelly @@ -44,7 +44,7 @@ THE SOFTWARE. -