From 57d64642be1f6810f964e77f11b7382885d05d0e Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Sat, 11 May 2024 00:53:55 +0100 Subject: [PATCH 001/449] Remove 'Disable project' button from project view (#9202) * Update makeDisabled.jelly * Update ProjectTest.java * Update ProjectTest.java --- .../lib/hudson/project/makeDisabled.jelly | 9 --------- test/src/test/java/hudson/model/ProjectTest.java | 14 ++++++-------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/core/src/main/resources/lib/hudson/project/makeDisabled.jelly b/core/src/main/resources/lib/hudson/project/makeDisabled.jelly index 9eb7f4f6571c..e53f9ab12ad9 100644 --- a/core/src/main/resources/lib/hudson/project/makeDisabled.jelly +++ b/core/src/main/resources/lib/hudson/project/makeDisabled.jelly @@ -41,14 +41,5 @@ THE SOFTWARE. - -
-
- - - -
-
-
diff --git a/test/src/test/java/hudson/model/ProjectTest.java b/test/src/test/java/hudson/model/ProjectTest.java index 82d9266e0e62..e3f2d84493e3 100644 --- a/test/src/test/java/hudson/model/ProjectTest.java +++ b/test/src/test/java/hudson/model/ProjectTest.java @@ -644,15 +644,13 @@ public void testDoDisable() throws Exception { JenkinsRule.WebClient wc = j.createWebClient(); wc.withBasicCredentials(user.getId(), "password"); - HtmlPage p = wc.goTo(project.getUrl()); - List forms = p.getForms(); - for (HtmlForm form : forms) { - if ("disable".equals(form.getAttribute("action"))) { - j.submit(form); - } - } - assertTrue("Project should be disabled.", project.isDisabled()); + HtmlPage p = wc.getPage(project, "configure"); + HtmlForm form = p.getFormByName("config"); + form.getInputByName("enable").click(); + j.submit(form); + + assertTrue("Project should be disabled.", project.isDisabled()); } @Test From 53b5e90aa60cebc7d2910b863ab1147ccff8f72e Mon Sep 17 00:00:00 2001 From: Scott K Logan Date: Fri, 10 May 2024 18:55:12 -0500 Subject: [PATCH 002/449] [JENKINS-21605] Further reduce number of recorded upstream causes (#9248) * Fix non-determinism in nested cause tests For deeplyNestedCauses, quickly triggering a jobs with no quiet period runs the possibility that a job is triggered while it is still in the queue. Triggering and waiting for the jobs to execute synchronously avoids this and also simplifies the code. The broadlyNesstedCauses test suffers from the same problem, but is additionally not structured in the way the original issue describes to reproduce the issue. Using the quiet period argument to scheduleBuild2, we can reliably produce a graph where each build is triggered by the other two jobs. An additional final job outside of the loop cuts off the 1 second quiet period from the last loop's iteration so that the test is never waiting for the quiet period of any jobs even though half of the schedule operations specify one. * Re-work nested cause trimming algorithm --- core/src/main/java/hudson/model/Cause.java | 18 ++++++++----- .../src/test/java/hudson/model/CauseTest.java | 25 ++++++++----------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/hudson/model/Cause.java b/core/src/main/java/hudson/model/Cause.java index 6990dd2b39e0..668587ffc8fc 100644 --- a/core/src/main/java/hudson/model/Cause.java +++ b/core/src/main/java/hudson/model/Cause.java @@ -182,6 +182,10 @@ public UpstreamCause(Run up) { upstreamCauses = new ArrayList<>(); Set traversed = new HashSet<>(); for (Cause c : up.getCauses()) { + if (traversed.size() >= MAX_LEAF) { + upstreamCauses.add(new DeeplyNestedUpstreamCause()); + break; + } upstreamCauses.add(trim(c, MAX_DEPTH, traversed)); } } @@ -239,14 +243,16 @@ public int hashCode() { } UpstreamCause uc = (UpstreamCause) c; List cs = new ArrayList<>(); - if (depth > 0) { - if (traversed.add(uc.upstreamUrl + uc.upstreamBuild)) { - for (Cause c2 : uc.upstreamCauses) { - cs.add(trim(c2, depth - 1, traversed)); + if (traversed.add(uc.upstreamUrl + uc.upstreamBuild)) { + for (Cause c2 : uc.upstreamCauses) { + if (depth <= 0 || traversed.size() >= MAX_LEAF) { + cs.add(new DeeplyNestedUpstreamCause()); + break; } + cs.add(trim(c2, depth - 1, traversed)); } - } else if (traversed.size() < MAX_LEAF) { - cs.add(new DeeplyNestedUpstreamCause()); + } else { + traversed.add(uc.upstreamUrl + uc.upstreamBuild + '#' + traversed.size()); } return new UpstreamCause(uc.upstreamProject, uc.upstreamBuild, uc.upstreamUrl, cs); } diff --git a/test/src/test/java/hudson/model/CauseTest.java b/test/src/test/java/hudson/model/CauseTest.java index 0d4caf54f61b..2484a03c52ed 100644 --- a/test/src/test/java/hudson/model/CauseTest.java +++ b/test/src/test/java/hudson/model/CauseTest.java @@ -63,9 +63,9 @@ public class CauseTest { FreeStyleProject b = j.createFreeStyleProject("b"); FreeStyleBuild early = null; FreeStyleBuild last = null; - List> futures = new ArrayList<>(); for (int i = 1; i <= 15; i++) { - last = recordFuture(b.scheduleBuild2(0, new Cause.UpstreamCause(recordFuture(a.scheduleBuild2(0, last == null ? null : new Cause.UpstreamCause(last)), futures).get())), futures).get(); + last = j.waitForCompletion(a.scheduleBuild2(0, last == null ? null : new Cause.UpstreamCause(last)).get()); + last = j.waitForCompletion(b.scheduleBuild2(0, new Cause.UpstreamCause(last)).get()); if (i == 5) { early = last; } @@ -74,9 +74,6 @@ public class CauseTest { assertTrue("keeps full history:\n" + buildXml, buildXml.contains("1")); buildXml = new XmlFile(Run.XSTREAM, new File(last.getRootDir(), "build.xml")).asString(); assertFalse("too big:\n" + buildXml, buildXml.contains("1")); - for (QueueTaskFuture future : futures) { - j.assertBuildStatusSuccess(j.waitForCompletion(future.waitForStart())); - } } @Issue("JENKINS-15747") @@ -88,16 +85,16 @@ public class CauseTest { Run last = null; for (int i = 1; i <= 10; i++) { Cause cause = last == null ? null : new Cause.UpstreamCause(last); - QueueTaskFuture next1 = recordFuture(a.scheduleBuild2(0, cause), futures); - recordFuture(a.scheduleBuild2(0, cause), futures); - cause = new Cause.UpstreamCause(next1.get()); - QueueTaskFuture next2 = recordFuture(b.scheduleBuild2(0, cause), futures); - recordFuture(b.scheduleBuild2(0, cause), futures); - cause = new Cause.UpstreamCause(next2.get()); - QueueTaskFuture next3 = recordFuture(c.scheduleBuild2(0, cause), futures); - recordFuture(c.scheduleBuild2(0, cause), futures); - last = next3.get(); + last = j.waitForCompletion(a.scheduleBuild2(0, cause).get()); + recordFuture(b.scheduleBuild2(1, cause), futures); + cause = new Cause.UpstreamCause(last); + last = j.waitForCompletion(b.scheduleBuild2(0, cause).get()); + recordFuture(c.scheduleBuild2(1, cause), futures); + cause = new Cause.UpstreamCause(last); + last = j.waitForCompletion(c.scheduleBuild2(0, cause).get()); + recordFuture(a.scheduleBuild2(1, cause), futures); } + last = j.waitForCompletion(a.scheduleBuild2(0, new Cause.UpstreamCause(last)).get()); int count = new XmlFile(Run.XSTREAM, new File(last.getRootDir(), "build.xml")).asString().split(Pattern.quote(" 100); //j.interactiveBreak(); From 46514cc234734f7524a07d6ce48aa86876618a69 Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Fri, 10 May 2024 16:55:28 -0700 Subject: [PATCH 003/449] Clean up `executable` package (#9251) --- war/src/main/java/executable/Main.java | 86 ++++++---------------- war/src/test/java/executable/MainTest.java | 17 ++--- 2 files changed, 28 insertions(+), 75 deletions(-) diff --git a/war/src/main/java/executable/Main.java b/war/src/main/java/executable/Main.java index 9812f3d5b9e1..a746a28a4ee6 100644 --- a/war/src/main/java/executable/Main.java +++ b/war/src/main/java/executable/Main.java @@ -40,8 +40,8 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Arrays; import java.util.Enumeration; import java.util.List; import java.util.MissingResourceException; @@ -76,8 +76,7 @@ public class Main { * This list must remain synchronized with the one in {@code * JavaVersionRecommendationAdminMonitor}. */ - private static final NavigableSet SUPPORTED_JAVA_VERSIONS = - new TreeSet<>(Arrays.asList(11, 17, 21)); + private static final NavigableSet SUPPORTED_JAVA_VERSIONS = new TreeSet<>(List.of(11, 17, 21)); /** * Sets custom session cookie name. @@ -109,16 +108,15 @@ public class Main { // Great! } else if (releaseVersion >= SUPPORTED_JAVA_VERSIONS.first()) { if (enableFutureJava) { - System.err.println( - String.format( - "Running with Java %d from %s, which is not fully supported. " - + "Continuing because %s is set. " - + "Supported Java versions are: %s. " - + "See https://jenkins.io/redirect/java-support/ for more information.", - releaseVersion, - System.getProperty("java.home"), - ENABLE_FUTURE_JAVA_CLI_SWITCH, - SUPPORTED_JAVA_VERSIONS)); + System.err.printf( + "Running with Java %d from %s, which is not fully supported. " + + "Continuing because %s is set. " + + "Supported Java versions are: %s. " + + "See https://jenkins.io/redirect/java-support/ for more information.%n", + releaseVersion, + System.getProperty("java.home"), + ENABLE_FUTURE_JAVA_CLI_SWITCH, + SUPPORTED_JAVA_VERSIONS); } else if (releaseVersion > SUPPORTED_JAVA_VERSIONS.last()) { throw new UnsupportedClassVersionError( String.format( @@ -152,25 +150,6 @@ public class Main { } } - /** - * Get the release version of the current JVM. - * - * @return The release version of the current JVM; e.g., 8, 11, or 17. - * @throws NumberFormatException If the release version could not be parsed. - */ - private static int getReleaseVersion() { - String version = System.getProperty("java.specification.version"); - version = version.trim(); - if (version.startsWith("1.")) { - String[] split = version.split("\\."); - if (split.length != 2) { - throw new NumberFormatException("Invalid Java specification version: " + version); - } - version = split[1]; - } - return Integer.parseInt(version); - } - /** * Returns true if the Java runtime version check should not be done, and any version allowed. * @@ -195,7 +174,7 @@ private static boolean hasArgument(@NonNull String argument, @NonNull String[] a justification = "User provided values for running the program") public static void main(String[] args) throws IllegalAccessException { try { - verifyJavaVersion(getReleaseVersion(), isFutureJavaEnabled(args)); + verifyJavaVersion(Runtime.version().feature(), isFutureJavaEnabled(args)); } catch (UnsupportedClassVersionError e) { System.err.println(e.getMessage()); System.err.println("See https://jenkins.io/redirect/java-support/ for more information."); @@ -206,12 +185,17 @@ public static void main(String[] args) throws IllegalAccessException { //to achieve this use --paramsFromStdIn if (hasArgument("--paramsFromStdIn", args)) { System.out.println("--paramsFromStdIn detected. Parameters are going to be read from stdin. Other parameters passed directly will be ignored."); - String argsInStdIn = readStringNonBlocking(System.in, 131072).trim(); + String argsInStdIn; + try { + argsInStdIn = new String(System.in.readNBytes(131072), StandardCharsets.UTF_8).trim(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } args = argsInStdIn.split(" +"); } // If someone just wants to know the version, print it out as soon as possible, with no extraneous file or webroot info. // This makes it easier to grab the version from a script - final List arguments = new ArrayList<>(Arrays.asList(args)); + final List arguments = new ArrayList<>(List.of(args)); if (arguments.contains("--version")) { System.out.println(getVersion("?")); return; @@ -365,24 +349,6 @@ public static void main(String[] args) throws IllegalAccessException { } } - /** - * Reads up to maxRead bytes from InputStream if available into a String - * - * @param in input stream to be read - * @param maxToRead maximum number of bytes to read from the in - * @return a String read from in - */ - private static String readStringNonBlocking(InputStream in, int maxToRead) { - byte[] buffer; - try { - buffer = new byte[Math.min(in.available(), maxToRead)]; - in.read(buffer); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - return new String(buffer); - } - private static void trimOffOurOptions(List arguments) { arguments.removeIf(arg -> arg.startsWith("--extractedFilesFolder") || arg.startsWith("--pluginroot") || arg.startsWith(ENABLE_FUTURE_JAVA_CLI_SWITCH)); @@ -443,21 +409,13 @@ public static File whoAmI(File directory) { myself.deleteOnExit(); try (InputStream is = Main.class.getProtectionDomain().getCodeSource().getLocation().openStream(); OutputStream os = new FileOutputStream(myself)) { - copyStream(is, os); + is.transferTo(os); } catch (IOException e) { throw new UncheckedIOException(e); } return myself; } - private static void copyStream(InputStream in, OutputStream out) throws IOException { - byte[] buf = new byte[8192]; - int len; - while ((len = in.read(buf)) > 0) { - out.write(buf, 0, len); - } - } - /** * Extract a resource from jar, mark it for deletion upon exit, and return its location. */ @@ -477,7 +435,7 @@ private static File extractFromJar(String resource, String fileName, String suff throw new UncheckedIOException("Jenkins failed to create a temporary file in " + tmpdir + ": " + e, e); } try (InputStream is = res.openStream(); OutputStream os = new FileOutputStream(tmp)) { - copyStream(is, os); + is.transferTo(os); } catch (IOException e) { throw new UncheckedIOException(e); } @@ -524,7 +482,7 @@ private static void deleteWinstoneTempContents(File file) { /** * Determines the home directory for Jenkins. - * + *

* People makes configuration mistakes, so we are trying to be nice * with those by doing {@link String#trim()}. */ diff --git a/war/src/test/java/executable/MainTest.java b/war/src/test/java/executable/MainTest.java index e690eb3996d0..676cdd5d2986 100644 --- a/war/src/test/java/executable/MainTest.java +++ b/war/src/test/java/executable/MainTest.java @@ -1,5 +1,7 @@ package executable; +import static org.junit.jupiter.api.Assertions.assertThrows; + import edu.umd.cs.findbugs.annotations.CheckForNull; import org.junit.jupiter.api.Test; @@ -51,17 +53,10 @@ private static void assertJavaCheckFails( releaseVersion, enableFutureJava); } - // TODO use assertThrows once we drop support for Java 8 in this module - boolean failed; - try { - Main.verifyJavaVersion(releaseVersion, enableFutureJava); - failed = false; - } catch (UnsupportedClassVersionError error) { - failed = true; - } - if (!failed) { - throw new AssertionError(message); - } + assertThrows( + UnsupportedClassVersionError.class, + () -> Main.verifyJavaVersion(releaseVersion, enableFutureJava), + message); } private static void assertJavaCheckPasses(int releaseVersion, boolean enableFutureJava) { From e2cace0f1f9c8f1b45bda1539588453e93c9ea46 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 May 2024 17:56:09 -0600 Subject: [PATCH 004/449] Bump eps1lon/actions-label-merge-conflict from 3.0.0 to 3.0.1 (#9256) Bumps [eps1lon/actions-label-merge-conflict](https://github.com/eps1lon/actions-label-merge-conflict) from 3.0.0 to 3.0.1. - [Release notes](https://github.com/eps1lon/actions-label-merge-conflict/releases) - [Changelog](https://github.com/eps1lon/actions-label-merge-conflict/blob/main/CHANGELOG.md) - [Commits](https://github.com/eps1lon/actions-label-merge-conflict/compare/v3.0.0...v3.0.1) --- updated-dependencies: - dependency-name: eps1lon/actions-label-merge-conflict dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/label-conflicting-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/label-conflicting-pr.yml b/.github/workflows/label-conflicting-pr.yml index 80079296c113..ae90f55bc77d 100644 --- a/.github/workflows/label-conflicting-pr.yml +++ b/.github/workflows/label-conflicting-pr.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Label conflicting PRs - uses: eps1lon/actions-label-merge-conflict@v3.0.0 + uses: eps1lon/actions-label-merge-conflict@v3.0.1 with: dirtyLabel: "unresolved-merge-conflict" repoToken: "${{ secrets.GITHUB_TOKEN }}" From fea7c82c9678e62851b5a193e3d9e08fb49b46f8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 May 2024 17:56:42 -0600 Subject: [PATCH 005/449] Update dependency sass to v1.77.0 (#9252) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- war/package.json | 2 +- war/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/war/package.json b/war/package.json index 07fec37bd2ae..d80e680b4745 100644 --- a/war/package.json +++ b/war/package.json @@ -42,7 +42,7 @@ "postcss-preset-env": "9.5.11", "postcss-scss": "4.0.9", "prettier": "3.2.5", - "sass": "1.76.0", + "sass": "1.77.0", "sass-loader": "14.2.1", "style-loader": "4.0.0", "stylelint": "16.5.0", diff --git a/war/yarn.lock b/war/yarn.lock index fc38d86a0dec..05f7aa791164 100644 --- a/war/yarn.lock +++ b/war/yarn.lock @@ -4391,7 +4391,7 @@ __metadata: postcss-preset-env: "npm:9.5.11" postcss-scss: "npm:4.0.9" prettier: "npm:3.2.5" - sass: "npm:1.76.0" + sass: "npm:1.77.0" sass-loader: "npm:14.2.1" sortablejs: "npm:1.15.2" style-loader: "npm:4.0.0" @@ -6348,16 +6348,16 @@ __metadata: languageName: node linkType: hard -"sass@npm:1.76.0": - version: 1.76.0 - resolution: "sass@npm:1.76.0" +"sass@npm:1.77.0": + version: 1.77.0 + resolution: "sass@npm:1.77.0" dependencies: chokidar: "npm:>=3.0.0 <4.0.0" immutable: "npm:^4.0.0" source-map-js: "npm:>=0.6.2 <2.0.0" bin: sass: sass.js - checksum: 10c0/976baf2c378e104f8d4ffca5375c8aa6f3d24f59d5c0a5db8d68a51f89edce45dedc25cfcd304b309fc8568d146de9e2c6cd189395e97bb2840d39feb13932ff + checksum: 10c0/bce0e5f5b535491e4e775045a79f19cbe10d800ef53b5f7698958d2992505d7b124c968169b05a0190842d8e0a24c2aa6d75dfbdd7c213820d9d59e227009c19 languageName: node linkType: hard From a8ceebfa7c98f1bffced783096df66764e050fe7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 11 May 2024 07:54:52 +0100 Subject: [PATCH 006/449] Update dependency node to v20.13.0 (#9261) 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 c1ad8601c0eb..3f5ee316b0ee 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -47,7 +47,7 @@ THE SOFTWARE. 8080 2.12.1-101.v85b_e08b_780dd - 20.12.2 + 20.13.0 1.22.19 From 144e6b1a98fd23cac66f393a0f6c026865357645 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 12 May 2024 15:37:31 +0200 Subject: [PATCH 007/449] Update dependency css-minimizer-webpack-plugin to v7 (#9255) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- war/package.json | 2 +- war/yarn.lock | 391 ++++++++++++++++++++++++----------------------- 2 files changed, 197 insertions(+), 196 deletions(-) diff --git a/war/package.json b/war/package.json index d80e680b4745..d7bf475bb21e 100644 --- a/war/package.json +++ b/war/package.json @@ -30,7 +30,7 @@ "babel-loader": "9.1.3", "clean-webpack-plugin": "4.0.0", "css-loader": "7.1.1", - "css-minimizer-webpack-plugin": "6.0.0", + "css-minimizer-webpack-plugin": "7.0.0", "eslint": "9.2.0", "eslint-config-prettier": "9.1.0", "eslint-formatter-checkstyle": "8.40.0", diff --git a/war/yarn.lock b/war/yarn.lock index 05f7aa791164..97cfb92d1118 100644 --- a/war/yarn.lock +++ b/war/yarn.lock @@ -1983,7 +1983,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.20, @jridgewell/trace-mapping@npm:^0.3.21, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.9": +"@jridgewell/trace-mapping@npm:^0.3.20, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.9": version: 0.3.25 resolution: "@jridgewell/trace-mapping@npm:0.3.25" dependencies: @@ -2952,7 +2952,7 @@ __metadata: languageName: node linkType: hard -"colord@npm:^2.9.1, colord@npm:^2.9.3": +"colord@npm:^2.9.3": version: 2.9.3 resolution: "colord@npm:2.9.3" checksum: 10c0/9699e956894d8996b28c686afe8988720785f476f59335c80ce852ded76ab3ebe252703aec53d9bef54f6219aea6b960fb3d9a8300058a1d0c0d4026460cd110 @@ -3063,12 +3063,12 @@ __metadata: languageName: node linkType: hard -"css-declaration-sorter@npm:^7.1.1": - version: 7.1.1 - resolution: "css-declaration-sorter@npm:7.1.1" +"css-declaration-sorter@npm:^7.2.0": + version: 7.2.0 + resolution: "css-declaration-sorter@npm:7.2.0" peerDependencies: postcss: ^8.0.9 - checksum: 10c0/bea446e441bafde21c3c7b3f7639559311da12eea140db7ee3c61e4f41df455b7b098df107f99bc0cca32a5020841cc94bf8a2d5efb1b383e51f9de478c4816e + checksum: 10c0/d8516be94f8f2daa233ef021688b965c08161624cbf830a4d7ee1099429437c0ee124d35c91b1c659cfd891a68e8888aa941726dab12279bc114aaed60a94606 languageName: node linkType: hard @@ -3116,14 +3116,14 @@ __metadata: languageName: node linkType: hard -"css-minimizer-webpack-plugin@npm:6.0.0": - version: 6.0.0 - resolution: "css-minimizer-webpack-plugin@npm:6.0.0" +"css-minimizer-webpack-plugin@npm:7.0.0": + version: 7.0.0 + resolution: "css-minimizer-webpack-plugin@npm:7.0.0" dependencies: - "@jridgewell/trace-mapping": "npm:^0.3.21" - cssnano: "npm:^6.0.3" + "@jridgewell/trace-mapping": "npm:^0.3.25" + cssnano: "npm:^7.0.1" jest-worker: "npm:^29.7.0" - postcss: "npm:^8.4.33" + postcss: "npm:^8.4.38" schema-utils: "npm:^4.2.0" serialize-javascript: "npm:^6.0.2" peerDependencies: @@ -3141,7 +3141,7 @@ __metadata: optional: true lightningcss: optional: true - checksum: 10c0/5ad6690c8700a190851f5dc263ae1086b68f4bfd7eeff715c689c6d1a0742763e7af792fe474854b7ce5ee6d4f2ee4d95b1e0714db32aba5ded69ccbf9aefd30 + checksum: 10c0/607258ea16b753b42cbcf88b0b20c99406d7f162ad3a4da50ec3e23d1fb652d1304815c0d0c577944256c76dff3df64e1708e5c5e255318694ba8aaba7820ca3 languageName: node linkType: hard @@ -3210,63 +3210,64 @@ __metadata: languageName: node linkType: hard -"cssnano-preset-default@npm:^6.0.3": - version: 6.0.3 - resolution: "cssnano-preset-default@npm:6.0.3" - dependencies: - css-declaration-sorter: "npm:^7.1.1" - cssnano-utils: "npm:^4.0.1" - postcss-calc: "npm:^9.0.1" - postcss-colormin: "npm:^6.0.2" - postcss-convert-values: "npm:^6.0.2" - postcss-discard-comments: "npm:^6.0.1" - postcss-discard-duplicates: "npm:^6.0.1" - postcss-discard-empty: "npm:^6.0.1" - postcss-discard-overridden: "npm:^6.0.1" - postcss-merge-longhand: "npm:^6.0.2" - postcss-merge-rules: "npm:^6.0.3" - postcss-minify-font-values: "npm:^6.0.1" - postcss-minify-gradients: "npm:^6.0.1" - postcss-minify-params: "npm:^6.0.2" - postcss-minify-selectors: "npm:^6.0.2" - postcss-normalize-charset: "npm:^6.0.1" - postcss-normalize-display-values: "npm:^6.0.1" - postcss-normalize-positions: "npm:^6.0.1" - postcss-normalize-repeat-style: "npm:^6.0.1" - postcss-normalize-string: "npm:^6.0.1" - postcss-normalize-timing-functions: "npm:^6.0.1" - postcss-normalize-unicode: "npm:^6.0.2" - postcss-normalize-url: "npm:^6.0.1" - postcss-normalize-whitespace: "npm:^6.0.1" - postcss-ordered-values: "npm:^6.0.1" - postcss-reduce-initial: "npm:^6.0.2" - postcss-reduce-transforms: "npm:^6.0.1" - postcss-svgo: "npm:^6.0.2" - postcss-unique-selectors: "npm:^6.0.2" +"cssnano-preset-default@npm:^7.0.1": + version: 7.0.1 + resolution: "cssnano-preset-default@npm:7.0.1" + dependencies: + browserslist: "npm:^4.23.0" + css-declaration-sorter: "npm:^7.2.0" + cssnano-utils: "npm:^5.0.0" + postcss-calc: "npm:^10.0.0" + postcss-colormin: "npm:^7.0.0" + postcss-convert-values: "npm:^7.0.0" + postcss-discard-comments: "npm:^7.0.0" + postcss-discard-duplicates: "npm:^7.0.0" + postcss-discard-empty: "npm:^7.0.0" + postcss-discard-overridden: "npm:^7.0.0" + postcss-merge-longhand: "npm:^7.0.0" + postcss-merge-rules: "npm:^7.0.0" + postcss-minify-font-values: "npm:^7.0.0" + postcss-minify-gradients: "npm:^7.0.0" + postcss-minify-params: "npm:^7.0.0" + postcss-minify-selectors: "npm:^7.0.0" + postcss-normalize-charset: "npm:^7.0.0" + postcss-normalize-display-values: "npm:^7.0.0" + postcss-normalize-positions: "npm:^7.0.0" + postcss-normalize-repeat-style: "npm:^7.0.0" + postcss-normalize-string: "npm:^7.0.0" + postcss-normalize-timing-functions: "npm:^7.0.0" + postcss-normalize-unicode: "npm:^7.0.0" + postcss-normalize-url: "npm:^7.0.0" + postcss-normalize-whitespace: "npm:^7.0.0" + postcss-ordered-values: "npm:^7.0.0" + postcss-reduce-initial: "npm:^7.0.0" + postcss-reduce-transforms: "npm:^7.0.0" + postcss-svgo: "npm:^7.0.0" + postcss-unique-selectors: "npm:^7.0.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/d100a1f8ab71adbb6df85e00f4a9e5d04ac06fc50343157eef853aded3f75dd0489dd845a5b2fb43ca701bd88c39c5aa88673f842bc1f94f4318c7b38ced1963 + checksum: 10c0/bee65239d25de2ba87e85b4091cbc1cac9ba1b57c9f803dff5a71ea8a55a885045805840dd732be284c28cca6343dece37fc76d7096aba37cfa02eff2ee7714c languageName: node linkType: hard -"cssnano-utils@npm:^4.0.1": - version: 4.0.1 - resolution: "cssnano-utils@npm:4.0.1" +"cssnano-utils@npm:^5.0.0": + version: 5.0.0 + resolution: "cssnano-utils@npm:5.0.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/20513a393402f283c85c450ece43d1a6a06a9906b524481043ac203a86888a4ca5cbef878c615a58fdd82a9e870ce62c6f3fea9f51814034a084d8980e17cf96 + checksum: 10c0/492593fb45151e8622357bb958d0d80475372de38523ef0587d77e9c5f386beb55c30b41f2f3c735a374a230bc61404eb7ae9c2beeab0666afb499442c62ecba languageName: node linkType: hard -"cssnano@npm:^6.0.3": - version: 6.0.3 - resolution: "cssnano@npm:6.0.3" +"cssnano@npm:^7.0.1": + version: 7.0.1 + resolution: "cssnano@npm:7.0.1" dependencies: - cssnano-preset-default: "npm:^6.0.3" - lilconfig: "npm:^3.0.0" + cssnano-preset-default: "npm:^7.0.1" + lilconfig: "npm:^3.1.1" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/d1669eb987fd96159bae262ef2f76c1a64fffefe8fa593918a6bda377977798b60fb4a6a871a9b9a9deb11258130ee254fdb8c3144769b3060ad9f2a95a4ed0a + checksum: 10c0/8b17d13efe98ec2db2fbde9ca24e91842b9afe2f80becc5e4271ee1170d77cf73eed3cdc2f35ed51bacdeac763ff85db45ae8e9627a8862bf01d457a819a640e languageName: node linkType: hard @@ -4375,7 +4376,7 @@ __metadata: babel-loader: "npm:9.1.3" clean-webpack-plugin: "npm:4.0.0" css-loader: "npm:7.1.1" - css-minimizer-webpack-plugin: "npm:6.0.0" + css-minimizer-webpack-plugin: "npm:7.0.0" eslint: "npm:9.2.0" eslint-config-prettier: "npm:9.1.0" eslint-formatter-checkstyle: "npm:8.40.0" @@ -4595,10 +4596,10 @@ __metadata: languageName: node linkType: hard -"lilconfig@npm:^3.0.0": - version: 3.0.0 - resolution: "lilconfig@npm:3.0.0" - checksum: 10c0/7f5ee7a658dc016cacf146815e8d88b06f06f4402823b8b0934e305a57a197f55ccc9c5cd4fb5ea1b2b821c8ccaf2d54abd59602a4931af06eabda332388d3e6 +"lilconfig@npm:^3.1.1": + version: 3.1.1 + resolution: "lilconfig@npm:3.1.1" + checksum: 10c0/311b559794546894e3fe176663427326026c1c644145be9e8041c58e268aa9328799b8dfe7e4dd8c6a4ae305feae95a1c9e007db3569f35b42b6e1bc8274754c languageName: node linkType: hard @@ -5306,15 +5307,15 @@ __metadata: languageName: node linkType: hard -"postcss-calc@npm:^9.0.1": - version: 9.0.1 - resolution: "postcss-calc@npm:9.0.1" +"postcss-calc@npm:^10.0.0": + version: 10.0.0 + resolution: "postcss-calc@npm:10.0.0" dependencies: - postcss-selector-parser: "npm:^6.0.11" + postcss-selector-parser: "npm:^6.0.16" postcss-value-parser: "npm:^4.2.0" peerDependencies: - postcss: ^8.2.2 - checksum: 10c0/e0df07337162dbcaac5d6e030c7fd289e21da8766a9daca5d6b2b3c8094bb524ae5d74c70048ea7fe5fe4960ce048c60ac97922d917c3bbff34f58e9d2b0eb0e + postcss: ^8.4.38 + checksum: 10c0/d4d529f2f71b49f17441eed74a7564ccd2779c72ed8648d4bb2530261a27c0ca01fe6a07260e7bf57e55f46dd68dea07e52fd1a6b538db7bc13015124be258a5 languageName: node linkType: hard @@ -5368,29 +5369,29 @@ __metadata: languageName: node linkType: hard -"postcss-colormin@npm:^6.0.2": - version: 6.0.2 - resolution: "postcss-colormin@npm:6.0.2" +"postcss-colormin@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-colormin@npm:7.0.0" dependencies: - browserslist: "npm:^4.22.2" + browserslist: "npm:^4.23.0" caniuse-api: "npm:^3.0.0" - colord: "npm:^2.9.1" + colord: "npm:^2.9.3" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/229681f9b89ba0909b4c69563837b0c32cc3d1c17ed1b00c33d4abfb0a0ef455124968e4885b5f92c64482e92074cd1958018ec111ed5d118f1e24baeda19c14 + checksum: 10c0/d365a5365e0a94748309d32c7208cd06249bc53eb82cc32c771de4073b109fa8552e58d60dbe84d7e69e68081ed8a01fbf645d38a650e90cb2e13b21043cd796 languageName: node linkType: hard -"postcss-convert-values@npm:^6.0.2": - version: 6.0.2 - resolution: "postcss-convert-values@npm:6.0.2" +"postcss-convert-values@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-convert-values@npm:7.0.0" dependencies: - browserslist: "npm:^4.22.2" + browserslist: "npm:^4.23.0" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/882d0b7839ef07ac8ffbf9cb48db0f610939a3496bd0321c7f23096ead676f13e09ab3d9c20ff3dbe2c887e855826051ca7dffeaffce5068cfdc9aaa573a3842 + checksum: 10c0/5d7cfa06f307e024574a1842016f006691e0c1932352f53a99ce8f2f9930c64c3c1ae17518e9e4e5176630b99f1beaab37bc339bc779fb07dc543670ae66bb21 languageName: node linkType: hard @@ -5448,39 +5449,39 @@ __metadata: languageName: node linkType: hard -"postcss-discard-comments@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-discard-comments@npm:6.0.1" +"postcss-discard-comments@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-discard-comments@npm:7.0.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/5e9128ffb8c005081bb0521f5a23cf090e8513d928ed39935504ffde2e335a62a7e1a749c5c7bc2d03f06a8667900d19dd7eed19dfa4273043b5fd760476260d + checksum: 10c0/7fef7deea85c1e68161f69057be19a3aedd54d23c9b464c9b1531faa7a115f0c96a4f0ee3a560ce300578599dbc8114fe0fb744208b20b9d2fd8df1b4b39c58a languageName: node linkType: hard -"postcss-discard-duplicates@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-discard-duplicates@npm:6.0.1" +"postcss-discard-duplicates@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-discard-duplicates@npm:7.0.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/b9ea10a3c7528bb1630613c11756f809a95da634822d943fa91b28f2a37787e7cdb9ff96deed9776e2c3753d35e42c8afd5074b630930df7b5150573d4beda23 + checksum: 10c0/37d568dc18d47b8b9f0fd6d5115b1faf96c2bf429fc4586508a773533479e18627d6260cad6a3ca7d3bfc2f220fd9448410aee40e07f2ec6c6f96bbe3595dbc8 languageName: node linkType: hard -"postcss-discard-empty@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-discard-empty@npm:6.0.1" +"postcss-discard-empty@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-discard-empty@npm:7.0.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/6b95e588a3e8fb262e56bd313060daf29d7c9d44184bb6c4c5858ae81d6cd2907b15b3e3023b6621d50a67cfc10e6077920ff1e908892b207dee29477376498f + checksum: 10c0/b54fc9ad59a6015f6b82b8c826717a4a2f82b272608f6ae37a0b568f4f6c503f5ac7d13d415853a946a0422cb37b9fe1d5ddcee91fe0c2086001138710600d8b languageName: node linkType: hard -"postcss-discard-overridden@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-discard-overridden@npm:6.0.1" +"postcss-discard-overridden@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-discard-overridden@npm:7.0.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/22f9d56e53b90bc0f8e6d1c24d6da6c7c1a9d757644a128a7a4263a5479aaa8eca4ce3bfe9db10358051635ed40e8778a68c3f1831b7163eae10ced001db4a87 + checksum: 10c0/ca00ed1d4e8793fc780039f235fa2caef123d3aa28cae47cc1472ca03b21386c39fae1f11fbf319dcb94c6bda923824067254c7e20e8b00354b47015dc754658 languageName: node linkType: hard @@ -5595,77 +5596,77 @@ __metadata: languageName: node linkType: hard -"postcss-merge-longhand@npm:^6.0.2": - version: 6.0.2 - resolution: "postcss-merge-longhand@npm:6.0.2" +"postcss-merge-longhand@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-merge-longhand@npm:7.0.0" dependencies: postcss-value-parser: "npm:^4.2.0" - stylehacks: "npm:^6.0.2" + stylehacks: "npm:^7.0.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/2b3fae51bffc5962258d638bc7f415237593b515f369233e023f0eae5b13116297463c04b8c47a7b7af51cba5faaa7f517b653f6123e51935d670d4d4de5a26d + checksum: 10c0/5f814f396a5107dcb5e74c2d4e55ebcd03b9bc2b3619ed7aea63a441854023ce349bc371d30aec1ac33a375139afac02709e7721e055b5e624701ac6576e8a10 languageName: node linkType: hard -"postcss-merge-rules@npm:^6.0.3": - version: 6.0.3 - resolution: "postcss-merge-rules@npm:6.0.3" +"postcss-merge-rules@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-merge-rules@npm:7.0.0" dependencies: - browserslist: "npm:^4.22.2" + browserslist: "npm:^4.23.0" caniuse-api: "npm:^3.0.0" - cssnano-utils: "npm:^4.0.1" - postcss-selector-parser: "npm:^6.0.15" + cssnano-utils: "npm:^5.0.0" + postcss-selector-parser: "npm:^6.0.16" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/c8355db11aa60bedcb1e6535fcd70f6ecec2dadd5c2975d3accf0eedbc92af782ac1f5e91a53866816ce332e4cbf1b94749a9425067935be066bc0c974e30fee + checksum: 10c0/d9cb3a4e55db57aa7ba0bb1caefb82db93c8493d2b3db66091dae9d5794ca04729e660115765ff254d0eb960e4db037f6c5b92562b396b05216888d12acc08e0 languageName: node linkType: hard -"postcss-minify-font-values@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-minify-font-values@npm:6.0.1" +"postcss-minify-font-values@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-minify-font-values@npm:7.0.0" dependencies: postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/15af236245a6d27f1c83c943ef90d144ca043894bbd86f134506a984811a936a06824739984824965c7c3fd5a0ff4ed299f26a33f3b628662aa4fb40d7536fd0 + checksum: 10c0/f8be40099a6986d96b9cd2eb9c32a9c681efc6ecd6504c9ab7e01feb9e688c8b9656dfd7f35aa6de2585a86d607f62152ee81d0175e712e4658d184d25f63d58 languageName: node linkType: hard -"postcss-minify-gradients@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-minify-gradients@npm:6.0.1" +"postcss-minify-gradients@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-minify-gradients@npm:7.0.0" dependencies: - colord: "npm:^2.9.1" - cssnano-utils: "npm:^4.0.1" + colord: "npm:^2.9.3" + cssnano-utils: "npm:^5.0.0" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/e700c3f6dc425072ff739fb18bb71c970599e0d909b326f4a5c84e91cf24c4f1ee78e4d161bd4cdf6e25b7d78f1ad082bb885afdd2a150f9b281520fc6359d5c + checksum: 10c0/15d162192b598242e14def81a62e30cf273ab14f1db702c391e6bdd442c570a1aa76fc326874253a2d67f75b4d4fe73ba4f664e85dbff883f24b7090c340bfad languageName: node linkType: hard -"postcss-minify-params@npm:^6.0.2": - version: 6.0.2 - resolution: "postcss-minify-params@npm:6.0.2" +"postcss-minify-params@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-minify-params@npm:7.0.0" dependencies: - browserslist: "npm:^4.22.2" - cssnano-utils: "npm:^4.0.1" + browserslist: "npm:^4.23.0" + cssnano-utils: "npm:^5.0.0" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/6638460d2be4a2eca8adee8409b70d6c6a19aff8cf93fda1b45c9da627b258b6baaa6acb48f51d26cd287704a235f9c9ae2e4744335b1fd47e163177c33896df + checksum: 10c0/28a7ae313a197aeaff8b3fa1e695a6443b11a74258374a05adee6a1b05f5849ef52037b7a5069d6910614b03b4610acdaf4a76f38b89cb42e813a8cb5ec2fc01 languageName: node linkType: hard -"postcss-minify-selectors@npm:^6.0.2": - version: 6.0.2 - resolution: "postcss-minify-selectors@npm:6.0.2" +"postcss-minify-selectors@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-minify-selectors@npm:7.0.0" dependencies: - postcss-selector-parser: "npm:^6.0.15" + postcss-selector-parser: "npm:^6.0.16" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/5437b586c1237fc442e7e6078d4f23c987efc456366368b07a0da67332b04bd55821cedf0441e73e1209689f63139e272d930508e2963ba6e27c46561a661128 + checksum: 10c0/6baf0ea71b8dfd01bdb5b516d01aa00244c55cad8d9c674358d735cef2a6aca6586dd480d419cc8d3f470e6d2d7d19354592044f19766993caf9800d3d7e0d36 languageName: node linkType: hard @@ -5726,101 +5727,101 @@ __metadata: languageName: node linkType: hard -"postcss-normalize-charset@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-charset@npm:6.0.1" +"postcss-normalize-charset@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-normalize-charset@npm:7.0.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/8c09eedaf8813123875c65ab35120f14a87d6b9e8d6805fa808e3a714a8f868d15123f34f61e2240d89225f2f5c2bdabbcdf6385ce86b2487370d8994a65a857 + checksum: 10c0/06d9c4487a4b0e195133a1fb7a115db7014e49d2567cce73e24c59f473f0e65a1999850a726afb3bdb2d36017a3e5c92ac4fd2a7ecc427da4ff79522765fabdd languageName: node linkType: hard -"postcss-normalize-display-values@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-display-values@npm:6.0.1" +"postcss-normalize-display-values@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-normalize-display-values@npm:7.0.0" dependencies: postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/d08a92c653fb4f2506e029ceb8e3fdae9bc937fb1a7e80ecde759d02f6d15f69211af384d89d8582b160fd129abd9c77c8c64d75379417098ee5a2ba779e33d3 + checksum: 10c0/439524e1d3ed36d6265c05da10540e17aa8605e1b396f71ca4364ab3b8b98ca97763c58c211fb9492662429d43613a7fe7009a8638c84a8db327e572c382272a languageName: node linkType: hard -"postcss-normalize-positions@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-positions@npm:6.0.1" +"postcss-normalize-positions@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-normalize-positions@npm:7.0.0" dependencies: postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/bb0267b13c92791543f5e9f94b119a0540e08aa46f600acd73a692cd38d07d2d2fddb11148a81adb58e3f65671eebb05ea38d2ded48f3202b2582f1199aa848e + checksum: 10c0/428763c937cd178c8ee544cd93a9d1fef667dc9a8700ffe2e61b0beeea7f64f712492b9aeb8a1ef927ab752ec34be7ddeb23d2b50e4bc6eba02b0e58312b27a7 languageName: node linkType: hard -"postcss-normalize-repeat-style@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-repeat-style@npm:6.0.1" +"postcss-normalize-repeat-style@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-normalize-repeat-style@npm:7.0.0" dependencies: postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/f6e943dbbf9341dd6ce2c9fc6820e8ae2a838d1db84f58f75b1e5c1b8b9d6895d17fb30b320e2189b8747f844713ec687540b5b1d52ccd6c9108d6d35328c659 + checksum: 10c0/cf7cd9f355fd26f1c9b0c11a923029ac5ea3020520db5a9778dd19c5ee1f48a1f1f368b4ae75fc6b63cb5761eef72333e486ab0de1537b9cb62d213a8c5576d0 languageName: node linkType: hard -"postcss-normalize-string@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-string@npm:6.0.1" +"postcss-normalize-string@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-normalize-string@npm:7.0.0" dependencies: postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/afcdd69522fc3ebafc349c2ef4b62f1e734ade9b6148fd20f2b841477808ac6cf6e5bfbb533c492fdc6bb2184b84be8ebb800a6ae174c4313f87fb0695088cc0 + checksum: 10c0/8857563f85841ce432bb9a5a9ba129847890b61693adff96d565b69dc2d5456f54dec33f4f6ce5b0abf0a484dbfb0145846d99f988959c5ac875a86a2a180576 languageName: node linkType: hard -"postcss-normalize-timing-functions@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-timing-functions@npm:6.0.1" +"postcss-normalize-timing-functions@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-normalize-timing-functions@npm:7.0.0" dependencies: postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/c1c81d0dcb2f74fbd69cc45b0b6bd6cde390a0c9df602aabbf3eb2149a49da48e808837e811d22a525ffb036e158e63b4b2cf12c94cf28f2c2f6af858876134e + checksum: 10c0/bc5f6999b4c9e28e5be785ef90fe68fd48d44059ecc73ee194c2603260597d685b13a1e1751df9a2cee100fea7abb7e1b1cbcf1a7a428a576961705c9d426788 languageName: node linkType: hard -"postcss-normalize-unicode@npm:^6.0.2": - version: 6.0.2 - resolution: "postcss-normalize-unicode@npm:6.0.2" +"postcss-normalize-unicode@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-normalize-unicode@npm:7.0.0" dependencies: - browserslist: "npm:^4.22.2" + browserslist: "npm:^4.23.0" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/ea696194f65ad31de2a9c022f1946a07c298f04070706d88a20061845e1e052e645c74b5bc785595814db87d14e435f85e968a44855dedc207d8c0b5d43b1aee + checksum: 10c0/f2d6ab0076c006dcf3ed33ba30686f2d29e81a408c66acced22e2c942df6d613697ea786137833dd258aafab5fda4d3eb27df13a82df830357dbad9b79154881 languageName: node linkType: hard -"postcss-normalize-url@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-url@npm:6.0.1" +"postcss-normalize-url@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-normalize-url@npm:7.0.0" dependencies: postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/4e3e713a95e01f263feccd041b2b10016a0a09e494c81567f012d1326d9b2d57dc4a68956a820313630370c0ef591bdbb37cc96ed259022559623be179aad436 + checksum: 10c0/3050e228be48fe0121d1316c267e629b232e8401a547128d142c3dea55eeae1e232c9beeea5c76439009188993b14925c5cf40e3a44856d076a7b8fcf4721f86 languageName: node linkType: hard -"postcss-normalize-whitespace@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-whitespace@npm:6.0.1" +"postcss-normalize-whitespace@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-normalize-whitespace@npm:7.0.0" dependencies: postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/259c0b7653f033ed14303602a30e458c37dc63ee55f47226b6379a6ea553ca7c9b971d49715b8f3f36a3a06927f6f87d7997c027ad4664af3bca37a5fe30352e + checksum: 10c0/8d61234962a4850fc61292592171e1d13de2e90d96a2eaed8c85672a05caceda02a3bd1cb495cb72414741f99d50083362df14923efaca1b3e09657d24cea34b languageName: node linkType: hard @@ -5833,15 +5834,15 @@ __metadata: languageName: node linkType: hard -"postcss-ordered-values@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-ordered-values@npm:6.0.1" +"postcss-ordered-values@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-ordered-values@npm:7.0.0" dependencies: - cssnano-utils: "npm:^4.0.1" + cssnano-utils: "npm:^5.0.0" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/2e71f035c90b26d7a8d31e1b716f977532367f75bc76de3318b6ba7b2e1ec43c011cc09e741f59f7d93dff427b7d90a35db0b460d2f171a6f0c6e8c938ef30ad + checksum: 10c0/42b14f9518b573318594c2aeb2f13fd1fbe44936d14f1b28a438e7a82644ace9a2946699bebfe7a2d383534dc24e7203c35308d749f3c585a86daa238ad920a4 languageName: node linkType: hard @@ -5957,26 +5958,26 @@ __metadata: languageName: node linkType: hard -"postcss-reduce-initial@npm:^6.0.2": - version: 6.0.2 - resolution: "postcss-reduce-initial@npm:6.0.2" +"postcss-reduce-initial@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-reduce-initial@npm:7.0.0" dependencies: - browserslist: "npm:^4.22.2" + browserslist: "npm:^4.23.0" caniuse-api: "npm:^3.0.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/d35ad6f9725cdceb390a97a461e8594df7fbed4c55497c90d07c42f8343bf80139e720eaebc580bf480bf10e92959490aa308af66d8802ba71c327bdf08c93a1 + checksum: 10c0/ed50cd680ce258df953b82ce9b3fb52564d08548724577810800e236d017d80430cbccb4b1ad38b0f4d521663598e44ab93136b20064231181ef49e1e113ae10 languageName: node linkType: hard -"postcss-reduce-transforms@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-reduce-transforms@npm:6.0.1" +"postcss-reduce-transforms@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-reduce-transforms@npm:7.0.0" dependencies: postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/de7631302311071d86622166539162e69df506785e3674afab0602c86ed9aa67799e44405b40327f0011d58089d2dc4e2ae481b21812177818e28f9272d350a5 + checksum: 10c0/b2d4b65e71d38b604b41937850d1d64794964d6eced90f05891cfae8a78c7a9fed49911f51da9dcc5d715ac18e8bc7eacf691f2c5321dfe4d781f3e4442dfea9 languageName: node linkType: hard @@ -6025,7 +6026,7 @@ __metadata: languageName: node linkType: hard -"postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.0.13, postcss-selector-parser@npm:^6.0.15, postcss-selector-parser@npm:^6.0.16, postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4": +"postcss-selector-parser@npm:^6.0.13, postcss-selector-parser@npm:^6.0.16, postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4": version: 6.0.16 resolution: "postcss-selector-parser@npm:6.0.16" dependencies: @@ -6035,26 +6036,26 @@ __metadata: languageName: node linkType: hard -"postcss-svgo@npm:^6.0.2": - version: 6.0.2 - resolution: "postcss-svgo@npm:6.0.2" +"postcss-svgo@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-svgo@npm:7.0.0" dependencies: postcss-value-parser: "npm:^4.2.0" svgo: "npm:^3.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/db607404d09af256c7957a0ace822d651a00a52a1796da603f93ba3f0a095ac7595e1f624b9dc53f362ab10e382845d7873f485980f9c92fcb86256833f5e835 + checksum: 10c0/0e724069b5de83aa2b8f8a4746cb60cb663e0a8bbab0e4ba995649cb0562205af57d1f54b89fb90d8ae04a4b7ac3ac6e3751afffc3cff697cb19f7a36b71b195 languageName: node linkType: hard -"postcss-unique-selectors@npm:^6.0.2": - version: 6.0.2 - resolution: "postcss-unique-selectors@npm:6.0.2" +"postcss-unique-selectors@npm:^7.0.0": + version: 7.0.0 + resolution: "postcss-unique-selectors@npm:7.0.0" dependencies: - postcss-selector-parser: "npm:^6.0.15" + postcss-selector-parser: "npm:^6.0.16" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/a0fe112d1094f90e1bfcfd2174a74b2fd0630a24449e9942923d02956c7d64ea4add5adede53d9efb3f6d40cd388ac150d032a115f6a46b73d5f3d3d26fa1bb7 + checksum: 10c0/33b532ad0e9271c5a379859e18adfdc72986bb538672cc0fbc06295d824f82dba3f7b57264e18a3214901bc5244ff5408d28b530374d24a088507287c7f520ce languageName: node linkType: hard @@ -6610,15 +6611,15 @@ __metadata: languageName: node linkType: hard -"stylehacks@npm:^6.0.2": - version: 6.0.2 - resolution: "stylehacks@npm:6.0.2" +"stylehacks@npm:^7.0.0": + version: 7.0.0 + resolution: "stylehacks@npm:7.0.0" dependencies: - browserslist: "npm:^4.22.2" - postcss-selector-parser: "npm:^6.0.15" + browserslist: "npm:^4.23.0" + postcss-selector-parser: "npm:^6.0.16" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/658cac8b28edcb94d1db67808ab3aaa511cb1b9293594fc95607ee42ac4f57e742d9a1fa3ff5d5849db692971dc2a310e9ac1ed0bd4ea4bc48c80f5a6ef823fc + checksum: 10c0/c1c0231974ab7922af3a535a9cb78bfe84997767da7defe111cc76d7f10c9e139fe8cb0f9d5bea87b0c0cc0166c82a6ec98a3d6242d7e29ef90adceecfd330ae languageName: node linkType: hard From ad571f8dec181369de350432cbdaafcf1d01fa47 Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Sun, 12 May 2024 06:39:20 -0700 Subject: [PATCH 008/449] Clean up file parameter tests (#9260) --- .../java/hudson/model/FileParameterValue.java | 7 -- .../FileParameterValuePersistenceTest.java | 81 +++++++++++++++++++ .../src/test/java/hudson/model/QueueTest.java | 68 ---------------- 3 files changed, 81 insertions(+), 75 deletions(-) create mode 100644 test/src/test/java/hudson/model/FileParameterValuePersistenceTest.java diff --git a/core/src/main/java/hudson/model/FileParameterValue.java b/core/src/main/java/hudson/model/FileParameterValue.java index e9e30e63463b..1d9bade1e31c 100644 --- a/core/src/main/java/hudson/model/FileParameterValue.java +++ b/core/src/main/java/hudson/model/FileParameterValue.java @@ -43,7 +43,6 @@ import jenkins.util.SystemProperties; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemHeaders; -import org.apache.commons.fileupload.disk.DiskFileItem; import org.apache.commons.fileupload.util.FileItemHeadersImpl; import org.apache.commons.io.FilenameUtils; import org.kohsuke.accmod.Restricted; @@ -55,12 +54,6 @@ /** * {@link ParameterValue} for {@link FileParameterDefinition}. * - *

Persistence

- *

- * {@link DiskFileItem} is persistable via serialization, - * (although the data may get very large in XML) so this object - * as a whole is persistable. - * * @author Kohsuke Kawaguchi */ public class FileParameterValue extends ParameterValue { diff --git a/test/src/test/java/hudson/model/FileParameterValuePersistenceTest.java b/test/src/test/java/hudson/model/FileParameterValuePersistenceTest.java new file mode 100644 index 000000000000..263e60576510 --- /dev/null +++ b/test/src/test/java/hudson/model/FileParameterValuePersistenceTest.java @@ -0,0 +1,81 @@ +package hudson.model; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import hudson.Functions; +import hudson.tasks.BatchFile; +import hudson.tasks.Shell; +import java.io.File; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import org.htmlunit.html.HtmlForm; +import org.htmlunit.html.HtmlInput; +import org.htmlunit.html.HtmlPage; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.jvnet.hudson.test.Issue; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.JenkinsSessionRule; + +public class FileParameterValuePersistenceTest { + + private static final String FILENAME = "file.txt"; + private static final String CONTENTS = "foobar"; + + @Rule + public JenkinsSessionRule sessions = new JenkinsSessionRule(); + + @Rule + public TemporaryFolder tmp = new TemporaryFolder(); + + @Issue("JENKINS-13536") + @Test + public void fileParameterValuePersistence() throws Throwable { + sessions.then(j -> { + FreeStyleProject p = j.createFreeStyleProject("p"); + p.addProperty(new ParametersDefinitionProperty(new FileParameterDefinition(FILENAME, "The file."))); + p.getBuildersList().add(Functions.isWindows() ? new BatchFile("type " + FILENAME) : new Shell("cat " + FILENAME)); + File test = tmp.newFile(); + Files.writeString(test.toPath(), CONTENTS, StandardCharsets.UTF_8); + try (JenkinsRule.WebClient wc = j.createWebClient()) { + // ParametersDefinitionProperty/index.jelly sends a 405 + wc.setThrowExceptionOnFailingStatusCode(false); + HtmlPage page = wc.goTo("job/" + p.getName() + "/build?delay=0sec"); + assertEquals(405, page.getWebResponse().getStatusCode()); + HtmlForm form = page.getFormByName("parameters"); + HtmlInput input = form.getInputByName("file"); + input.setValue(test.getPath()); + page = j.submit(form); + assertEquals(200, page.getWebResponse().getStatusCode()); + } + FreeStyleBuild b; + while ((b = p.getLastBuild()) == null) { + Thread.sleep(100); + } + j.assertBuildStatusSuccess(j.waitForCompletion(b)); + FileParameterValue fpv = (FileParameterValue) b.getAction(ParametersAction.class).getParameter(FILENAME); + fpv.getFile().delete(); + verifyPersistence(j); + }); + sessions.then(FileParameterValuePersistenceTest::verifyPersistence); + } + + private static void verifyPersistence(JenkinsRule j) throws Throwable { + FreeStyleProject p = j.jenkins.getItemByFullName("p", FreeStyleProject.class); + FreeStyleBuild b = p.getLastBuild(); + j.assertLogContains(CONTENTS, b); + Path saved = b.getRootDir().toPath().resolve("fileParameters").resolve(FILENAME); + assertTrue(Files.isRegularFile(saved)); + assertEquals(CONTENTS, Files.readString(saved, StandardCharsets.UTF_8)); + assertTrue(b.getWorkspace().child(FILENAME).exists()); + try (JenkinsRule.WebClient wc = j.createWebClient()) { + HtmlPage page = wc.goTo(p.getUrl() + "ws"); + assertThat(page.getWebResponse().getContentAsString(), containsString(FILENAME)); + } + } +} diff --git a/test/src/test/java/hudson/model/QueueTest.java b/test/src/test/java/hudson/model/QueueTest.java index 878b04e28df9..fa76fd88ae0d 100644 --- a/test/src/test/java/hudson/model/QueueTest.java +++ b/test/src/test/java/hudson/model/QueueTest.java @@ -78,7 +78,6 @@ import hudson.triggers.SCMTrigger.SCMTriggerCause; import hudson.triggers.TimerTrigger.TimerTriggerCause; import hudson.util.OneShotEvent; -import hudson.util.XStream2; import java.io.File; import java.io.IOException; import java.io.UncheckedIOException; @@ -103,30 +102,17 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import jenkins.model.BlockedBecauseOfBuildInProgress; import jenkins.model.Jenkins; import jenkins.model.queue.QueueIdStrategy; import jenkins.security.QueueItemAuthenticatorConfiguration; import org.acegisecurity.acls.sid.PrincipalSid; -import org.apache.commons.fileupload.FileUploadException; -import org.apache.commons.fileupload.disk.DiskFileItemFactory; -import org.apache.commons.fileupload.servlet.ServletFileUpload; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.servlet.ServletHandler; -import org.eclipse.jetty.servlet.ServletHolder; import org.htmlunit.HttpMethod; import org.htmlunit.Page; import org.htmlunit.ScriptResult; import org.htmlunit.WebRequest; import org.htmlunit.html.DomElement; import org.htmlunit.html.DomNode; -import org.htmlunit.html.HtmlFileInput; -import org.htmlunit.html.HtmlForm; -import org.htmlunit.html.HtmlFormUtil; import org.htmlunit.html.HtmlPage; import org.htmlunit.xml.XmlPage; import org.junit.Assert; @@ -294,60 +280,6 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListen r.assertBuildStatusSuccess(r.waitForCompletion(b1)); } - public static final class FileItemPersistenceTestServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - - @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { - resp.setContentType("text/html"); - resp.getWriter().println( - "

" + - "" + - "
" - ); - } - - @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException { - try { - ServletFileUpload f = new ServletFileUpload(new DiskFileItemFactory()); - List v = f.parseRequest(req); - assertEquals(1, v.size()); - XStream2 xs = new XStream2(); - System.out.println(xs.toXML(v.get(0))); - } catch (FileUploadException e) { - throw new ServletException(e); - } - } - } - - @Test public void fileItemPersistence() throws Exception { - // TODO: write a synchronous connector? - byte[] testData = new byte[1024]; - for (int i = 0; i < testData.length; i++) testData[i] = (byte) i; - - - Server server = new Server(); - ServerConnector connector = new ServerConnector(server); - server.addConnector(connector); - - ServletHandler handler = new ServletHandler(); - handler.addServletWithMapping(new ServletHolder(new FileItemPersistenceTestServlet()), "/"); - server.setHandler(handler); - - server.start(); - - try { - JenkinsRule.WebClient wc = r.createWebClient(); - @SuppressWarnings("deprecation") - HtmlPage p = (HtmlPage) wc.getPage("http://localhost:" + connector.getLocalPort() + '/'); - HtmlForm f = p.getFormByName("main"); - HtmlFileInput input = f.getInputByName("test"); - input.setData(testData); - HtmlFormUtil.submit(f); - } finally { - server.stop(); - } - } - @Issue("JENKINS-33467") @Test public void foldableCauseAction() throws Exception { final OneShotEvent buildStarted = new OneShotEvent(); From e6a5d3e404c1c03ab85390de15a50d1509b3ebef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 12 May 2024 18:16:19 +0100 Subject: [PATCH 009/449] Update Yarn to v4.2.2 (#9262) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Alexander Brandes --- war/package.json | 2 +- war/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/war/package.json b/war/package.json index d7bf475bb21e..de59cc9e2814 100644 --- a/war/package.json +++ b/war/package.json @@ -65,5 +65,5 @@ "defaults", "not IE 11" ], - "packageManager": "yarn@4.2.1" + "packageManager": "yarn@4.2.2" } diff --git a/war/pom.xml b/war/pom.xml index 3f5ee316b0ee..bb6a4d965f53 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -51,8 +51,8 @@ THE SOFTWARE. 1.22.19 - 4.2.1 - 15ce76682a8cd2090257b883cd69c637925b29573f9573e8403ec227d5ab6815 + 4.2.2 + 1aa43a5304405be7a7cb9cb5de7b97de9c4e8ddd3273e4dad00d6ae3eb39f0ef From 6130d2f398836feed755b14cc67d7d24c707907a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 12 May 2024 18:16:30 +0100 Subject: [PATCH 010/449] Update dependency globals to v15.2.0 (#9264) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- war/package.json | 2 +- war/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/war/package.json b/war/package.json index de59cc9e2814..9f07be28aeb1 100644 --- a/war/package.json +++ b/war/package.json @@ -34,7 +34,7 @@ "eslint": "9.2.0", "eslint-config-prettier": "9.1.0", "eslint-formatter-checkstyle": "8.40.0", - "globals": "15.1.0", + "globals": "15.2.0", "handlebars-loader": "1.7.3", "mini-css-extract-plugin": "2.9.0", "postcss": "8.4.38", diff --git a/war/yarn.lock b/war/yarn.lock index 97cfb92d1118..3cab3eaa9fa6 100644 --- a/war/yarn.lock +++ b/war/yarn.lock @@ -3957,10 +3957,10 @@ __metadata: languageName: node linkType: hard -"globals@npm:15.1.0": - version: 15.1.0 - resolution: "globals@npm:15.1.0" - checksum: 10c0/ae9cd15057dc6a21d6dbafe9f47b66bd063c6d3c9215fa1e8294bd130d89f188c48370a11a9525a5a33bd8689fc4fdfd3f474d930692d7abb7459cd982503336 +"globals@npm:15.2.0": + version: 15.2.0 + resolution: "globals@npm:15.2.0" + checksum: 10c0/ba8c34ef10fc1e65319bfde912a76dbe7654085af8b09d897974cfbe000c6d950ddcf28b4a0de372fe4144836aede32210a97b27ef184f68e1ff8bcd1a74fc5e languageName: node linkType: hard @@ -4380,7 +4380,7 @@ __metadata: eslint: "npm:9.2.0" eslint-config-prettier: "npm:9.1.0" eslint-formatter-checkstyle: "npm:8.40.0" - globals: "npm:15.1.0" + globals: "npm:15.2.0" handlebars: "npm:4.7.8" handlebars-loader: "npm:1.7.3" hotkeys-js: "npm:3.12.2" From b235abaf1435d574c200efd9a5b409190cfd7e1a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 08:18:40 +0100 Subject: [PATCH 011/449] Update dependency node to v20.13.1 (#9267) 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 bb6a4d965f53..be061b083bf1 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -47,7 +47,7 @@ THE SOFTWARE. 8080 2.12.1-101.v85b_e08b_780dd - 20.13.0 + 20.13.1 1.22.19 From 6371bc1b5aa8caa742dbdb45a5ce65b7b83c522b Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Mon, 13 May 2024 11:46:55 -0700 Subject: [PATCH 012/449] Remove unnecessary references in allowed classes list (#9265) --- .../src/main/resources/jenkins/security/whitelisted-classes.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/src/main/resources/jenkins/security/whitelisted-classes.txt b/core/src/main/resources/jenkins/security/whitelisted-classes.txt index c2f974a7ef9f..b1805a6bd387 100644 --- a/core/src/main/resources/jenkins/security/whitelisted-classes.txt +++ b/core/src/main/resources/jenkins/security/whitelisted-classes.txt @@ -133,8 +133,6 @@ java.util.logging.Level java.util.logging.LogRecord java.util.regex.Pattern -org.apache.commons.fileupload.disk.DiskFileItem -org.apache.commons.fileupload.util.FileItemHeadersImpl org.apache.tools.ant.Location # TODO remove when https://github.com/jenkinsci/xtrigger-lib/pull/9 is widely adopted in fstrigger-plugin, urltrigger-plugin, etc. From a751e556c199a9a50188cfb64f4ccf8eb97b12aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 13:50:27 -0700 Subject: [PATCH 013/449] Bump io.jenkins.plugins:design-library from 296.v56576267b_508 to 303.v6b_23c12334c9 (#9269) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[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 7ea028b43b7d..6ab4427927ca 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -329,7 +329,7 @@ THE SOFTWARE. io.jenkins.plugins design-library - 296.v56576267b_508 + 303.v6b_23c12334c9 hpi ${project.build.outputDirectory}/plugins design-library.jpi From 46237384bd58757a985e0949d5a8c7a998b9e256 Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Mon, 13 May 2024 18:08:37 -0700 Subject: [PATCH 014/449] Revert "Remove 'Disable project' button from project view" (#9272) This reverts commit 57d64642be1f6810f964e77f11b7382885d05d0e. --- .../lib/hudson/project/makeDisabled.jelly | 9 +++++++++ test/src/test/java/hudson/model/ProjectTest.java | 14 ++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/core/src/main/resources/lib/hudson/project/makeDisabled.jelly b/core/src/main/resources/lib/hudson/project/makeDisabled.jelly index e53f9ab12ad9..9eb7f4f6571c 100644 --- a/core/src/main/resources/lib/hudson/project/makeDisabled.jelly +++ b/core/src/main/resources/lib/hudson/project/makeDisabled.jelly @@ -41,5 +41,14 @@ THE SOFTWARE. + +
+
+ + + +
+
+
diff --git a/test/src/test/java/hudson/model/ProjectTest.java b/test/src/test/java/hudson/model/ProjectTest.java index e3f2d84493e3..82d9266e0e62 100644 --- a/test/src/test/java/hudson/model/ProjectTest.java +++ b/test/src/test/java/hudson/model/ProjectTest.java @@ -644,13 +644,15 @@ public void testDoDisable() throws Exception { JenkinsRule.WebClient wc = j.createWebClient(); wc.withBasicCredentials(user.getId(), "password"); + HtmlPage p = wc.goTo(project.getUrl()); - HtmlPage p = wc.getPage(project, "configure"); - HtmlForm form = p.getFormByName("config"); - form.getInputByName("enable").click(); - j.submit(form); - - assertTrue("Project should be disabled.", project.isDisabled()); + List forms = p.getForms(); + for (HtmlForm form : forms) { + if ("disable".equals(form.getAttribute("action"))) { + j.submit(form); + } + } + assertTrue("Project should be disabled.", project.isDisabled()); } @Test From 968f8705ee274b4ea8672d456e75f09e091ee6e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 19:53:46 -0700 Subject: [PATCH 015/449] Bump io.jenkins.plugins:ionicons-api from 73.vb_f522f227457 to 74.v93d5eb_813d5f (#9270) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[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 6ab4427927ca..3523fe70d00e 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -78,7 +78,7 @@ THE SOFTWARE. io.jenkins.plugins ionicons-api - 73.vb_f522f227457 + 74.v93d5eb_813d5f io.jenkins.plugins diff --git a/war/pom.xml b/war/pom.xml index be061b083bf1..fd636c87e4f9 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -463,7 +463,7 @@ THE SOFTWARE. io.jenkins.plugins ionicons-api - 73.vb_f522f227457 + 74.v93d5eb_813d5f hpi
From 98103bdccf47bbb927c502d0646a06725a002904 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 21:45:48 -0700 Subject: [PATCH 016/449] Update dependency sass to v1.77.1 (#9273) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- war/package.json | 2 +- war/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/war/package.json b/war/package.json index 9f07be28aeb1..cd548f1d1814 100644 --- a/war/package.json +++ b/war/package.json @@ -42,7 +42,7 @@ "postcss-preset-env": "9.5.11", "postcss-scss": "4.0.9", "prettier": "3.2.5", - "sass": "1.77.0", + "sass": "1.77.1", "sass-loader": "14.2.1", "style-loader": "4.0.0", "stylelint": "16.5.0", diff --git a/war/yarn.lock b/war/yarn.lock index 3cab3eaa9fa6..40af33bad843 100644 --- a/war/yarn.lock +++ b/war/yarn.lock @@ -4392,7 +4392,7 @@ __metadata: postcss-preset-env: "npm:9.5.11" postcss-scss: "npm:4.0.9" prettier: "npm:3.2.5" - sass: "npm:1.77.0" + sass: "npm:1.77.1" sass-loader: "npm:14.2.1" sortablejs: "npm:1.15.2" style-loader: "npm:4.0.0" @@ -6349,16 +6349,16 @@ __metadata: languageName: node linkType: hard -"sass@npm:1.77.0": - version: 1.77.0 - resolution: "sass@npm:1.77.0" +"sass@npm:1.77.1": + version: 1.77.1 + resolution: "sass@npm:1.77.1" dependencies: chokidar: "npm:>=3.0.0 <4.0.0" immutable: "npm:^4.0.0" source-map-js: "npm:>=0.6.2 <2.0.0" bin: sass: sass.js - checksum: 10c0/bce0e5f5b535491e4e775045a79f19cbe10d800ef53b5f7698958d2992505d7b124c968169b05a0190842d8e0a24c2aa6d75dfbdd7c213820d9d59e227009c19 + checksum: 10c0/edcfc7d038234b1198c3ddcac5963fcd1e17a9c1ee0f9bd09784ab5353b60ff50b189b4c9154b34f5da9ca0eaab8b189fd3e83a4b43a494151ad4735f8e5f364 languageName: node linkType: hard From f0d4f26bc87ad99954b7f1f7e54570a0f16e41e6 Mon Sep 17 00:00:00 2001 From: Jenkins Release Bot <66998184+jenkins-release-bot@users.noreply.github.com> Date: Tue, 14 May 2024 13:15:24 +0000 Subject: [PATCH 017/449] [maven-release-plugin] prepare release jenkins-2.458 --- 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/jetty10/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 91fac96bf44b..d0b1bf6dacf6 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.458 jenkins-bom diff --git a/cli/pom.xml b/cli/pom.xml index 14d6323ca762..ff3347d3dbce 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -5,7 +5,7 @@ org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.458 cli diff --git a/core/pom.xml b/core/pom.xml index faef477b9cd2..16a2264d85c4 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -29,7 +29,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.458 jenkins-core diff --git a/coverage/pom.xml b/coverage/pom.xml index fe1e89a120dc..a01a7316c1e0 100644 --- a/coverage/pom.xml +++ b/coverage/pom.xml @@ -5,7 +5,7 @@ org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.458 jenkins-coverage diff --git a/pom.xml b/pom.xml index 46793065ac9e..5ac7db0b3e89 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.458 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.458 https://github.com/jenkinsci/jenkins @@ -75,7 +75,7 @@ THE SOFTWARE. 2.458 -SNAPSHOT - 2024-05-07T14:35:14Z + 2024-05-14T10:34:13Z github diff --git a/test/pom.xml b/test/pom.xml index 3523fe70d00e..21dfd7fc04ac 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.458 jenkins-test diff --git a/war/pom.xml b/war/pom.xml index fd636c87e4f9..f5f313a56582 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.458 jenkins-war diff --git a/websocket/jetty10/pom.xml b/websocket/jetty10/pom.xml index c91e1583c039..2821964882ea 100644 --- a/websocket/jetty10/pom.xml +++ b/websocket/jetty10/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.458 ../.. diff --git a/websocket/spi/pom.xml b/websocket/spi/pom.xml index a99aada6a446..4219bd4624d4 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.458 ../.. From 6fd81b8a9ab429eded73a2fe0d239c40c0419d61 Mon Sep 17 00:00:00 2001 From: Jenkins Release Bot <66998184+jenkins-release-bot@users.noreply.github.com> Date: Tue, 14 May 2024 13:15:47 +0000 Subject: [PATCH 018/449] [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/jetty10/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 d0b1bf6dacf6..91fac96bf44b 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.458 + ${revision}${changelist} jenkins-bom diff --git a/cli/pom.xml b/cli/pom.xml index ff3347d3dbce..14d6323ca762 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -5,7 +5,7 @@ org.jenkins-ci.main jenkins-parent - 2.458 + ${revision}${changelist} cli diff --git a/core/pom.xml b/core/pom.xml index 16a2264d85c4..faef477b9cd2 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -29,7 +29,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.458 + ${revision}${changelist} jenkins-core diff --git a/coverage/pom.xml b/coverage/pom.xml index a01a7316c1e0..fe1e89a120dc 100644 --- a/coverage/pom.xml +++ b/coverage/pom.xml @@ -5,7 +5,7 @@ org.jenkins-ci.main jenkins-parent - 2.458 + ${revision}${changelist} jenkins-coverage diff --git a/pom.xml b/pom.xml index 5ac7db0b3e89..6293399fbd82 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.458 + ${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.458 + ${scmTag} https://github.com/jenkinsci/jenkins @@ -73,9 +73,9 @@ THE SOFTWARE. - 2.458 + 2.459 -SNAPSHOT - 2024-05-14T10:34:13Z + 2024-05-14T13:15:25Z github diff --git a/test/pom.xml b/test/pom.xml index 21dfd7fc04ac..3523fe70d00e 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.458 + ${revision}${changelist} jenkins-test diff --git a/war/pom.xml b/war/pom.xml index f5f313a56582..fd636c87e4f9 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.458 + ${revision}${changelist} jenkins-war diff --git a/websocket/jetty10/pom.xml b/websocket/jetty10/pom.xml index 2821964882ea..c91e1583c039 100644 --- a/websocket/jetty10/pom.xml +++ b/websocket/jetty10/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.458 + ${revision}${changelist} ../.. diff --git a/websocket/spi/pom.xml b/websocket/spi/pom.xml index 4219bd4624d4..a99aada6a446 100644 --- a/websocket/spi/pom.xml +++ b/websocket/spi/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.458 + ${revision}${changelist} ../.. From bcb5ed8f2218208b11b029d023a70bc7c0851418 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 14 May 2024 10:11:54 -0600 Subject: [PATCH 019/449] Update dependency postcss-preset-env to v9.5.12 (#9274) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- war/package.json | 2 +- war/yarn.lock | 66 ++++++++++++++++++++++++------------------------ 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/war/package.json b/war/package.json index cd548f1d1814..8194b247611a 100644 --- a/war/package.json +++ b/war/package.json @@ -39,7 +39,7 @@ "mini-css-extract-plugin": "2.9.0", "postcss": "8.4.38", "postcss-loader": "8.1.1", - "postcss-preset-env": "9.5.11", + "postcss-preset-env": "9.5.12", "postcss-scss": "4.0.9", "prettier": "3.2.5", "sass": "1.77.1", diff --git a/war/yarn.lock b/war/yarn.lock index 40af33bad843..2e5390e52164 100644 --- a/war/yarn.lock +++ b/war/yarn.lock @@ -1432,15 +1432,15 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-cascade-layers@npm:^4.0.4": - version: 4.0.4 - resolution: "@csstools/postcss-cascade-layers@npm:4.0.4" +"@csstools/postcss-cascade-layers@npm:^4.0.5": + version: 4.0.6 + resolution: "@csstools/postcss-cascade-layers@npm:4.0.6" dependencies: - "@csstools/selector-specificity": "npm:^3.0.3" + "@csstools/selector-specificity": "npm:^3.1.1" postcss-selector-parser: "npm:^6.0.13" peerDependencies: postcss: ^8.4 - checksum: 10c0/87fdd1e3d846e45c2e415f24f66076e04c3c4539e8b802f1114b2a0fef9421d562d9eb61464ba3599d73805555ad8e95c51a8827cb3ddacfda01ec0df4afbfe0 + checksum: 10c0/134019e9b3f71de39034658e2a284f549883745a309f774d8d272871f9e65680e0981c893766537a8a56ed7f41dba2d0f9fc3cb4fa4057c227bc193976a2ec79 languageName: node linkType: hard @@ -1564,15 +1564,15 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-is-pseudo-class@npm:^4.0.6": - version: 4.0.6 - resolution: "@csstools/postcss-is-pseudo-class@npm:4.0.6" +"@csstools/postcss-is-pseudo-class@npm:^4.0.7": + version: 4.0.8 + resolution: "@csstools/postcss-is-pseudo-class@npm:4.0.8" dependencies: - "@csstools/selector-specificity": "npm:^3.0.3" + "@csstools/selector-specificity": "npm:^3.1.1" postcss-selector-parser: "npm:^6.0.13" peerDependencies: postcss: ^8.4 - checksum: 10c0/aa071954e08dc9368fbeddbec6a8da2dea3a771b33bad53f67f3bc5a6b2f0a270909948f3e7b29ec885f4cceee245f16388809aeb0620284a1d66ad1f2026f28 + checksum: 10c0/82f191571c3e0973354a54ef15feeb17f9408b4abbefad19fc0f087683b1212fc854cdf09a47324267dd47be4c5cb47d63b8d083695a67c3f8f3e53df3d561f6 languageName: node linkType: hard @@ -1798,12 +1798,12 @@ __metadata: languageName: node linkType: hard -"@csstools/selector-specificity@npm:^3.0.3": - version: 3.0.3 - resolution: "@csstools/selector-specificity@npm:3.0.3" +"@csstools/selector-specificity@npm:^3.0.3, @csstools/selector-specificity@npm:^3.1.1": + version: 3.1.1 + resolution: "@csstools/selector-specificity@npm:3.1.1" peerDependencies: postcss-selector-parser: ^6.0.13 - checksum: 10c0/e4f0355165882ddde8bd4a2f0252868150e67b9fae927fd2d94a91cee31e438e7041059f20b9c755a93b0bd8e527a9f78b01168fe67b3539be32091240aa63bf + checksum: 10c0/1d4a3f8015904d6aeb3203afe0e1f6db09b191d9c1557520e3e960c9204ad852df9db4cbde848643f78a26f6ea09101b4e528dbb9193052db28258dbcc8a6e1d languageName: node linkType: hard @@ -3079,16 +3079,16 @@ __metadata: languageName: node linkType: hard -"css-has-pseudo@npm:^6.0.3": - version: 6.0.3 - resolution: "css-has-pseudo@npm:6.0.3" +"css-has-pseudo@npm:^6.0.4": + version: 6.0.5 + resolution: "css-has-pseudo@npm:6.0.5" dependencies: - "@csstools/selector-specificity": "npm:^3.0.3" + "@csstools/selector-specificity": "npm:^3.1.1" postcss-selector-parser: "npm:^6.0.13" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/bbe663eff5256233c7bcce256cd8de7d93d82f2d4f2ca104af8e39e2159170d67746d3a2954385d03ec4ea7ef2728fe9a7d8cb62c52c0a6df1ad3d3bb1e3439d + checksum: 10c0/946930b7e699d6dbcb8426ebcd593228ee0e2143a148fb2399111ea4c9ed8d6eb3447e944251f1be44ae987d5ab16e450b0b006ca197f318c2a3760ba431fbb9 languageName: node linkType: hard @@ -4389,7 +4389,7 @@ __metadata: mini-css-extract-plugin: "npm:2.9.0" postcss: "npm:8.4.38" postcss-loader: "npm:8.1.1" - postcss-preset-env: "npm:9.5.11" + postcss-preset-env: "npm:9.5.12" postcss-scss: "npm:4.0.9" prettier: "npm:3.2.5" sass: "npm:1.77.1" @@ -5714,16 +5714,16 @@ __metadata: languageName: node linkType: hard -"postcss-nesting@npm:^12.1.2": - version: 12.1.2 - resolution: "postcss-nesting@npm:12.1.2" +"postcss-nesting@npm:^12.1.3": + version: 12.1.4 + resolution: "postcss-nesting@npm:12.1.4" dependencies: "@csstools/selector-resolve-nested": "npm:^1.1.0" - "@csstools/selector-specificity": "npm:^3.0.3" + "@csstools/selector-specificity": "npm:^3.1.1" postcss-selector-parser: "npm:^6.0.13" peerDependencies: postcss: ^8.4 - checksum: 10c0/39d1d100f61863f904393b17169be83cdf82bd50d530efb3e3ae0c7b0f838b254e10e5d12e25119cf31dce9e351a2b770a03f9b2029ff33bef0ec924c0d2f642 + checksum: 10c0/b3408de4c04b58a88a56fa81aeff59b12615c78d4f5a57e09c1ee47e74cff51f8c9cad1684da0059067303cf65b4b688f85f0c5ca8d54af8c4ab998f727ab9fd languageName: node linkType: hard @@ -5877,11 +5877,11 @@ __metadata: languageName: node linkType: hard -"postcss-preset-env@npm:9.5.11": - version: 9.5.11 - resolution: "postcss-preset-env@npm:9.5.11" +"postcss-preset-env@npm:9.5.12": + version: 9.5.12 + resolution: "postcss-preset-env@npm:9.5.12" dependencies: - "@csstools/postcss-cascade-layers": "npm:^4.0.4" + "@csstools/postcss-cascade-layers": "npm:^4.0.5" "@csstools/postcss-color-function": "npm:^3.0.16" "@csstools/postcss-color-mix-function": "npm:^2.0.16" "@csstools/postcss-exponential-functions": "npm:^1.0.7" @@ -5891,7 +5891,7 @@ __metadata: "@csstools/postcss-hwb-function": "npm:^3.0.15" "@csstools/postcss-ic-unit": "npm:^3.0.6" "@csstools/postcss-initial": "npm:^1.0.1" - "@csstools/postcss-is-pseudo-class": "npm:^4.0.6" + "@csstools/postcss-is-pseudo-class": "npm:^4.0.7" "@csstools/postcss-light-dark-function": "npm:^1.0.5" "@csstools/postcss-logical-float-and-clear": "npm:^2.0.1" "@csstools/postcss-logical-overflow": "npm:^1.0.1" @@ -5913,7 +5913,7 @@ __metadata: autoprefixer: "npm:^10.4.19" browserslist: "npm:^4.22.3" css-blank-pseudo: "npm:^6.0.2" - css-has-pseudo: "npm:^6.0.3" + css-has-pseudo: "npm:^6.0.4" css-prefers-color-scheme: "npm:^9.0.1" cssdb: "npm:^8.0.0" postcss-attribute-case-insensitive: "npm:^6.0.3" @@ -5933,7 +5933,7 @@ __metadata: postcss-image-set-function: "npm:^6.0.3" postcss-lab-function: "npm:^6.0.16" postcss-logical: "npm:^7.0.1" - postcss-nesting: "npm:^12.1.2" + postcss-nesting: "npm:^12.1.3" postcss-opacity-percentage: "npm:^2.0.0" postcss-overflow-shorthand: "npm:^5.0.1" postcss-page-break: "npm:^3.0.4" @@ -5943,7 +5943,7 @@ __metadata: postcss-selector-not: "npm:^7.0.2" peerDependencies: postcss: ^8.4 - checksum: 10c0/9460f4ce18cf1af7582d0a1f366151f59b6e9b0c7cbb62e59081dc91da14760a749f59fa52bc190e5e2c8fd531952c647719d19c4740aa1a0ebcb93f075ad931 + checksum: 10c0/3e0276b2061baa396547f9c0090fcb0c6149d3735c7aefa99a8e520701aae0b7265578b59d5e4efa9f5e61659c161e39590a5d63bac49469b99da1c549b63231 languageName: node linkType: hard From 9f8da7addbd937f3e6fe429a41862e8263efcb93 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 10:03:50 -0700 Subject: [PATCH 020/449] Update jenkins/ath Docker tag to v5829 (#9278) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- ath.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ath.sh b/ath.sh index e39c053ef66e..8bde184008c4 100644 --- a/ath.sh +++ b/ath.sh @@ -6,7 +6,7 @@ set -o xtrace cd "$(dirname "$0")" # https://github.com/jenkinsci/acceptance-test-harness/releases -export ATH_VERSION=5814.vdc5d6d484b_40 +export ATH_VERSION=5829.v1ea_976c1636e if [[ $# -eq 0 ]]; then export JDK=17 From 6aadc6298524c86b85db6d072921be140744fdf2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 10:04:43 -0700 Subject: [PATCH 021/449] Bump commons-logging:commons-logging from 1.3.1 to 1.3.2 (#9279) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index 91fac96bf44b..d137e44beb6e 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -340,7 +340,7 @@ THE SOFTWARE. commons-logging commons-logging - 1.3.1 + 1.3.2 provided From 1dea9a19ca16dda3d3ea5285e1be3fabcae851d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 19:51:49 -0600 Subject: [PATCH 022/449] Bump org.springframework:spring-framework-bom from 5.3.34 to 5.3.35 (#9280) Bumps [org.springframework:spring-framework-bom](https://github.com/spring-projects/spring-framework) from 5.3.34 to 5.3.35. - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v5.3.34...v5.3.35) --- updated-dependencies: - dependency-name: org.springframework:spring-framework-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index d137e44beb6e..4d4ae6622938 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -55,7 +55,7 @@ THE SOFTWARE. org.springframework spring-framework-bom - 5.3.34 + 5.3.35 pom import From 24572788ce8b728582aabcaaedffa929ebd4fdcd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 May 2024 08:03:06 +0100 Subject: [PATCH 023/449] Update dependency postcss-preset-env to v9.5.13 (#9282) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- war/package.json | 2 +- war/yarn.lock | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/war/package.json b/war/package.json index 8194b247611a..5e37993906c1 100644 --- a/war/package.json +++ b/war/package.json @@ -39,7 +39,7 @@ "mini-css-extract-plugin": "2.9.0", "postcss": "8.4.38", "postcss-loader": "8.1.1", - "postcss-preset-env": "9.5.12", + "postcss-preset-env": "9.5.13", "postcss-scss": "4.0.9", "prettier": "3.2.5", "sass": "1.77.1", diff --git a/war/yarn.lock b/war/yarn.lock index 2e5390e52164..a0fe9d620215 100644 --- a/war/yarn.lock +++ b/war/yarn.lock @@ -1432,7 +1432,7 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-cascade-layers@npm:^4.0.5": +"@csstools/postcss-cascade-layers@npm:^4.0.6": version: 4.0.6 resolution: "@csstools/postcss-cascade-layers@npm:4.0.6" dependencies: @@ -1564,7 +1564,7 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-is-pseudo-class@npm:^4.0.7": +"@csstools/postcss-is-pseudo-class@npm:^4.0.8": version: 4.0.8 resolution: "@csstools/postcss-is-pseudo-class@npm:4.0.8" dependencies: @@ -3079,7 +3079,7 @@ __metadata: languageName: node linkType: hard -"css-has-pseudo@npm:^6.0.4": +"css-has-pseudo@npm:^6.0.5": version: 6.0.5 resolution: "css-has-pseudo@npm:6.0.5" dependencies: @@ -4389,7 +4389,7 @@ __metadata: mini-css-extract-plugin: "npm:2.9.0" postcss: "npm:8.4.38" postcss-loader: "npm:8.1.1" - postcss-preset-env: "npm:9.5.12" + postcss-preset-env: "npm:9.5.13" postcss-scss: "npm:4.0.9" prettier: "npm:3.2.5" sass: "npm:1.77.1" @@ -5714,7 +5714,7 @@ __metadata: languageName: node linkType: hard -"postcss-nesting@npm:^12.1.3": +"postcss-nesting@npm:^12.1.4": version: 12.1.4 resolution: "postcss-nesting@npm:12.1.4" dependencies: @@ -5877,11 +5877,11 @@ __metadata: languageName: node linkType: hard -"postcss-preset-env@npm:9.5.12": - version: 9.5.12 - resolution: "postcss-preset-env@npm:9.5.12" +"postcss-preset-env@npm:9.5.13": + version: 9.5.13 + resolution: "postcss-preset-env@npm:9.5.13" dependencies: - "@csstools/postcss-cascade-layers": "npm:^4.0.5" + "@csstools/postcss-cascade-layers": "npm:^4.0.6" "@csstools/postcss-color-function": "npm:^3.0.16" "@csstools/postcss-color-mix-function": "npm:^2.0.16" "@csstools/postcss-exponential-functions": "npm:^1.0.7" @@ -5891,7 +5891,7 @@ __metadata: "@csstools/postcss-hwb-function": "npm:^3.0.15" "@csstools/postcss-ic-unit": "npm:^3.0.6" "@csstools/postcss-initial": "npm:^1.0.1" - "@csstools/postcss-is-pseudo-class": "npm:^4.0.7" + "@csstools/postcss-is-pseudo-class": "npm:^4.0.8" "@csstools/postcss-light-dark-function": "npm:^1.0.5" "@csstools/postcss-logical-float-and-clear": "npm:^2.0.1" "@csstools/postcss-logical-overflow": "npm:^1.0.1" @@ -5913,7 +5913,7 @@ __metadata: autoprefixer: "npm:^10.4.19" browserslist: "npm:^4.22.3" css-blank-pseudo: "npm:^6.0.2" - css-has-pseudo: "npm:^6.0.4" + css-has-pseudo: "npm:^6.0.5" css-prefers-color-scheme: "npm:^9.0.1" cssdb: "npm:^8.0.0" postcss-attribute-case-insensitive: "npm:^6.0.3" @@ -5933,7 +5933,7 @@ __metadata: postcss-image-set-function: "npm:^6.0.3" postcss-lab-function: "npm:^6.0.16" postcss-logical: "npm:^7.0.1" - postcss-nesting: "npm:^12.1.3" + postcss-nesting: "npm:^12.1.4" postcss-opacity-percentage: "npm:^2.0.0" postcss-overflow-shorthand: "npm:^5.0.1" postcss-page-break: "npm:^3.0.4" @@ -5943,7 +5943,7 @@ __metadata: postcss-selector-not: "npm:^7.0.2" peerDependencies: postcss: ^8.4 - checksum: 10c0/3e0276b2061baa396547f9c0090fcb0c6149d3735c7aefa99a8e520701aae0b7265578b59d5e4efa9f5e61659c161e39590a5d63bac49469b99da1c549b63231 + checksum: 10c0/5bbb6e87b1b3acc816ef445836f85df5f50ac96bdc3d571952a83794c80863c652d27ab14c66f6b88f86f5664119d49b357e4184162022cc3436676f3fbe833b languageName: node linkType: hard From dabf61f3e27dabe53d3183e97dea349bc2d182a5 Mon Sep 17 00:00:00 2001 From: Kevin Guerroudj <91883215+Kevin-CB@users.noreply.github.com> Date: Fri, 17 May 2024 15:56:10 +0200 Subject: [PATCH 024/449] Clarify artifacts permission description (#9276) clarify artifacts permission --- core/src/main/resources/hudson/model/Messages.properties | 2 +- core/src/main/resources/hudson/model/Messages_fr.properties | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/main/resources/hudson/model/Messages.properties b/core/src/main/resources/hudson/model/Messages.properties index 96950428fee4..2b1a6559fa58 100644 --- a/core/src/main/resources/hudson/model/Messages.properties +++ b/core/src/main/resources/hudson/model/Messages.properties @@ -241,7 +241,7 @@ Run.UpdatePermission.Description=\ Run.ArtifactsPermission.Description=\ This permission grants the ability to retrieve the artifacts produced by \ builds. If you don’t want an user to access the artifacts, you can do so by \ - revoking this permission. + revoking this permission. This does not restrict the listing of artifacts. Run.InProgressDuration={0} and counting Run.NotStartedYet=Not started yet Run.ArtifactsBrowserTitle=Artifacts of {0} {1} diff --git a/core/src/main/resources/hudson/model/Messages_fr.properties b/core/src/main/resources/hudson/model/Messages_fr.properties index 1d64aee184f3..e6794e6fc49e 100644 --- a/core/src/main/resources/hudson/model/Messages_fr.properties +++ b/core/src/main/resources/hudson/model/Messages_fr.properties @@ -231,7 +231,8 @@ Run.UpdatePermission.Description=\ par exemple pour laisser des notes sur la cause d''échec d''un build. Run.ArtifactsPermission.Description=\ Ce droit permet de récupérer les artefacts produits par les builds. \ - Si un utilisateur ne doit pas accéder aux artefacts, vous pouvez l''en empêcher en désactivant ce droit. + Si un utilisateur ne doit pas accéder aux artefacts, vous pouvez l''en empêcher en désactivant ce droit. \ + Ce droit ne limite pas la possibilité de lister les artefacts. Run.InProgressDuration={0} et décompte Run.NotStartedYet=Pas encore commencé Run.ArtifactsBrowserTitle=Artefacts de {0} {1} From 5089ad5e5962d22294d48d57e5cccc68b26c5236 Mon Sep 17 00:00:00 2001 From: Markus Winter Date: Fri, 17 May 2024 17:16:27 +0200 Subject: [PATCH 025/449] [JENKINS-73158] avoid jumping layout due to tooltips (#9263) * [JENKINS-73158] avoid jumping layout due to tooltips The fix for JENKINS-72744 made the tooltip get appended to the parent element. But this can also cause troubles in some cases. To avoid this one can now decide whether the tooltip should be appended to the body (the default) or to the parent. Adjust all locations where a tooltip is displayed inside a widget to append it to the parent. This works well with those tooltips and avoids a jumping layout in the custom-folder-icon and potentially other places. * explicitly append to parent * fix attribute --- .../jenkins/widgets/HistoryPageFilter/queue-items.jelly | 4 ++-- core/src/main/resources/lib/hudson/progressBar.jelly | 1 + core/src/main/resources/lib/hudson/queue.jelly | 4 +++- core/src/main/resources/lib/layout/stopButton.jelly | 4 ++-- war/src/main/js/components/tooltips/index.js | 7 ++++++- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items.jelly b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items.jelly index 74c5535be819..4f51055a7a98 100644 --- a/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items.jelly +++ b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items.jelly @@ -57,8 +57,8 @@ THE SOFTWARE. -
- +
+
diff --git a/core/src/main/resources/lib/hudson/progressBar.jelly b/core/src/main/resources/lib/hudson/progressBar.jelly index b4e230263bcc..5a78ca5876e9 100644 --- a/core/src/main/resources/lib/hudson/progressBar.jelly +++ b/core/src/main/resources/lib/hudson/progressBar.jelly @@ -55,6 +55,7 @@ THE SOFTWARE. app-progress-bar ${attrs.large?'app-progress-bar--large':null} ${attrs.red?'app-progress-bar--error':null} ${attrs.href} ${attrs.tooltip} + true ${attrs.id} ${attrs.tooltipTemplate} diff --git a/core/src/main/resources/lib/hudson/queue.jelly b/core/src/main/resources/lib/hudson/queue.jelly index f36c84a59d65..8a78c2b70b2f 100644 --- a/core/src/main/resources/lib/hudson/queue.jelly +++ b/core/src/main/resources/lib/hudson/queue.jelly @@ -74,7 +74,9 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/lib/layout/stopButton.jelly b/core/src/main/resources/lib/layout/stopButton.jelly index 336184090622..a44675e302dd 100644 --- a/core/src/main/resources/lib/layout/stopButton.jelly +++ b/core/src/main/resources/lib/layout/stopButton.jelly @@ -39,12 +39,12 @@ THE SOFTWARE. - + - + diff --git a/war/src/main/js/components/tooltips/index.js b/war/src/main/js/components/tooltips/index.js index 3521163917cd..443c4179ed14 100644 --- a/war/src/main/js/components/tooltips/index.js +++ b/war/src/main/js/components/tooltips/index.js @@ -5,7 +5,6 @@ const TOOLTIP_BASE = { arrow: false, theme: "tooltip", animation: "tooltip", - appendTo: "parent", }; /** @@ -21,6 +20,10 @@ function registerTooltip(element) { const tooltip = element.getAttribute("tooltip"); const htmlTooltip = element.getAttribute("data-html-tooltip"); + let appendTo = document.body; + if (element.hasAttribute("data-tooltip-append-to-parent")) { + appendTo = "parent"; + } if ( tooltip !== null && tooltip.trim().length > 0 && @@ -40,6 +43,7 @@ function registerTooltip(element) { onHidden(instance) { instance.reference.setAttribute("title", instance.props.content); }, + appendTo: appendTo, }, TOOLTIP_BASE, ), @@ -58,6 +62,7 @@ function registerTooltip(element) { instance.reference.getAttribute("data-tooltip-interactive") === "true"; }, + appendTo: appendTo, }, TOOLTIP_BASE, ), From 90a6ac5c38f33b6674ba78bdfee0a5fe2b757166 Mon Sep 17 00:00:00 2001 From: Markus Winter Date: Sat, 18 May 2024 16:40:17 +0200 Subject: [PATCH 026/449] [JENKINS-73114] avoid conflicts with css classes from bootstrap (#9254) * [JENKINS-73114] avoid conflict of css classes with bootstrap jenkins and bootstrap both have definitions for alert and alert-warning, alert-info, alert-danger. Bootstrap css definitions are included when e.g. the warning-ng plugin is installed and a job is configured to scan for warnings. The css classes from bootstrap are then chosen instead of the ones for Jenkins for things like the admin monitors. To make things umambiguous, add additional classes prefixed with `jenkins-` and make use of them in code. Keep the old definitions for backward compatibility with plugins. Followup changes are needed in plugins (Mostly those that define admin monitors) and the design-library * fix test --- .../message.jelly | 2 +- .../PluginDeprecationMonitor/message.jelly | 2 +- .../PluginUpdateMonitor/message.jelly | 2 +- .../hudson/PluginManager/advanced.jelly | 2 +- .../hudson/PluginManager/installed.jelly | 10 +-- .../hudson/PluginManager/updates.jelly | 16 ++--- .../message.jelly | 2 +- .../HudsonHomeDiskUsageMonitor/message.jelly | 2 +- .../NullIdDescriptorMonitor/message.jelly | 2 +- .../diagnosis/OldDataMonitor/message.jelly | 2 +- .../ReverseProxySetupMonitor/message.jelly | 2 +- .../TooManyJobsButNoView/message.jelly | 2 +- .../logging/LogRecorder/configure.jelly | 2 +- .../logging/LogRecorderManager/all.jelly | 2 +- .../CoreUpdateMonitor/message.jelly | 2 +- .../MonitorMarkedNodeOffline/message.jelly | 2 +- .../AdministrativeMonitorImpl/message.jelly | 2 +- .../SlowTriggerAdminMonitor/message.groovy | 2 +- .../util/AdministrativeError/message.jelly | 2 +- .../util/DoubleLaunchChecker/message.jelly | 2 +- .../diagnosis/HsErrPidList/message.jelly | 2 +- .../message.jelly | 2 +- .../ControllerExecutorsAgents/message.jelly | 2 +- .../ControllerExecutorsNoAgents/message.jelly | 2 +- .../RootUrlNotSetMonitor/message.jelly | 2 +- .../SecurityIsOffMonitor/message.jelly | 2 +- .../authenticate-security-token.jelly | 2 +- .../install/pluginSetupWizard.properties | 6 +- .../install/pluginSetupWizard_fr.properties | 4 +- .../install/pluginSetupWizard_it.properties | 6 +- .../install/pluginSetupWizard_lt.properties | 2 +- .../install/pluginSetupWizard_pl.properties | 4 +- .../pluginSetupWizard_pt_BR.properties | 6 +- .../install/pluginSetupWizard_sr.properties | 4 +- .../pluginSetupWizard_sv_SE.properties | 6 +- .../pluginSetupWizard_zh_CN.properties | 6 +- .../pluginSetupWizard_zh_TW.properties | 6 +- .../resources.css | 17 +++-- .../model/BuiltInNodeMigration/message.jelly | 2 +- .../message.jelly | 2 +- .../jenkins/model/Jenkins/downgrade.jelly | 2 +- .../message.jelly | 2 +- .../message.jelly | 2 +- .../RekeySecretAdminMonitor/message.groovy | 8 +-- .../message.groovy | 2 +- .../UpdateSiteWarningsMonitor/message.groovy | 2 +- .../message.jelly | 2 +- .../message.jelly | 2 +- .../message.jelly | 2 +- .../CSRFAdministrativeMonitor/message.jelly | 2 +- .../test/java/hudson/PluginManagerTest.java | 2 +- .../js/templates/plugin-manager/available.hbs | 8 +-- war/src/main/scss/components/_alert.scss | 71 ++++++++++--------- war/src/main/scss/pages/_manage-jenkins.scss | 39 +++++----- war/src/main/scss/simple-page.scss | 3 +- 55 files changed, 149 insertions(+), 147 deletions(-) diff --git a/core/src/main/resources/hudson/PluginManager/PluginCycleDependenciesMonitor/message.jelly b/core/src/main/resources/hudson/PluginManager/PluginCycleDependenciesMonitor/message.jelly index 5ccac430ecd2..cb20ebf8dfe7 100644 --- a/core/src/main/resources/hudson/PluginManager/PluginCycleDependenciesMonitor/message.jelly +++ b/core/src/main/resources/hudson/PluginManager/PluginCycleDependenciesMonitor/message.jelly @@ -24,7 +24,7 @@ THE SOFTWARE. -
+
${%PluginCycles}
diff --git a/core/src/main/resources/hudson/PluginManager/PluginDeprecationMonitor/message.jelly b/core/src/main/resources/hudson/PluginManager/PluginDeprecationMonitor/message.jelly index 45c4cead0a44..1f5ec400bd3c 100644 --- a/core/src/main/resources/hudson/PluginManager/PluginDeprecationMonitor/message.jelly +++ b/core/src/main/resources/hudson/PluginManager/PluginDeprecationMonitor/message.jelly @@ -24,7 +24,7 @@ THE SOFTWARE. -
+
${%DeprecatedPlugins}
diff --git a/core/src/main/resources/hudson/PluginManager/PluginUpdateMonitor/message.jelly b/core/src/main/resources/hudson/PluginManager/PluginUpdateMonitor/message.jelly index 73182ec483e4..b1f9ba193d49 100644 --- a/core/src/main/resources/hudson/PluginManager/PluginUpdateMonitor/message.jelly +++ b/core/src/main/resources/hudson/PluginManager/PluginUpdateMonitor/message.jelly @@ -24,7 +24,7 @@ THE SOFTWARE. -
+
${%RequiredPluginUpdates}
diff --git a/core/src/main/resources/hudson/PluginManager/advanced.jelly b/core/src/main/resources/hudson/PluginManager/advanced.jelly index 8d0e6abcd22e..81948afa6e80 100644 --- a/core/src/main/resources/hudson/PluginManager/advanced.jelly +++ b/core/src/main/resources/hudson/PluginManager/advanced.jelly @@ -37,7 +37,7 @@ THE SOFTWARE. -
+
${%proxyMovedBlurb(rootURL+"/manage/configure")}
diff --git a/core/src/main/resources/hudson/PluginManager/installed.jelly b/core/src/main/resources/hudson/PluginManager/installed.jelly index c22c9ddeeba1..3c3ee43e0193 100644 --- a/core/src/main/resources/hudson/PluginManager/installed.jelly +++ b/core/src/main/resources/hudson/PluginManager/installed.jelly @@ -54,7 +54,7 @@ THE SOFTWARE. data-is-restart-required="${app.updateCenter.isRestartRequiredForCompletion()}" /> -
${%Warning}: ${%requires.restart}
+
${%Warning}: ${%requires.restart}

${%Build Time Trend}

-
+
+
+ + ${handler.setBuilds(it.builds)} + + + + + + + + + + + + + + + + + +
${%S}${%Build}${%Time Since}${%Duration}${%Agent}
+ +
[${%Build time graph}]
- - -
- - ${handler.setBuilds(it.builds)} - - - - - - - - - - -
${%Build}${%Duration}${%Agent}
-
diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_resources.css b/core/src/main/resources/hudson/model/Job/buildTimeTrend_resources.css index 13efe1c1e375..af8ba3705509 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_resources.css +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_resources.css @@ -1,3 +1,10 @@ -img.build-time-graph { - float: right; +#buildTimeTrend { + display: flex; + gap: 15px; +} + +@media (max-width: 1300px) { + #buildTimeTrend { + flex-direction: column-reverse; + } } diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_resources.js b/core/src/main/resources/hudson/model/Job/buildTimeTrend_resources.js index 8a6cbfd49253..9ea25a3441de 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_resources.js +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_resources.js @@ -2,30 +2,31 @@ * Public method to be called by progressiveRendering's callback */ window.buildTimeTrend_displayBuilds = function (data) { - var p = document.getElementById("trend"); - var isDistributedBuildsEnabled = - "true" === p.getAttribute("data-is-distributed-build-enabled"); - var rootURL = document.head.getAttribute("data-rooturl"); + const p = document.getElementById("trend"); + p.classList.remove("jenkins-hidden"); - for (var x = 0; data.length > x; x++) { - var e = data[x]; - var tr = document.createElement("tr"); + const showAgent = "true" === p.dataset.showAgent; + const rootURL = document.head.getAttribute("data-rooturl"); + + for (let x = 0; data.length > x; x++) { + const e = data[x]; + let tr = document.createElement("tr"); let td = document.createElement("td"); td.setAttribute("data", e.iconColorOrdinal); - - let link = document.createElement("a"); - link.classList.add("build-status-link"); - link.href = e.consoleUrl; - td.appendChild(link); + td.classList.add("jenkins-table__cell--tight", "jenkins-table__icon"); + let div = document.createElement("div"); + div.classList.add("jenkins-table__cell__button-wrapper"); let svg = generateSVGIcon(e.iconName); - link.appendChild(svg); + svg.setAttribute("tooltip", e.iconColorDescription); + div.appendChild(svg); + td.appendChild(div); tr.appendChild(td); td = document.createElement("td"); td.setAttribute("data", e.number); - link = document.createElement("a"); + let link = document.createElement("a"); link.href = e.number + "/"; link.classList.add("model-link", "inside"); link.innerText = escapeHTML(e.displayName); @@ -33,15 +34,20 @@ window.buildTimeTrend_displayBuilds = function (data) { td.appendChild(link); tr.appendChild(td); + td = document.createElement("td"); + td.setAttribute("data", e.timestampString2); + td.textContent = e.timestampString; + tr.appendChild(td); + td = document.createElement("td"); td.setAttribute("data", e.duration); td.innerText = escapeHTML(e.durationString); tr.appendChild(td); - if (isDistributedBuildsEnabled) { - var buildInfo = null; - var buildInfoStr = escapeHTML(e.builtOnStr || ""); + if (showAgent) { + let buildInfo = null; + let buildInfoStr = escapeHTML(e.builtOnStr || ""); if (e.builtOn) { buildInfo = document.createElement("a"); buildInfo.href = rootURL + "/computer/" + e.builtOn; @@ -58,6 +64,19 @@ window.buildTimeTrend_displayBuilds = function (data) { } tr.appendChild(td); } + + let tdConsole = document.createElement("td"); + tdConsole.classList.add("jenkins-table__cell--tight"); + let div2 = document.createElement("div"); + div2.classList.add("jenkins-table__cell__button-wrapper"); + link = document.createElement("a"); + link.classList.add("jenkins-button", "jenkins-button--tertiary"); + link.href = e.consoleUrl; + link.appendChild(generateSVGIcon("console")); + div2.appendChild(link); + tdConsole.appendChild(div2); + tr.appendChild(tdConsole); + p.appendChild(tr); Behaviour.applySubtree(tr); } @@ -132,7 +151,7 @@ window.displayBuilds = function (data) { var div2 = document.createElement("div"); div2.classList.add("jenkins-table__cell__button-wrapper"); var a3 = document.createElement("a"); - a3.classList.add("jenkins-button"); + a3.classList.add("jenkins-button", "jenkins-button--tertiary"); a3.href = e.consoleUrl; a3.innerHTML = p.dataset.consoleOutputIcon; div2.appendChild(a3); diff --git a/test/src/test/java/jenkins/widgets/BuildTimeTrendTest.java b/test/src/test/java/jenkins/widgets/BuildTimeTrendTest.java index cd729ed55668..38823a27a99a 100644 --- a/test/src/test/java/jenkins/widgets/BuildTimeTrendTest.java +++ b/test/src/test/java/jenkins/widgets/BuildTimeTrendTest.java @@ -74,7 +74,7 @@ public void withAbstractJob_OnBuiltInNode() throws Exception { wc.withThrowExceptionOnFailingStatusCode(false); HtmlPage page = wc.getPage(p, "buildTimeTrend"); - HtmlTable table = page.getDocumentElement().querySelector("table[data-is-distributed-build-enabled=false]"); + HtmlTable table = page.getDocumentElement().querySelector("table[data-show-agent=false]"); assertNotNull(table); } @@ -91,7 +91,7 @@ public void withAbstractJob_OnAgentNode() throws Exception { wc.withThrowExceptionOnFailingStatusCode(false); HtmlPage page = wc.getPage(p, "buildTimeTrend"); - DomNodeList anchors = page.getDocumentElement().querySelectorAll("table[data-is-distributed-build-enabled=true] td a"); + DomNodeList anchors = page.getDocumentElement().querySelectorAll("table[data-show-agent=true] td a"); Optional anchor = anchors.stream() .filter(a -> a.getTextContent().equals(agent.getNodeName())) .findFirst(); @@ -115,7 +115,7 @@ public void withAbstractJob_OnBoth() throws Exception { wc.withThrowExceptionOnFailingStatusCode(false); HtmlPage page = wc.getPage(p, "buildTimeTrend"); - DomNodeList anchors = page.getDocumentElement().querySelectorAll("table[data-is-distributed-build-enabled=true] td a"); + DomNodeList anchors = page.getDocumentElement().querySelectorAll("table[data-show-agent=true] td a"); Optional anchor = anchors.stream() .filter(a -> a.getTextContent().equals(agent.getNodeName())) .findFirst(); @@ -123,7 +123,7 @@ public void withAbstractJob_OnBoth() throws Exception { assertTrue(anchor.isPresent()); String builtInNode = hudson.model.Messages.Hudson_Computer_DisplayName(); - DomNodeList tds = page.getDocumentElement().querySelectorAll("table[data-is-distributed-build-enabled=true] td"); + DomNodeList tds = page.getDocumentElement().querySelectorAll("table[data-show-agent=true] td"); Optional td = tds.stream() .filter(t -> t.getTextContent().equals(builtInNode)) .findFirst(); @@ -142,7 +142,7 @@ public void withNonAbstractJob_withoutAgents() throws Exception { wc.withThrowExceptionOnFailingStatusCode(false); HtmlPage page = wc.getPage(p, "buildTimeTrend"); - DomNodeList tds = page.getDocumentElement().querySelectorAll("table[data-is-distributed-build-enabled=false] td"); + DomNodeList tds = page.getDocumentElement().querySelectorAll("table[data-show-agent=false] td"); Optional td = tds.stream() .filter(t -> t.getTextContent().equals("#1")) .findFirst(); @@ -168,7 +168,7 @@ public void withNonAbstractJob_withAgents() throws Exception { wc.withThrowExceptionOnFailingStatusCode(false); HtmlPage page = wc.getPage(p, "buildTimeTrend"); - DomNodeList tds = page.getDocumentElement().querySelectorAll("table[data-is-distributed-build-enabled=true] td"); + DomNodeList tds = page.getDocumentElement().querySelectorAll("table[data-show-agent=false] td"); Optional td = tds.stream() .filter(t -> t.getTextContent().equals("#1")) .findFirst(); From 0255a59b2364d2f838eaa64ee5e0fdb365e486b5 Mon Sep 17 00:00:00 2001 From: Markus Winter Date: Mon, 22 Jul 2024 18:34:15 +0200 Subject: [PATCH 230/449] experimental flag to run Jenkins without YUI (#9489) * experimental flag to run Jenkins without YUI The YUI library is old and no longer maintained. Add a user experimental flag to disable YUI. It's disabled by default. When enabling all the YUI related js libraries and css classes are not loaded. Following PR are required to get Jenkins to not show any errors eventually #7569 Some plugins that use YUI (not complete): credentials ldap global-build-stats build-monitor categorized-view Plugins that make use of makeButton (not complete) credentials (fixed with https://github.com/jenkinsci/credentials-plugin/pull/533) openid acceptance-test-harness * fix typo Co-authored-by: Jan Faracik <43062514+janfaracik@users.noreply.github.com> * add license and restrict class --------- Co-authored-by: Jan Faracik <43062514+janfaracik@users.noreply.github.com> --- .../RemoveYuiUserExperimentalFlag.java | 49 +++++++++++++++++++ .../main/resources/lib/layout/layout.jelly | 47 ++++++++++-------- 2 files changed, 75 insertions(+), 21 deletions(-) create mode 100644 core/src/main/java/jenkins/model/experimentalflags/RemoveYuiUserExperimentalFlag.java diff --git a/core/src/main/java/jenkins/model/experimentalflags/RemoveYuiUserExperimentalFlag.java b/core/src/main/java/jenkins/model/experimentalflags/RemoveYuiUserExperimentalFlag.java new file mode 100644 index 000000000000..e8f8dcc31775 --- /dev/null +++ b/core/src/main/java/jenkins/model/experimentalflags/RemoveYuiUserExperimentalFlag.java @@ -0,0 +1,49 @@ +/* + * The MIT License + * + * Copyright (c) 2024, Markus Winter + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.model.experimentalflags; + +import edu.umd.cs.findbugs.annotations.Nullable; +import hudson.Extension; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +@Extension +@Restricted(NoExternalUse.class) +public class RemoveYuiUserExperimentalFlag extends BooleanUserExperimentalFlag { + public RemoveYuiUserExperimentalFlag() { + super("remove-yui.flag"); + } + + @Override + public String getDisplayName() { + return "Remove YUI"; + } + + @Nullable + @Override + public String getShortDescription() { + return "Remove YUI from all Jenkins UI pages. This will break anything that depends on YUI"; + } +} diff --git a/core/src/main/resources/lib/layout/layout.jelly b/core/src/main/resources/lib/layout/layout.jelly index 21ac81ff18b6..210ca66f855a 100644 --- a/core/src/main/resources/lib/layout/layout.jelly +++ b/core/src/main/resources/lib/layout/layout.jelly @@ -128,31 +128,36 @@ THE SOFTWARE. - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + From ec7578abf32655cf39eea1ae3dad265988287d5a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 10 Aug 2024 11:20:38 -0700 Subject: [PATCH 293/449] Update dependency postcss to v8.4.41 (#9592) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- war/package.json | 2 +- war/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/war/package.json b/war/package.json index 48ab2e839ad7..9e0a75b39f46 100644 --- a/war/package.json +++ b/war/package.json @@ -37,7 +37,7 @@ "globals": "15.9.0", "handlebars-loader": "1.7.3", "mini-css-extract-plugin": "2.9.0", - "postcss": "8.4.40", + "postcss": "8.4.41", "postcss-loader": "8.1.1", "postcss-preset-env": "10.0.0", "postcss-scss": "4.0.9", diff --git a/war/yarn.lock b/war/yarn.lock index 609ea58f7f1e..5ece4c425d1e 100644 --- a/war/yarn.lock +++ b/war/yarn.lock @@ -4473,7 +4473,7 @@ __metadata: jquery: "npm:3.7.1" lodash: "npm:4.17.21" mini-css-extract-plugin: "npm:2.9.0" - postcss: "npm:8.4.40" + postcss: "npm:8.4.41" postcss-loader: "npm:8.1.1" postcss-preset-env: "npm:10.0.0" postcss-scss: "npm:4.0.9" @@ -6153,14 +6153,14 @@ __metadata: languageName: node linkType: hard -"postcss@npm:8.4.40, postcss@npm:^8.4.33, postcss@npm:^8.4.38, postcss@npm:^8.4.40": - version: 8.4.40 - resolution: "postcss@npm:8.4.40" +"postcss@npm:8.4.41, postcss@npm:^8.4.33, postcss@npm:^8.4.38, postcss@npm:^8.4.40": + version: 8.4.41 + resolution: "postcss@npm:8.4.41" dependencies: nanoid: "npm:^3.3.7" picocolors: "npm:^1.0.1" source-map-js: "npm:^1.2.0" - checksum: 10c0/65ed67573e5443beaeb582282ff27a6be7c7fe3b4d9fa15761157616f2b97510cb1c335023c26220b005909f007337026d6e3ff092f25010b484ad484e80ea7f + checksum: 10c0/c1828fc59e7ec1a3bf52b3a42f615dba53c67960ed82a81df6441b485fe43c20aba7f4e7c55425762fd99c594ecabbaaba8cf5b30fd79dfec5b52a9f63a2d690 languageName: node linkType: hard From aeeb5e70f95819e584e082ff8ca9be297ba4e250 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 10 Aug 2024 11:20:47 -0700 Subject: [PATCH 294/449] Update slf4j monorepo to v2.0.16 (#9596) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index b0f3457cbf0a..80dafa99ec43 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -39,7 +39,7 @@ THE SOFTWARE. 2.0.0-M2 - 2.0.15 + 2.0.16 1892.v73465f3d074d 2.4.21 From b349b6be4237657003e0c91d2b68a1e08aaf3507 Mon Sep 17 00:00:00 2001 From: Markus Winter Date: Sat, 10 Aug 2024 22:53:59 +0200 Subject: [PATCH 295/449] [JENKINS-73563] create a jenkins-button instead of a yui button in makeButton (#9511) Co-authored-by: Kevin Guerroudj <91883215+Kevin-CB@users.noreply.github.com> --- .../main/webapp/scripts/hudson-behavior.js | 86 ++++++++++++------- 1 file changed, 54 insertions(+), 32 deletions(-) diff --git a/war/src/main/webapp/scripts/hudson-behavior.js b/war/src/main/webapp/scripts/hudson-behavior.js index 110a09fa199f..60e6167cf6dd 100644 --- a/war/src/main/webapp/scripts/hudson-behavior.js +++ b/war/src/main/webapp/scripts/hudson-behavior.js @@ -903,57 +903,79 @@ function escapeHTML(html) { } /** - * Wraps a diff --git a/war/src/main/js/components/row-selection-controller/index.js b/war/src/main/js/components/row-selection-controller/index.js index d4de91b89de4..31fa374ee2c3 100644 --- a/war/src/main/js/components/row-selection-controller/index.js +++ b/war/src/main/js/components/row-selection-controller/index.js @@ -4,7 +4,10 @@ const rowSelectionControllers = document.querySelectorAll( rowSelectionControllers.forEach((headerCheckbox) => { const table = headerCheckbox.closest(".jenkins-table"); - const tableCheckboxes = table.querySelectorAll("input[type='checkbox']"); + const checkboxClass = headerCheckbox.dataset.checkboxClass; + const tableCheckboxes = table.querySelectorAll( + `input[type='checkbox'].${checkboxClass}`, + ); const moreOptionsButton = table.querySelector( ".jenkins-table__checkbox-options", ); From 15e045f03d652a7e76dc3d68e071119c86fdba6a Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Fri, 30 Aug 2024 09:26:19 -0400 Subject: [PATCH 376/449] Friendlier handling of `DeploymentHandshakeException` from CLI in `-webSocket` mode (#9591) --- cli/src/main/java/hudson/cli/CLI.java | 24 ++++++++++++++++++- .../test/java/hudson/cli/CLIActionTest.java | 17 +++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/cli/src/main/java/hudson/cli/CLI.java b/cli/src/main/java/hudson/cli/CLI.java index 684b01f54981..910331b3ee9a 100644 --- a/cli/src/main/java/hudson/cli/CLI.java +++ b/cli/src/main/java/hudson/cli/CLI.java @@ -32,6 +32,7 @@ import jakarta.websocket.ClientEndpointConfig; import jakarta.websocket.Endpoint; import jakarta.websocket.EndpointConfig; +import jakarta.websocket.HandshakeResponse; import jakarta.websocket.Session; import java.io.DataInputStream; import java.io.File; @@ -64,6 +65,7 @@ import org.glassfish.tyrus.client.ClientManager; import org.glassfish.tyrus.client.ClientProperties; import org.glassfish.tyrus.client.SslEngineConfigurator; +import org.glassfish.tyrus.client.exception.DeploymentHandshakeException; import org.glassfish.tyrus.container.jdk.client.JdkClientContainer; /** @@ -340,13 +342,19 @@ public void onOpen(Session session, EndpointConfig config) {} } class Authenticator extends ClientEndpointConfig.Configurator { + HandshakeResponse hr; @Override public void beforeRequest(Map> headers) { if (factory.authorization != null) { headers.put("Authorization", List.of(factory.authorization)); } } + @Override + public void afterResponse(HandshakeResponse hr) { + this.hr = hr; + } } + var authenticator = new Authenticator(); ClientManager client = ClientManager.createClient(JdkClientContainer.class.getName()); // ~ ContainerProvider.getWebSocketContainer() client.getProperties().put(ClientProperties.REDIRECT_ENABLED, true); // https://tyrus-project.github.io/documentation/1.13.1/index/tyrus-proprietary-config.html#d0e1775 @@ -357,7 +365,21 @@ public void beforeRequest(Map> headers) { sslEngineConfigurator.setHostnameVerifier((s, sslSession) -> true); client.getProperties().put(ClientProperties.SSL_ENGINE_CONFIGURATOR, sslEngineConfigurator); } - Session session = client.connectToServer(new CLIEndpoint(), ClientEndpointConfig.Builder.create().configurator(new Authenticator()).build(), URI.create(url.replaceFirst("^http", "ws") + "cli/ws")); + Session session; + try { + session = client.connectToServer(new CLIEndpoint(), ClientEndpointConfig.Builder.create().configurator(authenticator).build(), URI.create(url.replaceFirst("^http", "ws") + "cli/ws")); + } catch (DeploymentHandshakeException x) { + System.err.println("CLI handshake failed with status code " + x.getHttpStatusCode()); + if (authenticator.hr != null) { + for (var entry : authenticator.hr.getHeaders().entrySet()) { + // org.glassfish.tyrus.core.Utils.parseHeaderValue improperly splits values like Date at commas, so undo that: + System.err.println(entry.getKey() + ": " + String.join(", ", entry.getValue())); + } + // UpgradeResponse.getReasonPhrase is useless since Jetty generates it from the code, + // and the body is not accessible at all. + } + return 15; // compare CLICommand.main + } PlainCLIProtocol.Output out = new PlainCLIProtocol.Output() { @Override public void send(byte[] data) throws IOException { diff --git a/test/src/test/java/hudson/cli/CLIActionTest.java b/test/src/test/java/hudson/cli/CLIActionTest.java index 57086142bfb9..dab7ec8a88ad 100644 --- a/test/src/test/java/hudson/cli/CLIActionTest.java +++ b/test/src/test/java/hudson/cli/CLIActionTest.java @@ -1,5 +1,9 @@ package hudson.cli; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import hudson.Functions; @@ -131,6 +135,19 @@ private void assertExitCode(int code, boolean useApiToken, File jar, String... a assertEquals(code, proc.join()); } + @Test public void authenticationFailed() throws Exception { + j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); + j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy().grant(Jenkins.ADMINISTER).everywhere().toAuthenticated()); + var jar = tmp.newFile("jenkins-cli.jar"); + FileUtils.copyURLToFile(j.jenkins.getJnlpJars("jenkins-cli.jar").getURL(), jar); + var baos = new ByteArrayOutputStream(); + var exitStatus = new Launcher.LocalLauncher(StreamTaskListener.fromStderr()).launch().cmds( + "java", "-jar", jar.getAbsolutePath(), "-s", j.getURL().toString(), "-auth", "user:bogustoken", "who-am-i" + ).stdout(baos).start().join(); + assertThat(baos.toString(), allOf(containsString("status code 401"), containsString("Server: Jetty"))); + assertThat(exitStatus, is(15)); + } + @Issue("JENKINS-41745") @Test public void encodingAndLocale() throws Exception { From 5fe9a448059c5aafd2fa354cdabb12e05b3978e2 Mon Sep 17 00:00:00 2001 From: Allan Burdajewicz Date: Fri, 30 Aug 2024 23:26:27 +1000 Subject: [PATCH 377/449] [JENKINS-73422] Add escape hatch for Authenticated user access to Resource URL (#9644) Co-authored-by: Daniel Beck <1831569+daniel-beck@users.noreply.github.com> --- .../jenkins/security/ResourceDomainRootAction.java | 6 +++++- .../test/java/jenkins/security/ResourceDomainTest.java | 10 +++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/jenkins/security/ResourceDomainRootAction.java b/core/src/main/java/jenkins/security/ResourceDomainRootAction.java index 7955103d6be5..fc18071fade7 100644 --- a/core/src/main/java/jenkins/security/ResourceDomainRootAction.java +++ b/core/src/main/java/jenkins/security/ResourceDomainRootAction.java @@ -117,7 +117,7 @@ public Object getDynamic(String id, StaplerRequest req, StaplerResponse rsp) thr return null; } - if (!ACL.isAnonymous2(Jenkins.getAuthentication2())) { + if (!ALLOW_AUTHENTICATED_USER && !ACL.isAnonymous2(Jenkins.getAuthentication2())) { rsp.sendError(400); return null; } @@ -327,4 +327,8 @@ private static Token decode(String value) { // Not @Restricted because the entire class is @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") public static /* not final for Groovy */ int VALID_FOR_MINUTES = SystemProperties.getInteger(ResourceDomainRootAction.class.getName() + ".validForMinutes", 30); + + /* Escape hatch for a security hardening preventing one of the known ways to elevate arbitrary file read to RCE */ + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static /* not final for Groovy */ boolean ALLOW_AUTHENTICATED_USER = SystemProperties.getBoolean(ResourceDomainRootAction.class.getName() + ".allowAuthenticatedUser", false); } diff --git a/test/src/test/java/jenkins/security/ResourceDomainTest.java b/test/src/test/java/jenkins/security/ResourceDomainTest.java index 42f2a1dbbf78..b8f2d551b094 100644 --- a/test/src/test/java/jenkins/security/ResourceDomainTest.java +++ b/test/src/test/java/jenkins/security/ResourceDomainTest.java @@ -399,7 +399,7 @@ public HttpResponse doDynamic() throws Exception { } @Test - public void authenticatedCannotAccessResourceDomain() throws Exception { + public void authenticatedCannotAccessResourceDomainUnlessAllowedBySystemProperty() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); final MockAuthorizationStrategy authorizationStrategy = new MockAuthorizationStrategy(); authorizationStrategy.grant(Jenkins.ADMINISTER).everywhere().to("admin").grant(Jenkins.READ).everywhere().toEveryone(); @@ -416,5 +416,13 @@ public void authenticatedCannotAccessResourceDomain() throws Exception { try (JenkinsRule.WebClient wc = j.createWebClient().withBasicCredentials("admin")) { assertThat(assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(new URL(resourceUrl))).getStatusCode(), is(400)); } + + ResourceDomainRootAction.ALLOW_AUTHENTICATED_USER = true; + try (JenkinsRule.WebClient wc = j.createWebClient().withBasicApiToken("admin")) { + assertThat(wc.getPage(new URL(resourceUrl)).getWebResponse().getStatusCode(), is(200)); + } + try (JenkinsRule.WebClient wc = j.createWebClient().withBasicCredentials("admin")) { + assertThat(wc.getPage(new URL(resourceUrl)).getWebResponse().getStatusCode(), is(200)); + } } } From 9ac4bf149091afbec0187767153815d6051996c9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 30 Aug 2024 15:44:17 -0700 Subject: [PATCH 378/449] Update dependency com.puppycrawl.tools:checkstyle to v10.18.1 (#9676) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 921d6a9f7009..c3052864caba 100644 --- a/pom.xml +++ b/pom.xml @@ -282,7 +282,7 @@ THE SOFTWARE. com.puppycrawl.tools checkstyle - 10.18.0 + 10.18.1 From 3ccaa256b89c7e3a6c13cc385bda6f5fc74e682b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 30 Aug 2024 15:44:33 -0700 Subject: [PATCH 379/449] Update dependency org.jenkins-ci.main:jenkins-test-harness to v2265 (#9677) 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 21089219623c..2038fd503716 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -178,7 +178,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-test-harness - 2254.vcff7a_d4969e5 + 2265.v3da_49c8134d6 test From c67e2a9ec369d29da332ed578aed4f05450081c5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 31 Aug 2024 10:04:17 +0200 Subject: [PATCH 380/449] Update dependency stylelint to v16.9.0 (#9678) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- war/package.json | 2 +- war/yarn.lock | 36 ++++++++++++++++++------------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/war/package.json b/war/package.json index 0fa3f50d288c..5c62e8cf14f3 100644 --- a/war/package.json +++ b/war/package.json @@ -45,7 +45,7 @@ "sass": "1.77.8", "sass-loader": "16.0.1", "style-loader": "4.0.0", - "stylelint": "16.8.2", + "stylelint": "16.9.0", "stylelint-checkstyle-reporter": "1.0.0", "stylelint-config-standard": "36.0.1", "webpack": "5.94.0", diff --git a/war/yarn.lock b/war/yarn.lock index b9d57852342d..62914daa4472 100644 --- a/war/yarn.lock +++ b/war/yarn.lock @@ -1394,7 +1394,7 @@ __metadata: languageName: node linkType: hard -"@csstools/css-parser-algorithms@npm:^3.0.0, @csstools/css-parser-algorithms@npm:^3.0.1": +"@csstools/css-parser-algorithms@npm:^3.0.1": version: 3.0.1 resolution: "@csstools/css-parser-algorithms@npm:3.0.1" peerDependencies: @@ -1403,14 +1403,14 @@ __metadata: languageName: node linkType: hard -"@csstools/css-tokenizer@npm:^3.0.0, @csstools/css-tokenizer@npm:^3.0.1": +"@csstools/css-tokenizer@npm:^3.0.1": version: 3.0.1 resolution: "@csstools/css-tokenizer@npm:3.0.1" checksum: 10c0/c9ed4373e5731b5375ea9791590081019c04e95f08b46b272977e5e7b8c3d560affc62e82263cb8def1df1e57f0673140e7e16a14a5e7be04e6a234be088d1d3 languageName: node linkType: hard -"@csstools/media-query-list-parser@npm:^3.0.0, @csstools/media-query-list-parser@npm:^3.0.1": +"@csstools/media-query-list-parser@npm:^3.0.1": version: 3.0.1 resolution: "@csstools/media-query-list-parser@npm:3.0.1" peerDependencies: @@ -4402,7 +4402,7 @@ __metadata: sass-loader: "npm:16.0.1" sortablejs: "npm:1.15.2" style-loader: "npm:4.0.0" - stylelint: "npm:16.8.2" + stylelint: "npm:16.9.0" stylelint-checkstyle-reporter: "npm:1.0.0" stylelint-config-standard: "npm:36.0.1" tippy.js: "npm:6.3.7" @@ -4799,7 +4799,7 @@ __metadata: languageName: node linkType: hard -"micromatch@npm:^4.0.4, micromatch@npm:^4.0.7": +"micromatch@npm:^4.0.4, micromatch@npm:^4.0.8": version: 4.0.8 resolution: "micromatch@npm:4.0.8" dependencies: @@ -6662,13 +6662,13 @@ __metadata: languageName: node linkType: hard -"stylelint@npm:16.8.2": - version: 16.8.2 - resolution: "stylelint@npm:16.8.2" +"stylelint@npm:16.9.0": + version: 16.9.0 + resolution: "stylelint@npm:16.9.0" dependencies: - "@csstools/css-parser-algorithms": "npm:^3.0.0" - "@csstools/css-tokenizer": "npm:^3.0.0" - "@csstools/media-query-list-parser": "npm:^3.0.0" + "@csstools/css-parser-algorithms": "npm:^3.0.1" + "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/media-query-list-parser": "npm:^3.0.1" "@csstools/selector-specificity": "npm:^4.0.0" "@dual-bundle/import-meta-resolve": "npm:^4.1.0" balanced-match: "npm:^2.0.0" @@ -6690,7 +6690,7 @@ __metadata: known-css-properties: "npm:^0.34.0" mathml-tag-names: "npm:^2.1.3" meow: "npm:^13.2.0" - micromatch: "npm:^4.0.7" + micromatch: "npm:^4.0.8" normalize-path: "npm:^3.0.0" picocolors: "npm:^1.0.1" postcss: "npm:^8.4.41" @@ -6701,13 +6701,13 @@ __metadata: resolve-from: "npm:^5.0.0" string-width: "npm:^4.2.3" strip-ansi: "npm:^7.1.0" - supports-hyperlinks: "npm:^3.0.0" + supports-hyperlinks: "npm:^3.1.0" svg-tags: "npm:^1.0.0" table: "npm:^6.8.2" write-file-atomic: "npm:^5.0.1" bin: stylelint: bin/stylelint.mjs - checksum: 10c0/898cde9b5d981f249133df709458eebf2af0a525e72410ddfafd76a7308f7da493578b6a909c593cc70061556b9eda1fed4f477385ee615435f0996d9e18d8df + checksum: 10c0/d3ff9c8945c56b04a2fa16ec33d163325496d5db94b6fcb5adf74c76f7f794ac992888273f9a3317652ba8b6195168b2ffff382ca2a667a241e2ace8c9505ae2 languageName: node linkType: hard @@ -6738,13 +6738,13 @@ __metadata: languageName: node linkType: hard -"supports-hyperlinks@npm:^3.0.0": - version: 3.0.0 - resolution: "supports-hyperlinks@npm:3.0.0" +"supports-hyperlinks@npm:^3.1.0": + version: 3.1.0 + resolution: "supports-hyperlinks@npm:3.1.0" dependencies: has-flag: "npm:^4.0.0" supports-color: "npm:^7.0.0" - checksum: 10c0/36aaa55e67645dded8e0f846fd81d7dd05ce82ea81e62347f58d86213577eb627b2b45298656ce7a70e7155e39f071d0d3f83be91e112aed801ebaa8db1ef1d0 + checksum: 10c0/78cc3e17eb27e6846fa355a8ebf343befe36272899cd409e45317a06c1997e95c23ff99d91080a517bd8c96508d4fa456e6ceb338c02ba5d7544277dbec0f10f languageName: node linkType: hard From 9fc6a55698c6b92e7711fc0dde5a863c5db90834 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Sep 2024 15:45:31 +0100 Subject: [PATCH 381/449] Update dependency @babel/cli to v7.25.6 (#9679) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- war/package.json | 2 +- war/yarn.lock | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/war/package.json b/war/package.json index 5c62e8cf14f3..71015ede4105 100644 --- a/war/package.json +++ b/war/package.json @@ -23,7 +23,7 @@ "lint": "yarn lint:js && yarn lint:css" }, "devDependencies": { - "@babel/cli": "7.24.8", + "@babel/cli": "7.25.6", "@babel/core": "7.25.2", "@babel/preset-env": "7.25.4", "@eslint/js": "9.9.1", diff --git a/war/yarn.lock b/war/yarn.lock index 62914daa4472..62ea2de5f6b4 100644 --- a/war/yarn.lock +++ b/war/yarn.lock @@ -22,13 +22,13 @@ __metadata: languageName: node linkType: hard -"@babel/cli@npm:7.24.8": - version: 7.24.8 - resolution: "@babel/cli@npm:7.24.8" +"@babel/cli@npm:7.25.6": + version: 7.25.6 + resolution: "@babel/cli@npm:7.25.6" dependencies: "@jridgewell/trace-mapping": "npm:^0.3.25" "@nicolo-ribaudo/chokidar-2": "npm:2.1.8-no-fsevents.3" - chokidar: "npm:^3.4.0" + chokidar: "npm:^3.6.0" commander: "npm:^6.2.0" convert-source-map: "npm:^2.0.0" fs-readdir-recursive: "npm:^1.1.0" @@ -45,7 +45,7 @@ __metadata: bin: babel: ./bin/babel.js babel-external-helpers: ./bin/babel-external-helpers.js - checksum: 10c0/b7f464ccb00db60aed63d71e980df823900d20c740bc2d9eb36c3abd4b3e2402cc438818382344085ef6603aeea2e6ee19af8f0ecb934966eccf077b87af7c7c + checksum: 10c0/861d3c2ed6c47b25a322c2f6127f56783d8d333fc2d02d3815f86301fe1102eca5f61b8a5c8610a6a2872d1ccfce24fd6d4a91f4f73536e43b8e2f28f9dcf5ed languageName: node linkType: hard @@ -2833,9 +2833,9 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:>=3.0.0 <4.0.0, chokidar@npm:^3.4.0": - version: 3.5.3 - resolution: "chokidar@npm:3.5.3" +"chokidar@npm:>=3.0.0 <4.0.0, chokidar@npm:^3.6.0": + version: 3.6.0 + resolution: "chokidar@npm:3.6.0" dependencies: anymatch: "npm:~3.1.2" braces: "npm:~3.0.2" @@ -2848,7 +2848,7 @@ __metadata: dependenciesMeta: fsevents: optional: true - checksum: 10c0/1076953093e0707c882a92c66c0f56ba6187831aa51bb4de878c1fec59ae611a3bf02898f190efec8e77a086b8df61c2b2a3ea324642a0558bdf8ee6c5dc9ca1 + checksum: 10c0/8361dcd013f2ddbe260eacb1f3cb2f2c6f2b0ad118708a343a5ed8158941a39cb8fb1d272e0f389712e74ee90ce8ba864eece9e0e62b9705cb468a2f6d917462 languageName: node linkType: hard @@ -4375,7 +4375,7 @@ __metadata: version: 0.0.0-use.local resolution: "jenkins-ui@workspace:." dependencies: - "@babel/cli": "npm:7.24.8" + "@babel/cli": "npm:7.25.6" "@babel/core": "npm:7.25.2" "@babel/preset-env": "npm:7.25.4" "@eslint/js": "npm:9.9.1" From 1008dcb1dfe1ce00499ccc4e0b0a5bcd918882da Mon Sep 17 00:00:00 2001 From: Thorsten Scherler Date: Sun, 1 Sep 2024 16:50:49 +0200 Subject: [PATCH 382/449] [JENKINS-73695] BUG: Dashboard shows white space on certain width space >900px (#9667) --- .../resources/lib/hudson/projectView.jelly | 34 ++++++++++--------- war/src/main/scss/abstracts/_theme.scss | 1 + war/src/main/scss/base/_layout-commons.scss | 13 +++++-- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/core/src/main/resources/lib/hudson/projectView.jelly b/core/src/main/resources/lib/hudson/projectView.jelly index de8d4a9316b1..75842abc1e9f 100644 --- a/core/src/main/resources/lib/hudson/projectView.jelly +++ b/core/src/main/resources/lib/hudson/projectView.jelly @@ -67,23 +67,25 @@ THE SOFTWARE.
- - - - - - - - - - - +
+
+ + + + + + + + + + - - - - -
+ + + + + +
diff --git a/war/src/main/scss/abstracts/_theme.scss b/war/src/main/scss/abstracts/_theme.scss index 9004709c76a1..c108634f7c85 100644 --- a/war/src/main/scss/abstracts/_theme.scss +++ b/war/src/main/scss/abstracts/_theme.scss @@ -267,6 +267,7 @@ $semantics: ( --tab-baseline-default-display: none; // Side panel + --side-panel-width: 340px; --panel-header-bg-color: var(--light-grey); --panel-border-color: var(--light-grey); --side-panel-hover-color: var(--panel-border-color); diff --git a/war/src/main/scss/base/_layout-commons.scss b/war/src/main/scss/base/_layout-commons.scss index c42e6dcafe67..ce45451b0add 100644 --- a/war/src/main/scss/base/_layout-commons.scss +++ b/war/src/main/scss/base/_layout-commons.scss @@ -84,7 +84,7 @@ } body.two-column #main-panel { - width: calc(100% - 320px); + width: calc(100% - var(--side-panel-width)); flex: 1; display: block; } @@ -98,7 +98,7 @@ body.full-screen #main-panel { } body.two-column #side-panel { - width: 340px; + width: var(--side-panel-width); } /* stylelint-disable-next-line media-query-no-invalid */ @@ -118,9 +118,16 @@ body.two-column #side-panel { } } +.app-project-status-table { + width: 100%; + overflow-x: auto; +} + @media (width >= 1170px) { body.two-column #main-panel { - width: calc(100% - 370px); + width: calc( + 100% - calc(var(--side-panel-width) + calc(var(--section-padding) * 2)) + ); } } From 3069dded3adabd0d43f3b309dfc51a1205d7ce7e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 13:33:14 -0700 Subject: [PATCH 383/449] Update dependency io.jenkins.plugins:snakeyaml-api to v2.3-123.v13484c65210a_ (#9682) 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 e6b4bf8251b7..621208036302 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -372,7 +372,7 @@ THE SOFTWARE. io.jenkins.plugins snakeyaml-api - 2.2-121.v5a_68b_9300b_d4 + 2.3-123.v13484c65210a_ hpi From 4187ee4d2d7ea54a1c2f5b40470a46182817fe81 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 13:33:32 -0700 Subject: [PATCH 384/449] Update dependency io.jenkins.plugins:commons-lang3-api to v3.17.0-84.vb_b_938040b_078 (#9680) 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 2038fd503716..28d74acd4513 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -63,7 +63,7 @@ THE SOFTWARE. io.jenkins.plugins commons-lang3-api - 3.16.0-82.ve2b_07d659d95 + 3.17.0-84.vb_b_938040b_078 diff --git a/war/pom.xml b/war/pom.xml index 621208036302..9045cdc38056 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -502,7 +502,7 @@ THE SOFTWARE. io.jenkins.plugins commons-lang3-api - 3.16.0-82.ve2b_07d659d95 + 3.17.0-84.vb_b_938040b_078 hpi From 4e9b6d8a3dd93aa57c7d0e9464006e2eadc125fc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 13:34:16 -0700 Subject: [PATCH 385/449] Update dependency org.jenkins-ci.plugins:script-security to v1358 (#9685) 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 28d74acd4513..229c19fe390e 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -118,7 +118,7 @@ THE SOFTWARE. org.jenkins-ci.plugins script-security - 1354.va_70a_fe478c7f + 1358.vb_26663c13537 org.jenkins-ci.plugins.workflow diff --git a/war/pom.xml b/war/pom.xml index 9045cdc38056..3772fa834be2 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -300,7 +300,7 @@ THE SOFTWARE. org.jenkins-ci.plugins script-security - 1354.va_70a_fe478c7f + 1358.vb_26663c13537 hpi From 7006cded64f63f788ae91dd7b7587a4a39e70273 Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Tue, 3 Sep 2024 14:59:04 -0700 Subject: [PATCH 386/449] [JENKINS-73278] Migrate core from EE 8 to EE 9 (#9672) Co-authored-by: Kevin Guerroudj <91883215+Kevin-CB@users.noreply.github.com> Co-authored-by: Daniel Beck <1831569+daniel-beck@users.noreply.github.com> --- .github/renovate.json | 11 - .idea/encodings.xml | 9 +- bom/pom.xml | 14 +- core/pom.xml | 20 +- .../java/hudson/DescriptorExtensionList.java | 2 +- .../main/java/hudson/ExpressionFactory2.java | 4 +- core/src/main/java/hudson/FilePath.java | 2 +- core/src/main/java/hudson/Functions.java | 166 ++++++++++--- .../main/java/hudson/LocalPluginManager.java | 15 +- core/src/main/java/hudson/Plugin.java | 66 +++++- core/src/main/java/hudson/PluginManager.java | 91 ++++++-- core/src/main/java/hudson/PluginWrapper.java | 6 +- .../hudson/ProxyConfigurationManager.java | 4 +- .../java/hudson/ResponseHeaderFilter.java | 16 +- core/src/main/java/hudson/Util.java | 14 +- core/src/main/java/hudson/WebAppMain.java | 22 +- core/src/main/java/hudson/cli/CLIAction.java | 16 +- .../java/hudson/cli/CliCrumbExclusion.java | 8 +- .../cli/ReloadConfigurationCommand.java | 2 +- .../java/hudson/cli/UpdateNodeCommand.java | 2 +- .../hudson/console/AnnotatedLargeText.java | 61 ++++- .../console/ConsoleAnnotationDescriptor.java | 10 +- .../console/ConsoleAnnotatorFactory.java | 10 +- .../java/hudson/console/HyperlinkNote.java | 4 +- .../java/hudson/diagnosis/OldDataMonitor.java | 12 +- .../diagnosis/ReverseProxySetupMonitor.java | 4 +- .../diagnosis/TooManyJobsButNoView.java | 6 +- .../hudson/init/impl/GroovyInitScript.java | 2 +- .../impl/InstallUncaughtExceptionHandler.java | 18 +- .../lifecycle/WindowsInstallerLink.java | 16 +- .../main/java/hudson/logging/LogRecorder.java | 12 +- .../hudson/logging/LogRecorderManager.java | 12 +- .../java/hudson/markup/MarkupFormatter.java | 25 +- .../main/java/hudson/model/AbstractBuild.java | 13 +- .../main/java/hudson/model/AbstractItem.java | 107 ++++++++- .../hudson/model/AbstractModelObject.java | 53 ++++- .../java/hudson/model/AbstractProject.java | 80 +++++-- .../main/java/hudson/model/Actionable.java | 46 +++- .../hudson/model/AdministrativeMonitor.java | 8 +- core/src/main/java/hudson/model/AllView.java | 28 ++- core/src/main/java/hudson/model/Api.java | 71 +++++- .../model/AutoCompletionCandidates.java | 8 +- .../src/main/java/hudson/model/BallColor.java | 2 +- .../model/BooleanParameterDefinition.java | 4 +- .../hudson/model/BuildAuthorizationToken.java | 32 ++- .../hudson/model/BuildTimelineWidget.java | 20 +- .../model/ChoiceParameterDefinition.java | 6 +- core/src/main/java/hudson/model/Computer.java | 34 +-- .../main/java/hudson/model/ComputerSet.java | 20 +- .../main/java/hudson/model/Descriptor.java | 157 ++++++++++--- .../hudson/model/DirectlyModifiableView.java | 2 +- .../hudson/model/DirectoryBrowserSupport.java | 23 +- core/src/main/java/hudson/model/Executor.java | 3 +- core/src/main/java/hudson/model/Failure.java | 10 +- .../hudson/model/FileParameterDefinition.java | 8 +- .../java/hudson/model/FileParameterValue.java | 8 +- core/src/main/java/hudson/model/Hudson.java | 42 +++- core/src/main/java/hudson/model/Item.java | 4 +- .../java/hudson/model/ItemGroupMixIn.java | 25 +- core/src/main/java/hudson/model/Job.java | 102 ++++++-- .../main/java/hudson/model/JobProperty.java | 22 ++ .../hudson/model/JobPropertyDescriptor.java | 19 ++ core/src/main/java/hudson/model/Label.java | 6 +- core/src/main/java/hudson/model/ListView.java | 39 +++- .../hudson/model/ManageJenkinsAction.java | 8 +- .../hudson/model/ModifiableItemGroup.java | 49 +++- .../hudson/model/MultiStageTimeSeries.java | 8 +- core/src/main/java/hudson/model/MyView.java | 28 ++- .../java/hudson/model/MyViewsProperty.java | 10 +- core/src/main/java/hudson/model/Node.java | 18 ++ .../hudson/model/PaneStatusProperties.java | 6 +- .../hudson/model/ParameterDefinition.java | 58 ++++- .../java/hudson/model/ParameterValue.java | 6 +- .../model/ParametersDefinitionProperty.java | 37 +-- .../model/PasswordParameterDefinition.java | 4 +- core/src/main/java/hudson/model/Project.java | 36 ++- .../src/main/java/hudson/model/ProxyView.java | 37 ++- core/src/main/java/hudson/model/Queue.java | 8 +- core/src/main/java/hudson/model/RSS.java | 57 ++++- .../model/ReconfigurableDescribable.java | 31 ++- core/src/main/java/hudson/model/Run.java | 93 +++++++- .../hudson/model/RunParameterDefinition.java | 6 +- .../model/SimpleParameterDefinition.java | 4 +- core/src/main/java/hudson/model/Slave.java | 14 +- .../java/hudson/model/StockStatusIcon.java | 4 +- .../model/StringParameterDefinition.java | 4 +- .../main/java/hudson/model/TaskAction.java | 14 +- .../hudson/model/TextParameterDefinition.java | 4 +- .../hudson/model/TopLevelItemDescriptor.java | 2 +- .../main/java/hudson/model/UpdateCenter.java | 40 +++- .../java/hudson/model/UsageStatistics.java | 6 +- core/src/main/java/hudson/model/User.java | 20 +- .../main/java/hudson/model/UserProperty.java | 16 ++ core/src/main/java/hudson/model/View.java | 147 ++++++++++-- .../java/hudson/model/ViewDescriptor.java | 6 +- core/src/main/java/hudson/model/ViewJob.java | 30 ++- .../main/java/hudson/model/ViewProperty.java | 16 ++ .../java/hudson/model/labels/LabelAtom.java | 10 +- .../UserPropertyCategoryAccountAction.java | 8 +- .../UserPropertyCategoryAction.java | 8 +- .../java/hudson/scm/AbstractScmTagAction.java | 34 ++- .../java/hudson/scm/RepositoryBrowsers.java | 17 +- core/src/main/java/hudson/scm/SCMS.java | 22 +- core/src/main/java/hudson/search/Search.java | 59 ++++- .../hudson/search/UserSearchProperty.java | 4 +- .../security/AccessDeniedException2.java | 3 +- .../security/AccessDeniedException3.java | 15 +- .../security/AccessDeniedHandlerImpl.java | 8 +- .../AuthenticationProcessingFilter2.java | 10 +- .../security/AuthorizationStrategy.java | 4 +- .../security/BasicAuthenticationFilter.java | 28 +-- .../hudson/security/ChainedServletFilter.java | 19 +- .../security/ContainerAuthentication.java | 4 +- .../security/FederatedLoginService.java | 8 +- .../security/GlobalSecurityConfiguration.java | 12 +- .../HttpSessionContextIntegrationFilter2.java | 12 +- .../HudsonAuthenticationEntryPoint.java | 8 +- .../java/hudson/security/HudsonFilter.java | 19 +- .../security/HudsonPrivateSecurityRealm.java | 63 ++--- .../hudson/security/LegacySecurityRealm.java | 4 +- .../main/java/hudson/security/NoopFilter.java | 15 +- .../security/RememberMeServicesProxy.java | 4 +- .../java/hudson/security/SecurityRealm.java | 106 +++++++-- .../TokenBasedRememberMeServices2.java | 4 +- .../UnwrapSecurityExceptionFilter.java | 14 +- .../hudson/security/csrf/CrumbExclusion.java | 65 +++++- .../hudson/security/csrf/CrumbFilter.java | 20 +- .../hudson/security/csrf/CrumbIssuer.java | 109 ++++++++- .../security/csrf/DefaultCrumbIssuer.java | 9 +- .../csrf/GlobalCrumbIssuerConfiguration.java | 4 +- core/src/main/java/hudson/slaves/Cloud.java | 26 ++- .../EnvironmentVariablesNodeProperty.java | 2 +- .../java/hudson/slaves/NodeDescriptor.java | 8 +- .../main/java/hudson/slaves/NodeProperty.java | 19 ++ .../java/hudson/slaves/SlaveComputer.java | 16 +- .../java/hudson/tasks/ArtifactArchiver.java | 4 +- .../main/java/hudson/tasks/BuildTrigger.java | 4 +- .../main/java/hudson/tasks/Fingerprinter.java | 4 +- core/src/main/java/hudson/tasks/Maven.java | 4 +- core/src/main/java/hudson/tasks/Shell.java | 4 +- .../java/hudson/tools/ToolDescriptor.java | 21 +- .../main/java/hudson/triggers/SCMTrigger.java | 8 +- .../main/java/hudson/util/BootFailure.java | 2 +- .../hudson/util/CharacterEncodingFilter.java | 16 +- .../main/java/hudson/util/ComboBoxModel.java | 8 +- .../java/hudson/util/DescribableList.java | 23 +- .../main/java/hudson/util/DescriptorList.java | 2 +- .../main/java/hudson/util/ErrorObject.java | 10 +- core/src/main/java/hudson/util/FormApply.java | 21 +- .../java/hudson/util/FormFillFailure.java | 12 +- .../main/java/hudson/util/FormValidation.java | 18 +- core/src/main/java/hudson/util/Graph.java | 46 +++- .../main/java/hudson/util/HttpResponses.java | 8 +- .../java/hudson/util/HudsonIsLoading.java | 12 +- .../java/hudson/util/HudsonIsRestarting.java | 12 +- .../main/java/hudson/util/ListBoxModel.java | 37 ++- .../hudson/util/MultipartFormDataParser.java | 50 +++- .../java/hudson/util/PluginServletFilter.java | 69 ++++-- .../java/hudson/util/QueryParameterMap.java | 10 +- .../java/hudson/util/RemotingDiagnostics.java | 6 +- .../views/GlobalDefaultViewConfiguration.java | 4 +- .../java/hudson/views/ListViewColumn.java | 3 +- .../main/java/hudson/views/MyViewsTabBar.java | 4 +- .../main/java/hudson/views/ViewsTabBar.java | 4 +- .../java/hudson/widgets/HistoryWidget.java | 12 +- .../hudson/widgets/RenderOnDemandClosure.java | 12 +- .../java/jenkins/ErrorAttributeFilter.java | 16 +- core/src/main/java/jenkins/I18n.java | 4 +- .../jenkins/JenkinsHttpSessionListener.java | 4 +- .../main/java/jenkins/agents/CloudSet.java | 29 ++- .../java/jenkins/agents/WebSocketAgents.java | 6 +- .../AppearanceGlobalConfiguration.java | 12 +- .../jenkins/console/ConsoleUrlProvider.java | 4 +- ...ConsoleUrlProviderGlobalConfiguration.java | 4 +- .../ControllerExecutorsAgents.java | 6 +- .../ControllerExecutorsNoAgents.java | 6 +- .../diagnostics/SecurityIsOffMonitor.java | 6 +- .../diagnostics/URICheckEncodingMonitor.java | 4 +- .../GlobalFingerprintConfiguration.java | 4 +- .../java/jenkins/install/SetupWizard.java | 31 +-- .../management/AdministrativeMonitorsApi.java | 10 +- .../AdministrativeMonitorsConfiguration.java | 4 +- .../AdministrativeMonitorsDecorator.java | 4 +- .../java/jenkins/management/ShutdownLink.java | 10 +- .../model/ArtifactManagerConfiguration.java | 4 +- .../main/java/jenkins/model/AssetManager.java | 10 +- .../jenkins/model/BuiltInNodeMigration.java | 8 +- .../GlobalBuildDiscarderConfiguration.java | 4 +- .../jenkins/model/GlobalConfiguration.java | 23 +- .../GlobalNodePropertiesConfiguration.java | 4 +- .../model/GlobalPluginConfiguration.java | 6 +- ...balProjectNamingStrategyConfiguration.java | 4 +- .../model/GlobalQuietPeriodConfiguration.java | 4 +- .../GlobalSCMRetryCountConfiguration.java | 4 +- core/src/main/java/jenkins/model/Jenkins.java | 220 ++++++++++++------ .../model/JenkinsLocationConfiguration.java | 6 +- .../model/MasterBuildConfiguration.java | 4 +- .../model/ModelObjectWithChildren.java | 27 ++- .../model/ModelObjectWithContextMenu.java | 53 +++-- .../jenkins/model/OptionalJobProperty.java | 16 +- .../jenkins/model/ParameterizedJobMixIn.java | 76 ++++-- .../jenkins/model/ProjectNamingStrategy.java | 2 +- .../UserExperimentalFlagsProperty.java | 4 +- .../model/item_category/Categories.java | 8 +- .../jenkins/mvn/GlobalSettingsProvider.java | 21 +- .../java/jenkins/mvn/SettingsProvider.java | 18 +- .../AcegiSecurityExceptionFilter.java | 14 +- .../jenkins/security/ApiCrumbExclusion.java | 8 +- .../java/jenkins/security/ApiTokenFilter.java | 2 +- .../jenkins/security/ApiTokenProperty.java | 4 +- .../AuthenticationSuccessHandler.java | 4 +- .../BasicHeaderApiTokenAuthenticator.java | 6 +- .../security/BasicHeaderAuthenticator.java | 46 +++- .../security/BasicHeaderProcessor.java | 19 +- .../BasicHeaderRealPasswordAuthenticator.java | 6 +- .../LastGrantedAuthoritiesProperty.java | 4 +- .../NonSerializableSecurityContext.java | 2 +- .../QueueItemAuthenticatorConfiguration.java | 4 +- .../security/ResourceDomainConfiguration.java | 6 +- .../security/ResourceDomainFilter.java | 6 +- .../security/ResourceDomainRootAction.java | 16 +- .../jenkins/security/SecureRequester.java | 33 ++- .../security/SuspiciousRequestFilter.java | 18 +- .../UpdateSiteWarningsConfiguration.java | 4 +- .../seed/UserSeedSecurityListener.java | 6 +- .../stapler/StaplerDispatchValidator.java | 18 +- .../StaplerFilteredActionListener.java | 12 +- .../StaticRoutingDecisionProvider.java | 2 +- .../security/stapler/WebMethodConstants.java | 12 +- .../slaves/EncryptedSlaveAgentJnlpFile.java | 18 +- .../EnvVarsFilterGlobalConfiguration.java | 4 +- .../telemetry/impl/StaplerDispatches.java | 4 +- .../jenkins/telemetry/impl/UserLanguages.java | 6 +- .../tools/GlobalToolConfiguration.java | 12 +- .../jenkins/util/FullDuplexHttpService.java | 16 +- .../java/jenkins/util/HttpServletFilter.java | 19 +- .../jenkins/util/HttpSessionListener.java | 38 ++- .../jenkins/util/JSONSignatureValidator.java | 4 +- .../main/java/jenkins/util/JenkinsJVM.java | 2 +- .../jenkins/util/ProgressiveRendering.java | 8 +- .../java/jenkins/util/ScriptListener.java | 4 +- .../java/jenkins/util/SystemProperties.java | 6 +- .../jenkins/util/groovy/GroovyHookScript.java | 13 +- .../java/jenkins/websocket/WebSockets.java | 18 +- .../ui/rememberme/RememberMeServices.java | 4 +- .../RememberMeServicesSpringImpl.java | 4 +- .../jenkins/model/Jenkins/_404.jelly | 6 +- .../jenkins/model/Jenkins/_404_simple.jelly | 4 +- .../jenkins/model/Jenkins/oops.jelly | 2 +- core/src/test/java/hudson/FunctionsTest.java | 36 +-- .../hudson/GetLocaleStaticHelpUrlTest.java | 24 +- .../src/test/java/hudson/model/QueueTest.java | 8 +- core/src/test/java/hudson/model/ViewTest.java | 8 +- .../java/hudson/util/FormValidationTest.java | 5 +- .../jenkins/model/JenkinsGetRootUrlTest.java | 28 +-- .../stapler/StaplerSignaturesTest.java | 10 +- pom.xml | 5 +- .../java/hudson/CustomPluginManagerTest.java | 2 +- .../PluginManagerCheckUpdateCenterTest.java | 12 +- .../test/java/hudson/PluginManagerTest.java | 12 +- test/src/test/java/hudson/PluginTest.java | 2 +- .../java/hudson/cli/BuildCommandTest.java | 4 +- test/src/test/java/hudson/cli/CLITest.java | 22 +- .../hudson/diagnosis/OldDataMonitorTest.java | 4 +- test/src/test/java/hudson/model/ApiTest.java | 2 +- .../model/ComputerConfigDotXmlTest.java | 16 +- .../java/hudson/model/DescriptorTest.java | 8 +- .../model/DirectoryBrowserSupportTest.java | 6 +- .../java/hudson/model/JobPropertyTest.java | 6 +- .../test/java/hudson/model/ListViewTest.java | 12 +- .../ParametersDefinitionPropertyTest.java | 8 +- .../test/java/hudson/model/ProjectTest.java | 3 +- .../src/test/java/hudson/model/QueueTest.java | 2 +- .../hudson/model/UpdateCenterCustomTest.java | 6 +- .../hudson/model/UsageStatisticsTest.java | 2 +- .../java/hudson/model/ViewDescriptorTest.java | 4 +- .../java/hudson/model/ViewPropertyTest.java | 4 +- test/src/test/java/hudson/model/ViewTest.java | 10 +- .../pages/SystemConfigurationTestCase.java | 4 +- .../test/java/hudson/security/LoginTest.java | 2 +- .../hudson/security/SecurityRealmTest.java | 4 +- .../TokenBasedRememberMeServices2Test.java | 2 +- .../test/java/hudson/security/WhoAmITest.java | 6 +- .../security/csrf/CrumbExclusionTest.java | 8 +- .../security/csrf/DefaultCrumbIssuerTest.java | 2 +- .../test/java/hudson/slaves/CloudTest.java | 4 +- .../java/hudson/slaves/NodePropertyTest.java | 4 +- .../java/hudson/util/BootFailureTest.java | 12 +- .../java/hudson/util/HudsonIsLoadingTest.java | 4 +- .../hudson/util/HudsonIsRestartingTest.java | 4 +- .../util/RobustReflectionConverterTest.java | 6 +- .../hudson/util/XStream2Security383Test.java | 12 +- .../GlobalDefaultViewConfigurationTest.java | 4 +- .../URICheckEncodingMonitorTest.java | 2 +- .../java/jenkins/install/InstallUtilTest.java | 2 +- .../java/jenkins/model/ContextMenuTest.java | 2 +- .../GlobalSCMRetryCountConfigurationTest.java | 6 +- .../model/ParameterizedJobMixInTest.java | 3 +- .../security/ApiTokenPropertyTest.java | 2 +- ...etJsonInErrorMessageSanitizerHtmlTest.java | 10 +- .../jenkins/security/Security3030Test.java | 54 ++--- .../jenkins/security/Security3135Test.java | 6 +- .../security/SuspiciousRequestFilterTest.java | 2 +- .../seed/UserSeedSecurityListenerTest.java | 4 +- .../CustomRoutingDecisionProviderTest.java | 4 +- .../security/stapler/DoActionFilterTest.java | 36 +-- .../jenkins/security/stapler/DynamicTest.java | 4 +- .../security/stapler/PreventRoutingTest.java | 4 +- .../security/stapler/Security400Test.java | 2 +- .../security/stapler/StaplerAbstractTest.java | 6 +- .../stapler/StaplerDispatchValidatorTest.java | 2 +- .../stapler/StaplerRoutableActionTest.java | 4 +- .../StaticRoutingDecisionProviderTest.java | 18 +- .../security/stapler/TypedFilterTest.java | 10 +- .../java/jenkins/telemetry/TelemetryTest.java | 14 +- .../util/FullDuplexHttpServiceTest.java | 12 +- .../jenkins/util/SystemPropertiesTest.java | 10 +- .../java/lib/form/AdvancedButtonTest.java | 4 +- .../test/java/lib/form/BooleanRadioTest.java | 4 +- .../test/java/lib/form/DropdownListTest.java | 4 +- test/src/test/java/lib/form/EnumSetTest.java | 4 +- test/src/test/java/lib/form/EnumTest.java | 4 +- .../java/lib/form/ExpandableTextboxTest.java | 4 +- test/src/test/java/lib/form/NameRefTest.java | 4 +- test/src/test/java/lib/form/PasswordTest.java | 4 +- .../test/java/lib/form/RepeatableTest.java | 4 +- test/src/test/java/lib/form/RowSetTest.java | 4 +- .../java/lib/form/RowVisibilityGroupTest.java | 4 +- .../java/lib/form/ValidateButtonTest.java | 6 +- .../java/lib/layout/ConfirmationLinkTest.java | 4 +- .../test/java/lib/layout/StopButtonTest.java | 4 +- test/src/test/java/lib/layout/TaskTest.java | 8 +- .../stapler/MockStaplerRequestBuilder.java | 6 +- .../org/kohsuke/stapler/Security1097Test.java | 4 +- war/pom.xml | 24 +- websocket/jetty10/pom.xml | 85 ------- .../jenkins/websocket/Jetty10Provider.java | 179 -------------- .../{jetty12-ee8 => jetty12-ee9}/pom.xml | 6 +- .../websocket/Jetty12EE9Provider.java} | 24 +- websocket/spi/pom.xml | 2 +- .../main/java/jenkins/websocket/Provider.java | 4 +- 341 files changed, 3991 insertions(+), 1872 deletions(-) delete mode 100644 websocket/jetty10/pom.xml delete mode 100644 websocket/jetty10/src/main/java/jenkins/websocket/Jetty10Provider.java rename websocket/{jetty12-ee8 => jetty12-ee9}/pom.xml (95%) rename websocket/{jetty12-ee8/src/main/java/jenkins/websocket/Jetty12EE8Provider.java => jetty12-ee9/src/main/java/jenkins/websocket/Jetty12EE9Provider.java} (90%) diff --git a/.github/renovate.json b/.github/renovate.json index aab994ad8187..1f023c99f4f5 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -91,17 +91,6 @@ "org.jfree:jfreechart" ] }, - { - "description": "Starting with 6.x, Spring requires Java 17 at a minimum.", - "matchManagers": [ - "maven" - ], - "allowedVersions": "<6.0.0", - "matchPackageNames": [ - "org.springframework:spring-framework-bom", - "org.springframework.security:spring-security-bom" - ] - }, { "description": "Starting with 7.x, Guice switches from javax.* to jakarta.* bindings. See https://github.com/google/guice/wiki/Guice700", "matchManagers": [ diff --git a/.idea/encodings.xml b/.idea/encodings.xml index ca018ebc3ab9..68f564fff79d 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -29,12 +29,9 @@ - - - - - - + + + diff --git a/bom/pom.xml b/bom/pom.xml index adf65f6cf439..cd55b58d52c9 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -39,7 +39,7 @@ THE SOFTWARE. 2.0.0-M2 - 1896.v8170998149d0 + 1903.v994a_db_314d58 2.4.21 @@ -62,15 +62,15 @@ THE SOFTWARE. org.springframework spring-framework-bom - 5.3.39 + 6.1.12 pom import - + org.springframework.security spring-security-bom - 5.8.14 + 6.3.3 pom import @@ -154,12 +154,12 @@ THE SOFTWARE. jakarta.servlet jakarta.servlet-api - 4.0.4 + 5.0.0 jakarta.servlet.jsp.jstl jakarta.servlet.jsp.jstl-api - 1.2.7 + 2.0.0 jaxen @@ -295,7 +295,7 @@ THE SOFTWARE. org.jvnet.hudson commons-jelly-tags-define - 1.1-jenkins-20240510 + 1.1-jenkins-20240903 org.jvnet.localizer diff --git a/core/pom.xml b/core/pom.xml index 8e30ae211ed7..9bff5e5ad0b2 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -217,6 +217,20 @@ THE SOFTWARE. jakarta.servlet.jsp.jstl jakarta.servlet.jsp.jstl-api + + + jakarta.el + jakarta.el-api + + + jakarta.servlet + jakarta.servlet-api + + + jakarta.xml.bind + jakarta.xml.bind-api + + jaxen @@ -288,7 +302,7 @@ THE SOFTWARE. org.apache.commons - commons-fileupload2-javax + commons-fileupload2-jakarta-servlet5 org.codehaus.groovy @@ -427,6 +441,10 @@ THE SOFTWARE. org.springframework.security spring-security-web + + io.micrometer + micrometer-observation + org.springframework spring-jcl diff --git a/core/src/main/java/hudson/DescriptorExtensionList.java b/core/src/main/java/hudson/DescriptorExtensionList.java index c92b6ae206c0..c658c83fe1fc 100644 --- a/core/src/main/java/hudson/DescriptorExtensionList.java +++ b/core/src/main/java/hudson/DescriptorExtensionList.java @@ -145,7 +145,7 @@ public T newInstanceFromRadioList(JSONObject config) throws FormException { if (config.isNullObject()) return null; // none was selected int idx = config.getInt("value"); - return get(idx).newInstance(Stapler.getCurrentRequest(), config); + return get(idx).newInstance(Stapler.getCurrentRequest2(), config); } /** diff --git a/core/src/main/java/hudson/ExpressionFactory2.java b/core/src/main/java/hudson/ExpressionFactory2.java index 7fcec22e7604..1bc99160439b 100644 --- a/core/src/main/java/hudson/ExpressionFactory2.java +++ b/core/src/main/java/hudson/ExpressionFactory2.java @@ -12,7 +12,7 @@ import org.apache.commons.jelly.expression.ExpressionSupport; import org.apache.commons.jexl.JexlContext; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.springframework.security.access.AccessDeniedException; /** @@ -78,7 +78,7 @@ public Object evaluate(JellyContext context) { // let the security exception pass through throw e; } catch (Exception e) { - StaplerRequest currentRequest = Stapler.getCurrentRequest(); + StaplerRequest2 currentRequest = Stapler.getCurrentRequest2(); LOGGER.log(Level.WARNING, "Caught exception evaluating: " + expression + " in " + (currentRequest != null ? currentRequest.getOriginalRequestURI() : "?") + ". Reason: " + e, e); return null; } finally { diff --git a/core/src/main/java/hudson/FilePath.java b/core/src/main/java/hudson/FilePath.java index 06773dd9a9ee..f5288b26d9d1 100644 --- a/core/src/main/java/hudson/FilePath.java +++ b/core/src/main/java/hudson/FilePath.java @@ -3510,7 +3510,7 @@ public FormValidation validateRelativePath(String value, boolean errorIfNotExist } private static void checkPermissionForValidate() { - AccessControlled subject = Stapler.getCurrentRequest().findAncestorObject(AbstractProject.class); + AccessControlled subject = Stapler.getCurrentRequest2().findAncestorObject(AbstractProject.class); if (subject == null) Jenkins.get().checkPermission(Jenkins.MANAGE); else diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index cd25f9bc9871..d2b62e99a2f2 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -95,6 +95,14 @@ import hudson.views.MyViewsTabBar; import hudson.views.ViewsTabBar; import hudson.widgets.RenderOnDemandClosure; +import io.jenkins.servlet.ServletExceptionWrapper; +import io.jenkins.servlet.http.CookieWrapper; +import io.jenkins.servlet.http.HttpServletRequestWrapper; +import io.jenkins.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.PrintStream; @@ -148,10 +156,6 @@ import java.util.logging.SimpleFormatter; import java.util.regex.Pattern; import java.util.stream.Collectors; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import jenkins.console.ConsoleUrlProvider; import jenkins.model.GlobalConfiguration; import jenkins.model.GlobalConfigurationCategory; @@ -176,7 +180,9 @@ import org.kohsuke.stapler.RawHtmlArgument; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.springframework.security.access.AccessDeniedException; /** @@ -276,8 +282,8 @@ public static boolean isExtensionsAvailable() { } public static void initPageVariables(JellyContext context) { - StaplerRequest currentRequest = Stapler.getCurrentRequest(); - currentRequest.getWebApp().getDispatchValidator().allowDispatch(currentRequest, Stapler.getCurrentResponse()); + StaplerRequest2 currentRequest = Stapler.getCurrentRequest2(); + currentRequest.getWebApp().getDispatchValidator().allowDispatch(currentRequest, Stapler.getCurrentResponse2()); String rootURL = currentRequest.getContextPath(); Functions h = new Functions(); @@ -372,7 +378,10 @@ public static String addSuffix(int n, String singular, String plural) { return buf.toString(); } - public static RunUrl decompose(StaplerRequest req) { + /** + * @since TODO + */ + public static RunUrl decompose(StaplerRequest2 req) { List ancestors = req.getAncestors(); // find the first and last Run instances @@ -405,12 +414,20 @@ public static RunUrl decompose(StaplerRequest req) { return new RunUrl((Run) f.getObject(), head, base, rest); } + /** + * @deprecated use {@link #decompose(StaplerRequest2)} + */ + @Deprecated + public static RunUrl decompose(StaplerRequest req) { + return decompose(StaplerRequest.toStaplerRequest2(req)); + } + /** * If we know the user's screen resolution, return it. Otherwise null. * @since 1.213 */ public static Area getScreenResolution() { - Cookie res = Functions.getCookie(Stapler.getCurrentRequest(), "screenResolution"); + Cookie res = Functions.getCookie(Stapler.getCurrentRequest2(), "screenResolution"); if (res != null) return Area.parse(res.getValue()); return null; @@ -592,6 +609,9 @@ public static Iterable reverse(Collection collection) { return list; } + /** + * @since TODO + */ public static Cookie getCookie(HttpServletRequest req, String name) { Cookie[] cookies = req.getCookies(); if (cookies != null) { @@ -604,12 +624,31 @@ public static Cookie getCookie(HttpServletRequest req, String name) { return null; } + /** + * @deprecated use {@link #getCookie(HttpServletRequest, String)} + */ + @Deprecated + public static javax.servlet.http.Cookie getCookie(javax.servlet.http.HttpServletRequest req, String name) { + return CookieWrapper.fromJakartaServletHttpCookie(getCookie(HttpServletRequestWrapper.toJakartaHttpServletRequest(req), name)); + } + + /** + * @since TODO + */ public static String getCookie(HttpServletRequest req, String name, String defaultValue) { Cookie c = getCookie(req, name); if (c == null || c.getValue() == null) return defaultValue; return c.getValue(); } + /** + * @deprecated use {@link #getCookie(HttpServletRequest, String, String)} + */ + @Deprecated + public static String getCookie(javax.servlet.http.HttpServletRequest req, String name, String defaultValue) { + return getCookie(HttpServletRequestWrapper.toJakartaHttpServletRequest(req), name, defaultValue); + } + private static final Pattern ICON_SIZE = Pattern.compile("\\d+x\\d+"); @Restricted(NoExternalUse.class) @@ -713,8 +752,10 @@ public static long getHourLocalTimezone() { * Finds the given object in the ancestor list and returns its URL. * This is used to determine the "current" URL assigned to the given object, * so that one can compute relative URLs from it. + * + * @since TODO */ - public static String getNearestAncestorUrl(StaplerRequest req, Object it) { + public static String getNearestAncestorUrl(StaplerRequest2 req, Object it) { List list = req.getAncestors(); for (int i = list.size() - 1; i >= 0; i--) { Ancestor anc = (Ancestor) list.get(i); @@ -724,11 +765,19 @@ public static String getNearestAncestorUrl(StaplerRequest req, Object it) { return null; } + /** + * @deprecated use {@link #getNearestAncestorUrl(StaplerRequest2, Object)} + */ + @Deprecated + public static String getNearestAncestorUrl(StaplerRequest req, Object it) { + return getNearestAncestorUrl(StaplerRequest.toStaplerRequest2(req), it); + } + /** * Finds the inner-most {@link SearchableModelObject} in scope. */ public static String getSearchURL() { - List list = Stapler.getCurrentRequest().getAncestors(); + List list = Stapler.getCurrentRequest2().getAncestors(); for (int i = list.size() - 1; i >= 0; i--) { Ancestor anc = (Ancestor) list.get(i); if (anc.getObject() instanceof SearchableModelObject) @@ -888,7 +937,7 @@ public static void checkPermission(Object object, Permission permission) throws if (object instanceof AccessControlled) checkPermission((AccessControlled) object, permission); else { - List ancs = Stapler.getCurrentRequest().getAncestors(); + List ancs = Stapler.getCurrentRequest2().getAncestors(); for (Ancestor anc : Iterators.reverse(ancs)) { Object o = anc.getObject(); if (o instanceof AccessControlled) { @@ -920,7 +969,7 @@ public static boolean hasPermission(Object object, Permission permission) throws if (object instanceof AccessControlled) return ((AccessControlled) object).hasPermission(permission); else { - List ancs = Stapler.getCurrentRequest().getAncestors(); + List ancs = Stapler.getCurrentRequest2().getAncestors(); for (Ancestor anc : Iterators.reverse(ancs)) { Object o = anc.getObject(); if (o instanceof AccessControlled) { @@ -931,10 +980,13 @@ public static boolean hasPermission(Object object, Permission permission) throws } } - public static void adminCheck(StaplerRequest req, StaplerResponse rsp, Object required, Permission permission) throws IOException, ServletException { + /** + * @since TODO + */ + public static void adminCheck(StaplerRequest2 req, StaplerResponse2 rsp, Object required, Permission permission) throws IOException, ServletException { // this is legacy --- all views should be eventually converted to // the permission based model. - if (required != null && !Hudson.adminCheck(req, rsp)) { + if (required != null && !Hudson.adminCheck(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp))) { // check failed. commit the FORBIDDEN response, then abort. rsp.setStatus(HttpServletResponse.SC_FORBIDDEN); rsp.getOutputStream().close(); @@ -946,10 +998,24 @@ public static void adminCheck(StaplerRequest req, StaplerResponse rsp, Object re checkPermission(permission); } + /** + * @deprecated use {@link #adminCheck(StaplerRequest2, StaplerResponse2, Object, Permission)} + */ + @Deprecated + public static void adminCheck(StaplerRequest req, StaplerResponse rsp, Object required, Permission permission) throws IOException, javax.servlet.ServletException { + try { + adminCheck(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), required, permission); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * Infers the hudson installation URL from the given request. + * + * @since TODO */ - public static String inferHudsonURL(StaplerRequest req) { + public static String inferHudsonURL(StaplerRequest2 req) { String rootUrl = Jenkins.get().getRootUrl(); if (rootUrl != null) // prefer the one explicitly configured, to work with load-balancer, frontend, etc. @@ -963,6 +1029,14 @@ public static String inferHudsonURL(StaplerRequest req) { return buf.toString(); } + /** + * @deprecated use {@link #inferHudsonURL(StaplerRequest2)} + */ + @Deprecated + public static String inferHudsonURL(StaplerRequest req) { + return inferHudsonURL(StaplerRequest.toStaplerRequest2(req)); + } + /** * Returns the link to be displayed in the footer of the UI. */ @@ -1226,7 +1300,7 @@ public static boolean hasAnyPermission(Object object, Permission[] permissions) if (object instanceof AccessControlled) return hasAnyPermission((AccessControlled) object, permissions); else { - AccessControlled ac = Stapler.getCurrentRequest().findAncestorObject(AccessControlled.class); + AccessControlled ac = Stapler.getCurrentRequest2().findAncestorObject(AccessControlled.class); if (ac != null) { return hasAnyPermission(ac, permissions); } @@ -1264,7 +1338,7 @@ public static void checkAnyPermission(Object object, Permission[] permissions) t if (object instanceof AccessControlled) checkAnyPermission((AccessControlled) object, permissions); else { - List ancs = Stapler.getCurrentRequest().getAncestors(); + List ancs = Stapler.getCurrentRequest2().getAncestors(); for (Ancestor anc : Iterators.reverse(ancs)) { Object o = anc.getObject(); if (o instanceof AccessControlled) { @@ -1335,7 +1409,7 @@ public static String getRelativeLinkTo(Item p) { Map ancestors = new HashMap<>(); View view = null; - StaplerRequest request = Stapler.getCurrentRequest(); + StaplerRequest2 request = Stapler.getCurrentRequest2(); for (Ancestor a : request.getAncestors()) { ancestors.put(a.getObject(), a.getRelativePath()); if (a.getObject() instanceof View) @@ -1681,7 +1755,7 @@ public static String getViewResource(Object it, String path) { if (it instanceof Descriptor) clazz = ((Descriptor) it).clazz; - String buf = Stapler.getCurrentRequest().getContextPath() + Jenkins.VIEW_RESOURCE_PATH + '/' + + String buf = Stapler.getCurrentRequest2().getContextPath() + Jenkins.VIEW_RESOURCE_PATH + '/' + clazz.getName().replace('.', '/').replace('$', '/') + '/' + path; return buf; @@ -1689,7 +1763,7 @@ public static String getViewResource(Object it, String path) { public static boolean hasView(Object it, String path) throws IOException { if (it == null) return false; - return Stapler.getCurrentRequest().getView(it, path) != null; + return Stapler.getCurrentRequest2().getView(it, path) != null; } /** @@ -1900,10 +1974,10 @@ public static String joinPath(String... components) { return null; } if (urlName.startsWith("/")) - return joinPath(Stapler.getCurrentRequest().getContextPath(), urlName); + return joinPath(Stapler.getCurrentRequest2().getContextPath(), urlName); else // relative URL name - return joinPath(Stapler.getCurrentRequest().getContextPath() + '/' + itUrl, urlName); + return joinPath(Stapler.getCurrentRequest2().getContextPath() + '/' + itUrl, urlName); } /** @@ -1966,7 +2040,7 @@ public String getServerName() { } catch (MalformedURLException e) { // fall back to HTTP request } - return Stapler.getCurrentRequest().getServerName(); + return Stapler.getCurrentRequest2().getServerName(); } /** @@ -2004,7 +2078,7 @@ public void calcCheckUrl(Map attributes, String userDefined, Object descriptor, * Used in {@code task.jelly} to decide if the page should be highlighted. */ public boolean hyperlinkMatchesCurrentPage(String href) { - String url = Stapler.getCurrentRequest().getRequestURL().toString(); + String url = Stapler.getCurrentRequest2().getRequestURL().toString(); if (href == null || href.length() <= 1) return ".".equals(href) && url.endsWith("/"); url = URLDecoder.decode(url, StandardCharsets.UTF_8); href = URLDecoder.decode(href, StandardCharsets.UTF_8); @@ -2063,12 +2137,23 @@ public static List> getCrumbIssuerDescriptors() { return CrumbIssuer.all(); } - public static String getCrumb(StaplerRequest req) { + /** + * @since TODO + */ + public static String getCrumb(StaplerRequest2 req) { Jenkins h = Jenkins.getInstanceOrNull(); CrumbIssuer issuer = h != null ? h.getCrumbIssuer() : null; return issuer != null ? issuer.getCrumb(req) : ""; } + /** + * @deprecated use {@link #getCrumb(StaplerRequest2)} + */ + @Deprecated + public static String getCrumb(StaplerRequest req) { + return getCrumb(req != null ? StaplerRequest.toStaplerRequest2(req) : null); + } + public static String getCrumbRequestField() { Jenkins h = Jenkins.getInstanceOrNull(); CrumbIssuer issuer = h != null ? h.getCrumbIssuer() : null; @@ -2081,7 +2166,7 @@ public static Date getCurrentTime() { public static Locale getCurrentLocale() { Locale locale = null; - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req != null) locale = req.getLocale(); if (locale == null) @@ -2094,7 +2179,7 @@ public static Locale getCurrentLocale() { * from {@link ConsoleAnnotatorFactory}s and {@link ConsoleAnnotationDescriptor}s. */ public static String generateConsoleAnnotationScriptAndStylesheet() { - String cp = Stapler.getCurrentRequest().getContextPath() + Jenkins.RESOURCE_PATH; + String cp = Stapler.getCurrentRequest2().getContextPath() + Jenkins.RESOURCE_PATH; StringBuilder buf = new StringBuilder(); for (ConsoleAnnotatorFactory f : ConsoleAnnotatorFactory.all()) { String path = cp + "/extensionList/" + ConsoleAnnotatorFactory.class.getName() + "/" + f.getClass().getName(); @@ -2147,7 +2232,7 @@ public String getPasswordValue(Object o) { } /* Mask from Extended Read */ - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (o instanceof Secret || Secret.BLANK_NONSECRET_PASSWORD_FIELDS_WITHOUT_ITEM_CONFIGURE) { if (req != null) { Item item = req.findAncestorObject(Item.class); @@ -2243,15 +2328,17 @@ public static boolean isWipeOutPermissionEnabled() { @Deprecated public static String createRenderOnDemandProxy(JellyContext context, String attributesToCapture) { - return Stapler.getCurrentRequest().createJavaScriptProxy(new RenderOnDemandClosure(context, attributesToCapture)); + return Stapler.getCurrentRequest2().createJavaScriptProxy(new RenderOnDemandClosure(context, attributesToCapture)); } /** * Called from renderOnDemand.jelly to generate the parameters for the proxy object generation. + * + * @since TODO */ @Restricted(NoExternalUse.class) - public static StaplerRequest.RenderOnDemandParameters createRenderOnDemandProxyParameters(JellyContext context, String attributesToCapture) { - return Stapler.getCurrentRequest().createJavaScriptProxyParameters(new RenderOnDemandClosure(context, attributesToCapture)); + public static StaplerRequest2.RenderOnDemandParameters createRenderOnDemandProxyParameters(JellyContext context, String attributesToCapture) { + return Stapler.getCurrentRequest2().createJavaScriptProxyParameters(new RenderOnDemandClosure(context, attributesToCapture)); } public static String getCurrentDescriptorByNameUrl() { @@ -2260,18 +2347,18 @@ public static String getCurrentDescriptorByNameUrl() { public static String setCurrentDescriptorByNameUrl(String value) { String o = getCurrentDescriptorByNameUrl(); - Stapler.getCurrentRequest().setAttribute("currentDescriptorByNameUrl", value); + Stapler.getCurrentRequest2().setAttribute("currentDescriptorByNameUrl", value); return o; } public static void restoreCurrentDescriptorByNameUrl(String old) { - Stapler.getCurrentRequest().setAttribute("currentDescriptorByNameUrl", old); + Stapler.getCurrentRequest2().setAttribute("currentDescriptorByNameUrl", old); } public static List getRequestHeaders(String name) { List r = new ArrayList<>(); - Enumeration e = Stapler.getCurrentRequest().getHeaders(name); + Enumeration e = Stapler.getCurrentRequest2().getHeaders(name); while (e.hasMoreElements()) { r.add(e.nextElement().toString()); } @@ -2366,6 +2453,7 @@ public static String breakableString(final String plain) { * Advertises the minimum set of HTTP headers that assist programmatic * discovery of Jenkins. */ + @SuppressFBWarnings(value = "UC_USELESS_VOID_METHOD", justification = "TODO needs triage") public static void advertiseHeaders(HttpServletResponse rsp) { Jenkins j = Jenkins.getInstanceOrNull(); if (j != null) { @@ -2375,6 +2463,14 @@ public static void advertiseHeaders(HttpServletResponse rsp) { } } + /** + * @deprecated use {@link #advertiseHeaders(HttpServletResponse)} + */ + @Deprecated + public static void advertiseHeaders(javax.servlet.http.HttpServletResponse rsp) { + advertiseHeaders(HttpServletResponseWrapper.toJakartaHttpServletResponse(rsp)); + } + @Restricted(NoExternalUse.class) // for actions.jelly and ContextMenu.add public static boolean isContextMenuVisible(Action a) { if (a instanceof ModelObjectWithContextMenu.ContextMenuVisibility) { @@ -2449,7 +2545,7 @@ public static String tryGetIconPath(String iconGuess, JellyContext context) { return iconGuess; } - StaplerRequest currentRequest = Stapler.getCurrentRequest(); + StaplerRequest2 currentRequest = Stapler.getCurrentRequest2(); String rootURL = currentRequest.getContextPath(); Icon iconMetadata = tryGetIcon(iconGuess); diff --git a/core/src/main/java/hudson/LocalPluginManager.java b/core/src/main/java/hudson/LocalPluginManager.java index d1fcfd678e3a..7ee8c68b40d3 100644 --- a/core/src/main/java/hudson/LocalPluginManager.java +++ b/core/src/main/java/hudson/LocalPluginManager.java @@ -26,11 +26,12 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; +import io.jenkins.servlet.ServletContextWrapper; +import jakarta.servlet.ServletContext; import java.io.File; import java.util.Collection; import java.util.Collections; import java.util.logging.Logger; -import javax.servlet.ServletContext; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; @@ -49,12 +50,20 @@ public LocalPluginManager(@CheckForNull ServletContext context, @NonNull File ro super(context, new File(rootDir, "plugins")); } + /** + * @deprecated use {@link #LocalPluginManager(ServletContext, File)} + */ + @Deprecated + public LocalPluginManager(@CheckForNull javax.servlet.ServletContext context, @NonNull File rootDir) { + this(context != null ? ServletContextWrapper.toJakartaServletContext(context) : null, rootDir); + } + /** * Creates a new LocalPluginManager * @param jenkins Jenkins instance that will use the plugin manager. */ public LocalPluginManager(@NonNull Jenkins jenkins) { - this(jenkins.servletContext, jenkins.getRootDir()); + this(jenkins.getServletContext(), jenkins.getRootDir()); } /** @@ -62,7 +71,7 @@ public LocalPluginManager(@NonNull Jenkins jenkins) { * @param rootDir Jenkins home directory. */ public LocalPluginManager(@NonNull File rootDir) { - this(null, rootDir); + this((ServletContext) null, rootDir); } @Override diff --git a/core/src/main/java/hudson/Plugin.java b/core/src/main/java/hudson/Plugin.java index c87a2cbe9b3c..1427da9fda8a 100644 --- a/core/src/main/java/hudson/Plugin.java +++ b/core/src/main/java/hudson/Plugin.java @@ -33,25 +33,29 @@ import hudson.model.Saveable; import hudson.model.listeners.ItemListener; import hudson.model.listeners.SaveableListener; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.Locale; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import jenkins.model.GlobalConfiguration; import jenkins.model.Jenkins; import jenkins.model.Loadable; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.SystemProperties; import net.sf.json.JSONObject; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; /** * Base class of Hudson plugin. @@ -92,11 +96,11 @@ public abstract class Plugin implements Loadable, Saveable, StaplerProxy { /** * You do not need to create custom subtypes: *
    - *
  • {@code config.jelly}, {@link #configure(StaplerRequest, JSONObject)}, {@link #load}, and {@link #save} + *
  • {@code config.jelly}, {@link #configure(StaplerRequest2, JSONObject)}, {@link #load}, and {@link #save} * can be replaced by {@link GlobalConfiguration} *
  • {@link #start} and {@link #postInitialize} can be replaced by {@link Initializer} (or {@link ItemListener#onLoaded}) *
  • {@link #stop} can be replaced by {@link Terminator} - *
  • {@link #setServletContext} can be replaced by {@link Jenkins#servletContext} + *
  • {@link #setServletContext} can be replaced by {@link Jenkins#getServletContext} *
* Note that every plugin gets a {@link DummyImpl} by default, * which will still route the URL space, serve {@link #getWrapper}, and so on. @@ -189,10 +193,10 @@ public void stop() throws Exception { /** * @since 1.233 - * @deprecated as of 1.305 override {@link #configure(StaplerRequest,JSONObject)} instead + * @deprecated as of 1.305 override {@link #configure(StaplerRequest2,JSONObject)} instead */ @Deprecated - public void configure(JSONObject formData) throws IOException, ServletException, FormException { + public void configure(JSONObject formData) throws IOException, javax.servlet.ServletException, FormException { } /** @@ -220,16 +224,60 @@ public void configure(JSONObject formData) throws IOException, ServletException, *

* If you are using this method, you'll likely be interested in * using {@link #save()} and {@link #load()}. + * @since TODO + */ + public void configure(StaplerRequest2 req, JSONObject formData) throws IOException, ServletException, FormException { + try { + if (Util.isOverridden(Plugin.class, getClass(), "configure", StaplerRequest.class, JSONObject.class)) { + configure(StaplerRequest.fromStaplerRequest2(req), formData); + } else { + configure(formData); + } + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } + + /** + * @deprecated use {@link #configure(StaplerRequest2, JSONObject)} * @since 1.305 */ - public void configure(StaplerRequest req, JSONObject formData) throws IOException, ServletException, FormException { + @Deprecated + public void configure(StaplerRequest req, JSONObject formData) throws IOException, javax.servlet.ServletException, FormException { configure(formData); } /** * This method serves static resources in the plugin under {@code hudson/plugin/SHORTNAME}. + * + * @since TODO + */ + public void doDynamic(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(Plugin.class, getClass(), "doDynamic", StaplerRequest.class, StaplerResponse.class)) { + try { + doDynamic(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doDynamicImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doDynamic(StaplerRequest2, StaplerResponse2)} */ - public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + @Deprecated + @StaplerNotDispatchable + public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doDynamicImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void doDynamicImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { String path = req.getRestOfPath(); String pathUC = path.toUpperCase(Locale.ENGLISH); diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java index 16c22e9ca90c..e1f5d4cc1184 100644 --- a/core/src/main/java/hudson/PluginManager.java +++ b/core/src/main/java/hudson/PluginManager.java @@ -66,6 +66,10 @@ import hudson.util.Service; import hudson.util.VersionNumber; import hudson.util.XStream2; +import io.jenkins.servlet.ServletContextWrapper; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FilenameFilter; @@ -118,8 +122,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; import javax.xml.XMLConstants; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; @@ -134,6 +136,7 @@ import jenkins.model.Jenkins; import jenkins.plugins.DetachedPluginsUtil; import jenkins.security.CustomClassFilter; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.SystemProperties; import jenkins.util.io.OnMaster; import jenkins.util.xml.RestrictiveEntityResolver; @@ -143,8 +146,8 @@ import org.apache.commons.fileupload2.core.DiskFileItemFactory; import org.apache.commons.fileupload2.core.FileItem; import org.apache.commons.fileupload2.core.FileUploadException; -import org.apache.commons.fileupload2.javax.JavaxServletDiskFileUpload; -import org.apache.commons.fileupload2.javax.JavaxServletFileUpload; +import org.apache.commons.fileupload2.jakarta.servlet5.JakartaServletDiskFileUpload; +import org.apache.commons.fileupload2.jakarta.servlet5.JakartaServletFileUpload; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; @@ -165,7 +168,8 @@ import org.kohsuke.stapler.StaplerOverridable; import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -237,11 +241,22 @@ PluginManager doCreate(@NonNull Class klass, return klass.getConstructor(Jenkins.class).newInstance(jenkins); } }, + SC_FILE2 { + @Override + @NonNull PluginManager doCreate(@NonNull Class klass, + @NonNull Jenkins jenkins) throws ReflectiveOperationException { + return klass.getConstructor(ServletContext.class, File.class).newInstance(jenkins.getServletContext(), jenkins.getRootDir()); + } + }, + /** + * @deprecated use {@link #SC_FILE2} + */ + @Deprecated SC_FILE { @Override @NonNull PluginManager doCreate(@NonNull Class klass, @NonNull Jenkins jenkins) throws ReflectiveOperationException { - return klass.getConstructor(ServletContext.class, File.class).newInstance(jenkins.servletContext, jenkins.getRootDir()); + return klass.getConstructor(javax.servlet.ServletContext.class, File.class).newInstance(jenkins.servletContext, jenkins.getRootDir()); } }, FILE { @@ -363,6 +378,9 @@ PluginManager doCreate(@NonNull Class klass, */ private final PluginStrategy strategy; + /** + * @since TODO + */ protected PluginManager(ServletContext context, File rootDir) { this.context = context; @@ -378,6 +396,14 @@ protected PluginManager(ServletContext context, File rootDir) { strategy = createPluginStrategy(); } + /** + * @deprecated use {@link #PluginManager(ServletContext, File)} + */ + @Deprecated + protected PluginManager(javax.servlet.ServletContext context, File rootDir) { + this(context != null ? ServletContextWrapper.toJakartaServletContext(context) : null, rootDir); + } + public Api getApi() { Jenkins.get().checkPermission(Jenkins.SYSTEM_READ); return new Api(this); @@ -655,7 +681,7 @@ void considerDetachedPlugin(String shortName, String source) { protected @NonNull Set loadPluginsFromWar(@NonNull String fromPath, @CheckForNull FilenameFilter filter) { Set names = new HashSet<>(); - ServletContext context = Jenkins.get().servletContext; + ServletContext context = Jenkins.get().getServletContext(); Set plugins = Util.fixNull(context.getResourcePaths(fromPath)); Set copiedPlugins = new HashSet<>(); Set dependencies = new HashSet<>(); @@ -723,7 +749,7 @@ protected static void addDependencies(URL hpiResUrl, String fromPath, Set d String dependencySpec = manifest.getMainAttributes().getValue("Plugin-Dependencies"); if (dependencySpec != null) { String[] dependencyTokens = dependencySpec.split(","); - ServletContext context = Jenkins.get().servletContext; + ServletContext context = Jenkins.get().getServletContext(); for (String dependencyToken : dependencyTokens) { if (dependencyToken.endsWith(";resolution:=optional")) { @@ -1597,7 +1623,7 @@ public HttpResponse doPlugins() { } @RequirePOST - public HttpResponse doUpdateSources(StaplerRequest req) throws IOException { + public HttpResponse doUpdateSources(StaplerRequest2 req) throws IOException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); if (req.hasParameter("remove")) { @@ -1632,7 +1658,7 @@ public void doInstallPluginsDone() { * Performs the installation of the plugins. */ @RequirePOST - public void doInstall(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doInstall(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); Set plugins = new LinkedHashSet<>(); @@ -1656,12 +1682,12 @@ public void doInstall(StaplerRequest req, StaplerResponse rsp) throws IOExceptio * @param req The request object. * @return A JSON response that includes a "correlationId" in the "data" element. * That "correlationId" can then be used in calls to - * {@link UpdateCenter#doInstallStatus(org.kohsuke.stapler.StaplerRequest)}. + * {@link UpdateCenter#doInstallStatus(org.kohsuke.stapler.StaplerRequest2)}. * @throws IOException Error reading JSON payload fro request. */ @RequirePOST @Restricted(DoNotUse.class) // WebOnly - public HttpResponse doInstallPlugins(StaplerRequest req) throws IOException { + public HttpResponse doInstallPlugins(StaplerRequest2 req) throws IOException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); String payload = IOUtils.toString(req.getInputStream(), req.getCharacterEncoding()); JSONObject request = JSONObject.fromObject(payload); @@ -1815,7 +1841,7 @@ public HttpResponse doSiteConfigure(@QueryParameter String site) throws IOExcept } @POST - public HttpResponse doProxyConfigure(StaplerRequest req) throws IOException, ServletException { + public HttpResponse doProxyConfigure(StaplerRequest2 req) throws IOException, ServletException { Jenkins jenkins = Jenkins.get(); jenkins.checkPermission(Jenkins.ADMINISTER); @@ -1880,14 +1906,39 @@ public void cleanup() { * Uploads a plugin. */ @RequirePOST - public HttpResponse doUploadPlugin(StaplerRequest req) throws IOException, ServletException { + public HttpResponse doUploadPlugin(StaplerRequest2 req) throws IOException, ServletException { + if (Util.isOverridden(PluginManager.class, getClass(), "doUploadPlugin", StaplerRequest.class)) { + try { + return doUploadPlugin(StaplerRequest.fromStaplerRequest2(req)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + return doUploadPluginImpl(req); + } + } + + /** + * @deprecated use {@link #doUploadPlugin(StaplerRequest2)} + */ + @Deprecated + @StaplerNotDispatchable + public HttpResponse doUploadPlugin(StaplerRequest req) throws IOException, javax.servlet.ServletException { + try { + return doUploadPluginImpl(StaplerRequest.toStaplerRequest2(req)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private HttpResponse doUploadPluginImpl(StaplerRequest2 req) throws IOException, ServletException { try { Jenkins.get().checkPermission(Jenkins.ADMINISTER); String fileName = ""; PluginCopier copier; File tmpDir = Files.createTempDirectory("uploadDir").toFile(); - JavaxServletFileUpload upload = new JavaxServletDiskFileUpload(DiskFileItemFactory.builder().setFile(tmpDir).get()); + JakartaServletFileUpload upload = new JakartaServletDiskFileUpload(DiskFileItemFactory.builder().setFile(tmpDir).get()); List items = upload.parseRequest(req); String string = items.get(1).getString(); if (string != null && !string.isBlank()) { @@ -1965,7 +2016,7 @@ public HttpResponse doUploadPlugin(StaplerRequest req) throws IOException, Servl } @Restricted(NoExternalUse.class) - @RequirePOST public FormValidation doCheckPluginUrl(StaplerRequest request, @QueryParameter String value) throws IOException { + @RequirePOST public FormValidation doCheckPluginUrl(StaplerRequest2 request, @QueryParameter String value) throws IOException { if (value != null && !value.isBlank()) { try { URL url = new URL(value); @@ -1984,7 +2035,7 @@ public HttpResponse doUploadPlugin(StaplerRequest req) throws IOException, Servl } @Restricted(NoExternalUse.class) - @RequirePOST public FormValidation doCheckUpdateSiteUrl(StaplerRequest request, @QueryParameter String value) throws InterruptedException { + @RequirePOST public FormValidation doCheckUpdateSiteUrl(StaplerRequest2 request, @QueryParameter String value) throws InterruptedException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); return checkUpdateSiteURL(value); } @@ -2217,7 +2268,7 @@ private void logPluginWarnings(Map.Entry requestedPlugin, } /** - * Like {@link #doInstallNecessaryPlugins(StaplerRequest)} but only checks if everything is installed + * Like {@link #doInstallNecessaryPlugins(StaplerRequest2)} but only checks if everything is installed * or if some plugins need updates or installation. * * This method runs without side-effect. I'm still requiring the ADMINISTER permission since @@ -2227,7 +2278,7 @@ private void logPluginWarnings(Map.Entry requestedPlugin, * @since 1.483 */ @RequirePOST - public JSONArray doPrevalidateConfig(StaplerRequest req) throws IOException { + public JSONArray doPrevalidateConfig(StaplerRequest2 req) throws IOException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); JSONArray response = new JSONArray(); @@ -2252,7 +2303,7 @@ public JSONArray doPrevalidateConfig(StaplerRequest req) throws IOException { * @since 1.483 */ @RequirePOST - public HttpResponse doInstallNecessaryPlugins(StaplerRequest req) throws IOException { + public HttpResponse doInstallNecessaryPlugins(StaplerRequest2 req) throws IOException { prevalidateConfig(req.getInputStream()); return HttpResponses.redirectViaContextPath("pluginManager/updates/"); } diff --git a/core/src/main/java/hudson/PluginWrapper.java b/core/src/main/java/hudson/PluginWrapper.java index 47cfcb02d955..c8cd9f5240a0 100644 --- a/core/src/main/java/hudson/PluginWrapper.java +++ b/core/src/main/java/hudson/PluginWrapper.java @@ -80,8 +80,8 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -1212,7 +1212,7 @@ public PluginWrapper getPlugin(String shortName) { /** * Depending on whether the user said "dismiss" or "correct", send him to the right place. */ - public void doAct(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doAct(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (req.hasParameter("correct")) { rsp.sendRedirect(req.getContextPath() + "/pluginManager"); diff --git a/core/src/main/java/hudson/ProxyConfigurationManager.java b/core/src/main/java/hudson/ProxyConfigurationManager.java index 52f15f84c87e..d3ae0d79ee0e 100644 --- a/core/src/main/java/hudson/ProxyConfigurationManager.java +++ b/core/src/main/java/hudson/ProxyConfigurationManager.java @@ -32,7 +32,7 @@ import net.sf.json.JSONObject; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; @Extension @Restricted(NoExternalUse.class) public class ProxyConfigurationManager extends GlobalConfiguration { @@ -48,7 +48,7 @@ public Descriptor getProxyDescriptor() { } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { ProxyConfiguration pc = req.bindJSON(ProxyConfiguration.class, json); try { saveProxyConfiguration(pc); diff --git a/core/src/main/java/hudson/ResponseHeaderFilter.java b/core/src/main/java/hudson/ResponseHeaderFilter.java index 90fb0be87d37..416e5c4c6919 100644 --- a/core/src/main/java/hudson/ResponseHeaderFilter.java +++ b/core/src/main/java/hudson/ResponseHeaderFilter.java @@ -24,15 +24,15 @@ package hudson; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Enumeration; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponse; +import org.kohsuke.stapler.CompatibleFilter; /** * This filter allows you to modify headers set by the container or other servlets @@ -77,7 +77,7 @@ * * @author Mike Wille */ -public class ResponseHeaderFilter implements Filter { +public class ResponseHeaderFilter implements CompatibleFilter { private FilterConfig config; @Override diff --git a/core/src/main/java/hudson/Util.java b/core/src/main/java/hudson/Util.java index abe9f97d6551..5ca66e9c4424 100644 --- a/core/src/main/java/hudson/Util.java +++ b/core/src/main/java/hudson/Util.java @@ -125,6 +125,7 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Various utility methods that don't have more proper home. @@ -1850,9 +1851,11 @@ public static long daysElapsedSince(@NonNull Date date) { /** * Find the specific ancestor, or throw an exception. * Useful for an ancestor we know is inside the URL to ease readability + * + * @since TODO */ @Restricted(NoExternalUse.class) - public static @NonNull T getNearestAncestorOfTypeOrThrow(@NonNull StaplerRequest request, @NonNull Class clazz) { + public static @NonNull T getNearestAncestorOfTypeOrThrow(@NonNull StaplerRequest2 request, @NonNull Class clazz) { T t = request.findAncestorObject(clazz); if (t == null) { throw new IllegalArgumentException("No ancestor of type " + clazz.getName() + " in the request"); @@ -1860,6 +1863,15 @@ public static long daysElapsedSince(@NonNull Date date) { return t; } + /** + * @deprecated use {@link #getNearestAncestorOfTypeOrThrow(StaplerRequest2, Class)} + */ + @Deprecated + @Restricted(NoExternalUse.class) + public static @NonNull T getNearestAncestorOfTypeOrThrow(@NonNull StaplerRequest request, @NonNull Class clazz) { + return getNearestAncestorOfTypeOrThrow(StaplerRequest.toStaplerRequest2(request), clazz); + } + @Restricted(NoExternalUse.class) public static void printRedirect(String contextPath, String redirectUrl, String message, PrintWriter out) { out.printf( diff --git a/core/src/main/java/hudson/WebAppMain.java b/core/src/main/java/hudson/WebAppMain.java index 9f328328c710..986452797f90 100644 --- a/core/src/main/java/hudson/WebAppMain.java +++ b/core/src/main/java/hudson/WebAppMain.java @@ -45,6 +45,12 @@ import hudson.util.NoHomeDir; import hudson.util.NoTempDir; import hudson.util.RingBufferLogHandler; +import io.jenkins.servlet.ServletContextEventWrapper; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.SessionTrackingMode; import java.io.File; import java.io.IOException; import java.io.OutputStream; @@ -65,11 +71,6 @@ import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletResponse; -import javax.servlet.SessionTrackingMode; import jenkins.model.Jenkins; import jenkins.util.JenkinsJVM; import jenkins.util.SystemProperties; @@ -320,10 +321,21 @@ private void recordBootAttempt(File home) { } } + /** + * @since TODO + */ public static void installExpressionFactory(ServletContextEvent event) { JellyFacet.setExpressionFactory(event, new ExpressionFactory2()); } + /** + * @deprecated use {@link #installExpressionFactory(ServletContextEvent)} + */ + @Deprecated + public static void installExpressionFactory(javax.servlet.ServletContextEvent event) { + installExpressionFactory(ServletContextEventWrapper.toJakartaServletContextEvent(event)); + } + /** * Installs log handler to monitor all Hudson logs. */ diff --git a/core/src/main/java/hudson/cli/CLIAction.java b/core/src/main/java/hudson/cli/CLIAction.java index 9e29b141560c..a2fc5f590197 100644 --- a/core/src/main/java/hudson/cli/CLIAction.java +++ b/core/src/main/java/hudson/cli/CLIAction.java @@ -26,6 +26,8 @@ import hudson.Extension; import hudson.model.UnprotectedRootAction; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; @@ -45,8 +47,6 @@ import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import jenkins.util.FullDuplexHttpService; import jenkins.util.SystemProperties; @@ -59,8 +59,8 @@ import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.springframework.security.core.Authentication; /** @@ -97,7 +97,7 @@ public String getUrlName() { return "cli"; } - public void doCommand(StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { + public void doCommand(StaplerRequest2 req, StaplerResponse2 rsp) throws ServletException, IOException { final Jenkins jenkins = Jenkins.get(); jenkins.checkPermission(Jenkins.READ); @@ -121,7 +121,7 @@ public boolean isWebSocketSupported() { /** * WebSocket endpoint. */ - public HttpResponse doWs(StaplerRequest req) { + public HttpResponse doWs(StaplerRequest2 req) { if (!WebSockets.isSupported()) { return HttpResponses.notFound(); } @@ -216,7 +216,7 @@ protected void closed(int statusCode, String reason) { @Override public Object getTarget() { - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req.getRestOfPath().isEmpty() && "POST".equals(req.getMethod())) { // CLI connection request if ("false".equals(req.getParameter("remoting"))) { @@ -349,7 +349,7 @@ private class PlainCliEndpointResponse extends FullDuplexHttpService.Response { } @Override - protected FullDuplexHttpService createService(StaplerRequest req, UUID uuid) throws IOException { + protected FullDuplexHttpService createService(StaplerRequest2 req, UUID uuid) throws IOException { return new FullDuplexHttpService(uuid) { @Override protected void run(InputStream upload, OutputStream download) throws IOException, InterruptedException { diff --git a/core/src/main/java/hudson/cli/CliCrumbExclusion.java b/core/src/main/java/hudson/cli/CliCrumbExclusion.java index 4e3064f43178..08c204eb55b1 100644 --- a/core/src/main/java/hudson/cli/CliCrumbExclusion.java +++ b/core/src/main/java/hudson/cli/CliCrumbExclusion.java @@ -26,11 +26,11 @@ import hudson.Extension; import hudson.security.csrf.CrumbExclusion; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; diff --git a/core/src/main/java/hudson/cli/ReloadConfigurationCommand.java b/core/src/main/java/hudson/cli/ReloadConfigurationCommand.java index 6b29dcf52904..aab260747f65 100644 --- a/core/src/main/java/hudson/cli/ReloadConfigurationCommand.java +++ b/core/src/main/java/hudson/cli/ReloadConfigurationCommand.java @@ -50,7 +50,7 @@ protected int run() throws Exception { // Or perhaps simpler to inline the thread body of doReload? j.doReload(); Object app; - while ((app = WebApp.get(j.servletContext).getApp()) instanceof HudsonIsLoading) { + while ((app = WebApp.get(j.getServletContext()).getApp()) instanceof HudsonIsLoading) { Thread.sleep(100); } if (app instanceof Jenkins) { diff --git a/core/src/main/java/hudson/cli/UpdateNodeCommand.java b/core/src/main/java/hudson/cli/UpdateNodeCommand.java index c9210f89cc68..5909a2f0fcf2 100644 --- a/core/src/main/java/hudson/cli/UpdateNodeCommand.java +++ b/core/src/main/java/hudson/cli/UpdateNodeCommand.java @@ -26,8 +26,8 @@ import hudson.Extension; import hudson.model.Node; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; import org.kohsuke.args4j.Argument; /** diff --git a/core/src/main/java/hudson/console/AnnotatedLargeText.java b/core/src/main/java/hudson/console/AnnotatedLargeText.java index 4e0d3b9908af..1798512f3e03 100644 --- a/core/src/main/java/hudson/console/AnnotatedLargeText.java +++ b/core/src/main/java/hudson/console/AnnotatedLargeText.java @@ -30,6 +30,7 @@ import edu.umd.cs.findbugs.annotations.CheckReturnValue; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.Util; import hudson.remoting.ObjectInputStreamEx; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -50,10 +51,13 @@ import javax.crypto.CipherOutputStream; import jenkins.model.Jenkins; import jenkins.security.CryptoConfidentialKey; +import jenkins.security.stapler.StaplerNotDispatchable; import org.jenkinsci.remoting.util.AnonymousClassWarnings; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.framework.io.ByteBuffer; import org.kohsuke.stapler.framework.io.LargeText; @@ -90,14 +94,44 @@ public AnnotatedLargeText(ByteBuffer memory, Charset charset, boolean completed, this.context = context; } + /** + * @since TODO + */ + public void doProgressiveHtml(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { + if (Util.isOverridden(AnnotatedLargeText.class, getClass(), "doProgressiveHtml", StaplerRequest.class, StaplerResponse.class)) { + doProgressiveHtml(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } else { + doProgressiveHtmlImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doProgressiveHtml(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable public void doProgressiveHtml(StaplerRequest req, StaplerResponse rsp) throws IOException { + doProgressiveHtmlImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } + + private void doProgressiveHtmlImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { req.setAttribute("html", true); doProgressText(req, rsp); } /** * Aliasing what I think was a wrong name in {@link LargeText} + * + * @since TODO */ + public void doProgressiveText(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { + doProgressText(req, rsp); + } + + /** + * @deprecated use {@link #doProgressiveText(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated public void doProgressiveText(StaplerRequest req, StaplerResponse rsp) throws IOException { doProgressText(req, rsp); } @@ -107,16 +141,35 @@ public void doProgressiveText(StaplerRequest req, StaplerResponse rsp) throws IO * and use this request attribute to differentiate. */ private boolean isHtml() { - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); return req != null && req.getAttribute("html") != null; } + /** + * @since TODO + */ @Override + protected void setContentType(StaplerResponse2 rsp) { + if (Util.isOverridden(AnnotatedLargeText.class, getClass(), "setContentType", StaplerResponse.class)) { + setContentType(StaplerResponse.fromStaplerResponse2(rsp)); + } else { + setContentTypeImpl(rsp); + } + } + + /** + * @deprecated use {@link #setContentType(StaplerResponse2)} + */ + @Deprecated protected void setContentType(StaplerResponse rsp) { + setContentTypeImpl(StaplerResponse.toStaplerResponse2(rsp)); + } + + private void setContentTypeImpl(StaplerResponse2 rsp) { rsp.setContentType(isHtml() ? "text/html;charset=UTF-8" : "text/plain;charset=UTF-8"); } - private ConsoleAnnotator createAnnotator(StaplerRequest req) throws IOException { + private ConsoleAnnotator createAnnotator(StaplerRequest2 req) throws IOException { try { String base64 = req != null ? req.getHeader("X-ConsoleAnnotator") : null; if (base64 != null) { @@ -176,7 +229,7 @@ public long writeRawLogTo(long start, OutputStream out) throws IOException { @CheckReturnValue public long writeHtmlTo(long start, Writer w) throws IOException { ConsoleAnnotationOutputStream caw = new ConsoleAnnotationOutputStream<>( - w, createAnnotator(Stapler.getCurrentRequest()), context, charset); + w, createAnnotator(Stapler.getCurrentRequest2()), context, charset); long r = super.writeLogTo(start, caw); ByteArrayOutputStream baos = new ByteArrayOutputStream(); @@ -185,7 +238,7 @@ public long writeHtmlTo(long start, Writer w) throws IOException { oos.writeLong(System.currentTimeMillis()); // send timestamp to prevent a replay attack oos.writeObject(caw.getConsoleAnnotator()); oos.close(); - StaplerResponse rsp = Stapler.getCurrentResponse(); + StaplerResponse2 rsp = Stapler.getCurrentResponse2(); if (rsp != null) rsp.setHeader("X-ConsoleAnnotator", Base64.getEncoder().encodeToString(baos.toByteArray())); return r; diff --git a/core/src/main/java/hudson/console/ConsoleAnnotationDescriptor.java b/core/src/main/java/hudson/console/ConsoleAnnotationDescriptor.java index bb68ccc66194..e63e2dab5cae 100644 --- a/core/src/main/java/hudson/console/ConsoleAnnotationDescriptor.java +++ b/core/src/main/java/hudson/console/ConsoleAnnotationDescriptor.java @@ -28,13 +28,13 @@ import hudson.DescriptorExtensionList; import hudson.ExtensionPoint; import hudson.model.Descriptor; +import jakarta.servlet.ServletException; import java.io.IOException; import java.net.URL; import java.util.concurrent.TimeUnit; -import javax.servlet.ServletException; import jenkins.model.Jenkins; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; /** @@ -81,12 +81,12 @@ private URL hasResource(String name) { } @WebMethod(name = "script.js") - public void doScriptJs(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doScriptJs(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { rsp.serveFile(req, hasResource("/script.js"), TimeUnit.DAYS.toMillis(1)); } @WebMethod(name = "style.css") - public void doStyleCss(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doStyleCss(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { rsp.serveFile(req, hasResource("/style.css"), TimeUnit.DAYS.toMillis(1)); } diff --git a/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java b/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java index b2f6948fd155..3e56f80ed5d0 100644 --- a/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java +++ b/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java @@ -28,15 +28,15 @@ import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.model.Run; +import jakarta.servlet.ServletException; import java.io.IOException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.net.URL; import java.util.concurrent.TimeUnit; -import javax.servlet.ServletException; import org.jvnet.tiger_types.Types; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; /** @@ -113,12 +113,12 @@ private URL getResource(String fileName) { * Serves the JavaScript file associated with this console annotator factory. */ @WebMethod(name = "script.js") - public void doScriptJs(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doScriptJs(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { rsp.serveFile(req, getResource("/script.js"), TimeUnit.DAYS.toMillis(1)); } @WebMethod(name = "style.css") - public void doStyleCss(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doStyleCss(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { rsp.serveFile(req, getResource("/style.css"), TimeUnit.DAYS.toMillis(1)); } diff --git a/core/src/main/java/hudson/console/HyperlinkNote.java b/core/src/main/java/hudson/console/HyperlinkNote.java index 1e582dab2b4a..8aa011660592 100644 --- a/core/src/main/java/hudson/console/HyperlinkNote.java +++ b/core/src/main/java/hudson/console/HyperlinkNote.java @@ -37,7 +37,7 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Turns a text into a hyperlink by specifying the URL separately. @@ -62,7 +62,7 @@ public HyperlinkNote(String url, int length) { public ConsoleAnnotator annotate(Object context, MarkupText text, int charPos) { String url = this.url; if (url.startsWith("/")) { - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req != null) { // if we are serving HTTP request, we want to use app relative URL url = req.getContextPath() + url; diff --git a/core/src/main/java/hudson/diagnosis/OldDataMonitor.java b/core/src/main/java/hudson/diagnosis/OldDataMonitor.java index e2bfa4678fc9..425c52150949 100644 --- a/core/src/main/java/hudson/diagnosis/OldDataMonitor.java +++ b/core/src/main/java/hudson/diagnosis/OldDataMonitor.java @@ -65,8 +65,8 @@ import org.kohsuke.stapler.HttpRedirect; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -310,7 +310,7 @@ public Iterator getVersionList() { * Depending on whether the user said "yes" or "no", send him to the right place. */ @RequirePOST - public HttpResponse doAct(StaplerRequest req, StaplerResponse rsp) throws IOException { + public HttpResponse doAct(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (req.hasParameter("no")) { disable(true); return HttpResponses.redirectViaContextPath("/manage"); @@ -324,7 +324,7 @@ public HttpResponse doAct(StaplerRequest req, StaplerResponse rsp) throws IOExce * Remove those items from the data map. */ @RequirePOST - public HttpResponse doUpgrade(StaplerRequest req, StaplerResponse rsp) { + public HttpResponse doUpgrade(StaplerRequest2 req, StaplerResponse2 rsp) { final String thruVerParam = req.getParameter("thruVer"); final VersionNumber thruVer = thruVerParam.equals("all") ? null : new VersionNumber(thruVerParam); @@ -341,7 +341,7 @@ public HttpResponse doUpgrade(StaplerRequest req, StaplerResponse rsp) { * Remove those items from the data map. */ @RequirePOST - public HttpResponse doDiscard(StaplerRequest req, StaplerResponse rsp) { + public HttpResponse doDiscard(StaplerRequest2 req, StaplerResponse2 rsp) { saveAndRemoveEntries(entry -> entry.getValue().max == null); return HttpResponses.forwardToPreviousPage(); @@ -377,7 +377,7 @@ private void saveAndRemoveEntries(Predicate handleException(j, e, req, rsp, 500)); + UncaughtExceptionFilter.setUncaughtExceptionHandler(j.getServletContext(), (e, context, req, rsp) -> handleException(j, e, req, rsp, 500)); try { Thread.setDefaultUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler()); LOGGER.log(Level.FINE, "Successfully installed a global UncaughtExceptionHandler."); @@ -53,10 +53,10 @@ private static void handleException(Jenkins j, Throwable e, HttpServletRequest r String id = UUID.randomUUID().toString(); LOGGER.log(isEOFException(e) ? Level.FINE : Level.WARNING, "Caught unhandled exception with ID " + id, e); req.setAttribute("jenkins.exception.id", id); - req.setAttribute("javax.servlet.error.exception", e); + req.setAttribute("jakarta.servlet.error.exception", e); rsp.setStatus(code); try { - WebApp.get(j.servletContext).getSomeStapler().invoke(req, rsp, j, "/oops"); + WebApp.get(j.getServletContext()).getSomeStapler().invoke(req, rsp, j, "/oops"); } catch (ServletException | IOException x) { if (!Stapler.isSocketException(x)) { throw x; @@ -75,7 +75,7 @@ public HttpResponses.HttpResponseException handleError(int code, Throwable cause } return new HttpResponses.HttpResponseException(cause) { @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { handleException(Jenkins.get(), cause, req, rsp, code); } }; diff --git a/core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java b/core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java index 875a3e4ef7e0..c54a90d1c576 100644 --- a/core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java +++ b/core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java @@ -35,6 +35,7 @@ import hudson.model.TaskListener; import hudson.util.StreamTaskListener; import hudson.util.jna.DotNet; +import jakarta.servlet.ServletException; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; @@ -43,7 +44,6 @@ import java.nio.file.Files; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import org.apache.commons.io.FileUtils; @@ -52,8 +52,8 @@ import org.apache.tools.ant.taskdefs.Move; import org.apache.tools.ant.types.FileSet; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -116,7 +116,7 @@ public boolean isInstalled() { * Performs installation. */ @RequirePOST - public void doDoInstall(StaplerRequest req, StaplerResponse rsp, @QueryParameter("dir") String _dir) throws IOException, ServletException { + public void doDoInstall(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter("dir") String _dir) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); if (installationDir != null) { @@ -168,7 +168,7 @@ public void doDoInstall(StaplerRequest req, StaplerResponse rsp, @QueryParameter /** * Copies a single resource into the target folder, by the given name, and handle errors gracefully. */ - private void copy(StaplerRequest req, StaplerResponse rsp, File dir, URL src, String name) throws ServletException, IOException { + private void copy(StaplerRequest2 req, StaplerResponse2 rsp, File dir, URL src, String name) throws ServletException, IOException { try { FileUtils.copyURLToFile(src, new File(dir, name)); } catch (IOException e) { @@ -179,7 +179,7 @@ private void copy(StaplerRequest req, StaplerResponse rsp, File dir, URL src, St } @RequirePOST - public void doRestart(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRestart(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); if (installationDir == null) { @@ -250,11 +250,11 @@ private DefaultLogger createLogger() { /** * Displays the error in a page. */ - protected final void sendError(Exception e, StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { + protected final void sendError(Exception e, StaplerRequest2 req, StaplerResponse2 rsp) throws ServletException, IOException { sendError(e.getMessage(), req, rsp); } - protected final void sendError(String message, StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { + protected final void sendError(String message, StaplerRequest2 req, StaplerResponse2 rsp) throws ServletException, IOException { req.setAttribute("message", message); req.setAttribute("pre", true); rsp.forward(Jenkins.get(), "error", req); diff --git a/core/src/main/java/hudson/logging/LogRecorder.java b/core/src/main/java/hudson/logging/LogRecorder.java index 86aea6575048..ad4c40028547 100644 --- a/core/src/main/java/hudson/logging/LogRecorder.java +++ b/core/src/main/java/hudson/logging/LogRecorder.java @@ -48,6 +48,7 @@ import hudson.util.HttpResponses; import hudson.util.RingBufferLogHandler; import hudson.util.XStream2; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.io.Serializable; @@ -71,7 +72,6 @@ import java.util.logging.LogManager; import java.util.logging.LogRecord; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.model.Loadable; import jenkins.security.MasterToSlaveCallable; @@ -82,8 +82,8 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; @@ -439,7 +439,7 @@ public LogRecorderManager getParent() { * Accepts submission from the configuration page. */ @POST - public synchronized void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); JSONObject src = req.getSubmittedForm(); @@ -536,7 +536,7 @@ public int hashCode() { * Deletes this recorder, then go back to the parent. */ @RequirePOST - public synchronized void doDoDelete(StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doDoDelete(StaplerResponse2 rsp) throws IOException, ServletException { delete(); rsp.sendRedirect2(".."); } @@ -562,7 +562,7 @@ public void delete() throws IOException { /** * RSS feed for log entries. */ - public void doRss(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRss(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { LogRecorderManager.doRss(req, rsp, getLogRecords()); } diff --git a/core/src/main/java/hudson/logging/LogRecorderManager.java b/core/src/main/java/hudson/logging/LogRecorderManager.java index 70856024df12..2c589adaa612 100644 --- a/core/src/main/java/hudson/logging/LogRecorderManager.java +++ b/core/src/main/java/hudson/logging/LogRecorderManager.java @@ -38,6 +38,7 @@ import hudson.model.RSS; import hudson.util.CopyOnWriteMap; import hudson.util.FormValidation; +import jakarta.servlet.ServletException; import java.io.File; import java.io.FileFilter; import java.io.IOException; @@ -53,7 +54,6 @@ import java.util.logging.LogManager; import java.util.logging.LogRecord; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.model.JenkinsLocationConfiguration; import jenkins.model.ModelObjectWithChildren; @@ -68,8 +68,8 @@ import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -188,7 +188,7 @@ public FormValidation doCheckNewName(@QueryParameter String name) { } @Override - public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + public ContextMenu doChildrenContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { ContextMenu menu = new ContextMenu(); menu.add("all", "All Jenkins Logs"); for (LogRecorder lr : recorders) { @@ -225,14 +225,14 @@ public HttpResponse doConfigLogger(@QueryParameter String name, @QueryParameter /** * RSS feed for log entries. */ - public void doRss(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRss(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { doRss(req, rsp, Jenkins.logRecords); } /** * Renders the given log recorders as RSS. */ - /*package*/ static void doRss(StaplerRequest req, StaplerResponse rsp, List logs) throws IOException, ServletException { + /*package*/ static void doRss(StaplerRequest2 req, StaplerResponse2 rsp, List logs) throws IOException, ServletException { // filter log records based on the log level String entryType = "all"; String level = req.getParameter("level"); diff --git a/core/src/main/java/hudson/markup/MarkupFormatter.java b/core/src/main/java/hudson/markup/MarkupFormatter.java index e588e0cfcc8e..a3bf53a739a1 100644 --- a/core/src/main/java/hudson/markup/MarkupFormatter.java +++ b/core/src/main/java/hudson/markup/MarkupFormatter.java @@ -28,6 +28,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.ExtensionPoint; import hudson.model.AbstractDescribableImpl; +import jakarta.servlet.ServletException; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; @@ -44,7 +45,8 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; import org.kohsuke.stapler.verb.GET; import org.kohsuke.stapler.verb.POST; @@ -138,7 +140,7 @@ public HttpResponse doPreviewDescription(@QueryParameter String text) throws IOE @GET @WebMethod(name = "previewDescription") @Restricted(NoExternalUse.class) - public HttpResponse previewsNowNeedPostForSecurity2153(@QueryParameter String text, StaplerRequest req) throws IOException { + public HttpResponse previewsNowNeedPostForSecurity2153(@QueryParameter String text, StaplerRequest2 req) throws IOException { LOGGER.log(Level.FINE, "Received a GET request at " + req.getRequestURL()); if (PREVIEWS_ALLOW_GET) { return doPreviewDescription(text); @@ -155,15 +157,18 @@ public HttpResponse previewsNowNeedPostForSecurity2153(@QueryParameter String te */ private static HttpResponse html(int status, @NonNull String html, @NonNull Map headers) { // TODO Move to Stapler's HttpResponses, (also add a corresponding 'text' method) - return (req, rsp, node) -> { - rsp.setContentType("text/html;charset=UTF-8"); - rsp.setStatus(status); - for (Map.Entry header : headers.entrySet()) { - rsp.setHeader(header.getKey(), header.getValue()); + return new HttpResponse() { + @Override + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { + rsp.setContentType("text/html;charset=UTF-8"); + rsp.setStatus(status); + for (Map.Entry header : headers.entrySet()) { + rsp.setHeader(header.getKey(), header.getValue()); + } + PrintWriter pw = rsp.getWriter(); + pw.print(html); + pw.flush(); } - PrintWriter pw = rsp.getWriter(); - pw.print(html); - pw.flush(); }; } } diff --git a/core/src/main/java/hudson/model/AbstractBuild.java b/core/src/main/java/hudson/model/AbstractBuild.java index 85d62df78896..d993d722eacb 100644 --- a/core/src/main/java/hudson/model/AbstractBuild.java +++ b/core/src/main/java/hudson/model/AbstractBuild.java @@ -62,6 +62,8 @@ import hudson.util.HttpResponses; import hudson.util.Iterators; import hudson.util.VariableResolver; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.io.InterruptedIOException; @@ -81,7 +83,6 @@ import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.model.lazy.BuildReference; import jenkins.model.lazy.LazyBuildMixIn; @@ -275,7 +276,7 @@ public Queue.Executable getParentExecutable() { */ @Deprecated(since = "2.364") public String getUpUrl() { - return Functions.getNearestAncestorUrl(Stapler.getCurrentRequest(), getParent()) + '/'; + return Functions.getNearestAncestorUrl(Stapler.getCurrentRequest2(), getParent()) + '/'; } /** @@ -1391,8 +1392,12 @@ public List getBuilds() { */ @Deprecated @RequirePOST // #doStop() should be preferred, but better to be safe - public void doStop(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - doStop().generateResponse(req, rsp, this); + public void doStop(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doStop().generateResponse(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), this); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } /** diff --git a/core/src/main/java/hudson/model/AbstractItem.java b/core/src/main/java/hudson/model/AbstractItem.java index adebec8f289f..af64ff19df34 100644 --- a/core/src/main/java/hudson/model/AbstractItem.java +++ b/core/src/main/java/hudson/model/AbstractItem.java @@ -25,7 +25,7 @@ package hudson.model; -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; +import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.NonNull; @@ -47,6 +47,8 @@ import hudson.util.FormValidation; import hudson.util.IOUtils; import hudson.util.Secret; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.io.OutputStream; @@ -59,7 +61,6 @@ import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.servlet.ServletException; import javax.xml.transform.Source; import javax.xml.transform.TransformerException; import javax.xml.transform.sax.SAXSource; @@ -70,6 +71,7 @@ import jenkins.model.Loadable; import jenkins.model.queue.ItemDeletion; import jenkins.security.NotReallyRoleSensitiveCallable; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.SystemProperties; import jenkins.util.xml.XMLUtils; import org.apache.tools.ant.Project; @@ -87,7 +89,9 @@ import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -530,7 +534,7 @@ public void onCopiedFrom(Item src) { @Override public final String getUrl() { // try to stick to the current view if possible - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); String shortUrl = getShortUrl(); String uri = req == null ? null : req.getRequestURI(); if (req != null) { @@ -644,9 +648,36 @@ private Object readResolve() { /** * Accepts the new description. + * + * @since TODO */ @RequirePOST - public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doSubmitDescription(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(AbstractItem.class, getClass(), "doSubmitDescription", StaplerRequest.class, StaplerResponse.class)) { + try { + doSubmitDescription(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doSubmitDescriptionImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doSubmitDescription(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doSubmitDescriptionImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void doSubmitDescriptionImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { checkPermission(CONFIGURE); setDescription(req.getParameter("description")); @@ -658,9 +689,32 @@ public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse * Note on the funny name: for reasons of historical compatibility, this URL is {@code /doDelete} * since it predates {@code }. {@code /delete} goes to a Jelly page * which should now be unused by core but is left in case plugins are still using it. + * + * @since TODO */ @RequirePOST - public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { + public void doDoDelete(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, InterruptedException { + if (Util.isOverridden(AbstractItem.class, getClass(), "doDoDelete", StaplerRequest.class, StaplerResponse.class)) { + try { + doDoDelete(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doDoDeleteImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doDoDelete(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException, InterruptedException { + doDoDeleteImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } + + private void doDoDeleteImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, InterruptedException { delete(); if (req == null || rsp == null) { // CLI return; @@ -681,8 +735,28 @@ public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOExcepti rsp.sendRedirect2(req.getContextPath() + '/' + url); } + /** + * @since TODO + */ @Override - public void delete(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void delete(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + deleteImpl(rsp); + } + + /** + * @deprecated use {@link #delete(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @Override + public void delete(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + deleteImpl(StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void deleteImpl(StaplerResponse2 rsp) throws IOException, ServletException { try { delete(); rsp.setStatus(204); @@ -755,10 +829,31 @@ protected void performDelete() throws IOException, InterruptedException { /** * Accepts {@code config.xml} submission, as well as serve it. + * + * @since TODO */ @WebMethod(name = "config.xml") + public void doConfigDotXml(StaplerRequest2 req, StaplerResponse2 rsp) + throws IOException { + if (Util.isOverridden(AbstractItem.class, getClass(), "doConfigDotXml", StaplerRequest.class, StaplerResponse.class)) { + doConfigDotXml(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } else { + doConfigDotXmlImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doConfigDotXml(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable public void doConfigDotXml(StaplerRequest req, StaplerResponse rsp) throws IOException { + doConfigDotXmlImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } + + private void doConfigDotXmlImpl(StaplerRequest2 req, StaplerResponse2 rsp) + throws IOException { if (req.getMethod().equals("GET")) { // read rsp.setContentType("application/xml"); diff --git a/core/src/main/java/hudson/model/AbstractModelObject.java b/core/src/main/java/hudson/model/AbstractModelObject.java index f6c7104f8e42..87b42527a86e 100644 --- a/core/src/main/java/hudson/model/AbstractModelObject.java +++ b/core/src/main/java/hudson/model/AbstractModelObject.java @@ -29,11 +29,14 @@ import hudson.search.SearchIndex; import hudson.search.SearchIndexBuilder; import hudson.search.SearchableModelObject; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -45,33 +48,69 @@ public abstract class AbstractModelObject implements SearchableModelObject { /** * Displays the error in a page. */ - protected final void sendError(Exception e, StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { + protected final void sendError(Exception e, StaplerRequest2 req, StaplerResponse2 rsp) throws ServletException, IOException { req.setAttribute("exception", e); sendError(e.getMessage(), req, rsp); } + /** + * @deprecated use {@link #sendError(Exception, StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + protected final void sendError(Exception e, StaplerRequest req, StaplerResponse rsp) throws javax.servlet.ServletException, IOException { + try { + sendError(e, StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException ex) { + throw ServletExceptionWrapper.fromJakartaServletException(ex); + } + } + protected final void sendError(Exception e) throws ServletException, IOException { - sendError(e, Stapler.getCurrentRequest(), Stapler.getCurrentResponse()); + sendError(e, Stapler.getCurrentRequest2(), Stapler.getCurrentResponse2()); } - protected final void sendError(String message, StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { + protected final void sendError(String message, StaplerRequest2 req, StaplerResponse2 rsp) throws ServletException, IOException { req.setAttribute("message", message); rsp.forward(this, "error", req); } + /** + * @deprecated use {@link #sendError(String, StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + protected final void sendError(String message, StaplerRequest req, StaplerResponse rsp) throws javax.servlet.ServletException, IOException { + try { + sendError(message, StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * @param pre * If true, the message is put in a PRE tag. */ - protected final void sendError(String message, StaplerRequest req, StaplerResponse rsp, boolean pre) throws ServletException, IOException { + protected final void sendError(String message, StaplerRequest2 req, StaplerResponse2 rsp, boolean pre) throws ServletException, IOException { req.setAttribute("message", message); if (pre) req.setAttribute("pre", true); rsp.forward(this, "error", req); } + /** + * @deprecated use {@link #sendError(String, StaplerRequest2, StaplerResponse2, boolean)} + */ + @Deprecated + protected final void sendError(String message, StaplerRequest req, StaplerResponse rsp, boolean pre) throws javax.servlet.ServletException, IOException { + try { + sendError(message, StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), pre); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + protected final void sendError(String message) throws ServletException, IOException { - sendError(message, Stapler.getCurrentRequest(), Stapler.getCurrentResponse()); + sendError(message, Stapler.getCurrentRequest2(), Stapler.getCurrentResponse2()); } /** @@ -82,7 +121,7 @@ protected final void sendError(String message) throws ServletException, IOExcept */ @Deprecated protected final void requirePOST() throws ServletException { - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req == null) return; // invoked outside the context of servlet String method = req.getMethod(); if (!method.equalsIgnoreCase("POST")) diff --git a/core/src/main/java/hudson/model/AbstractProject.java b/core/src/main/java/hudson/model/AbstractProject.java index 917ff1f7b81f..a380943687f7 100644 --- a/core/src/main/java/hudson/model/AbstractProject.java +++ b/core/src/main/java/hudson/model/AbstractProject.java @@ -77,6 +77,8 @@ import hudson.util.AlternativeUiTextProvider.Message; import hudson.util.DescribableList; import hudson.util.FormValidation; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -96,7 +98,6 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.BlockedBecauseOfBuildInProgress; import jenkins.model.Jenkins; import jenkins.model.ParameterizedJobMixIn; @@ -120,7 +121,9 @@ import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; @@ -769,7 +772,7 @@ public List getProminentActions() { @Override @POST - public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + public void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { super.doConfigSubmit(req, rsp); updateTransientActions(); @@ -1726,10 +1729,14 @@ protected SearchIndexBuilder makeSearchIndex() { // // - /** @deprecated use {@link #doBuild(StaplerRequest, StaplerResponse, TimeDuration)} */ + /** @deprecated use {@link #doBuild(StaplerRequest2, StaplerResponse2, TimeDuration)} */ @Deprecated - public void doBuild(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - doBuild(req, rsp, TimeDuration.fromString(req.getParameter("delay"))); + public void doBuild(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doBuild(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), TimeDuration.fromString(req.getParameter("delay"))); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } /** @@ -1739,7 +1746,7 @@ public void doBuild(StaplerRequest req, StaplerResponse rsp) throws IOException, * Inject {@link TimeDuration}. */ @Deprecated - public int getDelay(StaplerRequest req) throws ServletException { + public int getDelay(StaplerRequest req) throws javax.servlet.ServletException { String delay = req.getParameter("delay"); if (delay == null) return getQuietPeriod(); @@ -1749,26 +1756,59 @@ public int getDelay(StaplerRequest req) throws ServletException { if (delay.endsWith("secs")) delay = delay.substring(0, delay.length() - 4); return Integer.parseInt(delay); } catch (NumberFormatException e) { - throw new ServletException("Invalid delay parameter value: " + delay, e); + throw new javax.servlet.ServletException("Invalid delay parameter value: " + delay, e); } } - /** @deprecated use {@link #doBuildWithParameters(StaplerRequest, StaplerResponse, TimeDuration)} */ + /** @deprecated use {@link #doBuildWithParameters(StaplerRequest2, StaplerResponse2, TimeDuration)} */ @Deprecated - public void doBuildWithParameters(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - doBuildWithParameters(req, rsp, TimeDuration.fromString(req.getParameter("delay"))); + public void doBuildWithParameters(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doBuildWithParameters(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), TimeDuration.fromString(req.getParameter("delay"))); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } @Override // in case schedulePolling was overridden - public void doPolling(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doPolling(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { BuildAuthorizationToken.checkPermission((Job) this, authToken, req, rsp); schedulePolling(); rsp.sendRedirect("."); } + /** + * @since TODO + */ + @Override + protected void submit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { + if (Util.isOverridden(AbstractProject.class, getClass(), "submit", StaplerRequest.class, StaplerResponse.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + super.submit(req, rsp); + submitImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated @Override - protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException, FormException { super.submit(req, rsp); + try { + submitImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void submitImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { JSONObject json = req.getSubmittedForm(); makeDisabled(!json.optBoolean("enable")); @@ -1835,14 +1875,18 @@ protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOExceptio /** * @deprecated - * As of 1.261. Use {@link #buildDescribable(StaplerRequest, List)} instead. + * As of 1.261. Use {@link #buildDescribable(StaplerRequest2, List)} instead. */ @Deprecated - protected final > List buildDescribable(StaplerRequest req, List> descriptors, String prefix) throws FormException, ServletException { - return buildDescribable(req, descriptors); + protected final > List buildDescribable(StaplerRequest req, List> descriptors, String prefix) throws FormException, javax.servlet.ServletException { + try { + return buildDescribable(StaplerRequest.toStaplerRequest2(req), descriptors); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } - protected final > List buildDescribable(StaplerRequest req, List> descriptors) + protected final > List buildDescribable(StaplerRequest2 req, List> descriptors) throws FormException, ServletException { JSONObject data = req.getSubmittedForm(); @@ -1860,7 +1904,7 @@ protected final > List buildDescribable(StaplerReque /** * Serves the workspace files. */ - public DirectoryBrowserSupport doWs(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { + public DirectoryBrowserSupport doWs(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, InterruptedException { checkPermission(Item.WORKSPACE); FilePath ws = getSomeWorkspace(); if (ws == null || !ws.exists()) { @@ -1887,7 +1931,7 @@ public DirectoryBrowserSupport doWs(StaplerRequest req, StaplerResponse rsp) thr * Wipes out the workspace. */ @RequirePOST - public HttpResponse doDoWipeOutWorkspace() throws IOException, ServletException, InterruptedException { + public HttpResponse doDoWipeOutWorkspace() throws IOException, InterruptedException { checkPermission(Functions.isWipeOutPermissionEnabled() ? WIPEOUT : BUILD); R b = getSomeBuildWithWorkspace(); FilePath ws = b != null ? b.getWorkspace() : null; diff --git a/core/src/main/java/hudson/model/Actionable.java b/core/src/main/java/hudson/model/Actionable.java index 7e3e695d9c4f..d8088319021b 100644 --- a/core/src/main/java/hudson/model/Actionable.java +++ b/core/src/main/java/hudson/model/Actionable.java @@ -37,8 +37,11 @@ import java.util.logging.Logger; import jenkins.model.ModelObjectWithContextMenu; import jenkins.model.TransientActionFactory; +import jenkins.security.stapler.StaplerNotDispatchable; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -338,7 +341,26 @@ public T getAction(Class type) { return null; } + /** + * @since TODO + */ + public Object getDynamic(String token, StaplerRequest2 req, StaplerResponse2 rsp) { + if (Util.isOverridden(Actionable.class, getClass(), "getDynamic", String.class, StaplerRequest.class, StaplerResponse.class)) { + return getDynamic(token, StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } else { + return getDynamicImpl(token, req, rsp); + } + } + + /** + * @deprecated use {@link #getDynamic(String, StaplerRequest2, StaplerResponse2)} + */ + @Deprecated public Object getDynamic(String token, StaplerRequest req, StaplerResponse rsp) { + return getDynamicImpl(token, StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } + + private Object getDynamicImpl(String token, StaplerRequest2 req, StaplerResponse2 rsp) { for (Action a : getAllActions()) { if (a == null) continue; // be defensive @@ -351,7 +373,29 @@ public Object getDynamic(String token, StaplerRequest req, StaplerResponse rsp) return null; } - @Override public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + /** + * @since TODO + */ + @Override + public ContextMenu doContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { + if (Util.isOverridden(Actionable.class, getClass(), "doContextMenu", StaplerRequest.class, StaplerResponse.class)) { + return doContextMenu(StaplerRequest.fromStaplerRequest2(request), StaplerResponse.fromStaplerResponse2(response)); + } else { + return doContextMenuImpl(request, response); + } + } + + /** + * @deprecated use {@link #doContextMenu(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + @Override + public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + return doContextMenuImpl(StaplerRequest.toStaplerRequest2(request), StaplerResponse.toStaplerResponse2(response)); + } + + private ContextMenu doContextMenuImpl(StaplerRequest2 request, StaplerResponse2 response) throws Exception { return new ContextMenu().from(this, request, response); } diff --git a/core/src/main/java/hudson/model/AdministrativeMonitor.java b/core/src/main/java/hudson/model/AdministrativeMonitor.java index bdbfb48027d3..59518ba79e57 100644 --- a/core/src/main/java/hudson/model/AdministrativeMonitor.java +++ b/core/src/main/java/hudson/model/AdministrativeMonitor.java @@ -37,8 +37,8 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -175,7 +175,7 @@ public boolean isSecurity() { * URL binding to disable this monitor. */ @RequirePOST - public void doDisable(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doDisable(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); disable(true); rsp.sendRedirect2(req.getContextPath() + "/manage"); @@ -188,7 +188,7 @@ public void doDisable(StaplerRequest req, StaplerResponse rsp) throws IOExceptio * Changing this permission check to return {@link Jenkins#SYSTEM_READ} will make the active * administrative monitor appear on {@code manage.jelly} and on the globally visible * {@link jenkins.management.AdministrativeMonitorsDecorator} to users without Administer permission. - * {@link #doDisable(StaplerRequest, StaplerResponse)} will still always require Administer permission. + * {@link #doDisable(StaplerRequest2, StaplerResponse2)} will still always require Administer permission. *

*

* This method only allows for a single permission to be returned. If more complex permission checks are required, diff --git a/core/src/main/java/hudson/model/AllView.java b/core/src/main/java/hudson/model/AllView.java index ca1ef0d5cc0d..3972625ea7ab 100644 --- a/core/src/main/java/hudson/model/AllView.java +++ b/core/src/main/java/hudson/model/AllView.java @@ -26,7 +26,10 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; +import hudson.Util; import hudson.model.Descriptor.FormException; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.Collection; import java.util.List; @@ -34,12 +37,12 @@ import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.util.SystemProperties; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -91,7 +94,7 @@ public String getDisplayName() { @RequirePOST @Override - public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) + public Item doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { ItemGroup ig = getOwner().getItemGroup(); if (ig instanceof ModifiableItemGroup) @@ -110,7 +113,24 @@ public String getPostConstructLandingPage() { } @Override - protected void submit(StaplerRequest req) throws IOException, ServletException, FormException { + protected void submit(StaplerRequest2 req) throws IOException, ServletException, FormException { + if (Util.isOverridden(AllView.class, getClass(), "submit", StaplerRequest.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + // noop + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2)} + */ + @Deprecated + @Override + protected void submit(StaplerRequest req) throws IOException, javax.servlet.ServletException, FormException { // noop } diff --git a/core/src/main/java/hudson/model/Api.java b/core/src/main/java/hudson/model/Api.java index 23e72072112f..4b16e1b0b540 100644 --- a/core/src/main/java/hudson/model/Api.java +++ b/core/src/main/java/hudson/model/Api.java @@ -25,6 +25,10 @@ package hudson.model; import hudson.ExtensionList; +import hudson.Util; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; import java.io.StringReader; @@ -34,11 +38,10 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import javax.xml.transform.stream.StreamResult; import jenkins.model.Jenkins; import jenkins.security.SecureRequester; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.xml.FilteredFunctionContext; import org.dom4j.CharacterData; import org.dom4j.Document; @@ -52,7 +55,9 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.Flavor; import org.kohsuke.stapler.export.Model; @@ -96,7 +101,7 @@ public String getSearchUrl() { /** * Exposes the bean as XML. */ - public void doXml(StaplerRequest req, StaplerResponse rsp, + public void doXml(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String xpath, @QueryParameter String wrapper, @QueryParameter String tree, @@ -212,7 +217,7 @@ private boolean isSimpleOutput(Object result) { /** * Generate schema. */ - public void doSchema(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doSchema(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { setHeaders(rsp); rsp.setContentType("application/xml"); StreamResult r = new StreamResult(rsp.getOutputStream()); @@ -223,7 +228,32 @@ public void doSchema(StaplerRequest req, StaplerResponse rsp) throws IOException /** * Exposes the bean as JSON. */ - public void doJson(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doJson(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(Api.class, getClass(), "doJson", StaplerRequest.class, StaplerResponse.class)) { + try { + doJson(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doJsonImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doJson(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doJson(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doJsonImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void doJsonImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { if (req.getParameter("jsonp") == null || permit(req)) { setHeaders(rsp); rsp.serveExposedBean(req, bean, req.getParameter("jsonp") == null ? Flavor.JSON : Flavor.JSONP); @@ -235,12 +265,37 @@ public void doJson(StaplerRequest req, StaplerResponse rsp) throws IOException, /** * Exposes the bean as Python literal. */ - public void doPython(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doPython(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(Api.class, getClass(), "doPython", StaplerRequest.class, StaplerResponse.class)) { + try { + doPython(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doPythonImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doPython(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doPython(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doPythonImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void doPythonImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { setHeaders(rsp); rsp.serveExposedBean(req, bean, Flavor.PYTHON); } - private boolean permit(StaplerRequest req) { + private boolean permit(StaplerRequest2 req) { for (SecureRequester r : ExtensionList.lookup(SecureRequester.class)) { if (r.permit(req, bean)) { return true; @@ -250,7 +305,7 @@ private boolean permit(StaplerRequest req) { } @Restricted(NoExternalUse.class) - protected void setHeaders(StaplerResponse rsp) { + protected void setHeaders(StaplerResponse2 rsp) { rsp.setHeader("X-Jenkins", Jenkins.VERSION); rsp.setHeader("X-Jenkins-Session", Jenkins.SESSION_HASH); // to be really defensive against dumb browsers not taking into consideration the content-type being set diff --git a/core/src/main/java/hudson/model/AutoCompletionCandidates.java b/core/src/main/java/hudson/model/AutoCompletionCandidates.java index d2f5f17c255f..366f626e3144 100644 --- a/core/src/main/java/hudson/model/AutoCompletionCandidates.java +++ b/core/src/main/java/hudson/model/AutoCompletionCandidates.java @@ -28,16 +28,16 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.search.Search; import hudson.search.UserSearchProperty; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Locale; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Flavor; /** @@ -69,7 +69,7 @@ public List getValues() { } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object o) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object o) throws IOException, ServletException { Search.Result r = new Search.Result(); for (String value : values) { r.suggestions.add(new hudson.search.Search.Item(value)); diff --git a/core/src/main/java/hudson/model/BallColor.java b/core/src/main/java/hudson/model/BallColor.java index 5913f59466f9..3e8dc2f28802 100644 --- a/core/src/main/java/hudson/model/BallColor.java +++ b/core/src/main/java/hudson/model/BallColor.java @@ -113,7 +113,7 @@ public String getImage() { @Override public String getImageOf(String size) { - return Stapler.getCurrentRequest().getContextPath() + Jenkins.RESOURCE_PATH + "/images/" + size + '/' + image; + return Stapler.getCurrentRequest2().getContextPath() + Jenkins.RESOURCE_PATH + "/images/" + size + '/' + image; } /** diff --git a/core/src/main/java/hudson/model/BooleanParameterDefinition.java b/core/src/main/java/hudson/model/BooleanParameterDefinition.java index 6e9db32216fd..6bf1a50096e3 100644 --- a/core/src/main/java/hudson/model/BooleanParameterDefinition.java +++ b/core/src/main/java/hudson/model/BooleanParameterDefinition.java @@ -33,7 +33,7 @@ import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * {@link ParameterDefinition} that is either 'true' or 'false'. @@ -79,7 +79,7 @@ public void setDefaultValue(boolean defaultValue) { } @Override - public ParameterValue createValue(StaplerRequest req, JSONObject jo) { + public ParameterValue createValue(StaplerRequest2 req, JSONObject jo) { BooleanParameterValue value = req.bindJSON(BooleanParameterValue.class, jo); value.setDescription(getDescription()); return value; diff --git a/core/src/main/java/hudson/model/BuildAuthorizationToken.java b/core/src/main/java/hudson/model/BuildAuthorizationToken.java index a09ed113e1cf..3611824fb54d 100644 --- a/core/src/main/java/hudson/model/BuildAuthorizationToken.java +++ b/core/src/main/java/hudson/model/BuildAuthorizationToken.java @@ -27,11 +27,13 @@ import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; import hudson.Util; import hudson.security.ACL; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import javax.servlet.http.HttpServletResponse; import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.springframework.security.access.AccessDeniedException; /** @@ -51,7 +53,10 @@ public BuildAuthorizationToken(String token) { this.token = token; } - public static BuildAuthorizationToken create(StaplerRequest req) { + /** + * @since TODO + */ + public static BuildAuthorizationToken create(StaplerRequest2 req) { if (req.getParameter("pseudoRemoteTrigger") != null) { String token = Util.fixEmpty(req.getParameter("authToken")); if (token != null) @@ -61,11 +66,22 @@ public static BuildAuthorizationToken create(StaplerRequest req) { return null; } + /** + * @deprecated use {@link #create(StaplerRequest2)} + */ + @Deprecated + public static BuildAuthorizationToken create(StaplerRequest req) { + return create(StaplerRequest.toStaplerRequest2(req)); + } + @Deprecated public static void checkPermission(AbstractProject project, BuildAuthorizationToken token, StaplerRequest req, StaplerResponse rsp) throws IOException { - checkPermission((Job) project, token, req, rsp); + checkPermission((Job) project, token, StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); } - public static void checkPermission(Job project, BuildAuthorizationToken token, StaplerRequest req, StaplerResponse rsp) throws IOException { + /** + * @since TODO + */ + public static void checkPermission(Job project, BuildAuthorizationToken token, StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (token != null && token.token != null) { //check the provided token String providedToken = req.getParameter("token"); @@ -86,6 +102,14 @@ public static void checkPermission(Job project, BuildAuthorizationToken to throw HttpResponses.forwardToView(project, "requirePOST.jelly"); } + /** + * @deprecated use {@link #checkPermission(Job, BuildAuthorizationToken, StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + public static void checkPermission(Job project, BuildAuthorizationToken token, StaplerRequest req, StaplerResponse rsp) throws IOException { + checkPermission(project, token, StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } + public String getToken() { return token; } diff --git a/core/src/main/java/hudson/model/BuildTimelineWidget.java b/core/src/main/java/hudson/model/BuildTimelineWidget.java index 9691969162d4..4f5ccbf1c67a 100644 --- a/core/src/main/java/hudson/model/BuildTimelineWidget.java +++ b/core/src/main/java/hudson/model/BuildTimelineWidget.java @@ -25,12 +25,15 @@ package hudson.model; import hudson.util.RunList; +import jakarta.servlet.ServletException; +import java.io.IOException; import java.util.ArrayList; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * UI widget for showing the SIMILE timeline control. @@ -60,12 +63,15 @@ public BuildTimelineWidget(RunList builds) { return builds.getLastBuild(); } - public HttpResponse doData(StaplerRequest req, @QueryParameter long min, @QueryParameter long max) { - return (req1, rsp, node) -> { - JSONObject o = new JSONObject(); - o.put("events", JSONArray.fromObject(new ArrayList<>())); - rsp.setContentType("text/javascript;charset=UTF-8"); - o.write(rsp.getWriter()); + public HttpResponse doData(StaplerRequest2 req, @QueryParameter long min, @QueryParameter long max) { + return new HttpResponse() { + @Override + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { + JSONObject o = new JSONObject(); + o.put("events", JSONArray.fromObject(new ArrayList<>())); + rsp.setContentType("text/javascript;charset=UTF-8"); + o.write(rsp.getWriter()); + } }; } diff --git a/core/src/main/java/hudson/model/ChoiceParameterDefinition.java b/core/src/main/java/hudson/model/ChoiceParameterDefinition.java index 7b12a9b2cee3..98bdcf2e8072 100644 --- a/core/src/main/java/hudson/model/ChoiceParameterDefinition.java +++ b/core/src/main/java/hudson/model/ChoiceParameterDefinition.java @@ -20,7 +20,7 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.Exported; /** @@ -152,7 +152,7 @@ public boolean isValid(ParameterValue value) { } @Override - public ParameterValue createValue(StaplerRequest req, JSONObject jo) { + public ParameterValue createValue(StaplerRequest2 req, JSONObject jo) { StringParameterValue value = req.bindJSON(StringParameterValue.class, jo); value.setDescription(getDescription()); checkValue(value, value.getValue()); @@ -218,7 +218,7 @@ public String getHelpFile() { /* * We need this for JENKINS-26143 -- reflective creation cannot handle setChoices(Object). See that method for context. */ - public ParameterDefinition newInstance(@Nullable StaplerRequest req, @NonNull JSONObject formData) throws FormException { + public ParameterDefinition newInstance(@Nullable StaplerRequest2 req, @NonNull JSONObject formData) throws FormException { String name = formData.getString("name"); String desc = formData.getString("description"); String choiceText = formData.getString("choices"); diff --git a/core/src/main/java/hudson/model/Computer.java b/core/src/main/java/hudson/model/Computer.java index 14a311381a37..a4878a2c8f91 100644 --- a/core/src/main/java/hudson/model/Computer.java +++ b/core/src/main/java/hudson/model/Computer.java @@ -26,7 +26,7 @@ package hudson.model; -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; +import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; @@ -73,6 +73,7 @@ import hudson.util.RemotingDiagnostics; import hudson.util.RemotingDiagnostics.HeapDump; import hudson.util.RunList; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -105,7 +106,6 @@ import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.security.ImpersonatingExecutorService; import jenkins.security.MasterToSlaveCallable; @@ -129,8 +129,8 @@ import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -227,7 +227,7 @@ * @since 1.607 */ public void recordTermination() { - StaplerRequest request = Stapler.getCurrentRequest(); + StaplerRequest2 request = Stapler.getCurrentRequest2(); if (request != null) { terminatedBy.add(new TerminationRequest( String.format("Termination requested at %s by %s [id=%d] from HTTP request for %s", @@ -416,7 +416,7 @@ public String getOfflineCauseReason() { /** * If {@link #getChannel()}==null, attempts to relaunch the agent. */ - public abstract void doLaunchSlaveAgent(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException; + public abstract void doLaunchSlaveAgent(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException; /** * @deprecated since 2009-01-06. Use {@link #connect(boolean)} @@ -427,7 +427,7 @@ public final void launch() { } /** - * Do the same as {@link #doLaunchSlaveAgent(StaplerRequest, StaplerResponse)} + * Do the same as {@link #doLaunchSlaveAgent(StaplerRequest2, StaplerResponse2)} * but outside the context of serving a request. * *

@@ -1391,12 +1391,12 @@ public String call() throws IOException { // // @Restricted(DoNotUse.class) - public void doRssAll(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssAll(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (all builds)", getUrl(), getBuilds()); } @Restricted(DoNotUse.class) - public void doRssFailed(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssFailed(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (failed builds)", getUrl(), getBuilds().failureOnly()); } @@ -1407,7 +1407,7 @@ public void doRssFailed(StaplerRequest req, StaplerResponse rsp) throws IOExcept * @since 2.215 */ @Restricted(DoNotUse.class) - public void doRssLatest(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssLatest(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { final List lastBuilds = new ArrayList<>(); for (AbstractProject p : Jenkins.get().allItems(AbstractProject.class)) { if (p.getLastBuild() != null) { @@ -1452,7 +1452,7 @@ public Api getApi() { /** * Dumps the contents of the export table. */ - public void doDumpExportTable(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { + public void doDumpExportTable(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, InterruptedException { // this is a debug probe and may expose sensitive information checkPermission(Jenkins.ADMINISTER); @@ -1488,18 +1488,18 @@ public String call() throws IOException { * For system diagnostics. * Run arbitrary Groovy script. */ - public void doScript(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doScript(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { _doScript(req, rsp, "_script.jelly"); } /** * Run arbitrary Groovy script and return result as plain text. */ - public void doScriptText(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doScriptText(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { _doScript(req, rsp, "_scriptText.jelly"); } - protected void _doScript(StaplerRequest req, StaplerResponse rsp, String view) throws IOException, ServletException { + protected void _doScript(StaplerRequest2 req, StaplerResponse2 rsp, String view) throws IOException, ServletException { Jenkins._doScript(req, rsp, req.getView(this, view), getChannel(), getACL()); } @@ -1507,7 +1507,7 @@ protected void _doScript(StaplerRequest req, StaplerResponse rsp, String view) t * Accepts the update to the node configuration. */ @POST - public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + public void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { checkPermission(CONFIGURE); String proposedName = Util.fixEmptyAndTrim(req.getSubmittedForm().getString("name")); @@ -1547,7 +1547,7 @@ public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOExc * Accepts {@code config.xml} submission, as well as serve it. */ @WebMethod(name = "config.xml") - public void doConfigDotXml(StaplerRequest req, StaplerResponse rsp) + public void doConfigDotXml(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { if (req.getMethod().equals("GET")) { @@ -1626,7 +1626,7 @@ public void waitUntilOffline() throws InterruptedException { /** * Handles incremental log. */ - public void doProgressiveLog(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doProgressiveLog(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { getLogText().doProgressText(req, rsp); } diff --git a/core/src/main/java/hudson/model/ComputerSet.java b/core/src/main/java/hudson/model/ComputerSet.java index 5cb798978dea..f25d25a19a50 100644 --- a/core/src/main/java/hudson/model/ComputerSet.java +++ b/core/src/main/java/hudson/model/ComputerSet.java @@ -41,6 +41,7 @@ import hudson.util.DescribableList; import hudson.util.FormApply; import hudson.util.FormValidation; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; @@ -52,7 +53,6 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.model.ModelObjectWithChildren; import jenkins.model.ModelObjectWithContextMenu.ContextMenu; @@ -61,8 +61,8 @@ import net.sf.json.JSONObject; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -112,7 +112,7 @@ public Computer[] get_all() { } @Override - public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + public ContextMenu doChildrenContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { ContextMenu m = new ContextMenu(); for (Computer c : get_all()) { m.add(c); @@ -206,12 +206,12 @@ public String getSearchUrl() { return "/computers/"; } - public Computer getDynamic(String token, StaplerRequest req, StaplerResponse rsp) { + public Computer getDynamic(String token, StaplerRequest2 req, StaplerResponse2 rsp) { return Jenkins.get().getComputer(token); } @RequirePOST - public void do_launchAll(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void do_launchAll(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); for (Computer c : get_all()) { @@ -227,7 +227,7 @@ public void do_launchAll(StaplerRequest req, StaplerResponse rsp) throws IOExcep * TODO: ajax on the client side to wait until the update completion might be nice. */ @RequirePOST - public void doUpdateNow(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doUpdateNow(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.MANAGE); for (NodeMonitor nodeMonitor : NodeMonitor.getAll()) { @@ -244,7 +244,7 @@ public void doUpdateNow(StaplerRequest req, StaplerResponse rsp) throws IOExcept * First check point in creating a new agent. */ @RequirePOST - public synchronized void doCreateItem(StaplerRequest req, StaplerResponse rsp, + public synchronized void doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String name, @QueryParameter String mode, @QueryParameter String from) throws IOException, ServletException { final Jenkins app = Jenkins.get(); @@ -290,7 +290,7 @@ public synchronized void doCreateItem(StaplerRequest req, StaplerResponse rsp, * Really creates a new agent. */ @POST - public synchronized void doDoCreateItem(StaplerRequest req, StaplerResponse rsp, + public synchronized void doDoCreateItem(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String name, @QueryParameter String type) throws IOException, ServletException, FormException { final Jenkins app = Jenkins.get(); @@ -348,7 +348,7 @@ public FormValidation doCheckName(@QueryParameter String value) throws IOExcepti * Accepts submission from the configuration page. */ @POST - public synchronized HttpResponse doConfigSubmit(StaplerRequest req) throws IOException, ServletException, FormException { + public synchronized HttpResponse doConfigSubmit(StaplerRequest2 req) throws IOException, ServletException, FormException { BulkChange bc = new BulkChange(MONITORS_OWNER); try { Jenkins.get().checkPermission(Jenkins.MANAGE); diff --git a/core/src/main/java/hudson/model/Descriptor.java b/core/src/main/java/hudson/model/Descriptor.java index b5eb07784d27..e2067bfc6944 100644 --- a/core/src/main/java/hudson/model/Descriptor.java +++ b/core/src/main/java/hudson/model/Descriptor.java @@ -25,7 +25,7 @@ package hudson.model; import static hudson.util.QuotedStringTokenizer.quote; -import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; +import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; @@ -45,6 +45,9 @@ import hudson.util.ReflectionUtils; import hudson.util.ReflectionUtils.Parameter; import hudson.views.ListViewColumn; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletException; import java.beans.Introspector; import java.io.File; import java.io.IOException; @@ -71,13 +74,12 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletException; import jenkins.model.GlobalConfiguration; import jenkins.model.GlobalConfigurationCategory; import jenkins.model.Jenkins; import jenkins.model.Loadable; import jenkins.security.RedactSecretJsonInErrorMessageSanitizer; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.io.OnMaster; import net.sf.json.JSONArray; import net.sf.json.JSONObject; @@ -92,7 +94,9 @@ import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebApp; import org.kohsuke.stapler.jelly.JellyCompatibleFacet; import org.kohsuke.stapler.lang.Klass; @@ -382,7 +386,7 @@ public final String getDescriptorFullUrl() { * @since 1.402 */ public static String getCurrentDescriptorByNameUrl() { - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); // this override allows RenderOnDemandClosure to preserve the proper value Object url = req.getAttribute("currentDescriptorByNameUrl"); @@ -576,16 +580,33 @@ public T newInstance(StaplerRequest req) throws FormException { * * @throws FormException * Signals a problem in the submitted form. + * @since TODO + */ + public T newInstance(@Nullable StaplerRequest2 req, @NonNull JSONObject formData) throws FormException { + if (Util.isOverridden(Descriptor.class, getClass(), "newInstance", StaplerRequest.class, JSONObject.class)) { + return newInstance(req != null ? StaplerRequest.fromStaplerRequest2(req) : null, formData); + } else { + return newInstanceImpl(req, formData); + } + } + + /** + * @deprecated use {@link #newInstance(StaplerRequest2, JSONObject)} * @since 1.145 */ + @Deprecated public T newInstance(@Nullable StaplerRequest req, @NonNull JSONObject formData) throws FormException { + return newInstanceImpl(req != null ? StaplerRequest.toStaplerRequest2(req) : null, formData); + } + + private T newInstanceImpl(@Nullable StaplerRequest2 req, @NonNull JSONObject formData) throws FormException { try { Method m = getClass().getMethod("newInstance", StaplerRequest.class); if (!Modifier.isAbstract(m.getDeclaringClass().getModifiers())) { // this class overrides newInstance(StaplerRequest). // maintain the backward compatible behavior - return verifyNewInstance(newInstance(req)); + return verifyNewInstance(newInstance(StaplerRequest.fromStaplerRequest2(req))); } else { if (req == null) { // yes, req is supposed to be always non-null, but see the note above @@ -602,16 +623,25 @@ public T newInstance(@Nullable StaplerRequest req, @NonNull JSONObject formData) } /** - * Replacement for {@link StaplerRequest#bindJSON(Class, JSONObject)} which honors {@link #newInstance(StaplerRequest, JSONObject)}. - * This is automatically used inside {@link #newInstance(StaplerRequest, JSONObject)} so a direct call would only be necessary - * in case the top level binding might use a {@link Descriptor} which overrides {@link #newInstance(StaplerRequest, JSONObject)}. + * Replacement for {@link StaplerRequest2#bindJSON(Class, JSONObject)} which honors {@link #newInstance(StaplerRequest2, JSONObject)}. + * This is automatically used inside {@link #newInstance(StaplerRequest2, JSONObject)} so a direct call would only be necessary + * in case the top level binding might use a {@link Descriptor} which overrides {@link #newInstance(StaplerRequest2, JSONObject)}. + * @since TODO + */ + public static T bindJSON(StaplerRequest2 req, Class type, JSONObject src) { + return bindJSON(req, type, src, false); + } + + /** + * @deprecated use {@link #bindJSON(StaplerRequest2, Class, JSONObject)} * @since 2.342 */ + @Deprecated public static T bindJSON(StaplerRequest req, Class type, JSONObject src) { - return bindJSON(req, type, src, false); + return bindJSON(StaplerRequest.toStaplerRequest2(req), type, src); } - private static T bindJSON(StaplerRequest req, Class type, JSONObject src, boolean fromNewInstance) { + private static T bindJSON(StaplerRequest2 req, Class type, JSONObject src, boolean fromNewInstance) { BindInterceptor oldInterceptor = req.getBindInterceptor(); try { NewInstanceBindInterceptor interceptor; @@ -631,9 +661,9 @@ private static T bindJSON(StaplerRequest req, Class type, JSONObject src, } /** - * Ensures that calls to {@link StaplerRequest#bindJSON(Class, JSONObject)} from {@link #newInstance(StaplerRequest, JSONObject)} recurse properly. + * Ensures that calls to {@link StaplerRequest2#bindJSON(Class, JSONObject)} from {@link #newInstance(StaplerRequest2, JSONObject)} recurse properly. * {@code doConfigSubmit}-like methods will wind up calling {@code newInstance} directly - * or via {@link #newInstancesFromHeteroList(StaplerRequest, Object, Collection)}, + * or via {@link #newInstancesFromHeteroList(StaplerRequest2, Object, Collection)}, * which consult any custom {@code newInstance} overrides for top-level {@link Describable} objects. * But for nested describable objects Stapler would know nothing about {@code newInstance} without this trick. */ @@ -671,7 +701,7 @@ public Object instantiate(Class actualType, JSONObject json) { try { final Descriptor descriptor = Jenkins.get().getDescriptor(actualType); if (descriptor != null) { - return descriptor.newInstance(Stapler.getCurrentRequest(), json); + return descriptor.newInstance(Stapler.getCurrentRequest2(), json); } else { LOGGER.log(Level.WARNING, "Descriptor not found. Falling back to default instantiation " + actualType.getName() + " " + json); @@ -694,7 +724,7 @@ public Object onConvert(Type targetType, Class targetTypeErasure, Object jsonSou if (isApplicable(targetTypeErasure, json)) { LOGGER.log(Level.FINE, "switching to newInstance {0} {1}", new Object[] {targetTypeErasure.getName(), json}); try { - return Jenkins.get().getDescriptor(targetTypeErasure).newInstance(Stapler.getCurrentRequest(), json); + return Jenkins.get().getDescriptor(targetTypeErasure).newInstance(Stapler.getCurrentRequest2(), json); } catch (Exception x) { LOGGER.log(Level.WARNING, "falling back to default instantiation " + targetTypeErasure.getName() + " " + json, x); } @@ -776,13 +806,13 @@ public String getHelpFile(Klass clazz, String fieldName) { } try { - if (Stapler.getCurrentRequest().getView(c, "help" + suffix) != null) + if (Stapler.getCurrentRequest2().getView(c, "help" + suffix) != null) return page; } catch (IOException e) { throw new Error(e); } - if (getStaticHelpUrl(Stapler.getCurrentRequest(), c, suffix) != null) return page; + if (getStaticHelpUrl(Stapler.getCurrentRequest2(), c, suffix) != null) return page; } return null; } @@ -812,7 +842,7 @@ public final boolean isSubTypeOf(Class type) { /** * @deprecated - * As of 1.239, use {@link #configure(StaplerRequest, JSONObject)}. + * As of 1.239, use {@link #configure(StaplerRequest2, JSONObject)}. */ @Deprecated public boolean configure(StaplerRequest req) throws FormException { @@ -829,7 +859,21 @@ public boolean configure(StaplerRequest req) throws FormException { * See the developer documentation. * @return false * to keep the client in the same config page. + * @since TODO */ + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { + if (Util.isOverridden(Descriptor.class, getClass(), "configure", StaplerRequest.class, JSONObject.class)) { + return configure(StaplerRequest.fromStaplerRequest2(req), json); + } else { + // compatibility + return configure(StaplerRequest.fromStaplerRequest2(req)); + } + } + + /** + * @deprecated use {@link #configure(StaplerRequest2, JSONObject)} + */ + @Deprecated public boolean configure(StaplerRequest req, JSONObject json) throws FormException { // compatibility return configure(req); @@ -895,7 +939,7 @@ protected final String getViewPage(Class clazz, String pageName) { protected List getPossibleViewNames(String baseName) { List names = new ArrayList<>(); - for (Facet f : WebApp.get(Jenkins.get().servletContext).facets) { + for (Facet f : WebApp.get(Jenkins.get().getServletContext()).facets) { if (f instanceof JellyCompatibleFacet jcf) { for (String ext : jcf.getScriptExtensions()) names.add(baseName + ext); @@ -957,7 +1001,32 @@ protected PluginWrapper getPlugin() { /** * Serves {@code help.html} from the resource of {@link #clazz}. */ - public void doHelp(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doHelp(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(Descriptor.class, getClass(), "doHelp", StaplerRequest.class, StaplerResponse.class)) { + try { + doHelp(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doHelpImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doHelp(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doHelp(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doHelpImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void doHelpImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { String path = req.getRestOfPath(); if (path.contains("..")) throw new ServletException("Illegal path: " + path); @@ -972,13 +1041,13 @@ public void doHelp(StaplerRequest req, StaplerResponse rsp) throws IOException, } for (Klass c = getKlass(); c != null; c = c.getSuperClass()) { - RequestDispatcher rd = Stapler.getCurrentRequest().getView(c, "help" + path); + RequestDispatcher rd = Stapler.getCurrentRequest2().getView(c, "help" + path); if (rd != null) { // template based help page rd.forward(req, rsp); return; } - URL url = getStaticHelpUrl(Stapler.getCurrentRequest(), c, path); + URL url = getStaticHelpUrl(Stapler.getCurrentRequest2(), c, path); if (url != null) { // TODO: generalize macro expansion and perhaps even support JEXL rsp.setContentType("text/html;charset=UTF-8"); @@ -992,8 +1061,11 @@ public void doHelp(StaplerRequest req, StaplerResponse rsp) throws IOException, rsp.sendError(SC_NOT_FOUND); } + /** + * @since TODO + */ @Restricted(NoExternalUse.class) - public static URL getStaticHelpUrl(StaplerRequest req, Klass c, String suffix) { + public static URL getStaticHelpUrl(StaplerRequest2 req, Klass c, String suffix) { String base = "help" + suffix; URL url; @@ -1017,6 +1089,15 @@ public static URL getStaticHelpUrl(StaplerRequest req, Klass c, String suffix return c.getResource(base + ".html"); } + /** + * @deprecated use {@link #getStaticHelpUrl(StaplerRequest2, Klass, String)} + */ + @Deprecated + @Restricted(NoExternalUse.class) + public static URL getStaticHelpUrl(StaplerRequest req, Klass c, String suffix) { + return getStaticHelpUrl(StaplerRequest.toStaplerRequest2(req), c, suffix); + } + // // static methods @@ -1061,16 +1142,30 @@ Map, T> toMap(Iterable describables) { * List of descriptors to create instances from. * @return * Can be empty but never null. + * @since TODO */ public static > - List newInstancesFromHeteroList(StaplerRequest req, JSONObject formData, String key, + List newInstancesFromHeteroList(StaplerRequest2 req, JSONObject formData, String key, Collection> descriptors) throws FormException { return newInstancesFromHeteroList(req, formData.get(key), descriptors); } + /** + * @deprecated use {@link #newInstancesFromHeteroList(StaplerRequest2, JSONObject, String, Collection)} + */ + @Deprecated + public static > + List newInstancesFromHeteroList(StaplerRequest req, JSONObject formData, String key, + Collection> descriptors) throws FormException { + return newInstancesFromHeteroList(StaplerRequest.toStaplerRequest2(req), formData, key, descriptors); + } + + /** + * @since TODO + */ public static > - List newInstancesFromHeteroList(StaplerRequest req, Object formData, + List newInstancesFromHeteroList(StaplerRequest2 req, Object formData, Collection> descriptors) throws FormException { List items = new ArrayList<>(); @@ -1086,7 +1181,7 @@ List newInstancesFromHeteroList(StaplerRequest req, Object formData, if (kind != null) { // Only applies when Descriptor.getId is overridden. // Note that kind is only supported here, - // *not* inside the StaplerRequest.bindJSON which is normally called by newInstance + // *not* inside the StaplerRequest2.bindJSON which is normally called by newInstance // (since Descriptor.newInstance is not itself available to Stapler). // If you merely override getId for some reason, but use @DataBoundConstructor on your Describable, // there is no problem; but you can only rely on newInstance being called at top level. @@ -1114,6 +1209,16 @@ List newInstancesFromHeteroList(StaplerRequest req, Object formData, return items; } + /** + * @deprecated use {@link #newInstancesFromHeteroList(StaplerRequest2, JSONObject, String, Collection)} + */ + @Deprecated + public static > + List newInstancesFromHeteroList(StaplerRequest req, Object formData, + Collection> descriptors) throws FormException { + return newInstancesFromHeteroList(StaplerRequest.toStaplerRequest2(req), formData, descriptors); + } + /** * Finds a descriptor from a collection by its ID. * @param id should match {@link #getId} @@ -1199,7 +1304,7 @@ public String getFormField() { } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { if (FormApply.isApply(req)) { FormApply.applyResponse("notificationBar.show(" + quote(getMessage()) + ",notificationBar.ERROR)") .generateResponse(req, rsp, node); diff --git a/core/src/main/java/hudson/model/DirectlyModifiableView.java b/core/src/main/java/hudson/model/DirectlyModifiableView.java index 61362272c248..138f33a6a32c 100644 --- a/core/src/main/java/hudson/model/DirectlyModifiableView.java +++ b/core/src/main/java/hudson/model/DirectlyModifiableView.java @@ -26,8 +26,8 @@ import edu.umd.cs.findbugs.annotations.NonNull; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.interceptor.RequirePOST; diff --git a/core/src/main/java/hudson/model/DirectoryBrowserSupport.java b/core/src/main/java/hudson/model/DirectoryBrowserSupport.java index 9d455f4c1bd3..72da0c7514c1 100644 --- a/core/src/main/java/hudson/model/DirectoryBrowserSupport.java +++ b/core/src/main/java/hudson/model/DirectoryBrowserSupport.java @@ -27,6 +27,9 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.FilePath; import hudson.Util; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -55,8 +58,6 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import jenkins.security.MasterToSlaveCallable; import jenkins.security.ResourceDomainConfiguration; @@ -70,7 +71,9 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; /** * Has convenience methods to serve file system. @@ -157,7 +160,7 @@ public DirectoryBrowserSupport(ModelObject owner, VirtualFile base, String title } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { if (!ResourceDomainConfiguration.isResourceRequest(req) && ResourceDomainConfiguration.isResourceDomainConfigured()) { resourceToken = ResourceDomainRootAction.get().getToken(this, req); } @@ -191,11 +194,15 @@ public void setIndexFileName(String fileName) { * from the {@code doXYZ} method and let Stapler generate a response for you. */ @Deprecated - public void serveFile(StaplerRequest req, StaplerResponse rsp, FilePath root, String icon, boolean serveDirIndex) throws IOException, ServletException, InterruptedException { - serveFile(req, rsp, root.toVirtualFile(), icon, serveDirIndex); + public void serveFile(StaplerRequest req, StaplerResponse rsp, FilePath root, String icon, boolean serveDirIndex) throws IOException, javax.servlet.ServletException, InterruptedException { + try { + serveFile(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), root.toVirtualFile(), icon, serveDirIndex); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } - private void serveFile(StaplerRequest req, StaplerResponse rsp, VirtualFile root, String icon, boolean serveDirIndex) throws IOException, ServletException, InterruptedException { + private void serveFile(StaplerRequest2 req, StaplerResponse2 rsp, VirtualFile root, String icon, boolean serveDirIndex) throws IOException, ServletException, InterruptedException { // handle form submission String pattern = req.getParameter("pattern"); if (pattern == null) @@ -492,7 +499,7 @@ private boolean isDescendant(VirtualFile root, String relativePath) { } } - private String getPath(StaplerRequest req) { + private String getPath(StaplerRequest2 req) { String path = req.getRestOfPath(); if (path.isEmpty()) path = "/"; @@ -521,7 +528,7 @@ private static String createBackRef(int times) { return "../".repeat(times); } - private static void zip(StaplerResponse rsp, VirtualFile root, VirtualFile dir, String glob) throws IOException, InterruptedException { + private static void zip(StaplerResponse2 rsp, VirtualFile root, VirtualFile dir, String glob) throws IOException, InterruptedException { OutputStream outputStream = rsp.getOutputStream(); try (ZipOutputStream zos = new ZipOutputStream(outputStream)) { zos.setEncoding(Charset.defaultCharset().displayName()); // TODO JENKINS-20663 make this overridable via query parameter diff --git a/core/src/main/java/hudson/model/Executor.java b/core/src/main/java/hudson/model/Executor.java index 020399bdd5b8..94aa1c770d21 100644 --- a/core/src/main/java/hudson/model/Executor.java +++ b/core/src/main/java/hudson/model/Executor.java @@ -59,7 +59,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import javax.servlet.ServletException; import jenkins.model.CauseOfInterruption; import jenkins.model.CauseOfInterruption.UserInterruption; import jenkins.model.InterruptedBuildAction; @@ -852,7 +851,7 @@ public void start() { */ @RequirePOST @Deprecated - public void doStop(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doStop(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { doStop().generateResponse(req, rsp, this); } diff --git a/core/src/main/java/hudson/model/Failure.java b/core/src/main/java/hudson/model/Failure.java index 71318dd0464b..0546f0a7e090 100644 --- a/core/src/main/java/hudson/model/Failure.java +++ b/core/src/main/java/hudson/model/Failure.java @@ -25,12 +25,12 @@ package hudson.model; import edu.umd.cs.findbugs.annotations.CheckForNull; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Represents an error induced by user, encountered during HTTP request processing. @@ -55,7 +55,7 @@ public Failure(String message, boolean pre) { this.pre = pre; } - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node, @CheckForNull Throwable throwable) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node, @CheckForNull Throwable throwable) throws IOException, ServletException { if (throwable != null) { req.setAttribute("exception", throwable); } @@ -63,7 +63,7 @@ public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object nod } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { req.setAttribute("message", getMessage()); if (pre) req.setAttribute("pre", true); diff --git a/core/src/main/java/hudson/model/FileParameterDefinition.java b/core/src/main/java/hudson/model/FileParameterDefinition.java index 25cb08336da3..b8332f5911c5 100644 --- a/core/src/main/java/hudson/model/FileParameterDefinition.java +++ b/core/src/main/java/hudson/model/FileParameterDefinition.java @@ -29,17 +29,17 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import hudson.cli.CLICommand; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.util.Objects; -import javax.servlet.ServletException; import net.sf.json.JSONObject; import org.apache.commons.fileupload2.core.FileItem; import org.apache.commons.io.FileUtils; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * {@link ParameterDefinition} for doing file upload. @@ -65,7 +65,7 @@ public FileParameterDefinition(@NonNull String name, @CheckForNull String descri } @Override - public FileParameterValue createValue(StaplerRequest req, JSONObject jo) { + public FileParameterValue createValue(StaplerRequest2 req, JSONObject jo) { FileParameterValue p = req.bindJSON(FileParameterValue.class, jo); p.setLocation(getName()); p.setDescription(getDescription()); @@ -87,7 +87,7 @@ public String getHelpFile() { } @Override - public ParameterValue createValue(StaplerRequest req) { + public ParameterValue createValue(StaplerRequest2 req) { FileItem src; try { src = req.getFileItem2(getName()); diff --git a/core/src/main/java/hudson/model/FileParameterValue.java b/core/src/main/java/hudson/model/FileParameterValue.java index 343e30bb64f4..abeb1f41816a 100644 --- a/core/src/main/java/hudson/model/FileParameterValue.java +++ b/core/src/main/java/hudson/model/FileParameterValue.java @@ -50,8 +50,8 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * {@link ParameterValue} for {@link FileParameterDefinition}. @@ -235,9 +235,9 @@ public String toString() { } /** - * Serve this file parameter in response to a {@link StaplerRequest}. + * Serve this file parameter in response to a {@link StaplerRequest2}. */ - public DirectoryBrowserSupport doDynamic(StaplerRequest request, StaplerResponse response) { + public DirectoryBrowserSupport doDynamic(StaplerRequest2 request, StaplerResponse2 response) { AbstractBuild build = (AbstractBuild) request.findAncestor(AbstractBuild.class).getObject(); File fileParameter = getFileParameterFolderUnderBuild(build); return new DirectoryBrowserSupport(build, new FilePath(fileParameter), Messages.FileParameterValue_IndexTitle(), "folder.png", false); diff --git a/core/src/main/java/hudson/model/Hudson.java b/core/src/main/java/hudson/model/Hudson.java index 784fa47da20e..7d45fd63d749 100644 --- a/core/src/main/java/hudson/model/Hudson.java +++ b/core/src/main/java/hudson/model/Hudson.java @@ -38,14 +38,16 @@ import hudson.slaves.ComputerListener; import hudson.util.CopyOnWriteList; import hudson.util.FormValidation; +import io.jenkins.servlet.ServletContextWrapper; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.text.NumberFormat; import java.text.ParseException; import java.util.List; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import org.jvnet.hudson.reactor.ReactorException; import org.kohsuke.stapler.QueryParameter; @@ -78,14 +80,36 @@ public static Hudson getInstance() { return (Hudson) Jenkins.get(); } + /** + * @since TODO + */ public Hudson(File root, ServletContext context) throws IOException, InterruptedException, ReactorException { this(root, context, null); } + /** + * @deprecated use {@link #Hudson(File, ServletContext)} + */ + @Deprecated + public Hudson(File root, javax.servlet.ServletContext context) throws IOException, InterruptedException, ReactorException { + this(root, ServletContextWrapper.toJakartaServletContext(context)); + } + + /** + * @since TODO + */ public Hudson(File root, ServletContext context, PluginManager pluginManager) throws IOException, InterruptedException, ReactorException { super(root, context, pluginManager); } + /** + * @deprecated use {@link #Hudson(File, ServletContext, PluginManager)} + */ + @Deprecated + public Hudson(File root, javax.servlet.ServletContext context, PluginManager pluginManager) throws IOException, InterruptedException, ReactorException { + this(root, ServletContextWrapper.toJakartaServletContext(context), pluginManager); + } + /** * Gets all the installed {@link ItemListener}s. * @@ -173,8 +197,12 @@ public TopLevelItem getJobCaseInsensitive(String name) { */ @Deprecated @RequirePOST - public synchronized void doQuietDown(StaplerResponse rsp) throws IOException, ServletException { - doQuietDown().generateResponse(null, rsp, this); + public synchronized void doQuietDown(StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doQuietDown().generateResponse(null, StaplerResponse.toStaplerResponse2(rsp), this); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } /** @@ -184,7 +212,7 @@ public synchronized void doQuietDown(StaplerResponse rsp) throws IOException, Se * As on 1.267, moved to "/log/rss..." */ @Deprecated - public void doLogRss(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doLogRss(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { String qs = req.getQueryString(); rsp.sendRedirect2("./log/rss" + (qs == null ? "" : '?' + qs)); } @@ -194,7 +222,7 @@ public void doLogRss(StaplerRequest req, StaplerResponse rsp) throws IOException * Define your own check method, instead of relying on this generic one. */ @Deprecated - public void doFieldCheck(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doFieldCheck(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { doFieldCheck( fixEmpty(req.getParameter("value")), fixEmpty(req.getParameter("type")), diff --git a/core/src/main/java/hudson/model/Item.java b/core/src/main/java/hudson/model/Item.java index a57011579b15..838f4e6f75a7 100644 --- a/core/src/main/java/hudson/model/Item.java +++ b/core/src/main/java/hudson/model/Item.java @@ -41,7 +41,7 @@ import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import jenkins.util.io.OnMaster; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Basic configuration unit in Hudson. @@ -183,7 +183,7 @@ default String getRelativeNameFrom(@NonNull Item item) { /** * Returns the absolute URL of this item. This relies on the current - * {@link StaplerRequest} to figure out what the host name is, + * {@link StaplerRequest2} to figure out what the host name is, * so can be used only during processing client requests. * * @return diff --git a/core/src/main/java/hudson/model/ItemGroupMixIn.java b/core/src/main/java/hudson/model/ItemGroupMixIn.java index faa214dee621..62a46f395247 100644 --- a/core/src/main/java/hudson/model/ItemGroupMixIn.java +++ b/core/src/main/java/hudson/model/ItemGroupMixIn.java @@ -32,6 +32,9 @@ import hudson.util.CopyOnWriteMap; import hudson.util.Function1; import hudson.util.Secret; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -42,8 +45,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import javax.xml.transform.TransformerException; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; @@ -51,7 +52,9 @@ import jenkins.security.NotReallyRoleSensitiveCallable; import jenkins.util.xml.XMLUtils; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.springframework.security.access.AccessDeniedException; import org.xml.sax.SAXException; @@ -140,8 +143,10 @@ public static Map loadChildren(ItemGroup parent, File /** * Creates a {@link TopLevelItem} for example from the submission of the {@code /lib/hudson/newFromList/form} tag * or throws an exception if it fails. + * + * @since TODO */ - public synchronized TopLevelItem createTopLevelItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized TopLevelItem createTopLevelItem(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { acl.checkPermission(Item.CREATE); TopLevelItem result; @@ -206,10 +211,22 @@ public synchronized TopLevelItem createTopLevelItem(StaplerRequest req, StaplerR return result; } + /** + * @deprecated use {@link #createTopLevelItem(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + public synchronized TopLevelItem createTopLevelItem(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + return createTopLevelItem(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * Computes the redirection target URL for the newly created {@link TopLevelItem}. */ - protected String redirectAfterCreateItem(StaplerRequest req, TopLevelItem result) throws IOException { + protected String redirectAfterCreateItem(StaplerRequest2 req, TopLevelItem result) throws IOException { return req.getContextPath() + '/' + result.getUrl() + "configure"; } diff --git a/core/src/main/java/hudson/model/Job.java b/core/src/main/java/hudson/model/Job.java index 4bd28ff2e325..10637d666d68 100644 --- a/core/src/main/java/hudson/model/Job.java +++ b/core/src/main/java/hudson/model/Job.java @@ -24,8 +24,8 @@ package hudson.model; -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; -import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT; +import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST; +import static jakarta.servlet.http.HttpServletResponse.SC_NO_CONTENT; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.CheckForNull; @@ -69,6 +69,8 @@ import hudson.widgets.HistoryWidget; import hudson.widgets.HistoryWidget.Adapter; import hudson.widgets.Widget; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.awt.Color; import java.awt.Paint; import java.io.File; @@ -85,7 +87,6 @@ import java.util.SortedMap; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.BuildDiscarder; import jenkins.model.BuildDiscarderProperty; import jenkins.model.DirectlyModifiableTopLevelItemGroup; @@ -98,6 +99,7 @@ import jenkins.model.lazy.LazyBuildMixIn; import jenkins.scm.RunWithSCM; import jenkins.security.HexStringConfidentialKey; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.triggers.SCMTriggerItem; import jenkins.widgets.HasWidgets; import net.sf.json.JSONException; @@ -122,7 +124,9 @@ import org.kohsuke.args4j.CmdLineException; import org.kohsuke.stapler.StaplerOverridable; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; @@ -854,9 +858,43 @@ public RunT getNearestOldBuild(int n) { return m.get(m.firstKey()); } + /** + * @since TODO + */ + @Override + public Object getDynamic(String token, StaplerRequest2 req, + StaplerResponse2 rsp) { + if (Util.isOverridden(Job.class, getClass(), "getDynamic", String.class, StaplerRequest.class, StaplerResponse.class)) { + return getDynamic(token, StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } + try { + // try to interpret the token as build number + return getBuildByNumber(Integer.parseInt(token)); + } catch (NumberFormatException e) { + // try to map that to widgets + for (Widget w : getWidgets()) { + if (w.getUrlName().equals(token)) + return w; + } + + // is this a permalink? + for (Permalink p : getPermalinks()) { + if (p.getId().equals(token)) + return p.resolve(this); + } + + return super.getDynamic(token, req, rsp); + } + } + + /** + * @deprecated use {@link #getDynamic(String, StaplerRequest2, StaplerResponse2)} + */ + @Deprecated @Override public Object getDynamic(String token, StaplerRequest req, StaplerResponse rsp) { + // Intentionally not factoring this out into a common implementation method because it contains a call to super. try { // try to interpret the token as build number return getBuildByNumber(Integer.parseInt(token)); @@ -1092,7 +1130,7 @@ public PermalinkList getPermalinks() { * * @since 2.60 */ - public void doRssChangelog(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssChangelog(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { class FeedItem { ChangeLogSet.Entry e; int idx; @@ -1168,8 +1206,29 @@ public String getEntryAuthor(FeedItem entry) { } + /** + * @since TODO + */ + @Override + public ContextMenu doChildrenContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { + if (Util.isOverridden(Job.class, getClass(), "doChildrenContextMenu", StaplerRequest.class, StaplerResponse.class)) { + return doChildrenContextMenu(StaplerRequest.fromStaplerRequest2(request), StaplerResponse.fromStaplerResponse2(response)); + } else { + return doChildrenContextMenuImpl(request, response); + } + } - @Override public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + /** + * @deprecated use {@link #doChildrenContextMenu(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + @Override + public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + return doChildrenContextMenuImpl(StaplerRequest.toStaplerRequest2(request), StaplerResponse.toStaplerResponse2(response)); + } + + private ContextMenu doChildrenContextMenuImpl(StaplerRequest2 request, StaplerResponse2 response) { // not sure what would be really useful here. This needs more thoughts. // for the time being, I'm starting with permalinks ContextMenu menu = new ContextMenu(); @@ -1327,8 +1386,8 @@ private HealthReport getBuildStabilityHealthReport() { * Accepts submission from the configuration page. */ @POST - public synchronized void doConfigSubmit(StaplerRequest req, - StaplerResponse rsp) throws IOException, ServletException, FormException { + public synchronized void doConfigSubmit(StaplerRequest2 req, + StaplerResponse2 rsp) throws IOException, ServletException, FormException { checkPermission(CONFIGURE); description = req.getParameter("description"); @@ -1373,15 +1432,32 @@ public synchronized void doConfigSubmit(StaplerRequest req, /** * Derived class can override this to perform additional config submission * work. + * + * @since TODO */ - protected void submit(StaplerRequest req, StaplerResponse rsp) + protected void submit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { + if (Util.isOverridden(Job.class, getClass(), "submit", StaplerRequest.class, StaplerResponse.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + protected void submit(StaplerRequest req, StaplerResponse rsp) + throws IOException, javax.servlet.ServletException, FormException { } /** * Accepts and serves the job description */ - public void doDescription(StaplerRequest req, StaplerResponse rsp) + public void doDescription(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (req.getMethod().equals("GET")) { //read @@ -1407,7 +1483,7 @@ public void doDescription(StaplerRequest req, StaplerResponse rsp) /** * Returns the image that shows the current buildCommand status. */ - public void doBuildStatus(StaplerRequest req, StaplerResponse rsp) + public void doBuildStatus(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { rsp.sendRedirect2(req.getContextPath() + "/images/48x48/" + getBuildStatusUrl()); } @@ -1577,7 +1653,7 @@ private Calendar getLastBuildTime() { @RequirePOST public/* not synchronized. see renameTo() */void doDoRename( StaplerRequest req, StaplerResponse rsp) throws IOException, - ServletException { + javax.servlet.ServletException { String newName = req.getParameter("newName"); doConfirmRename(newName).generateResponse(req, rsp, null); } @@ -1589,12 +1665,12 @@ protected void checkRename(String newName) throws Failure { } } - public void doRssAll(StaplerRequest req, StaplerResponse rsp) + public void doRssAll(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (all builds)", getUrl(), getBuilds().newBuilds()); } - public void doRssFailed(StaplerRequest req, StaplerResponse rsp) + public void doRssFailed(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (failed builds)", getUrl(), getBuilds().failureOnly().newBuilds()); } diff --git a/core/src/main/java/hudson/model/JobProperty.java b/core/src/main/java/hudson/model/JobProperty.java index 14ff87591fe9..70ef159547c0 100644 --- a/core/src/main/java/hudson/model/JobProperty.java +++ b/core/src/main/java/hudson/model/JobProperty.java @@ -27,6 +27,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.ExtensionPoint; import hudson.Launcher; +import hudson.Util; import hudson.model.Descriptor.FormException; import hudson.model.queue.SubTask; import hudson.tasks.BuildStep; @@ -41,6 +42,7 @@ import jenkins.model.OptionalJobProperty; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.ExportedBean; /** @@ -183,8 +185,28 @@ public Collection getJobOverrides() { return Collections.emptyList(); } + /** + * @since TODO + */ + @Override + public JobProperty reconfigure(StaplerRequest2 req, JSONObject form) throws FormException { + if (Util.isOverridden(JobProperty.class, getClass(), "reconfigure", StaplerRequest.class, JSONObject.class)) { + return reconfigure(StaplerRequest.fromStaplerRequest2(req), form); + } else { + return reconfigureImpl(req, form); + } + } + + /** + * @deprecated use {@link #reconfigure(StaplerRequest2, JSONObject)} + */ + @Deprecated @Override public JobProperty reconfigure(StaplerRequest req, JSONObject form) throws FormException { + return reconfigureImpl(StaplerRequest.toStaplerRequest2(req), form); + } + + private JobProperty reconfigureImpl(StaplerRequest2 req, JSONObject form) throws FormException { return form == null ? null : getDescriptor().newInstance(req, form); } diff --git a/core/src/main/java/hudson/model/JobPropertyDescriptor.java b/core/src/main/java/hudson/model/JobPropertyDescriptor.java index 1f1c3aa7e6f0..eb9b990b7056 100644 --- a/core/src/main/java/hudson/model/JobPropertyDescriptor.java +++ b/core/src/main/java/hudson/model/JobPropertyDescriptor.java @@ -24,6 +24,7 @@ package hudson.model; +import hudson.Util; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; @@ -34,6 +35,7 @@ import net.sf.json.JSONObject; import org.jvnet.tiger_types.Types; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * {@link Descriptor} for {@link JobProperty}. @@ -61,6 +63,23 @@ protected JobPropertyDescriptor() { * null to avoid setting an instance of {@link JobProperty} to the target project (or just use {@link OptionalJobProperty}) */ @Override + public JobProperty newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { + if (Util.isOverridden(JobPropertyDescriptor.class, getClass(), "newInstance", StaplerRequest.class, JSONObject.class)) { + return newInstance(req != null ? StaplerRequest.fromStaplerRequest2(req) : null, formData); + } else { + // JobPropertyDescriptors are bit different in that we allow them even without any user-visible configuration parameter, + // so replace the lack of form data by an empty one. + if (formData.isNullObject()) formData = new JSONObject(); + + return super.newInstance(req, formData); + } + } + + /** + * @deprecated use {@link #newInstance(StaplerRequest2, JSONObject)} + */ + @Deprecated + @Override public JobProperty newInstance(StaplerRequest req, JSONObject formData) throws FormException { // JobPropertyDescriptors are bit different in that we allow them even without any user-visible configuration parameter, // so replace the lack of form data by an empty one. diff --git a/core/src/main/java/hudson/model/Label.java b/core/src/main/java/hudson/model/Label.java index 88661c6df690..53c51db9cc4b 100644 --- a/core/src/main/java/hudson/model/Label.java +++ b/core/src/main/java/hudson/model/Label.java @@ -71,8 +71,8 @@ import org.antlr.v4.runtime.CommonTokenStream; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -548,7 +548,7 @@ public String toString() { } @Override - public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + public ContextMenu doChildrenContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { ContextMenu menu = new ContextMenu(); for (Node node : getNodes()) { menu.add(node); diff --git a/core/src/main/java/hudson/model/ListView.java b/core/src/main/java/hudson/model/ListView.java index d8f6a8d48bcb..a2e25f1f1d1b 100644 --- a/core/src/main/java/hudson/model/ListView.java +++ b/core/src/main/java/hudson/model/ListView.java @@ -41,6 +41,8 @@ import hudson.views.ListViewColumn; import hudson.views.StatusFilter; import hudson.views.ViewJobFilter; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; @@ -55,7 +57,6 @@ import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import net.jcip.annotations.GuardedBy; import net.sf.json.JSONObject; @@ -67,7 +68,8 @@ import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; import org.springframework.security.access.AccessDeniedException; @@ -97,7 +99,7 @@ public class ListView extends View implements DirectlyModifiableView { /** * Whether to recurse in ItemGroups */ - private boolean recurse; + private volatile boolean recurse; /** * Compiled include pattern from the includeRegex string. @@ -357,7 +359,7 @@ public boolean isAddToCurrentView() { } } - private boolean needToAddToCurrentView(StaplerRequest req) throws ServletException { + private boolean needToAddToCurrentView(StaplerRequest2 req) throws ServletException { String json = req.getParameter("json"); if (json != null && !json.isEmpty()) { // Submitted via UI @@ -371,7 +373,7 @@ private boolean needToAddToCurrentView(StaplerRequest req) throws ServletExcepti @Override @POST - public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public Item doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { ItemGroup ig = getOwner().getItemGroup(); if (ig instanceof ModifiableItemGroup) { TopLevelItem item = ((ModifiableItemGroup) ig).doCreateItem(req, rsp); @@ -439,7 +441,32 @@ public HttpResponse doRemoveJobFromView(@QueryParameter String name) throws IOEx * Load view-specific properties here. */ @Override - protected void submit(StaplerRequest req) throws ServletException, FormException, IOException { + protected void submit(StaplerRequest2 req) throws ServletException, FormException, IOException { + if (Util.isOverridden(View.class, getClass(), "submit", StaplerRequest.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + submitImpl(req); + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2)} + */ + @Deprecated + @Override + protected void submit(StaplerRequest req) throws javax.servlet.ServletException, FormException, IOException { + try { + submitImpl(StaplerRequest.toStaplerRequest2(req)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void submitImpl(StaplerRequest2 req) throws ServletException, FormException, IOException { JSONObject json = req.getSubmittedForm(); synchronized (this) { recurse = json.optBoolean("recurse", true); diff --git a/core/src/main/java/hudson/model/ManageJenkinsAction.java b/core/src/main/java/hudson/model/ManageJenkinsAction.java index c6c37a57662a..776b37c4f265 100644 --- a/core/src/main/java/hudson/model/ManageJenkinsAction.java +++ b/core/src/main/java/hudson/model/ManageJenkinsAction.java @@ -36,8 +36,8 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerFallback; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Adds the "Manage Jenkins" link to the top page. @@ -70,7 +70,7 @@ public Object getStaplerFallback() { } @Override - public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws JellyException, IOException { + public ContextMenu doContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws JellyException, IOException { return new ContextMenu().from(this, request, response, "index"); } @@ -80,7 +80,7 @@ public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse respons */ @Restricted(NoExternalUse.class) public void addContextMenuItem(ContextMenu menu, String url, String icon, String iconXml, String text, boolean post, boolean requiresConfirmation, Badge badge, String message) { - if (Stapler.getCurrentRequest().findAncestorObject(this.getClass()) != null || !Util.isSafeToRedirectTo(url)) { + if (Stapler.getCurrentRequest2().findAncestorObject(this.getClass()) != null || !Util.isSafeToRedirectTo(url)) { // Default behavior if the URL is absolute or scheme-relative, or the current object is an ancestor (i.e. would resolve correctly) menu.add(url, icon, iconXml, text, post, requiresConfirmation, badge, message); return; diff --git a/core/src/main/java/hudson/model/ModifiableItemGroup.java b/core/src/main/java/hudson/model/ModifiableItemGroup.java index 726a0455dc74..35e41305afb5 100644 --- a/core/src/main/java/hudson/model/ModifiableItemGroup.java +++ b/core/src/main/java/hudson/model/ModifiableItemGroup.java @@ -24,10 +24,15 @@ package hudson.model; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; +import jenkins.security.stapler.StaplerNotDispatchable; +import org.kohsuke.stapler.ReflectionUtils; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; /** * {@link ItemGroup} that is a general purpose container, which allows users and the rest of the program @@ -45,5 +50,45 @@ public interface ModifiableItemGroup extends ItemGroup { * The request format follows that of {@code <n:form xmlns:n="/lib/form">}. * */ - T doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException; + @StaplerNotDispatchable + default T doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (ReflectionUtils.isOverridden( + ModifiableItemGroup.class, + getClass(), + "doCreateItem", + StaplerRequest.class, + StaplerResponse.class)) { + try { + return doCreateItem(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + ModifiableItemGroup.class.getSimpleName() + ".doCreateItem methods"); + } + } + + /** + * @deprecated use {@link #doCreateItem(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + default T doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + if (ReflectionUtils.isOverridden( + ModifiableItemGroup.class, + getClass(), + "doCreateItem", + StaplerRequest2.class, + StaplerResponse2.class)) { + try { + return doCreateItem(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + ModifiableItemGroup.class.getSimpleName() + ".doCreateItem methods"); + } + } } diff --git a/core/src/main/java/hudson/model/MultiStageTimeSeries.java b/core/src/main/java/hudson/model/MultiStageTimeSeries.java index ea9d25a043c0..84963cde928f 100644 --- a/core/src/main/java/hudson/model/MultiStageTimeSeries.java +++ b/core/src/main/java/hudson/model/MultiStageTimeSeries.java @@ -26,6 +26,7 @@ import hudson.util.ChartUtil; import hudson.util.NoOverlapCategoryAxis; +import jakarta.servlet.ServletException; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; @@ -39,7 +40,6 @@ import java.util.List; import java.util.Locale; import java.util.concurrent.TimeUnit; -import javax.servlet.ServletException; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis; @@ -53,7 +53,9 @@ import org.jvnet.localizer.Localizable; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -298,8 +300,8 @@ protected void configurePlot(CategoryPlot plot) { * Renders this object as an image. */ @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { - ChartUtil.generateGraph(req, rsp, createChart(), 500, 400); + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { + ChartUtil.generateGraph(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp), createChart(), 500, 400); } } diff --git a/core/src/main/java/hudson/model/MyView.java b/core/src/main/java/hudson/model/MyView.java index bc98d9a55f7f..93c9967e0e86 100644 --- a/core/src/main/java/hudson/model/MyView.java +++ b/core/src/main/java/hudson/model/MyView.java @@ -26,18 +26,21 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; +import hudson.Util; import hudson.model.Descriptor.FormException; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -64,7 +67,7 @@ public boolean contains(TopLevelItem item) { @RequirePOST @Override - public TopLevelItem doCreateItem(StaplerRequest req, StaplerResponse rsp) + public TopLevelItem doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { ItemGroup ig = getOwner().getItemGroup(); if (ig instanceof ModifiableItemGroup) { @@ -85,7 +88,24 @@ public String getPostConstructLandingPage() { } @Override - protected void submit(StaplerRequest req) throws IOException, ServletException, FormException { + protected void submit(StaplerRequest2 req) throws IOException, ServletException, FormException { + if (Util.isOverridden(MyView.class, getClass(), "submit", StaplerRequest.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + // noop + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2)} + */ + @Deprecated + @Override + protected void submit(StaplerRequest req) throws IOException, javax.servlet.ServletException, FormException { // noop } diff --git a/core/src/main/java/hudson/model/MyViewsProperty.java b/core/src/main/java/hudson/model/MyViewsProperty.java index 49fdfac48d2d..32ef03f73ecd 100644 --- a/core/src/main/java/hudson/model/MyViewsProperty.java +++ b/core/src/main/java/hudson/model/MyViewsProperty.java @@ -35,13 +35,13 @@ import hudson.util.FormValidation; import hudson.views.MyViewsTabBar; import hudson.views.ViewsTabBar; +import jakarta.servlet.ServletException; import java.io.IOException; import java.text.ParseException; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import net.sf.json.JSONObject; @@ -54,8 +54,8 @@ import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerFallback; import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.verb.POST; /** @@ -196,7 +196,7 @@ public HttpResponse doIndex() { } @POST - public synchronized void doCreateView(StaplerRequest req, StaplerResponse rsp) + public synchronized void doCreateView(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, ParseException, FormException { checkPermission(View.CREATE); addView(View.create(req, rsp, this)); @@ -276,7 +276,7 @@ public UserProperty newInstance(User user) { } @Override - public UserProperty reconfigure(StaplerRequest req, JSONObject form) throws FormException { + public UserProperty reconfigure(StaplerRequest2 req, JSONObject form) throws FormException { req.bindJSON(this, form); return this; } diff --git a/core/src/main/java/hudson/model/Node.java b/core/src/main/java/hudson/model/Node.java index 8ba16e77d4d3..55cacd269133 100644 --- a/core/src/main/java/hudson/model/Node.java +++ b/core/src/main/java/hudson/model/Node.java @@ -79,6 +79,7 @@ import org.kohsuke.stapler.BindInterceptor; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.springframework.security.core.Authentication; @@ -560,8 +561,25 @@ public ACL getACL() { return Jenkins.get().getAuthorizationStrategy().getACL(this); } + @Override + public Node reconfigure(@NonNull final StaplerRequest2 req, JSONObject form) throws FormException { + if (Util.isOverridden(Node.class, getClass(), "reconfigure", StaplerRequest.class, JSONObject.class)) { + return reconfigure(StaplerRequest.fromStaplerRequest2(req), form); + } else { + return reconfigureImpl(req, form); + } + } + + /** + * @deprecated use {@link #reconfigure(StaplerRequest2, JSONObject)} + */ + @Deprecated @Override public Node reconfigure(@NonNull final StaplerRequest req, JSONObject form) throws FormException { + return reconfigureImpl(StaplerRequest.toStaplerRequest2(req), form); + } + + private Node reconfigureImpl(@NonNull final StaplerRequest2 req, JSONObject form) throws FormException { if (form == null) return null; final JSONObject jsonForProperties = form.optJSONObject("nodeProperties"); diff --git a/core/src/main/java/hudson/model/PaneStatusProperties.java b/core/src/main/java/hudson/model/PaneStatusProperties.java index 4807020ca714..12cb0003d671 100644 --- a/core/src/main/java/hudson/model/PaneStatusProperties.java +++ b/core/src/main/java/hudson/model/PaneStatusProperties.java @@ -6,8 +6,8 @@ import hudson.Extension; import hudson.model.userproperty.UserPropertyCategory; import hudson.util.PersistedList; +import jakarta.servlet.http.HttpSession; import java.io.IOException; -import javax.servlet.http.HttpSession; import org.jenkinsci.Symbol; import org.kohsuke.stapler.Stapler; @@ -70,13 +70,13 @@ private static class PaneStatusPropertiesSessionFallback extends PaneStatusPrope @Override public boolean isCollapsed(String paneId) { - final HttpSession session = Stapler.getCurrentRequest().getSession(); + final HttpSession session = Stapler.getCurrentRequest2().getSession(); return session.getAttribute(format(attribute, paneId)) != null; } @Override public boolean toggleCollapsed(String paneId) { - final HttpSession session = Stapler.getCurrentRequest().getSession(); + final HttpSession session = Stapler.getCurrentRequest2().getSession(); final String property = format(attribute, paneId); final Object collapsed = session.getAttribute(property); if (collapsed == null) { diff --git a/core/src/main/java/hudson/model/ParameterDefinition.java b/core/src/main/java/hudson/model/ParameterDefinition.java index 262b632ab5a2..29653c0250f4 100644 --- a/core/src/main/java/hudson/model/ParameterDefinition.java +++ b/core/src/main/java/hudson/model/ParameterDefinition.java @@ -41,6 +41,7 @@ import net.sf.json.JSONObject; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -59,7 +60,7 @@ *

* Three classes are used to model build parameters. First is the * {@link ParameterDescriptor}, which tells Hudson what kind of implementations are - * available. From {@link ParameterDescriptor#newInstance(StaplerRequest, JSONObject)}, + * available. From {@link ParameterDescriptor#newInstance(StaplerRequest2, JSONObject)}, * Hudson creates {@link ParameterDefinition}s based on the job configuration. * For example, if the user defines two string parameters "database-type" and * "appserver-type", we'll get two {@link StringParameterDefinition} instances @@ -69,7 +70,7 @@ * When a job is configured with {@link ParameterDefinition} (or more precisely, * {@link ParametersDefinitionProperty}, which in turns retains {@link ParameterDefinition}s), * user would have to enter the values for the defined build parameters. - * The {@link #createValue(StaplerRequest, JSONObject)} method is used to convert this + * The {@link #createValue(StaplerRequest2, JSONObject)} method is used to convert this * form submission into {@link ParameterValue} objects, which are then accessible * during a build. * @@ -85,12 +86,12 @@ *

config.jelly

* {@link ParameterDefinition} class uses {@code config.jelly} to contribute a form * fragment in the job configuration screen. Values entered there are fed back to - * {@link ParameterDescriptor#newInstance(StaplerRequest, JSONObject)} to create {@link ParameterDefinition}s. + * {@link ParameterDescriptor#newInstance(StaplerRequest2, JSONObject)} to create {@link ParameterDefinition}s. * *

index.jelly

* The {@code index.jelly} view contributes a form fragment in the page where the user * enters actual values of parameters for a build. The result of this form submission - * is then fed to {@link ParameterDefinition#createValue(StaplerRequest, JSONObject)} to + * is then fed to {@link ParameterDefinition#createValue(StaplerRequest2, JSONObject)} to * create {@link ParameterValue}s. * * @see StringParameterDefinition @@ -183,14 +184,37 @@ public ParameterDescriptor getDescriptor() { * and submits it to the server. */ @CheckForNull - public abstract ParameterValue createValue(StaplerRequest req, JSONObject jo); + public /* abstract */ ParameterValue createValue(StaplerRequest2 req, JSONObject jo) { + return Util.ifOverridden( + () -> createValue(StaplerRequest.fromStaplerRequest2(req), jo), + ParameterDefinition.class, + getClass(), + "createValue", + StaplerRequest.class, + JSONObject.class); + } + + /** + * @deprecated use {@link #createValue(StaplerRequest2, JSONObject)} + */ + @CheckForNull + @Deprecated + public ParameterValue createValue(StaplerRequest req, JSONObject jo) { + return Util.ifOverridden( + () -> createValue(StaplerRequest.toStaplerRequest2(req), jo), + ParameterDefinition.class, + getClass(), + "createValue", + StaplerRequest2.class, + JSONObject.class); + } /** * Create a parameter value from a GET with query string. * If no value is available in the request, it returns a default value if possible, or null. * *

- * Unlike {@link #createValue(StaplerRequest, JSONObject)}, this method is intended to support + * Unlike {@link #createValue(StaplerRequest2, JSONObject)}, this method is intended to support * the programmatic POST-ing of the build URL. This form is less expressive (as it doesn't support * the tree form), but it's more scriptable. * @@ -202,8 +226,28 @@ public ParameterDescriptor getDescriptor() { * If the parameter is deemed required but was missing in the submission. */ @CheckForNull - public abstract ParameterValue createValue(StaplerRequest req); + public /* abstract */ ParameterValue createValue(StaplerRequest2 req) { + return Util.ifOverridden( + () -> createValue(StaplerRequest.fromStaplerRequest2(req)), + ParameterDefinition.class, + getClass(), + "createValue", + StaplerRequest.class); + } + /** + * @deprecated use {@link #createValue(StaplerRequest2)} + */ + @CheckForNull + @Deprecated + public ParameterValue createValue(StaplerRequest req) { + return Util.ifOverridden( + () -> createValue(StaplerRequest.toStaplerRequest2(req)), + ParameterDefinition.class, + getClass(), + "createValue", + StaplerRequest2.class); + } /** * Create a parameter value from the string given in the CLI. diff --git a/core/src/main/java/hudson/model/ParameterValue.java b/core/src/main/java/hudson/model/ParameterValue.java index 5da680b3bb76..2fd481446f4b 100644 --- a/core/src/main/java/hudson/model/ParameterValue.java +++ b/core/src/main/java/hudson/model/ParameterValue.java @@ -43,14 +43,14 @@ import net.sf.json.JSONObject; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; /** * A value for a parameter in a build. * - * Created by {@link ParameterDefinition#createValue(StaplerRequest, JSONObject)} for + * Created by {@link ParameterDefinition#createValue(StaplerRequest2, JSONObject)} for * a particular build (although this 'owner' build object is passed in for every method * call as a parameter so that the parameter won't have to persist it.) * @@ -240,7 +240,7 @@ public VariableResolver createVariableResolver(AbstractBuild build * @deprecated since 2008-09-20. * parameter definition may change any time. So if you find yourself * in need of accessing the information from {@link ParameterDefinition}, - * instead copy them in {@link ParameterDefinition#createValue(StaplerRequest, JSONObject)} + * instead copy them in {@link ParameterDefinition#createValue(StaplerRequest2, JSONObject)} * into {@link ParameterValue}. */ @Deprecated diff --git a/core/src/main/java/hudson/model/ParametersDefinitionProperty.java b/core/src/main/java/hudson/model/ParametersDefinitionProperty.java index 66a70047e89d..a9019e5a8f1f 100644 --- a/core/src/main/java/hudson/model/ParametersDefinitionProperty.java +++ b/core/src/main/java/hudson/model/ParametersDefinitionProperty.java @@ -25,8 +25,8 @@ package hudson.model; -import static javax.servlet.http.HttpServletResponse.SC_CREATED; -import static javax.servlet.http.HttpServletResponse.SC_SEE_OTHER; +import static jakarta.servlet.http.HttpServletResponse.SC_CREATED; +import static jakarta.servlet.http.HttpServletResponse.SC_SEE_OTHER; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; @@ -35,6 +35,8 @@ import hudson.model.Queue.WaitingItem; import hudson.model.queue.ScheduleResult; import hudson.util.AlternativeUiTextProvider; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.AbstractList; import java.util.ArrayList; @@ -43,7 +45,6 @@ import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.model.OptionalJobProperty; import jenkins.model.ParameterizedJobMixIn; @@ -56,7 +57,9 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -133,19 +136,23 @@ public Collection getJobActions(AbstractProject job) { return (AbstractProject) owner; } - /** @deprecated use {@link #_doBuild(StaplerRequest, StaplerResponse, TimeDuration)} */ + /** @deprecated use {@link #_doBuild(StaplerRequest2, StaplerResponse2, TimeDuration)} */ @Deprecated - public void _doBuild(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - _doBuild(req, rsp, TimeDuration.fromString(req.getParameter("delay"))); + public void _doBuild(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + _doBuild(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), TimeDuration.fromString(req.getParameter("delay"))); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } /** * Interprets the form submission and schedules a build for a parameterized job. * *

- * This method is supposed to be invoked from {@link ParameterizedJobMixIn#doBuild(StaplerRequest, StaplerResponse, TimeDuration)}. + * This method is supposed to be invoked from {@link ParameterizedJobMixIn#doBuild(StaplerRequest2, StaplerResponse2, TimeDuration)}. */ - public void _doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException { + public void _doBuild(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException { if (delay == null) delay = new TimeDuration(TimeUnit.MILLISECONDS.convert(getJob().getQuietPeriod(), TimeUnit.SECONDS)); @@ -185,13 +192,17 @@ public void _doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParameter Ti rsp.sendRedirect("."); } - /** @deprecated use {@link #buildWithParameters(StaplerRequest, StaplerResponse, TimeDuration)} */ + /** @deprecated use {@link #buildWithParameters(StaplerRequest2, StaplerResponse2, TimeDuration)} */ @Deprecated - public void buildWithParameters(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - buildWithParameters(req, rsp, TimeDuration.fromString(req.getParameter("delay"))); + public void buildWithParameters(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + buildWithParameters(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), TimeDuration.fromString(req.getParameter("delay"))); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } - public void buildWithParameters(StaplerRequest req, StaplerResponse rsp, @CheckForNull TimeDuration delay) throws IOException, ServletException { + public void buildWithParameters(StaplerRequest2 req, StaplerResponse2 rsp, @CheckForNull TimeDuration delay) throws IOException, ServletException { List values = new ArrayList<>(); for (ParameterDefinition d : parameterDefinitions) { ParameterValue value = d.createValue(req); @@ -232,7 +243,7 @@ public ParameterDefinition getParameterDefinition(String name) { @Symbol("parameters") public static class DescriptorImpl extends OptionalJobPropertyDescriptor { @Override - public ParametersDefinitionProperty newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public ParametersDefinitionProperty newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { ParametersDefinitionProperty prop = (ParametersDefinitionProperty) super.newInstance(req, formData); if (prop != null && prop.parameterDefinitions.isEmpty()) { return null; diff --git a/core/src/main/java/hudson/model/PasswordParameterDefinition.java b/core/src/main/java/hudson/model/PasswordParameterDefinition.java index 8074740088f0..901f1ee66712 100644 --- a/core/src/main/java/hudson/model/PasswordParameterDefinition.java +++ b/core/src/main/java/hudson/model/PasswordParameterDefinition.java @@ -36,7 +36,7 @@ import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Parameter whose value is a {@link Secret} and is hidden from the UI. @@ -80,7 +80,7 @@ public ParameterValue createValue(String value) { } @Override - public PasswordParameterValue createValue(StaplerRequest req, JSONObject jo) { + public PasswordParameterValue createValue(StaplerRequest2 req, JSONObject jo) { PasswordParameterValue value = req.bindJSON(PasswordParameterValue.class, jo); if (value.getValue().getPlainText().equals(DEFAULT_VALUE)) { value = new PasswordParameterValue(getName(), getDefaultValue()); diff --git a/core/src/main/java/hudson/model/Project.java b/core/src/main/java/hudson/model/Project.java index 7dc8b692d940..eb31add23938 100644 --- a/core/src/main/java/hudson/model/Project.java +++ b/core/src/main/java/hudson/model/Project.java @@ -40,6 +40,8 @@ import hudson.triggers.SCMTrigger; import hudson.triggers.Trigger; import hudson.util.DescribableList; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.Collection; import java.util.HashSet; @@ -49,11 +51,12 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.triggers.SCMTriggerItem; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; /** * Buildable software project. @@ -223,10 +226,39 @@ public MavenInstallation inferMavenInstallation() { // actions // // + + /** + * @since TODO + */ + @Override + protected void submit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { + if (Util.isOverridden(Project.class, getClass(), "submit", StaplerRequest.class, StaplerResponse.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + super.submit(req, rsp); + submitImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated @Override - protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException, FormException { super.submit(req, rsp); + try { + submitImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw new javax.servlet.ServletException(e); + } + } + private void submitImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { JSONObject json = req.getSubmittedForm(); getBuildWrappersList().rebuild(req, json, BuildWrappers.getFor(this)); diff --git a/core/src/main/java/hudson/model/ProxyView.java b/core/src/main/java/hudson/model/ProxyView.java index b3d19282752c..41aa51df389e 100644 --- a/core/src/main/java/hudson/model/ProxyView.java +++ b/core/src/main/java/hudson/model/ProxyView.java @@ -29,9 +29,10 @@ import hudson.Util; import hudson.model.Descriptor.FormException; import hudson.util.FormValidation; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.Collection; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; @@ -39,7 +40,8 @@ import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerFallback; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -98,7 +100,32 @@ public TopLevelItem getItem(String name) { } @Override - protected void submit(StaplerRequest req) throws IOException, ServletException, FormException { + protected void submit(StaplerRequest2 req) throws IOException, ServletException, FormException { + if (Util.isOverridden(ProxyView.class, getClass(), "submit", StaplerRequest.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + submitImpl(req); + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2)} + */ + @Deprecated + @Override + protected void submit(StaplerRequest req) throws IOException, javax.servlet.ServletException, FormException { + try { + submitImpl(StaplerRequest.toStaplerRequest2(req)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void submitImpl(StaplerRequest2 req) throws ServletException, FormException { String proxiedViewName = req.getSubmittedForm().getString("proxiedViewName"); if (Jenkins.get().getView(proxiedViewName) == null) { throw new FormException("Not an existing global view", "proxiedViewName"); @@ -108,7 +135,7 @@ protected void submit(StaplerRequest req) throws IOException, ServletException, @RequirePOST @Override - public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public Item doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { return getProxiedView().doCreateItem(req, rsp); } @@ -139,7 +166,7 @@ public String getDisplayName() { @Override public boolean isInstantiable() { // doesn't make sense to add a ProxyView to the global views - return !(Stapler.getCurrentRequest().findAncestorObject(ViewGroup.class) instanceof Jenkins); + return !(Stapler.getCurrentRequest2().findAncestorObject(ViewGroup.class) instanceof Jenkins); } } diff --git a/core/src/main/java/hudson/model/Queue.java b/core/src/main/java/hudson/model/Queue.java index 0d299fb9426d..a8d4ca08ea0d 100644 --- a/core/src/main/java/hudson/model/Queue.java +++ b/core/src/main/java/hudson/model/Queue.java @@ -76,6 +76,8 @@ import hudson.util.ConsistentHash; import hudson.util.Futures; import hudson.util.XStream2; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; @@ -107,8 +109,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import jenkins.model.queue.AsynchronousExecution; import jenkins.model.queue.CompositeCauseOfBlockage; @@ -130,7 +130,7 @@ import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -2415,7 +2415,7 @@ public Api getApi() throws AccessDeniedException { } } - public HttpResponse doIndex(StaplerRequest req) { + public HttpResponse doIndex(StaplerRequest2 req) { return HttpResponses.text("Queue item exists. For details check, for example, " + req.getRequestURI() + "api/json?tree=cancelled,executable[url]"); } diff --git a/core/src/main/java/hudson/model/RSS.java b/core/src/main/java/hudson/model/RSS.java index 19727656e729..bb41c8af10a2 100644 --- a/core/src/main/java/hudson/model/RSS.java +++ b/core/src/main/java/hudson/model/RSS.java @@ -26,13 +26,17 @@ import hudson.FeedAdapter; import hudson.util.RunList; +import io.jenkins.servlet.ServletExceptionWrapper; +import io.jenkins.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Collection; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; /** * RSS related code. @@ -52,8 +56,9 @@ public final class RSS { * Entries to be listed in the RSS feed. * @param adapter * Controls how to render entries to RSS. + * @since TODO */ - public static void forwardToRss(String title, String url, Collection entries, FeedAdapter adapter, StaplerRequest req, HttpServletResponse rsp) throws IOException, ServletException { + public static void forwardToRss(String title, String url, Collection entries, FeedAdapter adapter, StaplerRequest2 req, HttpServletResponse rsp) throws IOException, ServletException { req.setAttribute("adapter", adapter); req.setAttribute("title", title); req.setAttribute("url", url); @@ -72,6 +77,18 @@ public static void forwardToRss(String title, String url, Collection void forwardToRss(String title, String url, Collection entries, FeedAdapter adapter, StaplerRequest req, javax.servlet.http.HttpServletResponse rsp) throws IOException, javax.servlet.ServletException { + try { + forwardToRss(title, url, entries, adapter, StaplerRequest.toStaplerRequest2(req), HttpServletResponseWrapper.toJakartaHttpServletResponse(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * Sends the RSS feed to the client using a default feed adapter. * @@ -81,12 +98,25 @@ public static void forwardToRss(String title, String url, Collection feedAdapter) throws IOException, ServletException { + public static void rss(StaplerRequest2 req, StaplerResponse2 rsp, String title, String url, RunList runList, FeedAdapter feedAdapter) throws IOException, ServletException { final FeedAdapter feedAdapter_ = feedAdapter == null ? Run.FEED_ADAPTER : feedAdapter; forwardToRss(title, url, runList, feedAdapter_, req, rsp); } + + /** + * @deprecated use {@link #rss(StaplerRequest2, StaplerResponse2, String, String, RunList, FeedAdapter)} + * @since 2.215 + */ + @Deprecated + public static void rss(StaplerRequest req, StaplerResponse rsp, String title, String url, RunList runList, FeedAdapter feedAdapter) throws IOException, javax.servlet.ServletException { + try { + rss(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), title, url, runList, feedAdapter); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } } diff --git a/core/src/main/java/hudson/model/ReconfigurableDescribable.java b/core/src/main/java/hudson/model/ReconfigurableDescribable.java index 1747fdb452c1..c044391b77ad 100644 --- a/core/src/main/java/hudson/model/ReconfigurableDescribable.java +++ b/core/src/main/java/hudson/model/ReconfigurableDescribable.java @@ -26,10 +26,13 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.Util; import hudson.model.Descriptor.FormException; import hudson.slaves.NodeProperty; +import jenkins.security.stapler.StaplerNotDispatchable; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Marks modern {@link Describable}s that allow the current instances to pass information down to the next @@ -44,7 +47,7 @@ * Invisible Property: * This mechanism can be used to create an entirely invisible {@link Describable}, which is handy * for {@link NodeProperty}, {@link JobProperty}, etc. To do so, define an empty config.jelly to prevent it from - * showing up in the config UI, then implement {@link #reconfigure(StaplerRequest, JSONObject)} + * showing up in the config UI, then implement {@link #reconfigure(StaplerRequest2, JSONObject)} * and simply return {@code this}. * *

@@ -78,5 +81,29 @@ public interface ReconfigurableDescribable bytes) { return new String(byteArray, getCharset()); } - public void doBuildStatus(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doBuildStatus(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { rsp.sendRedirect2(req.getContextPath() + "/images/48x48/" + getBuildStatusUrl()); } @@ -2260,7 +2264,7 @@ public abstract static class StatusSummarizer implements ExtensionPoint { /** * Returns the build number in the body. */ - public void doBuildNumber(StaplerResponse rsp) throws IOException { + public void doBuildNumber(StaplerResponse2 rsp) throws IOException { rsp.setContentType("text/plain"); rsp.setCharacterEncoding("US-ASCII"); rsp.setStatus(HttpServletResponse.SC_OK); @@ -2270,7 +2274,7 @@ public void doBuildNumber(StaplerResponse rsp) throws IOException { /** * Returns the build time stamp in the body. */ - public void doBuildTimestamp(StaplerRequest req, StaplerResponse rsp, @QueryParameter String format) throws IOException { + public void doBuildTimestamp(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String format) throws IOException { rsp.setContentType("text/plain"); rsp.setCharacterEncoding("US-ASCII"); rsp.setStatus(HttpServletResponse.SC_OK); @@ -2282,8 +2286,27 @@ public void doBuildTimestamp(StaplerRequest req, StaplerResponse rsp, @QueryPara /** * Sends out the raw console output. + * + * @since TODO */ + public void doConsoleText(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { + if (Util.isOverridden(Run.class, getClass(), "doConsoleText", StaplerRequest.class, StaplerResponse.class)) { + doConsoleText(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } else { + doConsoleTextImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doConsoleText(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable public void doConsoleText(StaplerRequest req, StaplerResponse rsp) throws IOException { + doConsoleTextImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } + + private void doConsoleTextImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { rsp.setContentType("text/plain;charset=UTF-8"); try (InputStream input = getLogInputStream(); OutputStream os = rsp.getOutputStream(); @@ -2299,7 +2322,7 @@ public void doConsoleText(StaplerRequest req, StaplerResponse rsp) throws IOExce */ @Deprecated public void doProgressiveLog(StaplerRequest req, StaplerResponse rsp) throws IOException { - getLogText().doProgressText(req, rsp); + getLogText().doProgressText(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); } /** @@ -2320,7 +2343,7 @@ public boolean canToggleLogKeep() { } @RequirePOST - public void doToggleLogKeep(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doToggleLogKeep(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { keepLog(!keepLog); rsp.forwardToPreviousPage(req); } @@ -2341,9 +2364,37 @@ public void keepLog(boolean newValue) throws IOException { /** * Deletes the build when the button is pressed. + * + * @since TODO */ @RequirePOST - public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doDoDelete(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(Run.class, getClass(), "doDoDelete", StaplerRequest.class, StaplerResponse.class)) { + try { + doDoDelete(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + return; + } else { + doDoDeleteImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doDoDelete(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doDoDeleteImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void doDoDeleteImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { checkPermission(DELETE); // We should not simply delete the build if it has been explicitly @@ -2376,7 +2427,7 @@ public void setDescription(String description) throws IOException { * Accepts the new description. */ @RequirePOST - public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doSubmitDescription(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { setDescription(req.getParameter("description")); rsp.sendRedirect("."); // go to the top page } @@ -2507,7 +2558,7 @@ public long getEstimatedDuration() { } @POST - public @NonNull HttpResponse doConfigSubmit(StaplerRequest req) throws IOException, ServletException, FormException { + public @NonNull HttpResponse doConfigSubmit(StaplerRequest2 req) throws IOException, ServletException, FormException { checkPermission(UPDATE); try (BulkChange bc = new BulkChange(this)) { JSONObject json = req.getSubmittedForm(); @@ -2625,9 +2676,27 @@ public String getEntryAuthor(Run entry) { } } + @Override + public Object getDynamic(String token, StaplerRequest2 req, StaplerResponse2 rsp) { + if (Util.isOverridden(Run.class, getClass(), "getDynamic", String.class, StaplerRequest.class, StaplerResponse.class)) { + return getDynamic(token, StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } else { + Object returnedResult = super.getDynamic(token, req, rsp); + return getDynamicImpl(token, returnedResult); + } + } + + /** + * @deprecated use {@link #getDynamic(String, StaplerRequest2, StaplerResponse2)} + */ + @Deprecated @Override public Object getDynamic(String token, StaplerRequest req, StaplerResponse rsp) { Object returnedResult = super.getDynamic(token, req, rsp); + return getDynamicImpl(token, returnedResult); + } + + private Object getDynamicImpl(String token, Object returnedResult) { if (returnedResult == null) { //check transient actions too for (Action action : getTransientActions()) { @@ -2669,7 +2738,7 @@ public Object getTarget() { public static class RedirectUp { - public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doDynamic(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { // Compromise to handle both browsers (auto-redirect) and programmatic access // (want accurate 404 response).. send 404 with javascript to redirect browsers. rsp.setStatus(HttpServletResponse.SC_NOT_FOUND); diff --git a/core/src/main/java/hudson/model/RunParameterDefinition.java b/core/src/main/java/hudson/model/RunParameterDefinition.java index 9aec159686b9..487d895839dd 100644 --- a/core/src/main/java/hudson/model/RunParameterDefinition.java +++ b/core/src/main/java/hudson/model/RunParameterDefinition.java @@ -38,7 +38,7 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.Exported; public class RunParameterDefinition extends SimpleParameterDefinition { @@ -155,7 +155,7 @@ public String getHelpFile() { } @Override - public ParameterDefinition newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public ParameterDefinition newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { return req.bindJSON(RunParameterDefinition.class, formData); } @@ -202,7 +202,7 @@ public ParameterValue getDefaultParameterValue() { } @Override - public ParameterValue createValue(StaplerRequest req, JSONObject jo) { + public ParameterValue createValue(StaplerRequest2 req, JSONObject jo) { RunParameterValue value = req.bindJSON(RunParameterValue.class, jo); value.setDescription(getDescription()); return value; diff --git a/core/src/main/java/hudson/model/SimpleParameterDefinition.java b/core/src/main/java/hudson/model/SimpleParameterDefinition.java index 0be175bb4a86..f52f9a338922 100644 --- a/core/src/main/java/hudson/model/SimpleParameterDefinition.java +++ b/core/src/main/java/hudson/model/SimpleParameterDefinition.java @@ -5,7 +5,7 @@ import hudson.cli.CLICommand; import java.io.IOException; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Convenient base class for {@link ParameterDefinition} whose value can be represented in a context-independent single string token. @@ -31,7 +31,7 @@ protected SimpleParameterDefinition(@NonNull String name, @CheckForNull String d public abstract ParameterValue createValue(String value); @Override - public final ParameterValue createValue(StaplerRequest req) { + public final ParameterValue createValue(StaplerRequest2 req) { String[] value = req.getParameterValues(getName()); if (value == null) { return getDefaultParameterValue(); diff --git a/core/src/main/java/hudson/model/Slave.java b/core/src/main/java/hudson/model/Slave.java index 4ad75e039386..588dbf70b40d 100644 --- a/core/src/main/java/hudson/model/Slave.java +++ b/core/src/main/java/hudson/model/Slave.java @@ -51,6 +51,7 @@ import hudson.util.ClockDifference; import hudson.util.DescribableList; import hudson.util.FormValidation; +import jakarta.servlet.ServletException; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -69,7 +70,6 @@ import java.util.jar.Manifest; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.security.MasterToSlaveCallable; import jenkins.slaves.WorkspaceLocator; @@ -80,8 +80,8 @@ import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Information about a Hudson agent node. @@ -418,7 +418,7 @@ public JnlpJar(String fileName) { this.fileName = fileName; } - public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doIndex(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { URLConnection con = connect(); // since we end up redirecting users to jnlpJars/foo.jar/, set the content disposition // so that browsers can download them in the right file name. @@ -430,7 +430,7 @@ public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { doIndex(req, rsp); } @@ -465,7 +465,7 @@ public URL getURL() throws IOException { } } - URL res = Jenkins.get().servletContext.getResource("/WEB-INF/" + name); + URL res = Jenkins.get().getServletContext().getResource("/WEB-INF/" + name); if (res == null) { throw new FileNotFoundException(name); // giving up } else { @@ -622,7 +622,7 @@ public FormValidation doCheckNumExecutors(@QueryParameter String value) { /** * Performs syntactical check on the remote FS for agents. */ - public FormValidation doCheckRemoteFS(@QueryParameter String value) throws IOException, ServletException { + public FormValidation doCheckRemoteFS(@QueryParameter String value) throws IOException { if (Util.fixEmptyAndTrim(value) == null) return FormValidation.error(Messages.Slave_Remote_Director_Mandatory()); diff --git a/core/src/main/java/hudson/model/StockStatusIcon.java b/core/src/main/java/hudson/model/StockStatusIcon.java index 00ce50b0453b..4fb1a9bfa007 100644 --- a/core/src/main/java/hudson/model/StockStatusIcon.java +++ b/core/src/main/java/hudson/model/StockStatusIcon.java @@ -29,9 +29,9 @@ public StockStatusIcon(String image, Localizable description) { @Override public String getImageOf(String size) { if (image.endsWith(".svg")) { - return Stapler.getCurrentRequest().getContextPath() + Jenkins.RESOURCE_PATH + "/images/svgs/" + image; + return Stapler.getCurrentRequest2().getContextPath() + Jenkins.RESOURCE_PATH + "/images/svgs/" + image; } else { - return Stapler.getCurrentRequest().getContextPath() + Jenkins.RESOURCE_PATH + + return Stapler.getCurrentRequest2().getContextPath() + Jenkins.RESOURCE_PATH + "/images/" + size + "/" + image; } } diff --git a/core/src/main/java/hudson/model/StringParameterDefinition.java b/core/src/main/java/hudson/model/StringParameterDefinition.java index 8a5dfa9f1b04..160e1b1a9c0c 100644 --- a/core/src/main/java/hudson/model/StringParameterDefinition.java +++ b/core/src/main/java/hudson/model/StringParameterDefinition.java @@ -36,7 +36,7 @@ import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Parameter whose value is a string value. @@ -147,7 +147,7 @@ public String getHelpFile() { } @Override - public ParameterValue createValue(StaplerRequest req, JSONObject jo) { + public ParameterValue createValue(StaplerRequest2 req, JSONObject jo) { StringParameterValue value = req.bindJSON(StringParameterValue.class, jo); if (isTrim()) { value.doTrim(); diff --git a/core/src/main/java/hudson/model/TaskAction.java b/core/src/main/java/hudson/model/TaskAction.java index 60ca66ac0536..e0597218f5d5 100644 --- a/core/src/main/java/hudson/model/TaskAction.java +++ b/core/src/main/java/hudson/model/TaskAction.java @@ -27,12 +27,12 @@ import hudson.console.AnnotatedLargeText; import hudson.security.ACL; import hudson.security.Permission; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.ref.WeakReference; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.framework.io.LargeText; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -113,7 +113,7 @@ public TaskThread getWorkerThread() { /** * Handles incremental log output. */ - public void doProgressiveLog(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doProgressiveLog(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { AnnotatedLargeText text = obtainLog(); if (text != null) { text.doProgressText(req, rsp); @@ -125,7 +125,7 @@ public void doProgressiveLog(StaplerRequest req, StaplerResponse rsp) throws IOE /** * Handles incremental log output. */ - public void doProgressiveHtml(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doProgressiveHtml(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { AnnotatedLargeText text = obtainLog(); if (text != null) { text.doProgressiveHtml(req, rsp); @@ -138,7 +138,7 @@ public void doProgressiveHtml(StaplerRequest req, StaplerResponse rsp) throws IO * Clears the error status. */ @RequirePOST - public synchronized void doClearError(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doClearError(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { getACL().checkPermission(getPermission()); if (workerThread != null && !workerThread.isRunning()) diff --git a/core/src/main/java/hudson/model/TextParameterDefinition.java b/core/src/main/java/hudson/model/TextParameterDefinition.java index a22b1903e59b..96d973dc765a 100644 --- a/core/src/main/java/hudson/model/TextParameterDefinition.java +++ b/core/src/main/java/hudson/model/TextParameterDefinition.java @@ -32,7 +32,7 @@ import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * {@link StringParameterDefinition} that uses textarea, instead of text box. @@ -68,7 +68,7 @@ public StringParameterValue getDefaultParameterValue() { } @Override - public ParameterValue createValue(StaplerRequest req, JSONObject jo) { + public ParameterValue createValue(StaplerRequest2 req, JSONObject jo) { TextParameterValue value = req.bindJSON(TextParameterValue.class, jo); value.setDescription(getDescription()); return value; diff --git a/core/src/main/java/hudson/model/TopLevelItemDescriptor.java b/core/src/main/java/hudson/model/TopLevelItemDescriptor.java index d84e4a684f22..817c1194a3d5 100644 --- a/core/src/main/java/hudson/model/TopLevelItemDescriptor.java +++ b/core/src/main/java/hudson/model/TopLevelItemDescriptor.java @@ -164,7 +164,7 @@ public String getDescription() { DefaultScriptInvoker dsi = new DefaultScriptInvoker(); StringWriter sw = new StringWriter(); XMLOutput xml = dsi.createXMLOutput(sw, true); - dsi.invokeScript(Stapler.getCurrentRequest(), Stapler.getCurrentResponse(), s, this, xml); + dsi.invokeScript(Stapler.getCurrentRequest2(), Stapler.getCurrentResponse2(), s, this, xml); return sw.toString(); } catch (Exception e) { LOGGER.log(Level.WARNING, null, e); diff --git a/core/src/main/java/hudson/model/UpdateCenter.java b/core/src/main/java/hudson/model/UpdateCenter.java index 4df95b7b3f45..437444feb434 100644 --- a/core/src/main/java/hudson/model/UpdateCenter.java +++ b/core/src/main/java/hudson/model/UpdateCenter.java @@ -58,6 +58,7 @@ import hudson.util.PersistedList; import hudson.util.VersionNumber; import hudson.util.XStream2; +import jakarta.servlet.ServletException; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; @@ -107,7 +108,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.net.ssl.SSLHandshakeException; -import javax.servlet.ServletException; import jenkins.MissingDependencyException; import jenkins.RestartRequiredException; import jenkins.install.InstallUtil; @@ -115,6 +115,7 @@ import jenkins.model.Jenkins; import jenkins.model.Loadable; import jenkins.security.stapler.StaplerDispatchable; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.SystemProperties; import jenkins.util.Timer; import jenkins.util.io.OnMaster; @@ -129,7 +130,8 @@ import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -439,7 +441,25 @@ public Badge getBadge() { * @return The current connection status. */ @Restricted(DoNotUse.class) + public HttpResponse doConnectionStatus(StaplerRequest2 request) { + if (Util.isOverridden(UpdateCenter.class, getClass(), "doConnectionStatus", StaplerRequest.class)) { + return doConnectionStatus(StaplerRequest.fromStaplerRequest2(request)); + } else { + return doConnectionStatusImpl(request); + } + } + + /** + * @deprecated use {@link #doConnectionStatus(StaplerRequest2)} + */ + @Deprecated + @StaplerNotDispatchable + @Restricted(DoNotUse.class) public HttpResponse doConnectionStatus(StaplerRequest request) { + return doConnectionStatusImpl(StaplerRequest.toStaplerRequest2(request)); + } + + private HttpResponse doConnectionStatusImpl(StaplerRequest2 request) { Jenkins.get().checkPermission(Jenkins.SYSTEM_READ); try { String siteId = request.getParameter("siteId"); @@ -536,12 +556,12 @@ public synchronized void persistInstallStatus() { *

* Supports a "correlationId" request parameter if you only want to get the * install status of a set of plugins requested for install through - * {@link PluginManager#doInstallPlugins(org.kohsuke.stapler.StaplerRequest)}. + * {@link PluginManager#doInstallPlugins(org.kohsuke.stapler.StaplerRequest2)}. * * @return The current installation status of a plugin set. */ @Restricted(DoNotUse.class) - public HttpResponse doInstallStatus(StaplerRequest request) { + public HttpResponse doInstallStatus(StaplerRequest2 request) { try { String correlationId = request.getParameter("correlationId"); Map response = new HashMap<>(); @@ -754,7 +774,7 @@ private boolean checkMinVersion(@CheckForNull Plugin p, @CheckForNull VersionNum * Schedules a Jenkins upgrade. */ @RequirePOST - public void doUpgrade(StaplerResponse rsp) throws IOException, ServletException { + public void doUpgrade(StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); HudsonUpgradeJob job = new HudsonUpgradeJob(getCoreSource(), Jenkins.getAuthentication2()); if (!Lifecycle.get().canRewriteHudsonWar()) { @@ -786,7 +806,7 @@ public HttpResponse doInvalidateData() { * Schedules a Jenkins restart. */ @RequirePOST - public void doSafeRestart(StaplerRequest request, StaplerResponse response) throws IOException, ServletException { + public void doSafeRestart(StaplerRequest2 request, StaplerResponse2 response) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); synchronized (jobs) { if (!isRestartScheduled()) { @@ -801,7 +821,7 @@ public void doSafeRestart(StaplerRequest request, StaplerResponse response) thro * Cancel all scheduled jenkins restarts */ @RequirePOST - public void doCancelRestart(StaplerResponse response) throws IOException, ServletException { + public void doCancelRestart(StaplerResponse2 response) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); synchronized (jobs) { for (UpdateCenterJob job : jobs) { @@ -860,7 +880,7 @@ public boolean isDowngradable() { * Performs hudson downgrade. */ @RequirePOST - public void doDowngrade(StaplerResponse rsp) throws IOException, ServletException { + public void doDowngrade(StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); if (!isDowngradable()) { sendError("Jenkins downgrade is not possible, probably backup does not exist"); @@ -877,7 +897,7 @@ public void doDowngrade(StaplerResponse rsp) throws IOException, ServletExceptio * Performs hudson downgrade. */ @RequirePOST - public void doRestart(StaplerResponse rsp) throws IOException, ServletException { + public void doRestart(StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); HudsonDowngradeJob job = new HudsonDowngradeJob(getCoreSource(), Jenkins.getAuthentication2()); LOGGER.info("Scheduling the core downgrade"); @@ -2392,7 +2412,7 @@ private File getCached(DownloadJob job) { * Could make PluginManager#getDetachedLocation public and consume it here, but this method is * best-effort anyway. */ - src = Jenkins.get().servletContext.getResource(String.format("/WEB-INF/detached-plugins/%s.hpi", plugin.name)); + src = Jenkins.get().getServletContext().getResource(String.format("/WEB-INF/detached-plugins/%s.hpi", plugin.name)); } catch (MalformedURLException e) { return null; } diff --git a/core/src/main/java/hudson/model/UsageStatistics.java b/core/src/main/java/hudson/model/UsageStatistics.java index 341f135c52f1..04d1be58209a 100644 --- a/core/src/main/java/hudson/model/UsageStatistics.java +++ b/core/src/main/java/hudson/model/UsageStatistics.java @@ -67,7 +67,7 @@ import jenkins.security.FIPS140; import jenkins.util.SystemProperties; import net.sf.json.JSONObject; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * @author Kohsuke Kawaguchi @@ -138,7 +138,7 @@ public String getStatData() throws IOException { JSONObject o = new JSONObject(); o.put("stat", 1); o.put("install", j.getLegacyInstanceId()); - o.put("servletContainer", j.servletContext.getServerInfo()); + o.put("servletContainer", j.getServletContext().getServerInfo()); o.put("version", Jenkins.VERSION); List nodes = new ArrayList<>(); @@ -212,7 +212,7 @@ public Permission getRequiredGlobalConfigPagePermission() { } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { try { // for backward compatibility reasons, this configuration is stored in Jenkins if (DISABLED) { diff --git a/core/src/main/java/hudson/model/User.java b/core/src/main/java/hudson/model/User.java index 792622eb3c54..685a80e540a9 100644 --- a/core/src/main/java/hudson/model/User.java +++ b/core/src/main/java/hudson/model/User.java @@ -47,6 +47,8 @@ import hudson.util.FormValidation; import hudson.util.RunList; import hudson.util.XStream2; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -64,8 +66,6 @@ import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import jenkins.model.IdStrategy; import jenkins.model.Jenkins; import jenkins.model.Loadable; @@ -79,8 +79,8 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -485,7 +485,7 @@ private LegitimateButUnknownUserDetails(String username) throws IllegalArgumentE * Accepts the new description. */ @RequirePOST - public void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doSubmitDescription(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { checkPermission(Jenkins.ADMINISTER); description = req.getParameter("description"); @@ -882,7 +882,7 @@ public Api getApi() { * Deletes this user from Hudson. */ @RequirePOST - public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doDoDelete(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { checkPermission(Jenkins.ADMINISTER); if (idStrategy().equals(id, Jenkins.getAuthentication2().getName())) { rsp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Cannot delete self"); @@ -894,15 +894,15 @@ public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOExcepti rsp.sendRedirect2("../.."); } - public void doRssAll(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssAll(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (all builds)", getUrl(), getBuilds().newBuilds()); } - public void doRssFailed(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssFailed(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (failed builds)", getUrl(), getBuilds().regressionOnly()); } - public void doRssLatest(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssLatest(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { final List lastBuilds = new ArrayList<>(); for (Job p : Jenkins.get().allItems(Job.class)) { for (Run b = p.getLastBuild(); b != null; b = b.getPreviousBuild()) { @@ -1010,7 +1010,7 @@ public List getTransientActions() { } @Override - public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + public ContextMenu doContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { return new ContextMenu().from(this, request, response); } diff --git a/core/src/main/java/hudson/model/UserProperty.java b/core/src/main/java/hudson/model/UserProperty.java index a6ebeb738b23..9813cfaba62b 100644 --- a/core/src/main/java/hudson/model/UserProperty.java +++ b/core/src/main/java/hudson/model/UserProperty.java @@ -27,6 +27,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.DescriptorExtensionList; import hudson.ExtensionPoint; +import hudson.Util; import hudson.model.Descriptor.FormException; import hudson.model.userproperty.UserPropertyCategory; import java.util.ArrayList; @@ -34,6 +35,7 @@ import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.ExportedBean; /** @@ -101,8 +103,22 @@ public static List allByCategoryClass(@NonNull Class - * This method should call {@link ModifiableItemGroup#doCreateItem(StaplerRequest, StaplerResponse)} + * This method should call {@link ModifiableItemGroup#doCreateItem(StaplerRequest2, StaplerResponse2)} * and then add the newly created item to this view. * * @return * null if fails. + * @since TODO */ - public abstract Item doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException; + @RequirePOST + public /* abstract */ Item doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(View.class, getClass(), "doCreateItem", StaplerRequest.class, StaplerResponse.class)) { + try { + return doCreateItem(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + View.class.getSimpleName() + ".doCreateItem methods"); + } + } + + /** + * @deprecated use {@link #doCreateItem(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + if (Util.isOverridden(View.class, getClass(), "doCreateItem", StaplerRequest2.class, StaplerResponse2.class)) { + try { + return doCreateItem(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + View.class.getSimpleName() + ".doCreateItem methods"); + } + } /** * Makes sure that the given name is good as a job name. @@ -774,7 +859,7 @@ public FormValidation doCheckJobName(@QueryParameter String value) { * @return A {@link Categories} entity that is shown as JSON file. */ @Restricted(DoNotUse.class) - public Categories doItemCategories(StaplerRequest req, StaplerResponse rsp, @QueryParameter String iconStyle) throws IOException, ServletException { + public Categories doItemCategories(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String iconStyle) throws IOException, ServletException { getOwner().checkPermission(Item.CREATE); rsp.addHeader("Cache-Control", "no-cache, no-store, must-revalidate"); @@ -833,11 +918,11 @@ public Categories doItemCategories(StaplerRequest req, StaplerResponse rsp, @Que return categories; } - public void doRssAll(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssAll(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (all builds)", getUrl(), getBuilds().newBuilds()); } - public void doRssFailed(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssFailed(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (failed builds)", getUrl(), getBuilds().failureOnly().newBuilds()); } @@ -851,7 +936,7 @@ public BuildTimelineWidget getTimeline() { return new BuildTimelineWidget(getBuilds()); } - public void doRssLatest(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssLatest(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { List lastBuilds = new ArrayList<>(); for (TopLevelItem item : getItems()) { if (item instanceof Job job) { @@ -866,13 +951,13 @@ public void doRssLatest(StaplerRequest req, StaplerResponse rsp) throws IOExcept * Accepts {@code config.xml} submission, as well as serve it. */ @WebMethod(name = "config.xml") - public HttpResponse doConfigDotXml(StaplerRequest req) throws IOException { + public HttpResponse doConfigDotXml(StaplerRequest2 req) throws IOException { if (req.getMethod().equals("GET")) { // read checkPermission(READ); return new HttpResponse() { @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { rsp.setContentType("application/xml"); View.this.writeXml(rsp.getOutputStream()); } @@ -940,7 +1025,7 @@ public void updateByXml(Source source) throws IOException { } @Override - public ModelObjectWithContextMenu.ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + public ModelObjectWithContextMenu.ContextMenu doChildrenContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { ModelObjectWithContextMenu.ContextMenu m = new ModelObjectWithContextMenu.ContextMenu(); for (TopLevelItem i : getItems()) m.add(Functions.getRelativeLinkTo(i), Functions.getRelativeDisplayNameFrom(i, getOwner().getItemGroup())); @@ -964,15 +1049,15 @@ public static DescriptorExtensionList all() { /** * Returns the {@link ViewDescriptor} instances that can be instantiated for the {@link ViewGroup} in the current - * {@link StaplerRequest}. + * {@link StaplerRequest2}. *

- * NOTE: Historically this method is only ever called from a {@link StaplerRequest} - * @return the list of instantiable {@link ViewDescriptor} instances for the current {@link StaplerRequest} + * NOTE: Historically this method is only ever called from a {@link StaplerRequest2} + * @return the list of instantiable {@link ViewDescriptor} instances for the current {@link StaplerRequest2} */ @NonNull public static List allInstantiable() { List r = new ArrayList<>(); - StaplerRequest request = Stapler.getCurrentRequest(); + StaplerRequest2 request = Stapler.getCurrentRequest2(); if (request == null) { throw new IllegalStateException("This method can only be invoked from a stapler request"); } @@ -1018,7 +1103,10 @@ public static Permission getItemCreatePermission() { return Item.CREATE; } - public static View create(StaplerRequest req, StaplerResponse rsp, ViewGroup owner) + /** + * @since TODO + */ + public static View create(StaplerRequest2 req, StaplerResponse2 rsp, ViewGroup owner) throws FormException, IOException, ServletException { String mode = req.getParameter("mode"); @@ -1070,7 +1158,20 @@ public static View create(StaplerRequest req, StaplerResponse rsp, ViewGroup own return v; } - private static View copy(StaplerRequest req, ViewGroup owner, String name) throws IOException { + /** + * @deprecated use {@link #create(StaplerRequest2, StaplerResponse2, ViewGroup)} + */ + @Deprecated + public static View create(StaplerRequest req, StaplerResponse rsp, ViewGroup owner) + throws FormException, IOException, javax.servlet.ServletException { + try { + return create(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), owner); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private static View copy(StaplerRequest2 req, ViewGroup owner, String name) throws IOException { View v; String from = req.getParameter("from"); View src = owner.getView(from); diff --git a/core/src/main/java/hudson/model/ViewDescriptor.java b/core/src/main/java/hudson/model/ViewDescriptor.java index f38e5d846d9a..e140ac474054 100644 --- a/core/src/main/java/hudson/model/ViewDescriptor.java +++ b/core/src/main/java/hudson/model/ViewDescriptor.java @@ -40,7 +40,7 @@ import org.kohsuke.stapler.AncestorInPath; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * {@link Descriptor} for {@link View}. @@ -108,7 +108,7 @@ public AutoCompletionCandidates doAutoCompleteCopyNewItemFrom(@QueryParameter fi * Possible {@link ListViewColumnDescriptor}s that can be used with this view. */ public List> getColumnsDescriptors() { - StaplerRequest request = Stapler.getCurrentRequest(); + StaplerRequest2 request = Stapler.getCurrentRequest2(); if (request != null) { View view = request.findAncestorObject(clazz); return view == null ? DescriptorVisibilityFilter.applyType(clazz, ListViewColumn.all()) @@ -121,7 +121,7 @@ public List> getColumnsDescriptors() { * Possible {@link ViewJobFilter} types that can be used with this view. */ public List> getJobFiltersDescriptors() { - StaplerRequest request = Stapler.getCurrentRequest(); + StaplerRequest2 request = Stapler.getCurrentRequest2(); if (request != null) { View view = request.findAncestorObject(clazz); return view == null ? DescriptorVisibilityFilter.applyType(clazz, ViewJobFilter.all()) diff --git a/core/src/main/java/hudson/model/ViewJob.java b/core/src/main/java/hudson/model/ViewJob.java index 0da32700c1bd..055b98cafdb5 100644 --- a/core/src/main/java/hudson/model/ViewJob.java +++ b/core/src/main/java/hudson/model/ViewJob.java @@ -25,7 +25,10 @@ package hudson.model; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.Util; import hudson.model.Descriptor.FormException; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.util.LinkedHashSet; @@ -34,11 +37,12 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; /** * {@link Job} that monitors activities that happen outside Hudson, @@ -165,8 +169,30 @@ private void _reload() { protected abstract void reload(); @Override - protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + protected void submit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { + if (Util.isOverridden(ViewJob.class, getClass(), "submit", StaplerRequest.class, StaplerResponse.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + super.submit(req, rsp); + submitImpl(); + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @Override + protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException, FormException { super.submit(req, rsp); + submitImpl(); + } + + private void submitImpl() { // make sure to reload to reflect this config change. nextUpdate = 0; } diff --git a/core/src/main/java/hudson/model/ViewProperty.java b/core/src/main/java/hudson/model/ViewProperty.java index 31ad3078d449..15f0e62164c4 100644 --- a/core/src/main/java/hudson/model/ViewProperty.java +++ b/core/src/main/java/hudson/model/ViewProperty.java @@ -26,9 +26,11 @@ import hudson.DescriptorExtensionList; import hudson.ExtensionPoint; +import hudson.Util; import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Extensible property of {@link View}. @@ -68,8 +70,22 @@ public static DescriptorExtensionList all( return Jenkins.get().getDescriptorList(ViewProperty.class); } + @Override + public ViewProperty reconfigure(StaplerRequest2 req, JSONObject form) throws Descriptor.FormException { + if (Util.isOverridden(ViewProperty.class, getClass(), "reconfigure", StaplerRequest.class, JSONObject.class)) { + return reconfigure(StaplerRequest.fromStaplerRequest2(req), form); + } else { + return reconfigureImpl(req, form); + } + } + + @Deprecated @Override public ViewProperty reconfigure(StaplerRequest req, JSONObject form) throws Descriptor.FormException { + return reconfigureImpl(StaplerRequest.toStaplerRequest2(req), form); + } + + private ViewProperty reconfigureImpl(StaplerRequest2 req, JSONObject form) throws Descriptor.FormException { return form == null ? null : getDescriptor().newInstance(req, form); } } diff --git a/core/src/main/java/hudson/model/labels/LabelAtom.java b/core/src/main/java/hudson/model/labels/LabelAtom.java index 84ee083c488d..f5e597b71b30 100644 --- a/core/src/main/java/hudson/model/labels/LabelAtom.java +++ b/core/src/main/java/hudson/model/labels/LabelAtom.java @@ -46,6 +46,7 @@ import hudson.util.QuotedStringTokenizer; import hudson.util.VariableResolver; import hudson.util.XStream2; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -56,13 +57,12 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; @@ -221,7 +221,7 @@ public List getApplicablePropertyDescriptors() { * Accepts the update to the node configuration. */ @POST - public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + public void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { final Jenkins app = Jenkins.get(); app.checkPermission(Jenkins.ADMINISTER); @@ -249,7 +249,7 @@ private boolean isInvalidName() { */ @RequirePOST @Restricted(DoNotUse.class) - public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doSubmitDescription(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); setDescription(req.getParameter("description")); diff --git a/core/src/main/java/hudson/model/userproperty/UserPropertyCategoryAccountAction.java b/core/src/main/java/hudson/model/userproperty/UserPropertyCategoryAccountAction.java index 822cdc6f4c99..c0424e828419 100644 --- a/core/src/main/java/hudson/model/userproperty/UserPropertyCategoryAccountAction.java +++ b/core/src/main/java/hudson/model/userproperty/UserPropertyCategoryAccountAction.java @@ -32,20 +32,20 @@ import hudson.model.User; import hudson.model.UserProperty; import hudson.model.UserPropertyDescriptor; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.security.UserDetailsCache; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.verb.POST; @Restricted(NoExternalUse.class) @@ -91,7 +91,7 @@ private static List allByTwoCategoryClasses( } @POST - public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, Descriptor.FormException { + public void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, Descriptor.FormException { User targetUser = this.getTargetUser(); targetUser.checkPermission(Jenkins.ADMINISTER); diff --git a/core/src/main/java/hudson/model/userproperty/UserPropertyCategoryAction.java b/core/src/main/java/hudson/model/userproperty/UserPropertyCategoryAction.java index caec7c1bdf88..6eadb9f89ece 100644 --- a/core/src/main/java/hudson/model/userproperty/UserPropertyCategoryAction.java +++ b/core/src/main/java/hudson/model/userproperty/UserPropertyCategoryAction.java @@ -6,14 +6,14 @@ import hudson.model.UserProperty; import hudson.model.UserPropertyDescriptor; import hudson.util.FormApply; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import net.sf.json.JSONObject; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.verb.POST; public abstract class UserPropertyCategoryAction { @@ -31,7 +31,7 @@ public UserPropertyCategoryAction(User targetUser) { public @NonNull abstract List getMyCategoryDescriptors(); @POST - public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, Descriptor.FormException { + public void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, Descriptor.FormException { this.targetUser.checkPermission(Jenkins.ADMINISTER); JSONObject json = req.getSubmittedForm(); diff --git a/core/src/main/java/hudson/scm/AbstractScmTagAction.java b/core/src/main/java/hudson/scm/AbstractScmTagAction.java index b861a90b15fe..3bf14e753242 100644 --- a/core/src/main/java/hudson/scm/AbstractScmTagAction.java +++ b/core/src/main/java/hudson/scm/AbstractScmTagAction.java @@ -24,17 +24,22 @@ package hudson.scm; +import hudson.Util; import hudson.model.AbstractBuild; import hudson.model.BuildBadgeAction; import hudson.model.Run; import hudson.model.TaskAction; import hudson.security.ACL; import hudson.security.Permission; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; import jenkins.model.RunAction2; +import jenkins.security.stapler.StaplerNotDispatchable; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; /** * Common part of {@code CVSSCM.TagAction} and {@code SubversionTagAction}. @@ -108,7 +113,32 @@ protected ACL getACL() { return run.getACL(); } - public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doIndex(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(AbstractScmTagAction.class, getClass(), "doIndex", StaplerRequest.class, StaplerResponse.class)) { + try { + doIndex(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doIndexImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doIndex(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doIndexImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void doIndexImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { req.getView(this, chooseAction()).forward(req, rsp); } diff --git a/core/src/main/java/hudson/scm/RepositoryBrowsers.java b/core/src/main/java/hudson/scm/RepositoryBrowsers.java index 0a1e28d1a152..3562f1c13964 100644 --- a/core/src/main/java/hudson/scm/RepositoryBrowsers.java +++ b/core/src/main/java/hudson/scm/RepositoryBrowsers.java @@ -32,6 +32,7 @@ import java.util.List; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * List of all installed {@link RepositoryBrowsers}. @@ -63,7 +64,7 @@ public static List>> filter(Class @@ -82,13 +83,23 @@ T createInstance(Class type, StaplerRequest req, String fieldName) throws For /** * Creates an instance of {@link RepositoryBrowser} from a form submission. * - * @since 1.227 + * @since TODO */ public static - T createInstance(Class type, StaplerRequest req, JSONObject parent, String fieldName) throws FormException { + T createInstance(Class type, StaplerRequest2 req, JSONObject parent, String fieldName) throws FormException { JSONObject o = (JSONObject) parent.get(fieldName); if (o == null) return null; return req.bindJSON(type, o); } + + /** + * @deprecated use {@link #createInstance(Class, StaplerRequest2, JSONObject, String)} + * @since 1.227 + */ + @Deprecated + public static + T createInstance(Class type, StaplerRequest req, JSONObject parent, String fieldName) throws FormException { + return createInstance(type, StaplerRequest.toStaplerRequest2(req), parent, fieldName); + } } diff --git a/core/src/main/java/hudson/scm/SCMS.java b/core/src/main/java/hudson/scm/SCMS.java index a8fd4ddc4dc1..de92d453d248 100644 --- a/core/src/main/java/hudson/scm/SCMS.java +++ b/core/src/main/java/hudson/scm/SCMS.java @@ -28,9 +28,11 @@ import hudson.model.AbstractProject; import hudson.model.Descriptor.FormException; import hudson.util.DescriptorList; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.util.List; -import javax.servlet.ServletException; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * List of all installed SCMs. @@ -53,7 +55,7 @@ public class SCMS { * The project for which this SCM is configured to. */ @SuppressWarnings("deprecation") - public static SCM parseSCM(StaplerRequest req, AbstractProject target) throws FormException, ServletException { + public static SCM parseSCM(StaplerRequest2 req, AbstractProject target) throws FormException, ServletException { SCM scm = SCM.all().newInstanceFromRadioList(req.getSubmittedForm().getJSONObject("scm")); if (scm == null) { scm = new NullSCM(); // JENKINS-36043 workaround for AbstractMultiBranchProject.submit @@ -62,12 +64,24 @@ public static SCM parseSCM(StaplerRequest req, AbstractProject target) throws Fo return scm; } + /** + * @deprecated use {@link #parseSCM(StaplerRequest2, AbstractProject)} + */ + @Deprecated + public static SCM parseSCM(StaplerRequest req, AbstractProject target) throws FormException, javax.servlet.ServletException { + try { + return parseSCM(StaplerRequest.toStaplerRequest2(req), target); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * @deprecated as of 1.294 - * Use {@link #parseSCM(StaplerRequest, AbstractProject)} and pass in the caller's project type. + * Use {@link #parseSCM(StaplerRequest2, AbstractProject)} and pass in the caller's project type. */ @Deprecated - public static SCM parseSCM(StaplerRequest req) throws FormException, ServletException { + public static SCM parseSCM(StaplerRequest req) throws FormException, javax.servlet.ServletException { return parseSCM(req, null); } diff --git a/core/src/main/java/hudson/search/Search.java b/core/src/main/java/hudson/search/Search.java index a3a674ae1106..7773d9e9d696 100644 --- a/core/src/main/java/hudson/search/Search.java +++ b/core/src/main/java/hudson/search/Search.java @@ -25,12 +25,14 @@ package hudson.search; -import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; +import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Util; import hudson.util.EditDistance; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.AbstractList; import java.util.ArrayList; @@ -40,8 +42,8 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.MemoryReductionUtil; import jenkins.util.SystemProperties; import org.kohsuke.accmod.Restricted; @@ -50,7 +52,9 @@ import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.DataWriter; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -73,7 +77,32 @@ public class Search implements StaplerProxy { */ private static /* nonfinal for Jenkins script console */ int MAX_SEARCH_SIZE = Integer.getInteger(Search.class.getName() + ".MAX_SEARCH_SIZE", 500); - public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doIndex(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(Search.class, getClass(), "doIndex", StaplerRequest.class, StaplerResponse.class)) { + try { + doIndex(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doIndexImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doIndex(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doIndexImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void doIndexImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { List l = req.getAncestors(); for (int i = l.size() - 1; i >= 0; i--) { Ancestor a = l.get(i); @@ -110,7 +139,7 @@ public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, * * See http://developer.mozilla.org/en/docs/Supporting_search_suggestions_in_search_plugins */ - public void doSuggestOpenSearch(StaplerRequest req, StaplerResponse rsp, @QueryParameter String q) throws IOException, ServletException { + public void doSuggestOpenSearch(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String q) throws IOException, ServletException { rsp.setContentType(Flavor.JSON.contentType); DataWriter w = Flavor.JSON.createDataWriter(null, rsp); w.startArray(); @@ -126,7 +155,7 @@ public void doSuggestOpenSearch(StaplerRequest req, StaplerResponse rsp, @QueryP /** * Used by search box auto-completion. Returns JSON array. */ - public void doSuggest(StaplerRequest req, StaplerResponse rsp, @QueryParameter String query) throws IOException, ServletException { + public void doSuggest(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String query) throws IOException, ServletException { Result r = new Result(); for (SuggestedItem item : getSuggestions(req, query)) r.suggestions.add(new Item(item.getPath())); @@ -141,7 +170,23 @@ public void doSuggest(StaplerRequest req, StaplerResponse rsp, @QueryParameter S * can be empty but never null. The size of the list is always smaller than * a certain threshold to avoid showing too many options. */ + public SearchResult getSuggestions(StaplerRequest2 req, String query) { + if (Util.isOverridden(Search.class, getClass(), "getSuggestions", StaplerRequest.class, String.class)) { + return getSuggestions(StaplerRequest.fromStaplerRequest2(req), query); + } else { + return getSuggestionsImpl(req, query); + } + } + + /** + * @deprecated use {@link #getSuggestions(StaplerRequest2, String)} + */ + @Deprecated public SearchResult getSuggestions(StaplerRequest req, String query) { + return getSuggestionsImpl(StaplerRequest.toStaplerRequest2(req), query); + } + + private SearchResult getSuggestionsImpl(StaplerRequest2 req, String query) { Set paths = new HashSet<>(); // paths already added, to control duplicates SearchResultImpl r = new SearchResultImpl(); int max = Math.min( @@ -164,7 +209,7 @@ public int getMaxSearchSize() { return MAX_SEARCH_SIZE; } - private @CheckForNull SearchableModelObject findClosestSearchableModelObject(StaplerRequest req) { + private @CheckForNull SearchableModelObject findClosestSearchableModelObject(StaplerRequest2 req) { List l = req.getAncestors(); for (int i = l.size() - 1; i >= 0; i--) { Ancestor a = l.get(i); @@ -178,7 +223,7 @@ public int getMaxSearchSize() { /** * Creates merged search index for suggestion. */ - private SearchIndex makeSuggestIndex(StaplerRequest req) { + private SearchIndex makeSuggestIndex(StaplerRequest2 req) { SearchIndexBuilder builder = new SearchIndexBuilder(); for (Ancestor a : req.getAncestors()) { if (a.getObject() instanceof SearchableModelObject) { diff --git a/core/src/main/java/hudson/search/UserSearchProperty.java b/core/src/main/java/hudson/search/UserSearchProperty.java index a3515dd08874..7f36476b112b 100644 --- a/core/src/main/java/hudson/search/UserSearchProperty.java +++ b/core/src/main/java/hudson/search/UserSearchProperty.java @@ -8,7 +8,7 @@ import hudson.model.userproperty.UserPropertyCategory; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.Exported; public class UserSearchProperty extends hudson.model.UserProperty { @@ -51,7 +51,7 @@ public UserProperty newInstance(User user) { } @Override - public UserProperty newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public UserProperty newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { return new UserSearchProperty(formData.optBoolean("insensitiveSearch")); } diff --git a/core/src/main/java/hudson/security/AccessDeniedException2.java b/core/src/main/java/hudson/security/AccessDeniedException2.java index 00daee721251..e745669bad67 100644 --- a/core/src/main/java/hudson/security/AccessDeniedException2.java +++ b/core/src/main/java/hudson/security/AccessDeniedException2.java @@ -1,5 +1,6 @@ package hudson.security; +import io.jenkins.servlet.http.HttpServletResponseWrapper; import java.io.PrintWriter; import javax.servlet.http.HttpServletResponse; import jenkins.util.SystemProperties; @@ -42,7 +43,7 @@ public AccessDeniedException2(Throwable t, Authentication authentication, Permis * Reports the details of the access failure in HTTP headers to assist diagnosis. */ public void reportAsHeaders(HttpServletResponse rsp) { - toSpring().reportAsHeaders(rsp); + toSpring().reportAsHeaders(HttpServletResponseWrapper.toJakartaHttpServletResponse(rsp)); } /** diff --git a/core/src/main/java/hudson/security/AccessDeniedException3.java b/core/src/main/java/hudson/security/AccessDeniedException3.java index 82f5d50428ce..90fc521dfd7b 100644 --- a/core/src/main/java/hudson/security/AccessDeniedException3.java +++ b/core/src/main/java/hudson/security/AccessDeniedException3.java @@ -1,7 +1,8 @@ package hudson.security; +import io.jenkins.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.http.HttpServletResponse; import java.io.PrintWriter; -import javax.servlet.http.HttpServletResponse; import jenkins.util.SystemProperties; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.core.Authentication; @@ -43,6 +44,18 @@ public AccessDeniedException3(Throwable t, Authentication authentication, Permis * Reports the details of the access failure in HTTP headers to assist diagnosis. */ public void reportAsHeaders(HttpServletResponse rsp) { + reportAsHeadersImpl(rsp); + } + + /** + * @deprecated use {@link #reportAsHeaders(HttpServletResponse)} + */ + @Deprecated + public void reportAsHeaders(javax.servlet.http.HttpServletResponse rsp) { + reportAsHeadersImpl(HttpServletResponseWrapper.toJakartaHttpServletResponse(rsp)); + } + + private void reportAsHeadersImpl(HttpServletResponse rsp) { rsp.addHeader("X-You-Are-Authenticated-As", authentication.getName()); if (REPORT_GROUP_HEADERS) { for (GrantedAuthority auth : authentication.getAuthorities()) { diff --git a/core/src/main/java/hudson/security/AccessDeniedHandlerImpl.java b/core/src/main/java/hudson/security/AccessDeniedHandlerImpl.java index 68843cfddd16..b1f1e35e1fc8 100644 --- a/core/src/main/java/hudson/security/AccessDeniedHandlerImpl.java +++ b/core/src/main/java/hudson/security/AccessDeniedHandlerImpl.java @@ -24,10 +24,10 @@ package hudson.security; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -53,7 +53,7 @@ public void handle(HttpServletRequest req, HttpServletResponse rsp, AccessDenied ((AccessDeniedException3) cause).reportAsHeaders(rsp); } - WebApp.get(Jenkins.get().servletContext).getSomeStapler() + WebApp.get(Jenkins.get().getServletContext()).getSomeStapler() .invoke(req, rsp, Jenkins.get(), "/accessDenied"); } } diff --git a/core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java b/core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java index 2714ec8eba63..0c9559bf140f 100644 --- a/core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java +++ b/core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java @@ -26,14 +26,14 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.model.User; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import jenkins.security.SecurityListener; import jenkins.security.seed.UserSeedProperty; import jenkins.util.SystemProperties; diff --git a/core/src/main/java/hudson/security/AuthorizationStrategy.java b/core/src/main/java/hudson/security/AuthorizationStrategy.java index f77385829730..db3001fc40f2 100644 --- a/core/src/main/java/hudson/security/AuthorizationStrategy.java +++ b/core/src/main/java/hudson/security/AuthorizationStrategy.java @@ -47,7 +47,7 @@ import jenkins.security.stapler.StaplerAccessibleType; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Controls authorization throughout Hudson. @@ -241,7 +241,7 @@ public String getDisplayName() { } @Override - public @NonNull AuthorizationStrategy newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public @NonNull AuthorizationStrategy newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { return UNSECURED; } } diff --git a/core/src/main/java/hudson/security/BasicAuthenticationFilter.java b/core/src/main/java/hudson/security/BasicAuthenticationFilter.java index b2a06024278b..8586fb0317a0 100644 --- a/core/src/main/java/hudson/security/BasicAuthenticationFilter.java +++ b/core/src/main/java/hudson/security/BasicAuthenticationFilter.java @@ -27,24 +27,24 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.model.User; import hudson.util.Scrambler; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import jenkins.security.BasicApiTokenHelper; import jenkins.security.SecurityListener; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.CompatibleFilter; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; @@ -68,7 +68,7 @@ * This causes the container to perform authentication, but there's no way * to find out whether the user has been successfully authenticated or not. * So to find this out, we then redirect the user to - * {@link jenkins.model.Jenkins#doSecured(StaplerRequest, StaplerResponse) /secured/... page}. + * {@link jenkins.model.Jenkins#doSecured(StaplerRequest2, StaplerResponse2) /secured/... page}. * *

* The handler of the above URL checks if the user is authenticated, @@ -91,7 +91,7 @@ * * @author Kohsuke Kawaguchi */ -public class BasicAuthenticationFilter implements Filter { +public class BasicAuthenticationFilter implements CompatibleFilter { private ServletContext servletContext; @Override diff --git a/core/src/main/java/hudson/security/ChainedServletFilter.java b/core/src/main/java/hudson/security/ChainedServletFilter.java index 74e1e463f565..98bc725c2b1a 100644 --- a/core/src/main/java/hudson/security/ChainedServletFilter.java +++ b/core/src/main/java/hudson/security/ChainedServletFilter.java @@ -24,27 +24,28 @@ package hudson.security; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Arrays; import java.util.Collection; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import org.kohsuke.stapler.CompatibleFilter; /** * Servlet {@link Filter} that chains multiple {@link Filter}s. * * @author Kohsuke Kawaguchi */ -public class ChainedServletFilter implements Filter { +public class ChainedServletFilter implements CompatibleFilter { // array is assumed to be immutable once set protected volatile Filter[] filters; diff --git a/core/src/main/java/hudson/security/ContainerAuthentication.java b/core/src/main/java/hudson/security/ContainerAuthentication.java index be7bdc01ab62..571b5cc782e8 100644 --- a/core/src/main/java/hudson/security/ContainerAuthentication.java +++ b/core/src/main/java/hudson/security/ContainerAuthentication.java @@ -24,12 +24,12 @@ package hudson.security; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.security.Principal; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; import jenkins.model.Jenkins; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; diff --git a/core/src/main/java/hudson/security/FederatedLoginService.java b/core/src/main/java/hudson/security/FederatedLoginService.java index 2d176290d8be..38d91f7da901 100644 --- a/core/src/main/java/hudson/security/FederatedLoginService.java +++ b/core/src/main/java/hudson/security/FederatedLoginService.java @@ -30,13 +30,13 @@ import hudson.ExtensionPoint; import hudson.model.User; import hudson.model.UserProperty; +import jakarta.servlet.ServletException; import java.io.IOException; import java.io.Serializable; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; @@ -245,7 +245,7 @@ public UnclaimedIdentityException(FederatedIdentity identity) { } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { SecurityRealm sr = Jenkins.get().getSecurityRealm(); if (sr.allowsSignup()) { try { diff --git a/core/src/main/java/hudson/security/GlobalSecurityConfiguration.java b/core/src/main/java/hudson/security/GlobalSecurityConfiguration.java index 4c9dc1add7e7..a8657df65685 100644 --- a/core/src/main/java/hudson/security/GlobalSecurityConfiguration.java +++ b/core/src/main/java/hudson/security/GlobalSecurityConfiguration.java @@ -35,13 +35,13 @@ import hudson.model.Descriptor.FormException; import hudson.model.ManagementLink; import hudson.util.FormApply; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.Set; import java.util.TreeSet; import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.GlobalConfigurationCategory; import jenkins.model.Jenkins; import jenkins.util.ServerTcpPort; @@ -51,8 +51,8 @@ import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.verb.POST; /** @@ -108,7 +108,7 @@ public Category getCategory() { } @POST - public synchronized void doConfigure(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + public synchronized void doConfigure(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { // for compatibility reasons, the actual value is stored in Jenkins JSONObject json = req.getSubmittedForm(); BulkChange bc = new BulkChange(Jenkins.get()); @@ -125,7 +125,7 @@ public synchronized void doConfigure(StaplerRequest req, StaplerResponse rsp) th } } - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { // for compatibility reasons, the actual value is stored in Jenkins Jenkins j = Jenkins.get(); j.checkPermission(Jenkins.ADMINISTER); @@ -171,7 +171,7 @@ public boolean configure(StaplerRequest req, JSONObject json) throws FormExcepti return result; } - private boolean configureDescriptor(StaplerRequest req, JSONObject json, Descriptor d) throws FormException { + private boolean configureDescriptor(StaplerRequest2 req, JSONObject json, Descriptor d) throws FormException { // collapse the structure to remain backward compatible with the JSON structure before 1. String name = d.getJsonSafeClassName(); JSONObject js = json.has(name) ? json.getJSONObject(name) : new JSONObject(); // if it doesn't have the property, the method returns invalid null object. diff --git a/core/src/main/java/hudson/security/HttpSessionContextIntegrationFilter2.java b/core/src/main/java/hudson/security/HttpSessionContextIntegrationFilter2.java index 786df5d72879..c2c0d8a6abe1 100644 --- a/core/src/main/java/hudson/security/HttpSessionContextIntegrationFilter2.java +++ b/core/src/main/java/hudson/security/HttpSessionContextIntegrationFilter2.java @@ -25,13 +25,13 @@ package hudson.security; import hudson.model.User; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; import jenkins.security.seed.UserSeedProperty; import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.core.Authentication; diff --git a/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java b/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java index e99dfdc14f74..950cf3614c82 100644 --- a/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java +++ b/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java @@ -24,19 +24,19 @@ package hudson.security; -import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; +import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN; import hudson.Functions; import hudson.Util; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.text.MessageFormat; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.springframework.security.authentication.InsufficientAuthenticationException; diff --git a/core/src/main/java/hudson/security/HudsonFilter.java b/core/src/main/java/hudson/security/HudsonFilter.java index 333180b32ead..4438874b6030 100644 --- a/core/src/main/java/hudson/security/HudsonFilter.java +++ b/core/src/main/java/hudson/security/HudsonFilter.java @@ -26,17 +26,18 @@ import static java.util.logging.Level.SEVERE; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.logging.Logger; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; +import org.kohsuke.stapler.CompatibleFilter; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.web.authentication.RememberMeServices; @@ -52,7 +53,7 @@ * @author Kohsuke Kawaguchi * @since 1.160 */ -public class HudsonFilter implements Filter { +public class HudsonFilter implements CompatibleFilter { /** * The SecurityRealm specific filter. */ diff --git a/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java b/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java index bd122244c7e2..1a6ebe66f749 100644 --- a/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java +++ b/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java @@ -24,7 +24,7 @@ package hudson.security; -import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; +import static jakarta.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; import com.thoughtworks.xstream.converters.UnmarshallingContext; import edu.umd.cs.findbugs.annotations.NonNull; @@ -47,6 +47,15 @@ import hudson.util.Protector; import hudson.util.Scrambler; import hudson.util.XStream2; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import java.io.IOException; import java.lang.reflect.Constructor; import java.nio.charset.StandardCharsets; @@ -67,15 +76,6 @@ import java.util.regex.Pattern; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import jenkins.model.Jenkins; import jenkins.security.FIPS140; import jenkins.security.SecurityListener; @@ -85,14 +85,15 @@ import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.CompatibleFilter; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.ForwardToView; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; import org.mindrot.jbcrypt.BCrypt; import org.springframework.security.authentication.BadCredentialsException; @@ -236,10 +237,10 @@ protected UserDetails authenticate2(String username, String password) throws Aut @Override public HttpResponse commenceSignup(final FederatedIdentity identity) { // store the identity in the session so that we can use this later - Stapler.getCurrentRequest().getSession().setAttribute(FEDERATED_IDENTITY_SESSION_KEY, identity); + Stapler.getCurrentRequest2().getSession().setAttribute(FEDERATED_IDENTITY_SESSION_KEY, identity); return new ForwardToView(this, "signupWithFederatedIdentity.jelly") { @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { SignupInfo si = new SignupInfo(identity); si.errorMessage = Messages.HudsonPrivateSecurityRealm_WouldYouLikeToSignUp(identity.getPronoun(), identity.getIdentifier()); req.setAttribute("data", si); @@ -253,7 +254,7 @@ public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object nod * with {@link #commenceSignup}. */ @RequirePOST - public User doCreateAccountWithFederatedIdentity(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public User doCreateAccountWithFederatedIdentity(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { User u = _doCreateAccount(req, rsp, "signupWithFederatedIdentity.jelly"); if (u != null) ((FederatedIdentity) req.getSession().getAttribute(FEDERATED_IDENTITY_SESSION_KEY)).addTo(u); @@ -266,11 +267,11 @@ public User doCreateAccountWithFederatedIdentity(StaplerRequest req, StaplerResp * Creates an user account. Used for self-registration. */ @RequirePOST - public User doCreateAccount(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public User doCreateAccount(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { return _doCreateAccount(req, rsp, "signup.jelly"); } - private User _doCreateAccount(StaplerRequest req, StaplerResponse rsp, String formView) throws ServletException, IOException { + private User _doCreateAccount(StaplerRequest2 req, StaplerResponse2 rsp, String formView) throws ServletException, IOException { if (!allowsSignup()) throw HttpResponses.errorWithoutStack(SC_UNAUTHORIZED, "User sign up is prohibited"); @@ -287,7 +288,7 @@ private User _doCreateAccount(StaplerRequest req, StaplerResponse rsp, String fo /** * Lets the current user silently login as the given user and report back accordingly. */ - private void loginAndTakeBack(StaplerRequest req, StaplerResponse rsp, User u) throws ServletException, IOException { + private void loginAndTakeBack(StaplerRequest2 req, StaplerResponse2 rsp, User u) throws ServletException, IOException { HttpSession session = req.getSession(false); if (session != null) { // avoid session fixation @@ -309,11 +310,11 @@ private void loginAndTakeBack(StaplerRequest req, StaplerResponse rsp, User u) t /** * Creates a user account. Used by admins. * - * This version behaves differently from {@link #doCreateAccount(StaplerRequest, StaplerResponse)} in that + * This version behaves differently from {@link #doCreateAccount(StaplerRequest2, StaplerResponse2)} in that * this is someone creating another user. */ @RequirePOST - public void doCreateAccountByAdmin(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doCreateAccountByAdmin(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { createAccountByAdmin(req, rsp, "addUser.jelly", "."); // send the user back to the listing page on success } @@ -321,7 +322,7 @@ public void doCreateAccountByAdmin(StaplerRequest req, StaplerResponse rsp) thro * Creates a user account. Requires {@link Jenkins#ADMINISTER} */ @Restricted(NoExternalUse.class) - public User createAccountByAdmin(StaplerRequest req, StaplerResponse rsp, String addUserView, String successView) throws IOException, ServletException { + public User createAccountByAdmin(StaplerRequest2 req, StaplerResponse2 rsp, String addUserView, String successView) throws IOException, ServletException { checkPermission(Jenkins.ADMINISTER); User u = createAccount(req, rsp, false, addUserView); if (u != null && successView != null) { @@ -340,7 +341,7 @@ public User createAccountByAdmin(StaplerRequest req, StaplerResponse rsp, String * @throws AccountCreationFailedException if account creation failed due to invalid form input */ @Restricted(NoExternalUse.class) - public User createAccountFromSetupWizard(StaplerRequest req) throws IOException, AccountCreationFailedException { + public User createAccountFromSetupWizard(StaplerRequest2 req) throws IOException, AccountCreationFailedException { checkPermission(Jenkins.ADMINISTER); SignupInfo si = validateAccountCreationForm(req, false); if (!si.errors.isEmpty()) { @@ -366,7 +367,7 @@ private String getErrorMessages(SignupInfo si) { * This can be run by anyone, but only to create the very first user account. */ @RequirePOST - public void doCreateFirstAccount(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doCreateFirstAccount(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { if (hasSomeUser()) { rsp.sendError(SC_UNAUTHORIZED, "First user was already created"); return; @@ -400,7 +401,7 @@ private void tryToMakeAdmin(User u) { * null if failed. The browser is already redirected to retry by the time this method returns. * a valid {@link User} object if the user creation was successful. */ - private User createAccount(StaplerRequest req, StaplerResponse rsp, boolean validateCaptcha, String formView) throws ServletException, IOException { + private User createAccount(StaplerRequest2 req, StaplerResponse2 rsp, boolean validateCaptcha, String formView) throws ServletException, IOException { SignupInfo si = validateAccountCreationForm(req, validateCaptcha); if (!si.errors.isEmpty()) { @@ -416,11 +417,11 @@ private User createAccount(StaplerRequest req, StaplerResponse rsp, boolean vali * @param req the request to process * @param validateCaptcha whether to attempt to validate a captcha in the request * - * @return a {@link SignupInfo#SignupInfo(StaplerRequest) SignupInfo from given request}, with {@link + * @return a {@link SignupInfo#SignupInfo(StaplerRequest2) SignupInfo from given request}, with {@link * SignupInfo#errors} containing errors (keyed by field name), if any of the supported fields are invalid */ @SuppressFBWarnings(value = "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", justification = "written to by Stapler") - private SignupInfo validateAccountCreationForm(StaplerRequest req, boolean validateCaptcha) { + private SignupInfo validateAccountCreationForm(StaplerRequest2 req, boolean validateCaptcha) { // form field validation // this pattern needs to be generalized and moved to stapler SignupInfo si = new SignupInfo(req); @@ -632,7 +633,7 @@ public static final class SignupInfo { public SignupInfo() { } - public SignupInfo(StaplerRequest req) { + public SignupInfo(StaplerRequest2 req) { req.bindParameters(this); } @@ -707,7 +708,7 @@ public boolean isPasswordCorrect(String candidate) { public String getProtectedPassword() { // put session Id in it to prevent a replay attack. - return Protector.protect(Stapler.getCurrentRequest().getSession().getId() + ':' + getPassword()); + return Protector.protect(Stapler.getCurrentRequest2().getSession().getId() + ':' + getPassword()); } public String getUsername() { @@ -825,7 +826,7 @@ public String getDisplayName() { } @Override - public Details newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public Details newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { if (req == null) { // Should never happen, see newInstance() Javadoc throw new FormException("Stapler request is missing in the call", "staplerRequest"); @@ -858,7 +859,7 @@ public Details newInstance(StaplerRequest req, JSONObject formData) throws FormE } if (data != null) { - String prefix = Stapler.getCurrentRequest().getSession().getId() + ':'; + String prefix = Stapler.getCurrentRequest2().getSession().getId() + ':'; if (data.startsWith(prefix)) { return Details.fromHashedPassword(data.substring(prefix.length())); } @@ -1153,7 +1154,7 @@ public FormValidation doCheckAllowsSignup(@QueryParameter boolean value) { } } - private static final Filter CREATE_FIRST_USER_FILTER = new Filter() { + private static final Filter CREATE_FIRST_USER_FILTER = new CompatibleFilter() { @Override public void init(FilterConfig config) throws ServletException { } diff --git a/core/src/main/java/hudson/security/LegacySecurityRealm.java b/core/src/main/java/hudson/security/LegacySecurityRealm.java index 1e869475caf2..94c895782f74 100644 --- a/core/src/main/java/hudson/security/LegacySecurityRealm.java +++ b/core/src/main/java/hudson/security/LegacySecurityRealm.java @@ -28,10 +28,10 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import hudson.model.Descriptor; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterConfig; import java.util.ArrayList; import java.util.List; -import javax.servlet.Filter; -import javax.servlet.FilterConfig; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; diff --git a/core/src/main/java/hudson/security/NoopFilter.java b/core/src/main/java/hudson/security/NoopFilter.java index 3000bb2e81c0..2b2db184fc5f 100644 --- a/core/src/main/java/hudson/security/NoopFilter.java +++ b/core/src/main/java/hudson/security/NoopFilter.java @@ -24,20 +24,21 @@ package hudson.security; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; +import org.kohsuke.stapler.CompatibleFilter; /** * {@link Filter} that does nothing. * * @author Kohsuke Kawaguchi */ -public class NoopFilter implements Filter { +public class NoopFilter implements CompatibleFilter { @Override public void init(FilterConfig filterConfig) throws ServletException { } diff --git a/core/src/main/java/hudson/security/RememberMeServicesProxy.java b/core/src/main/java/hudson/security/RememberMeServicesProxy.java index 2220e313b0cc..1020002794ed 100644 --- a/core/src/main/java/hudson/security/RememberMeServicesProxy.java +++ b/core/src/main/java/hudson/security/RememberMeServicesProxy.java @@ -24,8 +24,8 @@ package hudson.security; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import jenkins.security.ConfidentialStore; import org.kohsuke.accmod.Restricted; diff --git a/core/src/main/java/hudson/security/SecurityRealm.java b/core/src/main/java/hudson/security/SecurityRealm.java index b969a57eb781..d10e7994ae22 100644 --- a/core/src/main/java/hudson/security/SecurityRealm.java +++ b/core/src/main/java/hudson/security/SecurityRealm.java @@ -36,6 +36,14 @@ import hudson.security.captcha.CaptchaSupport; import hudson.util.DescriptorList; import hudson.util.PluginServletFilter; +import io.jenkins.servlet.FilterConfigWrapper; +import io.jenkins.servlet.FilterWrapper; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpSession; import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; @@ -44,16 +52,12 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.Filter; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpSession; import jenkins.model.IdStrategy; import jenkins.model.Jenkins; import jenkins.security.AcegiSecurityExceptionFilter; import jenkins.security.AuthenticationSuccessHandler; import jenkins.security.BasicHeaderProcessor; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.SystemProperties; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; @@ -62,7 +66,9 @@ import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -264,7 +270,7 @@ public boolean canLogOut() { * of Hudson, but you can return arbitrary URL. * * @param req - * {@link StaplerRequest} that represents the current request. Primarily so that + * {@link StaplerRequest2} that represents the current request. Primarily so that * you can get the context path. By the time this method is called, the session * is already invalidated. Never null. * @param auth @@ -272,14 +278,31 @@ public boolean canLogOut() { * This parameter allows you to redirect people to different pages depending on who they are. * @return * never null. + * @since TODO + * @see #doLogout(StaplerRequest2, StaplerResponse2) + */ + protected String getPostLogOutUrl2(StaplerRequest2 req, Authentication auth) { + if (Util.isOverridden(SecurityRealm.class, getClass(), "getPostLogOutUrl2", StaplerRequest.class, Authentication.class)) { + return getPostLogOutUrl2(StaplerRequest.fromStaplerRequest2(req), auth); + } else { + return getPostLogOutUrl2Impl(req, auth); + } + } + + /** + * @deprecated use {@link #getPostLogOutUrl2(StaplerRequest2, Authentication)} * @since 2.266 - * @see #doLogout(StaplerRequest, StaplerResponse) */ + @Deprecated protected String getPostLogOutUrl2(StaplerRequest req, Authentication auth) { + return getPostLogOutUrl2Impl(StaplerRequest.toStaplerRequest2(req), auth); + } + + private String getPostLogOutUrl2Impl(StaplerRequest2 req, Authentication auth) { if (Util.isOverridden(SecurityRealm.class, getClass(), "getPostLogOutUrl", StaplerRequest.class, org.acegisecurity.Authentication.class) && !insideGetPostLogOutUrl.get()) { insideGetPostLogOutUrl.set(true); try { - return getPostLogOutUrl(req, org.acegisecurity.Authentication.fromSpring(auth)); + return getPostLogOutUrl(StaplerRequest.fromStaplerRequest2(req), org.acegisecurity.Authentication.fromSpring(auth)); } finally { insideGetPostLogOutUrl.set(false); } @@ -295,7 +318,7 @@ protected String getPostLogOutUrl2(StaplerRequest req, Authentication auth) { */ @Deprecated protected String getPostLogOutUrl(StaplerRequest req, org.acegisecurity.Authentication auth) { - return getPostLogOutUrl2(req, auth.toSpring()); + return getPostLogOutUrl2(StaplerRequest.toStaplerRequest2(req), auth.toSpring()); } public CaptchaSupport getCaptchaSupport() { @@ -315,11 +338,37 @@ public List> getCaptchaSupportDescriptors() { * *

* The default implementation erases the session and do a few other clean up, then - * redirect the user to the URL specified by {@link #getPostLogOutUrl2(StaplerRequest, Authentication)}. + * redirect the user to the URL specified by {@link #getPostLogOutUrl2(StaplerRequest2, Authentication)}. * + * @since TODO + */ + public void doLogout(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(SecurityRealm.class, getClass(), "doLogout", StaplerRequest.class, StaplerResponse.class)) { + try { + doLogout(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doLogoutImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doLogout(StaplerRequest2, StaplerResponse2)} * @since 1.314 */ - public void doLogout(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + @Deprecated + @StaplerNotDispatchable + public void doLogout(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doLogoutImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + void doLogoutImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { HttpSession session = req.getSession(false); if (session != null) session.invalidate(); @@ -333,7 +382,7 @@ public void doLogout(StaplerRequest req, StaplerResponse rsp) throws IOException rsp.sendRedirect2(getPostLogOutUrl2(req, auth)); } - private void resetRememberMeCookie(StaplerRequest req, StaplerResponse rsp, String contextPath) { + private void resetRememberMeCookie(StaplerRequest2 req, StaplerResponse2 rsp, String contextPath) { Cookie cookie = new Cookie(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, ""); cookie.setMaxAge(0); cookie.setSecure(req.isSecure()); @@ -342,7 +391,7 @@ private void resetRememberMeCookie(StaplerRequest req, StaplerResponse rsp, Stri rsp.addCookie(cookie); } - private void clearStaleSessionCookies(StaplerRequest req, StaplerResponse rsp, String contextPath) { + private void clearStaleSessionCookies(StaplerRequest2 req, StaplerResponse2 rsp, String contextPath) { /* While "executableWar.jetty.sessionIdCookieName" and * "executableWar.jetty.disableCustomSessionIdCookieName" * @@ -516,7 +565,7 @@ public HttpResponse commenceSignup(FederatedIdentity identity) { /** * Generates a captcha image. */ - public final void doCaptcha(StaplerRequest req, StaplerResponse rsp) throws IOException { + public final void doCaptcha(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (captchaSupport != null) { String id = req.getSession().getId(); rsp.setContentType("image/png"); @@ -533,7 +582,7 @@ public final void doCaptcha(StaplerRequest req, StaplerResponse rsp) throws IOEx */ protected final boolean validateCaptcha(String text) { if (captchaSupport != null) { - String id = Stapler.getCurrentRequest().getSession().getId(); + String id = Stapler.getCurrentRequest2().getSession().getId(); return captchaSupport.validateCaptcha(id, text); } @@ -570,10 +619,29 @@ public synchronized SecurityComponents getSecurityComponents() { * For other plugins that want to contribute {@link Filter}, see * {@link PluginServletFilter}. * - * @since 1.271 + * @since TODO */ public Filter createFilter(FilterConfig filterConfig) { - LOGGER.entering(SecurityRealm.class.getName(), "createFilter"); + if (Util.isOverridden(SecurityRealm.class, getClass(), "createFilter", javax.servlet.FilterConfig.class)) { + return FilterWrapper.toJakartaFilter(createFilter( + filterConfig != null ? FilterConfigWrapper.fromJakartaFilterConfig(filterConfig) : null)); + } else { + return createFilterImpl(filterConfig); + } + } + + /** + * @deprecated use {@link #createFilter(FilterConfig)} + * @since 1.271 + */ + @Deprecated + public javax.servlet.Filter createFilter(javax.servlet.FilterConfig filterConfig) { + return FilterWrapper.fromJakartaFilter(createFilterImpl( + filterConfig != null ? FilterConfigWrapper.toJakartaFilterConfig(filterConfig) : null)); + } + + private Filter createFilterImpl(FilterConfig filterConfig) { + LOGGER.entering(SecurityRealm.class.getName(), "createFilterImpl"); SecurityComponents sc = getSecurityComponents(); List filters = new ArrayList<>(); @@ -639,7 +707,7 @@ protected final List commonFilters() { @Restricted(DoNotUse.class) public static String getFrom() { String from = null; - final StaplerRequest request = Stapler.getCurrentRequest(); + final StaplerRequest2 request = Stapler.getCurrentRequest2(); // Try to obtain a return point from the query parameter if (request != null) { @@ -734,7 +802,7 @@ public String getDisplayName() { } @Override - public SecurityRealm newInstance(StaplerRequest req, JSONObject formData) throws Descriptor.FormException { + public SecurityRealm newInstance(StaplerRequest2 req, JSONObject formData) throws Descriptor.FormException { return NO_AUTHENTICATION; } } diff --git a/core/src/main/java/hudson/security/TokenBasedRememberMeServices2.java b/core/src/main/java/hudson/security/TokenBasedRememberMeServices2.java index 0e8e19d90a06..9b6974a3f2e4 100644 --- a/core/src/main/java/hudson/security/TokenBasedRememberMeServices2.java +++ b/core/src/main/java/hudson/security/TokenBasedRememberMeServices2.java @@ -27,6 +27,8 @@ import com.google.common.annotations.VisibleForTesting; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.model.User; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.security.MessageDigest; import java.util.Arrays; import java.util.Date; @@ -34,8 +36,6 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import jenkins.security.HMACConfidentialKey; import jenkins.security.ImpersonatingUserDetailsService2; diff --git a/core/src/main/java/hudson/security/UnwrapSecurityExceptionFilter.java b/core/src/main/java/hudson/security/UnwrapSecurityExceptionFilter.java index 2abfea11eb71..683725b2fe0d 100644 --- a/core/src/main/java/hudson/security/UnwrapSecurityExceptionFilter.java +++ b/core/src/main/java/hudson/security/UnwrapSecurityExceptionFilter.java @@ -24,14 +24,14 @@ package hudson.security; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; import org.apache.commons.jelly.JellyTagException; +import org.kohsuke.stapler.CompatibleFilter; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.access.ExceptionTranslationFilter; @@ -43,7 +43,7 @@ * * @author Kohsuke Kawaguchi */ -public class UnwrapSecurityExceptionFilter implements Filter { +public class UnwrapSecurityExceptionFilter implements CompatibleFilter { @Override public void init(FilterConfig filterConfig) throws ServletException { } diff --git a/core/src/main/java/hudson/security/csrf/CrumbExclusion.java b/core/src/main/java/hudson/security/csrf/CrumbExclusion.java index 4f4135bd9a88..e7d8d67a219f 100644 --- a/core/src/main/java/hudson/security/csrf/CrumbExclusion.java +++ b/core/src/main/java/hudson/security/csrf/CrumbExclusion.java @@ -8,11 +8,16 @@ import hudson.ExtensionList; import hudson.ExtensionPoint; +import hudson.Util; +import io.jenkins.servlet.FilterChainWrapper; +import io.jenkins.servlet.ServletExceptionWrapper; +import io.jenkins.servlet.http.HttpServletRequestWrapper; +import io.jenkins.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; /** * Allows plugins to define exceptions to the CSRF protection filter. @@ -32,7 +37,57 @@ public abstract class CrumbExclusion implements ExtensionPoint { * true to indicate that the callee had processed this request * (for example by reporting an error, or by executing the rest of the chain.) */ - public abstract boolean process(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException; + public /* abstract */ boolean process(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + if (Util.isOverridden( + CrumbExclusion.class, + getClass(), + "process", + javax.servlet.http.HttpServletRequest.class, + javax.servlet.http.HttpServletResponse.class, + javax.servlet.FilterChain.class)) { + try { + return process( + HttpServletRequestWrapper.fromJakartaHttpServletRequest(request), + HttpServletResponseWrapper.fromJakartaHttpServletResponse(response), + FilterChainWrapper.fromJakartaFilterChain(chain)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + CrumbExclusion.class.getSimpleName() + ".process methods"); + } + } + + /** + * @deprecated use {@link #process(HttpServletRequest, HttpServletResponse, FilterChain)} + */ + @Deprecated + public boolean process( + javax.servlet.http.HttpServletRequest request, + javax.servlet.http.HttpServletResponse response, + javax.servlet.FilterChain chain) + throws IOException, javax.servlet.ServletException { + if (Util.isOverridden( + CrumbExclusion.class, + getClass(), + "process", + HttpServletRequest.class, + HttpServletResponse.class, + FilterChain.class)) { + try { + return process( + HttpServletRequestWrapper.toJakartaHttpServletRequest(request), + HttpServletResponseWrapper.toJakartaHttpServletResponse(response), + FilterChainWrapper.toJakartaFilterChain(chain)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + CrumbExclusion.class.getSimpleName() + ".process methods"); + } + } public static ExtensionList all() { return ExtensionList.lookup(CrumbExclusion.class); diff --git a/core/src/main/java/hudson/security/csrf/CrumbFilter.java b/core/src/main/java/hudson/security/csrf/CrumbFilter.java index 8b4b558938e7..6835a4365a3c 100644 --- a/core/src/main/java/hudson/security/csrf/CrumbFilter.java +++ b/core/src/main/java/hudson/security/csrf/CrumbFilter.java @@ -7,6 +7,14 @@ package hudson.security.csrf; import hudson.util.MultipartFormDataParser; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -14,20 +22,12 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import org.kohsuke.MetaInfServices; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.CompatibleFilter; import org.kohsuke.stapler.ForwardToView; import org.kohsuke.stapler.interceptor.RequirePOST; import org.springframework.security.authentication.AnonymousAuthenticationToken; @@ -38,7 +38,7 @@ * * @author dty */ -public class CrumbFilter implements Filter { +public class CrumbFilter implements CompatibleFilter { /** * Because servlet containers generally don't specify the ordering of the initialization * (and different implementations indeed do this differently --- See JENKINS-3878), diff --git a/core/src/main/java/hudson/security/csrf/CrumbIssuer.java b/core/src/main/java/hudson/security/csrf/CrumbIssuer.java index cd0c51b03fb0..491ec735b591 100644 --- a/core/src/main/java/hudson/security/csrf/CrumbIssuer.java +++ b/core/src/main/java/hudson/security/csrf/CrumbIssuer.java @@ -6,26 +6,31 @@ package hudson.security.csrf; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.DescriptorExtensionList; import hudson.ExtensionPoint; +import hudson.Util; import hudson.init.Initializer; import hudson.model.Api; import hudson.model.Describable; import hudson.model.Descriptor; import hudson.util.MultipartFormDataParser; +import io.jenkins.servlet.ServletRequestWrapper; +import io.jenkins.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; import jenkins.model.Jenkins; import jenkins.security.stapler.StaplerAccessibleType; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebApp; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -64,7 +69,7 @@ public String getCrumbRequestField() { */ @Exported public String getCrumb() { - return getCrumb(Stapler.getCurrentRequest()); + return getCrumb(Stapler.getCurrentRequest2()); } /** @@ -89,6 +94,14 @@ public String getCrumb(ServletRequest request) { return crumb; } + /** + * @deprecated use {@link #getCrumb(ServletRequest)} + */ + @Deprecated + public String getCrumb(javax.servlet.ServletRequest request) { + return getCrumb(request != null ? wrap(request) : null); + } + /** * Create a crumb value based on user specific information in the request. * The crumb should be generated by building a cryptographic hash of: @@ -98,7 +111,30 @@ public String getCrumb(ServletRequest request) { *

  • an implementation specific guarded secret. * */ - protected abstract String issueCrumb(ServletRequest request, String salt); + protected /* abstract */ String issueCrumb(ServletRequest request, String salt) { + return Util.ifOverridden( + () -> issueCrumb( + request != null ? wrap(request) : null, salt), + CrumbIssuer.class, + getClass(), + "issueCrumb", + javax.servlet.ServletRequest.class, + String.class); + } + + /** + * @deprecated use {@link #issueCrumb(ServletRequest, String)} + */ + @Deprecated + protected String issueCrumb(javax.servlet.ServletRequest request, String salt) { + return Util.ifOverridden( + () -> issueCrumb(request != null ? wrap(request) : null, salt), + CrumbIssuer.class, + getClass(), + "issueCrumb", + ServletRequest.class, + String.class); + } /** * Get a crumb from a request parameter and validate it against other data @@ -126,12 +162,63 @@ public boolean validateCrumb(ServletRequest request, MultipartFormDataParser par return validateCrumb(request, crumbSalt, parser.get(crumbField)); } + /** + * @deprecated use {@link #validateCrumb(ServletRequest, MultipartFormDataParser)} + */ + @Deprecated + public boolean validateCrumb(javax.servlet.ServletRequest request, MultipartFormDataParser parser) { + return validateCrumb(request != null ? wrap(request) : null, parser); + } + + private static ServletRequest wrap(@NonNull javax.servlet.ServletRequest request) { + if (request instanceof javax.servlet.http.HttpServletRequest httpRequest) { + return HttpServletRequestWrapper.toJakartaHttpServletRequest(httpRequest); + } else { + return ServletRequestWrapper.toJakartaServletRequest(request); + } + } + /** * Validate a previously created crumb against information in the current request. * * @param crumb The previously generated crumb to validate against information in the current request */ - public abstract boolean validateCrumb(ServletRequest request, String salt, String crumb); + public /* abstract */ boolean validateCrumb(ServletRequest request, String salt, String crumb) { + return Util.ifOverridden( + () -> validateCrumb( + request != null ? wrap(request) : null, + salt, + crumb), + CrumbIssuer.class, + getClass(), + "validateCrumb", + javax.servlet.ServletRequest.class, + String.class, + String.class); + } + + private static javax.servlet.ServletRequest wrap(@NonNull ServletRequest request) { + if (request instanceof HttpServletRequest httpRequest) { + return HttpServletRequestWrapper.fromJakartaHttpServletRequest(httpRequest); + } else { + return ServletRequestWrapper.fromJakartaServletRequest(request); + } + } + + /** + * @deprecated use {@link #validateCrumb(ServletRequest, String, String)} + */ + @Deprecated + public boolean validateCrumb(javax.servlet.ServletRequest request, String salt, String crumb) { + return Util.ifOverridden( + () -> validateCrumb(request != null ? wrap(request) : null, salt, crumb), + CrumbIssuer.class, + getClass(), + "validateCrumb", + ServletRequest.class, + String.class, + String.class); + } /** * Access global configuration for the crumb issuer. @@ -157,15 +244,15 @@ public Api getApi() { */ @Initializer public static void initStaplerCrumbIssuer() { - WebApp.get(Jenkins.get().servletContext).setCrumbIssuer(new org.kohsuke.stapler.CrumbIssuer() { + WebApp.get(Jenkins.get().getServletContext()).setCrumbIssuer(new org.kohsuke.stapler.CrumbIssuer() { @Override - public String issueCrumb(StaplerRequest request) { + public String issueCrumb(StaplerRequest2 request) { CrumbIssuer ci = Jenkins.get().getCrumbIssuer(); return ci != null ? ci.getCrumb(request) : DEFAULT.issueCrumb(request); } @Override - public void validateCrumb(StaplerRequest request, String submittedCrumb) { + public void validateCrumb(StaplerRequest2 request, String submittedCrumb) { CrumbIssuer ci = Jenkins.get().getCrumbIssuer(); if (ci == null) { DEFAULT.validateCrumb(request, submittedCrumb); @@ -184,7 +271,7 @@ public static class RestrictedApi extends Api { super(instance); } - @Override public void doXml(StaplerRequest req, StaplerResponse rsp, @QueryParameter String xpath, @QueryParameter String wrapper, @QueryParameter String tree, @QueryParameter int depth) throws IOException, ServletException { + @Override public void doXml(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String xpath, @QueryParameter String wrapper, @QueryParameter String tree, @QueryParameter int depth) throws IOException, ServletException { setHeaders(rsp); String text; CrumbIssuer ci = (CrumbIssuer) bean; diff --git a/core/src/main/java/hudson/security/csrf/DefaultCrumbIssuer.java b/core/src/main/java/hudson/security/csrf/DefaultCrumbIssuer.java index 89c7da39e7b4..7a3bc0c9b1d2 100644 --- a/core/src/main/java/hudson/security/csrf/DefaultCrumbIssuer.java +++ b/core/src/main/java/hudson/security/csrf/DefaultCrumbIssuer.java @@ -12,13 +12,13 @@ import hudson.Util; import hudson.model.ModelObject; import hudson.model.PersistentDescriptor; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; import jenkins.model.Jenkins; import jenkins.security.HexStringConfidentialKey; import jenkins.util.SystemProperties; @@ -27,7 +27,7 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.springframework.security.core.Authentication; /** @@ -69,6 +69,7 @@ private synchronized void initializeMessageDigest() { } @Override + @SuppressFBWarnings(value = "NM_WRONG_PACKAGE", justification = "false positive") protected synchronized String issueCrumb(ServletRequest request, String salt) { if (request instanceof HttpServletRequest) { if (md != null) { @@ -135,7 +136,7 @@ public String getDisplayName() { } @Override - public DefaultCrumbIssuer newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public DefaultCrumbIssuer newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { if (req == null) { // This state is prohibited according to the Javadoc of the super method. throw new FormException("DefaultCrumbIssuer new instance method is called for null Stapler request. " diff --git a/core/src/main/java/hudson/security/csrf/GlobalCrumbIssuerConfiguration.java b/core/src/main/java/hudson/security/csrf/GlobalCrumbIssuerConfiguration.java index 6faa5dfc24e0..61a861fefbe3 100644 --- a/core/src/main/java/hudson/security/csrf/GlobalCrumbIssuerConfiguration.java +++ b/core/src/main/java/hudson/security/csrf/GlobalCrumbIssuerConfiguration.java @@ -35,7 +35,7 @@ import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Show the crumb configuration to the system config page. @@ -50,7 +50,7 @@ public class GlobalCrumbIssuerConfiguration extends GlobalConfiguration { } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { // for compatibility reasons, the actual value is stored in Jenkins Jenkins j = Jenkins.get(); diff --git a/core/src/main/java/hudson/slaves/Cloud.java b/core/src/main/java/hudson/slaves/Cloud.java index 6552685a05d0..3bff60c0d0ad 100644 --- a/core/src/main/java/hudson/slaves/Cloud.java +++ b/core/src/main/java/hudson/slaves/Cloud.java @@ -47,11 +47,11 @@ import hudson.slaves.NodeProvisioner.PlannedNode; import hudson.util.DescriptorList; import hudson.util.FormApply; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.Collection; import java.util.Objects; import java.util.concurrent.Future; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.kohsuke.accmod.Restricted; @@ -60,7 +60,8 @@ import org.kohsuke.stapler.HttpRedirect; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; @@ -319,7 +320,7 @@ public HttpResponse doDoDelete() throws IOException { * Accepts the update to the node configuration. */ @POST - public HttpResponse doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, Descriptor.FormException { + public HttpResponse doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, Descriptor.FormException { checkPermission(Jenkins.ADMINISTER); Jenkins j = Jenkins.get(); @@ -340,7 +341,26 @@ public HttpResponse doConfigSubmit(StaplerRequest req, StaplerResponse rsp) thro } + /** + * @since TODO + */ + public Cloud reconfigure(@NonNull final StaplerRequest2 req, JSONObject form) throws Descriptor.FormException { + if (Util.isOverridden(Cloud.class, getClass(), "reconfigure", StaplerRequest.class, JSONObject.class)) { + return reconfigure(StaplerRequest.fromStaplerRequest2(req), form); + } else { + return reconfigureImpl(req, form); + } + } + + /** + * @deprecated use {@link #reconfigure(StaplerRequest2, JSONObject)} + */ + @Deprecated public Cloud reconfigure(@NonNull final StaplerRequest req, JSONObject form) throws Descriptor.FormException { + return reconfigureImpl(StaplerRequest.toStaplerRequest2(req), form); + } + + private Cloud reconfigureImpl(@NonNull final StaplerRequest2 req, JSONObject form) throws Descriptor.FormException { if (form == null) return null; return getDescriptor().newInstance(req, form); } diff --git a/core/src/main/java/hudson/slaves/EnvironmentVariablesNodeProperty.java b/core/src/main/java/hudson/slaves/EnvironmentVariablesNodeProperty.java index be50bc982062..dd3ec84b131d 100644 --- a/core/src/main/java/hudson/slaves/EnvironmentVariablesNodeProperty.java +++ b/core/src/main/java/hudson/slaves/EnvironmentVariablesNodeProperty.java @@ -98,7 +98,7 @@ public String getDisplayName() { public String getHelpPage() { // yes, I know this is a hack. - ComputerSet object = Stapler.getCurrentRequest().findAncestorObject(ComputerSet.class); + ComputerSet object = Stapler.getCurrentRequest2().findAncestorObject(ComputerSet.class); if (object != null) { // we're on a node configuration page, show show that help page return "/help/system-config/nodeEnvironmentVariables.html"; diff --git a/core/src/main/java/hudson/slaves/NodeDescriptor.java b/core/src/main/java/hudson/slaves/NodeDescriptor.java index 8db1eb48139f..848cabbdf747 100644 --- a/core/src/main/java/hudson/slaves/NodeDescriptor.java +++ b/core/src/main/java/hudson/slaves/NodeDescriptor.java @@ -34,14 +34,14 @@ import hudson.model.Slave; import hudson.util.DescriptorList; import hudson.util.FormValidation; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * {@link Descriptor} for {@link Slave}. @@ -83,7 +83,7 @@ public final String newInstanceDetailPage() { * @param name * Name of the new node. */ - public void handleNewNodePage(ComputerSet computerSet, String name, StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void handleNewNodePage(ComputerSet computerSet, String name, StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { computerSet.checkName(name); req.setAttribute("descriptor", this); req.getView(computerSet, "_new.jelly").forward(req, rsp); diff --git a/core/src/main/java/hudson/slaves/NodeProperty.java b/core/src/main/java/hudson/slaves/NodeProperty.java index 8605edcf4515..bcb2a2422025 100644 --- a/core/src/main/java/hudson/slaves/NodeProperty.java +++ b/core/src/main/java/hudson/slaves/NodeProperty.java @@ -30,6 +30,7 @@ import hudson.ExtensionPoint; import hudson.FilePath; import hudson.Launcher; +import hudson.Util; import hudson.model.AbstractBuild; import hudson.model.BuildListener; import hudson.model.Descriptor.FormException; @@ -48,6 +49,7 @@ import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Extensible property of {@link Node}. @@ -171,8 +173,25 @@ public void buildEnvVars(@NonNull EnvVars env, @NonNull TaskListener listener) t // default is no-op } + @Override + public NodeProperty reconfigure(StaplerRequest2 req, JSONObject form) throws FormException { + if (Util.isOverridden(NodeProperty.class, getClass(), "reconfigure", StaplerRequest.class, JSONObject.class)) { + return reconfigure(StaplerRequest.fromStaplerRequest2(req), form); + } else { + return reconfigureImpl(req, form); + } + } + + /** + * @deprecated use {@link #reconfigure(StaplerRequest2, JSONObject)} + */ + @Deprecated @Override public NodeProperty reconfigure(StaplerRequest req, JSONObject form) throws FormException { + return reconfigureImpl(StaplerRequest.toStaplerRequest2(req), form); + } + + private NodeProperty reconfigureImpl(StaplerRequest2 req, JSONObject form) throws FormException { return form == null ? null : getDescriptor().newInstance(req, form); } diff --git a/core/src/main/java/hudson/slaves/SlaveComputer.java b/core/src/main/java/hudson/slaves/SlaveComputer.java index dbb579b9b3ae..4165f53a7245 100644 --- a/core/src/main/java/hudson/slaves/SlaveComputer.java +++ b/core/src/main/java/hudson/slaves/SlaveComputer.java @@ -97,8 +97,8 @@ import org.kohsuke.stapler.HttpRedirect; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -788,7 +788,7 @@ public List getLogRecords() throws IOException, InterruptedException */ @RequirePOST @Restricted(NoExternalUse.class) - public synchronized void doSubmitDescription(StaplerResponse rsp, @QueryParameter String description) throws IOException { + public synchronized void doSubmitDescription(StaplerResponse2 rsp, @QueryParameter String description) throws IOException { checkPermission(CONFIGURE); final Slave node = this.getNode(); @@ -828,7 +828,7 @@ public void run() { @RequirePOST @Override - public void doLaunchSlaveAgent(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doLaunchSlaveAgent(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { checkPermission(CONNECT); if (channel != null) { @@ -871,12 +871,12 @@ public Slave.JnlpJar getJnlpJars(String fileName) { } @WebMethod(name = "slave-agent.jnlp") // backward compatibility - public HttpResponse doSlaveAgentJnlp(StaplerRequest req, StaplerResponse res) { + public HttpResponse doSlaveAgentJnlp(StaplerRequest2 req, StaplerResponse2 res) { return doJenkinsAgentJnlp(req, res); } @WebMethod(name = "jenkins-agent.jnlp") - public HttpResponse doJenkinsAgentJnlp(StaplerRequest req, StaplerResponse res) { + public HttpResponse doJenkinsAgentJnlp(StaplerRequest2 req, StaplerResponse2 res) { LOGGER.log( Level.WARNING, "Agent \"" + getName() @@ -888,12 +888,12 @@ public HttpResponse doJenkinsAgentJnlp(StaplerRequest req, StaplerResponse res) class LowPermissionResponse { @WebMethod(name = "jenkins-agent.jnlp") - public HttpResponse doJenkinsAgentJnlp(StaplerRequest req, StaplerResponse res) { + public HttpResponse doJenkinsAgentJnlp(StaplerRequest2 req, StaplerResponse2 res) { return SlaveComputer.this.doJenkinsAgentJnlp(req, res); } @WebMethod(name = "slave-agent.jnlp") // backward compatibility - public HttpResponse doSlaveAgentJnlp(StaplerRequest req, StaplerResponse res) { + public HttpResponse doSlaveAgentJnlp(StaplerRequest2 req, StaplerResponse2 res) { return SlaveComputer.this.doJenkinsAgentJnlp(req, res); } } diff --git a/core/src/main/java/hudson/tasks/ArtifactArchiver.java b/core/src/main/java/hudson/tasks/ArtifactArchiver.java index 4300cd1538ab..0ee50010e6a2 100644 --- a/core/src/main/java/hudson/tasks/ArtifactArchiver.java +++ b/core/src/main/java/hudson/tasks/ArtifactArchiver.java @@ -63,7 +63,7 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Copies the artifacts into an archive directory. @@ -367,7 +367,7 @@ public FormValidation doCheckArtifacts(@AncestorInPath AbstractProject project, } @Override - public ArtifactArchiver newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public ArtifactArchiver newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { return req.bindJSON(ArtifactArchiver.class, formData); } diff --git a/core/src/main/java/hudson/tasks/BuildTrigger.java b/core/src/main/java/hudson/tasks/BuildTrigger.java index 5a58fc7e6716..af71ff83b147 100644 --- a/core/src/main/java/hudson/tasks/BuildTrigger.java +++ b/core/src/main/java/hudson/tasks/BuildTrigger.java @@ -73,7 +73,7 @@ import org.kohsuke.stapler.AncestorInPath; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.springframework.security.core.Authentication; /** @@ -385,7 +385,7 @@ public String getHelpFile() { } @Override - public BuildTrigger newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public BuildTrigger newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { String childProjectsString = formData.getString("childProjects").trim(); if (childProjectsString.endsWith(",")) { childProjectsString = childProjectsString.substring(0, childProjectsString.length() - 1).trim(); diff --git a/core/src/main/java/hudson/tasks/Fingerprinter.java b/core/src/main/java/hudson/tasks/Fingerprinter.java index 4d843b27b003..2d41e338f212 100644 --- a/core/src/main/java/hudson/tasks/Fingerprinter.java +++ b/core/src/main/java/hudson/tasks/Fingerprinter.java @@ -76,7 +76,7 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.springframework.security.access.AccessDeniedException; /** @@ -351,7 +351,7 @@ public FormValidation doCheckTargets(@AncestorInPath AbstractProject proje } @Override - public Publisher newInstance(StaplerRequest req, JSONObject formData) { + public Publisher newInstance(StaplerRequest2 req, JSONObject formData) { return req.bindJSON(Fingerprinter.class, formData); } diff --git a/core/src/main/java/hudson/tasks/Maven.java b/core/src/main/java/hudson/tasks/Maven.java index 3c22790d383c..2e9e27326b8e 100644 --- a/core/src/main/java/hudson/tasks/Maven.java +++ b/core/src/main/java/hudson/tasks/Maven.java @@ -80,7 +80,7 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Build by using Maven. @@ -479,7 +479,7 @@ public void setInstallations(MavenInstallation... installations) { } @Override - public Builder newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public Builder newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { if (req == null) { // This state is prohibited according to the Javadoc of the super method. throw new FormException("Maven Build Step new instance method is called for null Stapler request. " diff --git a/core/src/main/java/hudson/tasks/Shell.java b/core/src/main/java/hudson/tasks/Shell.java index e34c90b89d5c..9cd070136b55 100644 --- a/core/src/main/java/hudson/tasks/Shell.java +++ b/core/src/main/java/hudson/tasks/Shell.java @@ -53,7 +53,7 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Executes a series of commands by using a shell. @@ -234,7 +234,7 @@ public FormValidation doCheckUnstableReturn(@QueryParameter String value) { } @Override - public boolean configure(StaplerRequest req, JSONObject data) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject data) throws FormException { req.bindJSON(this, data); return super.configure(req, data); } diff --git a/core/src/main/java/hudson/tools/ToolDescriptor.java b/core/src/main/java/hudson/tools/ToolDescriptor.java index cc9a2399196d..e20eb353af63 100644 --- a/core/src/main/java/hudson/tools/ToolDescriptor.java +++ b/core/src/main/java/hudson/tools/ToolDescriptor.java @@ -26,6 +26,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.Util; import hudson.model.Descriptor; import hudson.util.DescribableList; import hudson.util.FormValidation; @@ -43,6 +44,7 @@ import org.jvnet.tiger_types.Types; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * {@link Descriptor} for {@link ToolInstallation}. @@ -144,8 +146,25 @@ public DescribableList, ToolPropertyDescriptor> getDefaultProper } @Override - @SuppressWarnings("unchecked") // cast to T[] + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { + if (Util.isOverridden(ToolDescriptor.class, getClass(), "configure", StaplerRequest.class, JSONObject.class)) { + return configure(StaplerRequest.fromStaplerRequest2(req), json); + } else { + return configureImpl(req, json); + } + } + + /** + * @deprecated use {@link #configure(StaplerRequest2, JSONObject)} + */ + @Deprecated + @Override public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + return configureImpl(StaplerRequest.toStaplerRequest2(req), json); + } + + @SuppressWarnings("unchecked") // cast to T[] + private boolean configureImpl(StaplerRequest2 req, JSONObject json) { setInstallations(req.bindJSONToList(clazz, json.get("tool")).toArray((T[]) Array.newInstance(clazz, 0))); return true; } diff --git a/core/src/main/java/hudson/triggers/SCMTrigger.java b/core/src/main/java/hudson/triggers/SCMTrigger.java index 43fdc6bb1062..f8277a345198 100644 --- a/core/src/main/java/hudson/triggers/SCMTrigger.java +++ b/core/src/main/java/hudson/triggers/SCMTrigger.java @@ -89,8 +89,8 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * {@link Trigger} that checks for SCM updates periodically. @@ -356,7 +356,7 @@ public boolean isPollingThreadCountOptionVisible() { } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { String t = json.optString("pollingThreadCount", null); if (doCheckPollingThreadCount(t).kind != FormValidation.Kind.OK) { setPollingThreadCount(THREADS_DEFAULT); @@ -466,7 +466,7 @@ public String getUrlName() { /** * Sends out the raw polling log output. */ - public void doPollingLog(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doPollingLog(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { rsp.setContentType("text/plain;charset=UTF-8"); try (OutputStream os = rsp.getOutputStream(); // Prevent jelly from flushing stream so Content-Length header can be added afterwards diff --git a/core/src/main/java/hudson/util/BootFailure.java b/core/src/main/java/hudson/util/BootFailure.java index f23cf7fa66b7..321d8239664c 100644 --- a/core/src/main/java/hudson/util/BootFailure.java +++ b/core/src/main/java/hudson/util/BootFailure.java @@ -2,6 +2,7 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.WebAppMain; +import jakarta.servlet.ServletContext; import java.io.BufferedReader; import java.io.File; import java.io.IOException; @@ -14,7 +15,6 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletContext; import jenkins.model.Jenkins; import jenkins.util.groovy.GroovyHookScript; import org.kohsuke.stapler.WebApp; diff --git a/core/src/main/java/hudson/util/CharacterEncodingFilter.java b/core/src/main/java/hudson/util/CharacterEncodingFilter.java index cb93c31e7d4a..2e42c0d8098c 100644 --- a/core/src/main/java/hudson/util/CharacterEncodingFilter.java +++ b/core/src/main/java/hudson/util/CharacterEncodingFilter.java @@ -24,17 +24,17 @@ package hudson.util; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; import jenkins.util.SystemProperties; +import org.kohsuke.stapler.CompatibleFilter; /** * Filter that sets the character encoding to be used in parsing the request @@ -42,7 +42,7 @@ * * @author Seiji Sogabe */ -public class CharacterEncodingFilter implements Filter { +public class CharacterEncodingFilter implements CompatibleFilter { /** * The default character encoding. diff --git a/core/src/main/java/hudson/util/ComboBoxModel.java b/core/src/main/java/hudson/util/ComboBoxModel.java index e245c890db2e..63cac72f4d0d 100644 --- a/core/src/main/java/hudson/util/ComboBoxModel.java +++ b/core/src/main/java/hudson/util/ComboBoxModel.java @@ -26,15 +26,15 @@ import static java.util.Arrays.asList; +import jakarta.servlet.ServletException; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; -import javax.servlet.ServletException; import net.sf.json.JSONArray; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Flavor; /** @@ -59,7 +59,7 @@ public ComboBoxModel(String... values) { } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { rsp.setContentType(Flavor.JSON.contentType); PrintWriter w = rsp.getWriter(); JSONArray.fromObject(this).write(w); diff --git a/core/src/main/java/hudson/util/DescribableList.java b/core/src/main/java/hudson/util/DescribableList.java index 9c62af2f191a..dbb499b4df66 100644 --- a/core/src/main/java/hudson/util/DescribableList.java +++ b/core/src/main/java/hudson/util/DescribableList.java @@ -50,6 +50,7 @@ import jenkins.model.DependencyDeclarer; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Persisted list of {@link Describable}s with some operations specific @@ -167,7 +168,7 @@ public Map toMap() { * @param json * Structured form data that includes the data for nested descriptor list. */ - public void rebuild(StaplerRequest req, JSONObject json, List> descriptors) throws FormException, IOException { + public void rebuild(StaplerRequest2 req, JSONObject json, List> descriptors) throws FormException, IOException { List newList = new ArrayList<>(); for (Descriptor d : descriptors) { @@ -193,9 +194,17 @@ public void rebuild(StaplerRequest req, JSONObject json, List> descriptors) throws FormException, IOException { + rebuild(StaplerRequest.toStaplerRequest2(req), json, descriptors); + } + /** * @deprecated as of 1.271 - * Use {@link #rebuild(StaplerRequest, JSONObject, List)} instead. + * Use {@link #rebuild(StaplerRequest2, JSONObject, List)} instead. */ @Deprecated public void rebuild(StaplerRequest req, JSONObject json, List> descriptors, String prefix) throws FormException, IOException { @@ -210,10 +219,18 @@ public void rebuild(StaplerRequest req, JSONObject json, List> descriptors, String key) throws FormException, IOException { + public void rebuildHetero(StaplerRequest2 req, JSONObject formData, Collection> descriptors, String key) throws FormException, IOException { replaceBy(Descriptor.newInstancesFromHeteroList(req, formData, key, descriptors)); } + /** + * @deprecated use {@link #rebuildHetero(StaplerRequest2, JSONObject, Collection, String)} + */ + @Deprecated + public void rebuildHetero(StaplerRequest req, JSONObject formData, Collection> descriptors, String key) throws FormException, IOException { + rebuildHetero(StaplerRequest.toStaplerRequest2(req), formData, descriptors, key); + } + /** * Picks up {@link DependencyDeclarer}s and allow it to build dependencies. */ diff --git a/core/src/main/java/hudson/util/DescriptorList.java b/core/src/main/java/hudson/util/DescriptorList.java index 94f105892cd8..c9b515d85c4e 100644 --- a/core/src/main/java/hudson/util/DescriptorList.java +++ b/core/src/main/java/hudson/util/DescriptorList.java @@ -160,7 +160,7 @@ public T newInstanceFromRadioList(JSONObject config) throws FormException { if (config.isNullObject()) return null; // none was selected int idx = config.getInt("value"); - return get(idx).newInstance(Stapler.getCurrentRequest(), config); + return get(idx).newInstance(Stapler.getCurrentRequest2(), config); } /** diff --git a/core/src/main/java/hudson/util/ErrorObject.java b/core/src/main/java/hudson/util/ErrorObject.java index 2f9f39ec8f19..48e1106b35f1 100644 --- a/core/src/main/java/hudson/util/ErrorObject.java +++ b/core/src/main/java/hudson/util/ErrorObject.java @@ -24,13 +24,13 @@ package hudson.util; -import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; +import static jakarta.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; import hudson.Functions; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Basis for error model objects. @@ -52,7 +52,7 @@ public String getStackTraceString() { return Functions.printThrowable(this); } - public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { + public void doDynamic(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, InterruptedException { rsp.setStatus(SC_SERVICE_UNAVAILABLE); req.getView(this, "index.jelly").forward(req, rsp); } diff --git a/core/src/main/java/hudson/util/FormApply.java b/core/src/main/java/hudson/util/FormApply.java index 8a1db5bebe4e..dc5e4d64df9b 100644 --- a/core/src/main/java/hudson/util/FormApply.java +++ b/core/src/main/java/hudson/util/FormApply.java @@ -24,11 +24,12 @@ package hudson.util; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; import org.kohsuke.stapler.HttpResponses.HttpResponseException; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Server-side code related to the {@code } button. @@ -47,7 +48,7 @@ public class FormApply { public static HttpResponseException success(final String destination) { return new HttpResponseException() { @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { if (isApply(req)) { // if the submission is via 'apply', show a response in the notification bar applyResponse("notificationBar.show('" + Messages.HttpResponses_Saved() + "',notificationBar.SUCCESS)") @@ -61,11 +62,21 @@ public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object nod /** * Is this submission from the "apply" button? + * + * @since TODO */ - public static boolean isApply(StaplerRequest req) { + public static boolean isApply(StaplerRequest2 req) { return Boolean.parseBoolean(req.getParameter("core:apply")); } + /** + * @deprecated use {@link #isApply(StaplerRequest2)} + */ + @Deprecated + public static boolean isApply(StaplerRequest req) { + return isApply(StaplerRequest.toStaplerRequest2(req)); + } + /** * Generates the response for the asynchronous background form submission (AKA the Apply button.) *

    @@ -75,7 +86,7 @@ public static boolean isApply(StaplerRequest req) { public static HttpResponseException applyResponse(final String script) { return new HttpResponseException() { @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { rsp.setContentType("text/html;charset=UTF-8"); rsp.getWriter().println("