Compare commits

..

7 Commits
3.0.1 ... 2.7.x

Author SHA1 Message Date
Jerome Prinet
51ca6c329e Update Gradle Enterprise plugins 2023-03-22 16:02:42 -03:00
Marcus Da Coregio
bd81ee5a49 Next Development Version 2023-03-21 10:59:24 -03:00
Marcus Da Coregio
ec6fd8a902 Release 2.7.1 2023-03-21 09:58:55 -03:00
Marcus Da Coregio
0320e60cf0 Update spring-security-bom to 5.7.7
Closes gh-2264
2023-03-21 09:55:04 -03:00
Marcus Da Coregio
90d0c1d778 Update spring-data-bom to 2021.2.9
Closes gh-2263
2023-03-21 09:55:04 -03:00
Marcus Da Coregio
058ae80419 Update spring-framework-bom to 5.3.26
Closes gh-2262
2023-03-21 09:55:04 -03:00
Marcus Da Coregio
89fb210f18 Update reactor-bom to 2020.0.30
Closes gh-2260
2023-03-21 09:55:04 -03:00
384 changed files with 8325 additions and 4617 deletions

6
.gitattributes vendored
View File

@@ -1,6 +0,0 @@
* text eol=lf
*.bat text eol=crlf
*.jar binary
*.jpg binary
*.png binary
*.mmdb binary

20
.github/actions/algolia-config.json vendored Normal file
View File

@@ -0,0 +1,20 @@
{
"index_name": "session-docs",
"start_urls": [
"https://docs.spring.io/spring-session/reference/"
],
"selectors": {
"lvl0": {
"selector": "//nav[@class='crumbs']//li[@class='crumb'][last()-1]",
"type": "xpath",
"global": true,
"default_value": "Home"
},
"lvl1": ".doc h1",
"lvl2": ".doc h2",
"lvl3": ".doc h3",
"lvl4": ".doc h4",
"text": ".doc p, .doc td.content, .doc th.tableblock"
}
}

20
.github/actions/algolia-deploy.sh vendored Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/bash
HOST="$1"
HOST_PATH="$2"
SSH_PRIVATE_KEY="$3"
SSH_KNOWN_HOST="$4"
if [ "$#" -ne 4 ]; then
echo -e "not enough arguments USAGE:\n\n$0 \$HOST \$HOST_PATH \$SSH_PRIVATE_KEY \$SSH_KNOWN_HOSTS \n\n" >&2
exit 1
fi
# Use a non-default path to avoid overriding when testing locally
SSH_PRIVATE_KEY_PATH=~/.ssh/github-actions-docs
install -m 600 -D /dev/null "$SSH_PRIVATE_KEY_PATH"
echo "$SSH_PRIVATE_KEY" > "$SSH_PRIVATE_KEY_PATH"
echo "$SSH_KNOWN_HOST" > ~/.ssh/known_hosts
rsync --delete -avze "ssh -i $SSH_PRIVATE_KEY_PATH" spring-session-docs/build/site/ "$HOST:$HOST_PATH"
rm -f "$SSH_PRIVATE_KEY_PATH"

21
.github/actions/algolia-docsearch-scraper.sh vendored Executable file
View File

@@ -0,0 +1,21 @@
#!/bin/bash
###
# Docs
# config.json https://docsearch.algolia.com/docs/config-file
# Run the crawler https://docsearch.algolia.com/docs/run-your-own/#run-the-crawl-from-the-docker-image
### USAGE
if [ "$#" -ne 3 ]; then
echo -e "not enough arguments USAGE:\n\n$0 \$ALGOLIA_APPLICATION_ID \$ALGOLIA_API_KEY \$CONFIG_FILE\n\n" >&2
exit 1
fi
# Script Parameters
APPLICATION_ID=$1
API_KEY=$2
CONFIG_FILE=$3
#### Script
script_dir=$(dirname $0)
docker run -e "APPLICATION_ID=$APPLICATION_ID" -e "API_KEY=$API_KEY" -e "CONFIG=$(cat $CONFIG_FILE | jq -r tostring)" algolia/docsearch-scraper

5
.github/actions/dispatch.sh vendored Executable file
View File

@@ -0,0 +1,5 @@
REPOSITORY_REF="$1"
TOKEN="$2"
curl -H "Accept: application/vnd.github.everest-preview+json" -H "Authorization: token ${TOKEN}" --request POST --data '{"event_type": "request-build-reference"}' https://api.github.com/repos/${REPOSITORY_REF}/dispatches
echo "Requested Build for $REPOSITORY_REF"

16
.github/workflows/algolia-index.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: Update Algolia Index
on:
schedule:
- cron: '0 10 * * *' # Once per day at 10am UTC
workflow_dispatch: # Manual trigger
jobs:
update:
name: Update Algolia Index
runs-on: ubuntu-latest
steps:
- name: Checkout Source
uses: actions/checkout@v2
- name: Update Index
run: ${GITHUB_WORKSPACE}/.github/actions/algolia-docsearch-scraper.sh "${{ secrets.ALGOLIA_APPLICATION_ID }}" "${{ secrets.ALGOLIA_WRITE_API_KEY }}" "${GITHUB_WORKSPACE}/.github/actions/algolia-config.json"

31
.github/workflows/antora-generate.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
name: Generate Antora Files and Request Build
on:
workflow_dispatch: # Manual trigger
push:
branches-ignore:
- 'gh-pages'
env:
GH_ACTIONS_REPO_TOKEN: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Source
uses: actions/checkout@v2
- name: Generate antora.yml
run: ./gradlew :spring-session-docs:generateAntora
- name: Extract Branch Name
id: extract_branch_name
run: echo "##[set-output name=generated_branch_name;]$(echo ${GITHUB_REPOSITORY}/${GITHUB_REF##*/})"
- name: Push generated antora files to the spring-generated-docs
uses: JamesIves/github-pages-deploy-action@4.1.4
with:
branch: ${{ steps.extract_branch_name.outputs.generated_branch_name }} # The branch the action should deploy to.
folder: "spring-session-docs/build/generateAntora" # The folder the action should deploy.
repository-name: "spring-io/spring-generated-docs"
token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
- name: Dispatch Build Request
run: ${GITHUB_WORKSPACE}/.github/actions/dispatch.sh 'spring-projects/spring-session' "$GH_ACTIONS_REPO_TOKEN"

View File

@@ -20,7 +20,7 @@ jobs:
if: github.repository == 'spring-projects/spring-session'
strategy:
matrix:
jdk: [17]
jdk: [8, 11]
fail-fast: false
steps:
- uses: actions/checkout@v2
@@ -53,7 +53,7 @@ jobs:
- name: Set up JDK
uses: actions/setup-java@v1
with:
java-version: '17'
java-version: '8'
- name: Setup gradle user name
run: |
mkdir -p ~/.gradle
@@ -81,7 +81,7 @@ jobs:
- name: Set up JDK
uses: actions/setup-java@v1
with:
java-version: '17'
java-version: '8'
- name: Setup gradle user name
run: |
mkdir -p ~/.gradle

View File

@@ -1,30 +0,0 @@
name: Deploy Docs
on:
push:
branches-ignore: [ gh-pages ]
tags: '**'
repository_dispatch:
types: request-build-reference # legacy
workflow_dispatch:
permissions: read-all
jobs:
build:
runs-on: ubuntu-latest
if: github.repository_owner == 'spring-projects'
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: docs-build
fetch-depth: 1
- name: Dispatch (partial build)
if: github.ref_type == 'branch'
env:
GH_TOKEN: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) -f build-refname=${{ github.ref_name }}
- name: Dispatch (full build)
if: github.ref_type == 'tag'
env:
GH_TOKEN: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD)

33
.github/workflows/deploy-reference.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
name: Build & Deploy Reference
on:
repository_dispatch:
types: request-build-reference
schedule:
- cron: '0 10 * * *' # Once per day at 10am UTC
workflow_dispatch: # Manual trigger
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'adopt'
cache: gradle
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
- name: Build with Gradle
run: ./gradlew :spring-session-docs:antora --stacktrace
- name: Cleanup Gradle Cache
# Remove some files from the Gradle cache, so they aren't cached by GitHub Actions.
# Restoring these files from a GitHub Actions cache might cause problems for future builds.
run: |
rm -f ~/.gradle/caches/modules-2/modules-2.lock
rm -f ~/.gradle/caches/modules-2/gc.properties
- name: Deploy
run: ${GITHUB_WORKSPACE}/.github/actions/algolia-deploy.sh "${{ secrets.DOCS_USERNAME }}@${{ secrets.DOCS_HOST }}" "/opt/www/domains/spring.io/docs/htdocs/spring-session/reference/" "${{ secrets.DOCS_SSH_KEY }}" "${{ secrets.DOCS_SSH_HOST_KEY }}"

View File

@@ -9,7 +9,7 @@ jobs:
if: github.repository == 'spring-projects/spring-session'
strategy:
matrix:
jdk: [17]
jdk: [8, 11]
fail-fast: false
steps:
- uses: actions/checkout@v2

View File

@@ -1,20 +0,0 @@
name: Rebuild Search Index
on:
schedule:
- cron: '0 10 * * *' # Once per day at 10am UTC
workflow_dispatch:
permissions: read-all
jobs:
build:
if: github.repository_owner == 'spring-projects'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: docs-build
fetch-depth: 1
- name: Dispatch
env:
GH_TOKEN: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
run: gh workflow run rebuild-search-index.yml -r $(git rev-parse --abbrev-ref HEAD)

2
.gitignore vendored
View File

@@ -14,5 +14,3 @@ out
!etc/eclipse/.checkstyle
!**/src/**/build
.DS_Store
spring-session-docs/package-lock.json
spring-session-docs/node_modules/

View File

@@ -3,4 +3,4 @@
# See https://sdkman.io/usage#config
# A summary is to add the following to ~/.sdkman/etc/config
# sdkman_auto_env=true
java=17.0.2-tem
java=8.0.332-zulu

View File

@@ -25,7 +25,7 @@ Additional Spring Session modules can be found in the https://github.com/spring-
== Getting Started
We recommend you visit the https://docs.spring.io/spring-session/docs/current/reference/html5/#samples[Spring Session Reference] and look through the "Samples and Guides" section to see which one best suits your needs.
We recommend you visit the https://docs.spring.io/spring-session/reference/index.html[Spring Session Reference] and look through the "Samples and Guides" section to see which one best suits your needs.
== Samples
@@ -63,7 +63,7 @@ Compile and test; build all jars, distribution zips, and docs
You can find the documentation, samples, and guides for using Spring Session on the https://projects.spring.io/spring-session/[Spring Session project site].
For more in depth information, visit the https://docs.spring.io/spring-session/reference/[Spring Session Reference].
For more in depth information, visit the https://docs.spring.io/spring-session/docs/current/reference/html5/[Spring Session Reference].
== Code of Conduct

View File

@@ -18,7 +18,7 @@ You can manually check at https://github.com/spring-projects/spring-session/mile
== 3. Update Release Version
Update the version number in `gradle.properties` for the release, for example `3.0.0-M1`, `3.0.0-RC1`, `3.0.4`
Update the version number in `gradle.properties` for the release, for example `2.7.0-M1`, `2.7.0-RC1`, `2.7.3`
== 4. Update Antora Version
@@ -26,9 +26,9 @@ You will need to update the antora.yml version.
For milestone / release candidate releases you should follow this format:
----
version: '3.0.0-RC1'
version: '2.7.0-RC1'
prerelease: 'true'
display_version: '3.0.0-RC1'
display_version: '2.7.0-RC1'
----
== 5. Build Locally
@@ -50,8 +50,8 @@ Wait for the artifact to appear in https://repo1.maven.org/maven2/org/springfram
Tag the release and then push the tag
....
git tag 3.0.0-RC1
git push origin 3.0.0-RC1
git tag 2.7.0-RC1
git push origin 2.7.0-RC1
....
== 8. Update to Next Development Version
@@ -76,7 +76,7 @@ java -jar github-changelog-generator.jar \
$MILESTONE release-notes
....
Note 1: `+$MILESTONE+` is something like `+3.0.4+` or `+3.0.0-M1+`. +
Note 1: `+$MILESTONE+` is something like `+2.7.1+` or `+2.7.0-M1+`. +
Note 2: This will create a file on your filesystem
called `+release-notes+`.

View File

@@ -4,7 +4,7 @@ buildscript {
snapshotBuild = version.endsWith('SNAPSHOT')
milestoneBuild = !(releaseBuild || snapshotBuild)
springBootVersion = '3.0.0-SNAPSHOT'
springBootVersion = '2.7.8'
}
repositories {
@@ -35,7 +35,7 @@ subprojects {
apply plugin: 'io.spring.javaformat'
plugins.withType(JavaPlugin) {
sourceCompatibility = JavaVersion.VERSION_17
sourceCompatibility = JavaVersion.VERSION_1_8
}
tasks.withType(Test) {
@@ -45,6 +45,4 @@ subprojects {
nohttp {
source.exclude "buildSrc/build/**"
source.exclude "spring-session-docs/.gradle/nodejs/**"
source.exclude "spring-session-docs/modules/ROOT/examples/**/build/**"
}

View File

@@ -4,7 +4,7 @@ plugins {
id "groovy"
}
sourceCompatibility = JavaVersion.VERSION_11
sourceCompatibility = 1.8
repositories {
jcenter()
@@ -26,10 +26,6 @@ sourceSets {
gradlePlugin {
plugins {
checkAntoraVersion {
id = "org.springframework.antora.check-version"
implementationClass = "org.springframework.gradle.antora.AntoraVersionPlugin"
}
managementConfiguration {
id = "io.spring.convention.management-configuration"
implementationClass = "io.spring.gradle.convention.ManagementConfigurationPlugin"
@@ -58,7 +54,6 @@ configurations {
dependencies {
implementation 'com.google.code.gson:gson:2.8.8'
implementation 'net.sourceforge.saxon:saxon:9.1.0.8'
implementation 'org.yaml:snakeyaml:1.30'
implementation localGroovy()
implementation 'io.github.gradle-nexus:publish-plugin:1.1.0'
@@ -67,9 +62,9 @@ dependencies {
implementation 'com.apollographql.apollo:apollo-runtime:2.4.5'
implementation 'com.github.ben-manes:gradle-versions-plugin:0.38.0'
implementation 'com.github.spullara.mustache.java:compiler:0.9.10'
implementation 'io.spring.javaformat:spring-javaformat-gradle-plugin:0.0.34'
implementation 'io.spring.javaformat:spring-javaformat-gradle-plugin:0.0.15'
implementation 'io.spring.nohttp:nohttp-gradle:0.0.9'
implementation 'net.sourceforge.htmlunit:htmlunit:2.37.0'
implementation 'net.sourceforge.htmlunit:htmlunit:2.55.0'
implementation 'org.hidetake:gradle-ssh-plugin:2.10.1'
implementation 'org.jfrog.buildinfo:build-info-extractor-gradle:4.29.0'
implementation 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7.1'

Binary file not shown.

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -35,7 +35,6 @@ public abstract class AbstractSpringJavaPlugin implements Plugin<Project> {
@Override
public final void apply(Project project) {
initialPlugins(project);
PluginManager pluginManager = project.getPluginManager();
pluginManager.apply(JavaPlugin.class);
pluginManager.apply(ManagementConfigurationPlugin.class)
@@ -70,7 +69,5 @@ public abstract class AbstractSpringJavaPlugin implements Plugin<Project> {
additionalPlugins(project);
}
protected void initialPlugins(Project project) {}
protected abstract void additionalPlugins(Project project);
}

View File

@@ -34,7 +34,7 @@ class JacocoPlugin implements Plugin<Project> {
project.tasks.check.dependsOn project.tasks.jacocoTestReport
project.jacoco {
toolVersion = '0.8.7'
toolVersion = '0.8.2'
}
}
}

View File

@@ -30,19 +30,4 @@ public class SpringSamplePlugin extends AbstractSpringJavaPlugin {
project.sonarqube.skipProject = true
}
}
@Override
protected void initialPlugins(Project project) {
if (project.hasProperty('springBootVersion')) {
String springBootVersion = project.springBootVersion
if (Utils.isSnapshot(springBootVersion)) {
project.ext.forceMavenRepositories = 'snapshot'
}
else if (Utils.isMilestone(springBootVersion)) {
project.ext.forceMavenRepositories = 'milestone'
}
}
}
}

View File

@@ -36,7 +36,7 @@ public class SpringSampleWarPlugin extends SpringSamplePlugin {
pluginManager.apply("org.gretty");
project.gretty {
servletContainer = 'tomcat10'
servletContainer = 'tomcat85'
contextPath = '/'
fileLogEnabled = false
}

View File

@@ -14,29 +14,16 @@ public class Utils {
static boolean isSnapshot(Project project) {
String projectVersion = projectVersion(project)
return isSnapshot(projectVersion)
return projectVersion.matches('^.*([.-]BUILD)?-SNAPSHOT$')
}
static boolean isMilestone(Project project) {
String projectVersion = projectVersion(project)
return isMilestone(projectVersion)
}
static boolean isRelease(Project project) {
String projectVersion = projectVersion(project)
return isRelease(projectVersion)
}
static boolean isSnapshot(String projectVersion) {
return projectVersion.matches('^.*([.-]BUILD)?-SNAPSHOT$')
}
static boolean isMilestone(String projectVersion) {
return projectVersion.matches('^.*[.-]M\\d+$') || projectVersion.matches('^.*[.-]RC\\d+$')
}
static boolean isRelease(String projectVersion) {
return !(isSnapshot(projectVersion) || isMilestone(projectVersion))
static boolean isRelease(Project project) {
return !(isSnapshot(project) || isMilestone(project))
}
private static String projectVersion(Project project) {

View File

@@ -1,71 +0,0 @@
package org.springframework.gradle.antora;
import org.gradle.api.Action;
import org.gradle.api.GradleException;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.tasks.TaskProvider;
import org.gradle.language.base.plugins.LifecycleBasePlugin;
public class AntoraVersionPlugin implements Plugin<Project> {
public static final String ANTORA_CHECK_VERSION_TASK_NAME = "antoraCheckVersion";
@Override
public void apply(Project project) {
TaskProvider<CheckAntoraVersionTask> antoraCheckVersion = project.getTasks().register(ANTORA_CHECK_VERSION_TASK_NAME, CheckAntoraVersionTask.class, new Action<CheckAntoraVersionTask>() {
@Override
public void execute(CheckAntoraVersionTask antoraCheckVersion) {
antoraCheckVersion.setGroup(LifecycleBasePlugin.VERIFICATION_GROUP);
antoraCheckVersion.setDescription("Checks the antora.yml version properties match the Gradle version");
antoraCheckVersion.getAntoraVersion().convention(project.provider(() -> getDefaultAntoraVersion(project)));
antoraCheckVersion.getAntoraPrerelease().convention(project.provider(() -> getDefaultAntoraPrerelease(project)));
antoraCheckVersion.getAntoraDisplayVersion().convention(project.provider(() -> getDefaultAntoraDisplayVersion(project)));
antoraCheckVersion.getAntoraYmlFile().fileProvider(project.provider(() -> project.file("antora.yml")));
}
});
project.getPlugins().withType(LifecycleBasePlugin.class, new Action<LifecycleBasePlugin>() {
@Override
public void execute(LifecycleBasePlugin lifecycleBasePlugin) {
project.getTasks().named(LifecycleBasePlugin.CHECK_TASK_NAME).configure(new Action<Task>() {
@Override
public void execute(Task check) {
check.dependsOn(antoraCheckVersion);
}
});
}
});
project.getTasks().register("antoraUpdateVersion", UpdateAntoraVersionTask.class, new Action<UpdateAntoraVersionTask>() {
@Override
public void execute(UpdateAntoraVersionTask antoraUpdateVersion) {
antoraUpdateVersion.setGroup("Release");
antoraUpdateVersion.setDescription("Updates the antora.yml version properties to match the Gradle version");
antoraUpdateVersion.getAntoraYmlFile().fileProvider(project.provider(() -> project.file("antora.yml")));
}
});
}
private static String getDefaultAntoraVersion(Project project) {
String projectVersion = getProjectVersion(project);
return AntoraVersionUtils.getDefaultAntoraVersion(projectVersion);
}
private static String getDefaultAntoraPrerelease(Project project) {
String projectVersion = getProjectVersion(project);
return AntoraVersionUtils.getDefaultAntoraPrerelease(projectVersion);
}
private static String getDefaultAntoraDisplayVersion(Project project) {
String projectVersion = getProjectVersion(project);
return AntoraVersionUtils.getDefaultAntoraDisplayVersion(projectVersion);
}
private static String getProjectVersion(Project project) {
Object projectVersion = project.getVersion();
if (projectVersion == null) {
throw new GradleException("Please define antoraVersion and antoraPrerelease on " + ANTORA_CHECK_VERSION_TASK_NAME + " or provide a Project version so they can be defaulted");
}
return String.valueOf(projectVersion);
}
}

View File

@@ -1,55 +0,0 @@
/*
* Copyright 2019-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.gradle.antora;
public class AntoraVersionUtils {
public static String getDefaultAntoraVersion(String projectVersion) {
int preReleaseIndex = getSnapshotIndex(projectVersion);
return isSnapshot(projectVersion) ? projectVersion.substring(0, preReleaseIndex) : projectVersion;
}
public static String getDefaultAntoraPrerelease(String projectVersion) {
if (isSnapshot(projectVersion)) {
int preReleaseIndex = getSnapshotIndex(projectVersion);
return projectVersion.substring(preReleaseIndex);
}
if (isPreRelease(projectVersion)) {
return Boolean.TRUE.toString();
}
return null;
}
public static String getDefaultAntoraDisplayVersion(String projectVersion) {
if (!isSnapshot(projectVersion) && isPreRelease(projectVersion)) {
return getDefaultAntoraVersion(projectVersion);
}
return null;
}
private static boolean isSnapshot(String projectVersion) {
return getSnapshotIndex(projectVersion) >= 0;
}
private static int getSnapshotIndex(String projectVersion) {
return projectVersion.lastIndexOf("-SNAPSHOT");
}
private static boolean isPreRelease(String projectVersion) {
return projectVersion.lastIndexOf("-") >= 0;
}
}

View File

@@ -1,96 +0,0 @@
package org.springframework.gradle.antora;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.TaskAction;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.representer.Representer;
public abstract class CheckAntoraVersionTask extends DefaultTask {
@TaskAction
public void check() throws FileNotFoundException {
File antoraYmlFile = getAntoraYmlFile().getAsFile().get();
String expectedAntoraVersion = getAntoraVersion().get();
String expectedAntoraPrerelease = getAntoraPrerelease().getOrElse(null);
String expectedAntoraDisplayVersion = getAntoraDisplayVersion().getOrElse(null);
Representer representer = new Representer();
representer.getPropertyUtils().setSkipMissingProperties(true);
Yaml yaml = new Yaml(new Constructor(AntoraYml.class), representer);
AntoraYml antoraYml = yaml.load(new FileInputStream(antoraYmlFile));
String actualAntoraPrerelease = antoraYml.getPrerelease();
boolean preReleaseMatches = antoraYml.getPrerelease() == null && expectedAntoraPrerelease == null ||
(actualAntoraPrerelease != null && actualAntoraPrerelease.equals(expectedAntoraPrerelease));
String actualAntoraDisplayVersion = antoraYml.getDisplay_version();
boolean displayVersionMatches = antoraYml.getDisplay_version() == null && expectedAntoraDisplayVersion == null ||
(actualAntoraDisplayVersion != null && actualAntoraDisplayVersion.equals(expectedAntoraDisplayVersion));
String actualAntoraVersion = antoraYml.getVersion();
if (!preReleaseMatches ||
!displayVersionMatches ||
!expectedAntoraVersion.equals(actualAntoraVersion)) {
throw new GradleException("The Gradle version of '" + getProject().getVersion() + "' should have version: '"
+ expectedAntoraVersion + "' prerelease: '" + expectedAntoraPrerelease + "' display_version: '"
+ expectedAntoraDisplayVersion + "' defined in " + antoraYmlFile + " but got version: '"
+ actualAntoraVersion + "' prerelease: '" + actualAntoraPrerelease + "' display_version: '" + actualAntoraDisplayVersion + "'");
}
}
@InputFile
public abstract RegularFileProperty getAntoraYmlFile();
@Input
public abstract Property<String> getAntoraVersion();
@Input
@Optional
public abstract Property<String> getAntoraPrerelease();
@Input
@Optional
public abstract Property<String> getAntoraDisplayVersion();
public static class AntoraYml {
private String version;
private String prerelease;
private String display_version;
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getPrerelease() {
return prerelease;
}
public void setPrerelease(String prerelease) {
this.prerelease = prerelease;
}
public String getDisplay_version() {
return display_version;
}
public void setDisplay_version(String display_version) {
this.display_version = display_version;
}
}
}

View File

@@ -1,130 +0,0 @@
/*
* Copyright 2019-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.gradle.antora;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import org.gradle.api.DefaultTask;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.TaskAction;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.nodes.NodeTuple;
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.representer.Representer;
public abstract class UpdateAntoraVersionTask extends DefaultTask {
@TaskAction
public void update() throws IOException {
String projectVersion = getProject().getVersion().toString();
File antoraYmlFile = getAntoraYmlFile().getAsFile().get();
String updatedAntoraVersion = AntoraVersionUtils.getDefaultAntoraVersion(projectVersion);
String updatedAntoraPrerelease = AntoraVersionUtils.getDefaultAntoraPrerelease(projectVersion);
String updatedAntoraDisplayVersion = AntoraVersionUtils.getDefaultAntoraDisplayVersion(projectVersion);
Representer representer = new Representer();
representer.getPropertyUtils().setSkipMissingProperties(true);
Yaml yaml = new Yaml(new Constructor(AntoraYml.class), representer);
AntoraYml antoraYml = yaml.load(new FileInputStream(antoraYmlFile));
System.out.println("Updating the version parameters in " + antoraYmlFile.getName() + " to version: "
+ updatedAntoraVersion + ", prerelease: " + updatedAntoraPrerelease + ", display_version: "
+ updatedAntoraDisplayVersion);
antoraYml.setVersion(updatedAntoraVersion);
antoraYml.setPrerelease(updatedAntoraPrerelease);
antoraYml.setDisplay_version(updatedAntoraDisplayVersion);
FileWriter outputWriter = new FileWriter(antoraYmlFile);
getYaml().dump(antoraYml, outputWriter);
}
@InputFile
public abstract RegularFileProperty getAntoraYmlFile();
public static class AntoraYml {
private String name;
private String version;
private String prerelease;
private String display_version;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getPrerelease() {
return prerelease;
}
public void setPrerelease(String prerelease) {
this.prerelease = prerelease;
}
public String getDisplay_version() {
return display_version;
}
public void setDisplay_version(String display_version) {
this.display_version = display_version;
}
}
private Yaml getYaml() {
Representer representer = new Representer() {
@Override
protected NodeTuple representJavaBeanProperty(Object javaBean,
org.yaml.snakeyaml.introspector.Property property, Object propertyValue, Tag customTag) {
// Don't write out null values
if (propertyValue == null) {
return null;
}
else {
return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
}
}
};
representer.addClassTag(AntoraYml.class, Tag.MAP);
DumperOptions ymlOptions = new DumperOptions();
ymlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
ymlOptions.setDefaultScalarStyle(DumperOptions.ScalarStyle.SINGLE_QUOTED);
return new Yaml(representer, ymlOptions);
}
}

View File

@@ -28,7 +28,7 @@ public class JavadocApiPluginITest {
.build();
assertThat(result.task(":api").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
File allClasses = new File(testKit.getRootDir(), "build/api/allclasses-noframe.html");
File index = new File(testKit.getRootDir(), "build/api/allclasses-index.html");
File index = new File(testKit.getRootDir(), "build/api/allclasses.html");
File listing = allClasses.exists() ? allClasses : index;
String listingText = FileUtils.readFileToString(listing);
assertThat(listingText).contains("sample/Api.html");

View File

@@ -9,7 +9,7 @@ repositories {
}
dependencies {
optional 'jakarta.servlet:jakarta.servlet-api:5.0.0'
optional 'jakarta.servlet:jakarta.servlet-api:4.0.4'
testImplementation platform('org.junit:junit-bom:5.8.1')
testImplementation 'org.junit.jupiter:junit-jupiter-api'
testImplementation 'org.junit.jupiter:junit-jupiter-engine'

View File

@@ -1,7 +1,7 @@
package sample;
import org.junit.jupiter.api.Test;
import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequest;
public class TheTest {
@Test

View File

@@ -1,10 +1,10 @@
plugins {
id "org.gretty" version "4.0.0"
id "org.gretty" version "3.0.7"
id "io.spring.convention.spring-sample-war"
}
dependencies {
provided 'jakarta.servlet:jakarta.servlet-api:5.0.0'
provided 'jakarta.servlet:jakarta.servlet-api:4.0.4'
testImplementation 'commons-io:commons-io:2.11.0'
testImplementation 'org.assertj:assertj-core:3.21.0'
testImplementation platform('org.junit:junit-bom:5.8.1')

View File

@@ -18,11 +18,11 @@ package sample;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/")
public class HelloServlet extends HttpServlet {

View File

@@ -1,3 +1,3 @@
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.parallel=true
version=3.0.1
version=2.7.2-SNAPSHOT

View File

@@ -1,45 +1,49 @@
dependencyManagement {
imports {
mavenBom 'io.projectreactor:reactor-bom:2022.0.5'
mavenBom 'com.fasterxml.jackson:jackson-bom:2.14.2'
mavenBom 'org.junit:junit-bom:5.9.2'
mavenBom 'org.mockito:mockito-bom:4.8.1'
mavenBom 'org.springframework:spring-framework-bom:6.0.6'
mavenBom 'org.springframework.data:spring-data-bom:2022.0.3'
mavenBom 'org.springframework.security:spring-security-bom:6.0.2'
mavenBom 'org.testcontainers:testcontainers-bom:1.17.3'
mavenBom 'io.projectreactor:reactor-bom:2020.0.30'
mavenBom 'com.fasterxml.jackson:jackson-bom:2.13.5'
mavenBom 'org.junit:junit-bom:5.8.2'
mavenBom 'org.springframework:spring-framework-bom:5.3.26'
mavenBom 'org.springframework.data:spring-data-bom:2021.2.9'
mavenBom 'org.springframework.security:spring-security-bom:5.7.7'
mavenBom 'org.testcontainers:testcontainers-bom:1.17.6'
}
dependencies {
dependency 'com.hazelcast:hazelcast:5.1.4'
dependency 'org.aspectj:aspectjweaver:1.9.9.1'
dependency 'ch.qos.logback:logback-core:1.4.4'
dependency 'com.google.code.findbugs:jsr305:3.0.2'
dependency 'com.h2database:h2:2.1.214'
dependency 'com.ibm.db2:jcc:11.5.7.0'
dependency 'com.microsoft.sqlserver:mssql-jdbc:11.2.1.jre17'
dependency 'com.oracle.database.jdbc:ojdbc8:21.7.0.0'
dependency 'com.zaxxer:HikariCP:5.0.1'
dependency 'edu.umd.cs.mtc:multithreadedtc:1.01'
dependency 'io.lettuce:lettuce-core:6.2.1.RELEASE'
dependency 'jakarta.servlet:jakarta.servlet-api:6.0.0'
dependency 'jakarta.websocket:jakarta.websocket-api:2.1.0'
dependency 'jakarta.websocket:jakarta.websocket-client-api:2.1.0'
dependency 'mysql:mysql-connector-java:8.0.30'
dependencySet(group: 'org.apache.derby', version: '10.16.1.1') {
entry 'derby'
entry 'derbytools'
dependencySet(group: 'com.hazelcast', version: '3.12.12') {
entry 'hazelcast'
entry 'hazelcast-client'
}
dependency 'org.assertj:assertj-core:3.23.1'
dependency 'org.aspectj:aspectjweaver:1.9.9.1'
dependency 'ch.qos.logback:logback-core:1.2.11'
dependency 'com.google.code.findbugs:jsr305:3.0.2'
dependency 'com.h2database:h2:1.4.200'
dependency 'com.ibm.db2:jcc:11.5.8.0'
dependency 'com.microsoft.sqlserver:mssql-jdbc:9.4.1.jre8'
dependency 'com.oracle.database.jdbc:ojdbc8:21.5.0.0'
dependency 'com.zaxxer:HikariCP:4.0.3'
dependency 'edu.umd.cs.mtc:multithreadedtc:1.01'
dependency 'io.lettuce:lettuce-core:6.1.10.RELEASE'
dependency 'jakarta.annotation:jakarta.annotation-api:1.3.5'
dependency 'jakarta.servlet:jakarta.servlet-api:4.0.4'
dependency 'mysql:mysql-connector-java:8.0.32'
dependency 'org.apache.derby:derby:10.14.2.0'
dependency 'org.assertj:assertj-core:3.22.0'
dependency 'org.hamcrest:hamcrest:2.2'
dependency 'org.hsqldb:hsqldb:2.7.0'
dependency 'org.mariadb.jdbc:mariadb-java-client:3.0.7'
dependencySet(group: 'org.mongodb', version: '4.8.2') {
dependency 'org.hsqldb:hsqldb:2.5.2'
dependency 'org.mariadb.jdbc:mariadb-java-client:2.7.8'
dependencySet(group: 'org.mockito', version: '4.5.1') {
entry 'mockito-core'
entry 'mockito-junit-jupiter'
}
dependencySet(group: 'org.mongodb', version: '4.6.1') {
entry 'mongodb-driver-core'
entry 'mongodb-driver-sync'
entry 'mongodb-driver-reactivestreams'
}
dependency 'org.postgresql:postgresql:42.5.0'
dependency 'org.postgresql:postgresql:42.3.8'
}
}

Binary file not shown.

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

6
gradlew vendored
View File

@@ -205,12 +205,6 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.

180
gradlew.bat vendored
View File

@@ -1,91 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -6,19 +6,20 @@ pluginManagement {
}
plugins {
id "com.gradle.enterprise" version "3.11.2"
id "com.gradle.enterprise" version "3.12.3"
id "io.spring.ge.conventions" version "0.0.7"
}
rootProject.name = 'spring-session-build'
include 'spring-session-bom'
include 'spring-session-core'
include 'spring-session-data-mongodb'
include 'spring-session-data-redis'
include 'spring-session-docs'
include 'spring-session-hazelcast'
include 'spring-session-jdbc'
include 'hazelcast4'
project(':hazelcast4').projectDir = file('spring-session-hazelcast/hazelcast4')
file('spring-session-samples').eachDirMatch(~/spring-session-sample-.*/) { dir ->
include dir.name

View File

@@ -1,15 +0,0 @@
import io.spring.gradle.convention.SpringModulePlugin
plugins {
id("io.spring.convention.bom")
}
dependencies {
constraints {
project.rootProject.allprojects { project ->
project.plugins.withType(SpringModulePlugin) {
api(project)
}
}
}
}

View File

@@ -6,6 +6,7 @@ dependencies {
api "org.springframework:spring-jcl"
optional "io.projectreactor:reactor-core"
optional "jakarta.annotation:jakarta.annotation-api"
optional "jakarta.servlet:jakarta.servlet-api"
optional "org.springframework:spring-context"
optional "org.springframework:spring-jdbc"
@@ -18,8 +19,6 @@ dependencies {
testImplementation "io.projectreactor:reactor-test"
testImplementation "org.mockito:mockito-core"
testImplementation "org.mockito:mockito-junit-jupiter"
testImplementation "org.mockito:mockito-inline"
testImplementation "edu.umd.cs.mtc:multithreadedtc"
testImplementation "org.springframework:spring-test"
testImplementation "org.assertj:assertj-core"

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,16 +48,10 @@ import java.util.UUID;
*/
public final class MapSession implements Session, Serializable {
/**
* Default {@link #setMaxInactiveInterval(Duration)} (30 minutes) in seconds.
*/
public static final int DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS = 1800;
/**
* Default {@link #setMaxInactiveInterval(Duration)} (30 minutes).
*/
public static final Duration DEFAULT_MAX_INACTIVE_INTERVAL = Duration
.ofSeconds(DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS);
public static final int DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS = 1800;
private String id;
@@ -72,7 +66,7 @@ public final class MapSession implements Session, Serializable {
/**
* Defaults to 30 minutes.
*/
private Duration maxInactiveInterval = DEFAULT_MAX_INACTIVE_INTERVAL;
private Duration maxInactiveInterval = Duration.ofSeconds(DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS);
/**
* Creates a new instance with a secure randomly generated identifier.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@ import java.util.Map;
import org.springframework.session.events.SessionDeletedEvent;
import org.springframework.session.events.SessionExpiredEvent;
import org.springframework.util.Assert;
/**
* A {@link SessionRepository} backed by a {@link java.util.Map} and that uses a
@@ -39,7 +38,11 @@ import org.springframework.util.Assert;
*/
public class MapSessionRepository implements SessionRepository<MapSession> {
private Duration defaultMaxInactiveInterval = Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS);
/**
* If non-null, this value is used to override
* {@link Session#setMaxInactiveInterval(Duration)}.
*/
private Integer defaultMaxInactiveInterval;
private final Map<String, Session> sessions;
@@ -56,13 +59,12 @@ public class MapSessionRepository implements SessionRepository<MapSession> {
}
/**
* Set the maximum inactive interval in seconds between requests before newly created
* sessions will be invalidated. A negative time indicates that the session will never
* time out. The default is 30 minutes.
* @param defaultMaxInactiveInterval the default maxInactiveInterval
* If non-null, this value is used to override
* {@link Session#setMaxInactiveInterval(Duration)}.
* @param defaultMaxInactiveInterval the number of seconds that the {@link Session}
* should be kept alive between client requests.
*/
public void setDefaultMaxInactiveInterval(Duration defaultMaxInactiveInterval) {
Assert.notNull(defaultMaxInactiveInterval, "defaultMaxInactiveInterval must not be null");
public void setDefaultMaxInactiveInterval(int defaultMaxInactiveInterval) {
this.defaultMaxInactiveInterval = defaultMaxInactiveInterval;
}
@@ -95,7 +97,9 @@ public class MapSessionRepository implements SessionRepository<MapSession> {
@Override
public MapSession createSession() {
MapSession result = new MapSession();
result.setMaxInactiveInterval(this.defaultMaxInactiveInterval);
if (this.defaultMaxInactiveInterval != null) {
result.setMaxInactiveInterval(Duration.ofSeconds(this.defaultMaxInactiveInterval));
}
return result;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@ import reactor.core.publisher.Mono;
import org.springframework.session.events.SessionDeletedEvent;
import org.springframework.session.events.SessionExpiredEvent;
import org.springframework.util.Assert;
/**
* A {@link ReactiveSessionRepository} backed by a {@link Map} and that uses a
@@ -41,7 +40,11 @@ import org.springframework.util.Assert;
*/
public class ReactiveMapSessionRepository implements ReactiveSessionRepository<MapSession> {
private Duration defaultMaxInactiveInterval = Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS);
/**
* If non-null, this value is used to override
* {@link Session#setMaxInactiveInterval(Duration)}.
*/
private Integer defaultMaxInactiveInterval;
private final Map<String, Session> sessions;
@@ -58,13 +61,12 @@ public class ReactiveMapSessionRepository implements ReactiveSessionRepository<M
}
/**
* Set the maximum inactive interval in seconds between requests before newly created
* sessions will be invalidated. A negative time indicates that the session will never
* time out. The default is 30 minutes.
* @param defaultMaxInactiveInterval the default maxInactiveInterval
* If non-null, this value is used to override
* {@link Session#setMaxInactiveInterval(Duration)}.
* @param defaultMaxInactiveInterval the number of seconds that the {@link Session}
* should be kept alive between client requests.
*/
public void setDefaultMaxInactiveInterval(Duration defaultMaxInactiveInterval) {
Assert.notNull(defaultMaxInactiveInterval, "defaultMaxInactiveInterval must not be null");
public void setDefaultMaxInactiveInterval(int defaultMaxInactiveInterval) {
this.defaultMaxInactiveInterval = defaultMaxInactiveInterval;
}
@@ -97,7 +99,9 @@ public class ReactiveMapSessionRepository implements ReactiveSessionRepository<M
public Mono<MapSession> createSession() {
return Mono.defer(() -> {
MapSession result = new MapSession();
result.setMaxInactiveInterval(this.defaultMaxInactiveInterval);
if (this.defaultMaxInactiveInterval != null) {
result.setMaxInactiveInterval(Duration.ofSeconds(this.defaultMaxInactiveInterval));
}
return Mono.just(result);
});
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright 2014-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.session.aot.hint;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.TreeSet;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.TypeReference;
/**
* A {@link RuntimeHintsRegistrar} for common session hints.
*
* @author Marcus Da Coregio
*/
class CommonSessionRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
Arrays.asList(TypeReference.of(String.class), TypeReference.of(ArrayList.class),
TypeReference.of(TreeSet.class), TypeReference.of(Number.class), TypeReference.of(Long.class),
TypeReference.of(Integer.class), TypeReference.of(StackTraceElement.class),
TypeReference.of(Throwable.class), TypeReference.of(Exception.class),
TypeReference.of(RuntimeException.class),
TypeReference.of("java.util.Collections$UnmodifiableCollection"),
TypeReference.of("java.util.Collections$UnmodifiableList"),
TypeReference.of("java.util.Collections$EmptyList"),
TypeReference.of("java.util.Collections$UnmodifiableRandomAccessList"),
TypeReference.of("java.util.Collections$UnmodifiableSet")).forEach(hints.serialization()::registerType);
}
}

View File

@@ -1,86 +0,0 @@
/*
* Copyright 2014-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.session.aot.hint;
import java.util.Arrays;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.TypeReference;
/**
* A {@link RuntimeHintsRegistrar} for common session security hints.
*
* @author Marcus Da Coregio
*/
class CommonSessionSecurityRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
registerSecurityHintsIfNeeded(hints);
registerOAuth2ClientHintsIfNeeded(hints);
registerOAuth2ResourceServerHintsIfNeeded(hints);
}
private void registerSecurityHintsIfNeeded(RuntimeHints hints) {
Arrays.asList(TypeReference.of("org.springframework.security.core.context.SecurityContextImpl"),
TypeReference.of("org.springframework.security.core.authority.SimpleGrantedAuthority"),
TypeReference.of("org.springframework.security.core.userdetails.User"),
TypeReference.of("org.springframework.security.authentication.AbstractAuthenticationToken"),
TypeReference.of("org.springframework.security.authentication.UsernamePasswordAuthenticationToken"),
TypeReference.of("org.springframework.security.core.AuthenticationException"),
TypeReference.of("org.springframework.security.authentication.BadCredentialsException"),
TypeReference.of("org.springframework.security.core.userdetails.UsernameNotFoundException"),
TypeReference.of("org.springframework.security.authentication.AccountExpiredException"),
TypeReference.of("org.springframework.security.authentication.ProviderNotFoundException"),
TypeReference.of("org.springframework.security.authentication.DisabledException"),
TypeReference.of("org.springframework.security.authentication.LockedException"),
TypeReference.of("org.springframework.security.authentication.AuthenticationServiceException"),
TypeReference.of("org.springframework.security.authentication.CredentialsExpiredException"),
TypeReference.of("org.springframework.security.authentication.InsufficientAuthenticationException"),
TypeReference
.of("org.springframework.security.web.authentication.session.SessionAuthenticationException"),
TypeReference.of(
"org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationException"),
TypeReference.of("org.springframework.security.core.userdetails.User$AuthorityComparator"))
.forEach((type) -> hints.serialization().registerType(type, (hint) -> hint.onReachableType(
TypeReference.of("org.springframework.security.core.context.SecurityContextImpl"))));
}
private void registerOAuth2ResourceServerHintsIfNeeded(RuntimeHints hints) {
Arrays.asList(
TypeReference.of("org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken"),
TypeReference.of(
"org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken"),
TypeReference.of("org.springframework.security.oauth2.core.OAuth2AuthenticationException"))
.forEach((type) -> hints.serialization().registerType(type, (hint) -> hint.onReachableType(TypeReference
.of("org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken"))));
}
private void registerOAuth2ClientHintsIfNeeded(RuntimeHints hints) {
Arrays.asList(
TypeReference.of("org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken"),
TypeReference
.of("org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken"),
TypeReference.of(
"org.springframework.security.oauth2.client.authentication.OAuth2AuthorizationCodeAuthenticationToken"),
TypeReference.of("org.springframework.security.oauth2.core.OAuth2AuthenticationException"))
.forEach((type) -> hints.serialization().registerType(type, (hint) -> hint.onReachableType(TypeReference
.of("org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken"))));
}
}

View File

@@ -1,40 +0,0 @@
/*
* Copyright 2014-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.session.aot.hint.server;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.security.web.server.csrf.DefaultCsrfToken;
import org.springframework.util.ClassUtils;
/**
* {@link RuntimeHintsRegistrar} for Reactive Session hints.
*
* @author Marcus Da Coregio
*/
class WebSessionSecurityRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
if (!ClassUtils.isPresent("org.springframework.web.server.WebSession", classLoader) || !ClassUtils
.isPresent("org.springframework.security.web.server.csrf.DefaultCsrfToken", classLoader)) {
return;
}
hints.serialization().registerType(DefaultCsrfToken.class);
}
}

View File

@@ -1,52 +0,0 @@
/*
* Copyright 2014-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.session.aot.hint.servlet;
import java.util.Arrays;
import java.util.Locale;
import java.util.TreeMap;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.TypeReference;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.csrf.DefaultCsrfToken;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
import org.springframework.security.web.savedrequest.SavedCookie;
import org.springframework.util.ClassUtils;
/**
* {@link RuntimeHintsRegistrar} for Servlet Session hints.
*
* @author Marcus Da Coregio
*/
class HttpSessionSecurityRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
if (!ClassUtils.isPresent("jakarta.servlet.http.HttpSession", classLoader)
|| !ClassUtils.isPresent("org.springframework.security.web.csrf.DefaultCsrfToken", classLoader)) {
return;
}
Arrays.asList(TypeReference.of(TreeMap.class), TypeReference.of(Locale.class),
TypeReference.of(DefaultSavedRequest.class), TypeReference.of(DefaultCsrfToken.class),
TypeReference.of(WebAuthenticationDetails.class), TypeReference.of(SavedCookie.class),
TypeReference.of("java.lang.String$CaseInsensitiveComparator"))
.forEach(hints.serialization()::registerType);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.session.SessionRepository;
import org.springframework.session.events.SessionCreatedEvent;
@@ -33,7 +34,7 @@ import org.springframework.session.events.SessionDestroyedEvent;
*
* <pre>
* <code>
* {@literal @Configuration(proxyBeanMethods = false)}
* {@literal @Configuration}
* {@literal @EnableSpringHttpSession}
* public class SpringHttpSessionConfig {
*
@@ -73,6 +74,7 @@ import org.springframework.session.events.SessionDestroyedEvent;
@Target({ java.lang.annotation.ElementType.TYPE })
@Documented
@Import(SpringHttpSessionConfiguration.class)
@Configuration(proxyBeanMethods = false)
public @interface EnableSpringHttpSession {
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,15 +19,15 @@ package org.springframework.session.config.annotation.web.http;
import java.util.ArrayList;
import java.util.List;
import jakarta.servlet.ServletContext;
import jakarta.servlet.SessionCookieConfig;
import jakarta.servlet.http.HttpSessionListener;
import javax.annotation.PostConstruct;
import javax.servlet.ServletContext;
import javax.servlet.SessionCookieConfig;
import javax.servlet.http.HttpSessionListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
@@ -91,7 +91,7 @@ import org.springframework.util.ObjectUtils;
* @see EnableSpringHttpSession
*/
@Configuration(proxyBeanMethods = false)
public class SpringHttpSessionConfiguration implements InitializingBean, ApplicationContextAware {
public class SpringHttpSessionConfiguration implements ApplicationContextAware {
private final Log logger = LogFactory.getLog(getClass());
@@ -107,8 +107,8 @@ public class SpringHttpSessionConfiguration implements InitializingBean, Applica
private List<HttpSessionListener> httpSessionListeners = new ArrayList<>();
@Override
public void afterPropertiesSet() {
@PostConstruct
public void init() {
CookieSerializer cookieSerializer = (this.cookieSerializer != null) ? this.cookieSerializer
: createDefaultCookieSerializer();
this.defaultHttpSessionIdResolver.setCookieSerializer(cookieSerializer);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
@@ -30,7 +31,7 @@ import org.springframework.context.annotation.Import;
*
* <pre>
* <code>
* {@literal @Configuration(proxyBeanMethods = false)}
* {@literal @Configuration}
* {@literal @EnableSpringWebSession}
* public class SpringWebFluxConfig {
*
@@ -49,6 +50,7 @@ import org.springframework.context.annotation.Import;
@Target({ java.lang.annotation.ElementType.TYPE })
@Documented
@Import(SpringWebSessionConfiguration.class)
@Configuration(proxyBeanMethods = false)
public @interface EnableSpringWebSession {
}

View File

@@ -16,9 +16,9 @@
package org.springframework.session.security.web.authentication;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2021 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,10 +19,10 @@ package org.springframework.session.web.context;
import java.util.Arrays;
import java.util.EnumSet;
import jakarta.servlet.DispatcherType;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterRegistration.Dynamic;
import jakarta.servlet.ServletContext;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration.Dynamic;
import javax.servlet.ServletContext;
import org.springframework.context.ApplicationContext;
import org.springframework.core.Conventions;

View File

@@ -18,8 +18,8 @@ package org.springframework.session.web.http;
import java.util.List;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.session.web.http.CookieSerializer.CookieValue;
@@ -32,8 +32,8 @@ import org.springframework.session.web.http.CookieSerializer.CookieValue;
* When a session is created, the HTTP response will have a cookie with the specified
* cookie name and the value of the session id. The cookie will be marked as a session
* cookie, use the context path for the path of the cookie, marked as HTTPOnly, and if
* {@link jakarta.servlet.http.HttpServletRequest#isSecure()} returns true, the cookie
* will be marked as secure. For example:
* {@link javax.servlet.http.HttpServletRequest#isSecure()} returns true, the cookie will
* be marked as secure. For example:
*
* <pre>
* HTTP/1.1 200 OK

View File

@@ -18,9 +18,9 @@ package org.springframework.session.web.http;
import java.util.List;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Strategy for reading and writing a cookie value to the {@link HttpServletResponse}.

View File

@@ -28,9 +28,9 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -88,8 +88,7 @@ public class DefaultCookieSerializer implements CookieSerializer {
private String sameSite = "Lax";
/*
* @see
* org.springframework.session.web.http.CookieSerializer#readCookieValues(jakarta.
* @see org.springframework.session.web.http.CookieSerializer#readCookieValues(javax.
* servlet.http.HttpServletRequest)
*/
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,8 +19,8 @@ package org.springframework.session.web.http;
import java.util.Collections;
import java.util.List;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* A {@link HttpSessionIdResolver} that uses a header to resolve the session id.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,11 +19,14 @@ package org.springframework.session.web.http;
import java.time.Duration;
import java.util.Collections;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.util.Set;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpSession;
import jakarta.servlet.http.HttpSessionBindingEvent;
import jakarta.servlet.http.HttpSessionBindingListener;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -38,11 +41,12 @@ import org.springframework.session.Session;
* @author Vedran Pavic
* @since 1.1
*/
@SuppressWarnings("deprecation")
class HttpSessionAdapter<S extends Session> implements HttpSession {
private static final Log logger = LogFactory.getLog(HttpSessionAdapter.class);
private final S session;
private S session;
private final ServletContext servletContext;
@@ -97,18 +101,35 @@ class HttpSessionAdapter<S extends Session> implements HttpSession {
return (int) this.session.getMaxInactiveInterval().getSeconds();
}
@Override
public HttpSessionContext getSessionContext() {
return NOOP_SESSION_CONTEXT;
}
@Override
public Object getAttribute(String name) {
checkState();
return this.session.getAttribute(name);
}
@Override
public Object getValue(String name) {
return getAttribute(name);
}
@Override
public Enumeration<String> getAttributeNames() {
checkState();
return Collections.enumeration(this.session.getAttributeNames());
}
@Override
public String[] getValueNames() {
checkState();
Set<String> attrs = this.session.getAttributeNames();
return attrs.toArray(new String[0]);
}
@Override
public void setAttribute(String name, Object value) {
checkState();
@@ -135,6 +156,11 @@ class HttpSessionAdapter<S extends Session> implements HttpSession {
}
}
@Override
public void putValue(String name, Object value) {
setAttribute(name, value);
}
@Override
public void removeAttribute(String name) {
checkState();
@@ -150,6 +176,11 @@ class HttpSessionAdapter<S extends Session> implements HttpSession {
}
}
@Override
public void removeValue(String name) {
removeAttribute(name);
}
@Override
public void invalidate() {
checkState();
@@ -172,4 +203,32 @@ class HttpSessionAdapter<S extends Session> implements HttpSession {
}
}
private static final HttpSessionContext NOOP_SESSION_CONTEXT = new HttpSessionContext() {
@Override
public HttpSession getSession(String sessionId) {
return null;
}
@Override
public Enumeration<String> getIds() {
return EMPTY_ENUMERATION;
}
};
private static final Enumeration<String> EMPTY_ENUMERATION = new Enumeration<String>() {
@Override
public boolean hasMoreElements() {
return false;
}
@Override
public String nextElement() {
throw new NoSuchElementException("a");
}
};
}

View File

@@ -18,8 +18,8 @@ package org.springframework.session.web.http;
import java.util.List;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Contract for session id resolution strategies. Allows for session id resolution through

View File

@@ -20,14 +20,14 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.Locale;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.WriteListener;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletResponseWrapper;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
/**
* Base class for response wrappers which encapsulate the logic for handling an event when
* the {@link jakarta.servlet.http.HttpServletResponse} is committed.
* the {@link javax.servlet.http.HttpServletResponse} is committed.
*
* @author Rob Winch
* @since 1.0
@@ -84,16 +84,16 @@ abstract class OnCommittedResponseWrapper extends HttpServletResponseWrapper {
/**
* Invoke this method to disable invoking
* {@link OnCommittedResponseWrapper#onResponseCommitted()} when the
* {@link jakarta.servlet.http.HttpServletResponse} is committed. This can be useful
* in the event that Async Web Requests are made.
* {@link javax.servlet.http.HttpServletResponse} is committed. This can be useful in
* the event that Async Web Requests are made.
*/
private void disableOnResponseCommitted() {
this.disableOnCommitted = true;
}
/**
* Implement the logic for handling the
* {@link jakarta.servlet.http.HttpServletResponse} being committed.
* Implement the logic for handling the {@link javax.servlet.http.HttpServletResponse}
* being committed.
*/
protected abstract void onResponseCommitted();
@@ -474,9 +474,8 @@ abstract class OnCommittedResponseWrapper extends HttpServletResponseWrapper {
/**
* Ensures{@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before
* calling methods that commit the response. We delegate all methods to the original
* {@link jakarta.servlet.ServletOutputStream} to ensure that the behavior is as close
* to the original {@link jakarta.servlet.ServletOutputStream} as possible. See
* SEC-2039
* {@link javax.servlet.ServletOutputStream} to ensure that the behavior is as close
* to the original {@link javax.servlet.ServletOutputStream} as possible. See SEC-2039
*
* @author Rob Winch
*/

View File

@@ -18,15 +18,15 @@ package org.springframework.session.web.http;
import java.io.IOException;
import jakarta.servlet.DispatcherType;
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 javax.servlet.DispatcherType;
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;
/**
* Allows for easily ensuring that a request is only invoked once per request. This is a

View File

@@ -18,10 +18,10 @@ package org.springframework.session.web.http;
import java.util.List;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpSession;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.springframework.context.ApplicationListener;
import org.springframework.session.Session;
@@ -79,8 +79,9 @@ public class SessionEventHttpSessionListenerAdapter
}
/*
* @see org.springframework.web.context.ServletContextAware#setServletContext(jakarta.
* servlet.ServletContext)
* @see
* org.springframework.web.context.ServletContextAware#setServletContext(javax.servlet
* .ServletContext)
*/
@Override
public void setServletContext(ServletContext servletContext) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,16 +20,16 @@ import java.io.IOException;
import java.time.Instant;
import java.util.List;
import jakarta.servlet.FilterChain;
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.HttpServletRequestWrapper;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import javax.servlet.FilterChain;
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.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -39,29 +39,29 @@ import org.springframework.session.Session;
import org.springframework.session.SessionRepository;
/**
* Switches the {@link jakarta.servlet.http.HttpSession} implementation to be backed by a
* Switches the {@link javax.servlet.http.HttpSession} implementation to be backed by a
* {@link org.springframework.session.Session}.
*
* The {@link SessionRepositoryFilter} wraps the
* {@link jakarta.servlet.http.HttpServletRequest} and overrides the methods to get an
* {@link jakarta.servlet.http.HttpSession} to be backed by a
* {@link javax.servlet.http.HttpServletRequest} and overrides the methods to get an
* {@link javax.servlet.http.HttpSession} to be backed by a
* {@link org.springframework.session.Session} returned by the
* {@link org.springframework.session.SessionRepository}.
*
* The {@link SessionRepositoryFilter} uses a {@link HttpSessionIdResolver} (default
* {@link CookieHttpSessionIdResolver}) to bridge logic between an
* {@link jakarta.servlet.http.HttpSession} and the
* {@link javax.servlet.http.HttpSession} and the
* {@link org.springframework.session.Session} abstraction. Specifically:
*
* <ul>
* <li>The session id is looked up using
* {@link HttpSessionIdResolver#resolveSessionIds(jakarta.servlet.http.HttpServletRequest)}
* {@link HttpSessionIdResolver#resolveSessionIds(javax.servlet.http.HttpServletRequest)}
* . The default is to look in a cookie named SESSION.</li>
* <li>The session id of newly created {@link org.springframework.session.Session} is sent
* to the client using
* {@link HttpSessionIdResolver#setSessionId(jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse, String)}
* {@link HttpSessionIdResolver#setSessionId(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, String)}
* <li>The client is notified that the session id is no longer valid with
* {@link HttpSessionIdResolver#expireSession(jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse)}
* {@link HttpSessionIdResolver#expireSession(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)}
* </li>
* </ul>
*
@@ -75,7 +75,6 @@ import org.springframework.session.SessionRepository;
* @author Rob Winch
* @author Vedran Pavic
* @author Josh Cummings
* @author Yanming Zhou
* @since 1.0
*/
@Order(SessionRepositoryFilter.DEFAULT_ORDER)
@@ -184,8 +183,8 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
}
/**
* A {@link jakarta.servlet.http.HttpServletRequest} that retrieves the
* {@link jakarta.servlet.http.HttpSession} using a
* A {@link javax.servlet.http.HttpServletRequest} that retrieves the
* {@link javax.servlet.http.HttpSession} using a
* {@link org.springframework.session.SessionRepository}.
*
* @author Rob Winch
@@ -223,11 +222,10 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
}
else {
S session = wrappedSession.getSession();
String requestedSessionId = getRequestedSessionId();
clearRequestedSessionCache();
SessionRepositoryFilter.this.sessionRepository.save(session);
String sessionId = session.getId();
if (!isRequestedSessionIdValid() || !sessionId.equals(requestedSessionId)) {
if (!isRequestedSessionIdValid() || !sessionId.equals(getRequestedSessionId())) {
SessionRepositoryFilter.this.httpSessionIdResolver.setSessionId(this, this.response, sessionId);
}
}
@@ -267,7 +265,14 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
if (requestedSession != null) {
requestedSession.setLastAccessedTime(Instant.now());
}
this.requestedSessionIdValid = (requestedSession != null);
return isRequestedSessionIdValid(requestedSession);
}
return this.requestedSessionIdValid;
}
private boolean isRequestedSessionIdValid(S session) {
if (this.requestedSessionIdValid == null) {
this.requestedSessionIdValid = session != null;
}
return this.requestedSessionIdValid;
}
@@ -351,6 +356,7 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
S session = SessionRepositoryFilter.this.sessionRepository.findById(sessionId);
if (session != null) {
this.requestedSession = session;
this.requestedSessionId = sessionId;
break;
}
}

View File

@@ -21,7 +21,7 @@ import java.util.EnumSet;
import java.util.Map;
import java.util.Set;
import jakarta.servlet.http.HttpSession;
import javax.servlet.http.HttpSession;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;

View File

@@ -1,5 +0,0 @@
org.springframework.aot.hint.RuntimeHintsRegistrar=\
org.springframework.session.aot.hint.CommonSessionRuntimeHints,\
org.springframework.session.aot.hint.CommonSessionSecurityRuntimeHints,\
org.springframework.session.aot.hint.servlet.HttpSessionSecurityRuntimeHints,\
org.springframework.session.aot.hint.server.WebSessionSecurityRuntimeHints

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,8 +60,8 @@ class MapSessionRepositoryTests {
@Test
void createSessionCustomDefaultExpiration() {
Duration expectedMaxInterval = new MapSession().getMaxInactiveInterval().plusSeconds(10);
this.repository.setDefaultMaxInactiveInterval(expectedMaxInterval);
final Duration expectedMaxInterval = new MapSession().getMaxInactiveInterval().plusSeconds(10);
this.repository.setDefaultMaxInactiveInterval((int) expectedMaxInterval.getSeconds());
Session session = this.repository.createSession();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -103,8 +103,8 @@ class ReactiveMapSessionRepositoryTests {
@Test
void createSessionWhenCustomMaxInactiveIntervalThenCustomMaxInactiveInterval() {
Duration expectedMaxInterval = new MapSession().getMaxInactiveInterval().plusSeconds(10);
this.repository.setDefaultMaxInactiveInterval(expectedMaxInterval);
final Duration expectedMaxInterval = new MapSession().getMaxInactiveInterval().plusSeconds(10);
this.repository.setDefaultMaxInactiveInterval((int) expectedMaxInterval.getSeconds());
Session session = this.repository.createSession().block();

View File

@@ -1,74 +0,0 @@
/*
* Copyright 2014-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.session.aot.hint;
import java.util.ArrayList;
import java.util.TreeSet;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.TypeReference;
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import org.springframework.core.io.support.SpringFactoriesLoader;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link CommonSessionRuntimeHints}
*
* @author Marcus Da Coregio
*/
class CommonSessionRuntimeHintsTests {
private final RuntimeHints hints = new RuntimeHints();
private final CommonSessionRuntimeHints commonSessionRuntimeHints = new CommonSessionRuntimeHints();
@ParameterizedTest
@MethodSource("getSerializationHintTypes")
void commonSessionTypesHasHints(TypeReference typeReference) {
this.commonSessionRuntimeHints.registerHints(this.hints, getClass().getClassLoader());
assertThat(RuntimeHintsPredicates.serialization().onType(typeReference)).accepts(this.hints);
}
@Test
void aotFactoriesContainsRegistrar() {
boolean match = SpringFactoriesLoader.forResourceLocation("META-INF/spring/aot.factories")
.load(RuntimeHintsRegistrar.class).stream()
.anyMatch((registrar) -> registrar instanceof CommonSessionRuntimeHints);
assertThat(match).isTrue();
}
private static Stream<TypeReference> getSerializationHintTypes() {
return Stream.of(TypeReference.of(String.class), TypeReference.of(ArrayList.class),
TypeReference.of(TreeSet.class), TypeReference.of(Number.class), TypeReference.of(Long.class),
TypeReference.of(Integer.class), TypeReference.of(StackTraceElement.class),
TypeReference.of(Throwable.class), TypeReference.of(Exception.class),
TypeReference.of(RuntimeException.class),
TypeReference.of("java.util.Collections$UnmodifiableCollection"),
TypeReference.of("java.util.Collections$UnmodifiableList"),
TypeReference.of("java.util.Collections$EmptyList"),
TypeReference.of("java.util.Collections$UnmodifiableRandomAccessList"),
TypeReference.of("java.util.Collections$UnmodifiableSet"));
}
}

View File

@@ -1,92 +0,0 @@
/*
* Copyright 2014-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.session.aot.hint;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.TypeReference;
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import org.springframework.core.io.support.SpringFactoriesLoader;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link CommonSessionSecurityRuntimeHints}
*
* @author Marcus Da Coregio
*/
class CommonSessionSecurityRuntimeHintsTests {
private final RuntimeHints hints = new RuntimeHints();
private final CommonSessionSecurityRuntimeHints commonSessionSecurityRuntimeHints = new CommonSessionSecurityRuntimeHints();
@ParameterizedTest
@MethodSource("getSerializationHintTypes")
void commonSecurityTypesHasHints(TypeReference typeReference) {
this.commonSessionSecurityRuntimeHints.registerHints(this.hints, getClass().getClassLoader());
assertThat(RuntimeHintsPredicates.serialization().onType(typeReference)).accepts(this.hints);
}
@Test
void aotFactoriesContainsRegistrar() {
boolean match = SpringFactoriesLoader.forResourceLocation("META-INF/spring/aot.factories")
.load(RuntimeHintsRegistrar.class).stream()
.anyMatch((registrar) -> registrar instanceof CommonSessionSecurityRuntimeHints);
assertThat(match).isTrue();
}
private static Stream<TypeReference> getSerializationHintTypes() {
return Stream.of(TypeReference.of("org.springframework.security.core.context.SecurityContextImpl"),
TypeReference.of("org.springframework.security.core.authority.SimpleGrantedAuthority"),
TypeReference.of("org.springframework.security.core.userdetails.User"),
TypeReference.of("org.springframework.security.authentication.AbstractAuthenticationToken"),
TypeReference.of("org.springframework.security.authentication.UsernamePasswordAuthenticationToken"),
TypeReference.of("org.springframework.security.core.AuthenticationException"),
TypeReference.of("org.springframework.security.authentication.BadCredentialsException"),
TypeReference.of("org.springframework.security.core.userdetails.UsernameNotFoundException"),
TypeReference.of("org.springframework.security.authentication.AccountExpiredException"),
TypeReference.of("org.springframework.security.authentication.ProviderNotFoundException"),
TypeReference.of("org.springframework.security.authentication.DisabledException"),
TypeReference.of("org.springframework.security.authentication.LockedException"),
TypeReference.of("org.springframework.security.authentication.AuthenticationServiceException"),
TypeReference.of("org.springframework.security.authentication.CredentialsExpiredException"),
TypeReference.of("org.springframework.security.authentication.InsufficientAuthenticationException"),
TypeReference
.of("org.springframework.security.web.authentication.session.SessionAuthenticationException"),
TypeReference.of(
"org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationException"),
TypeReference.of("org.springframework.security.core.userdetails.User$AuthorityComparator"),
TypeReference.of("org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken"),
TypeReference.of(
"org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken"),
TypeReference.of("org.springframework.security.oauth2.core.OAuth2AuthenticationException"),
TypeReference.of("org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken"),
TypeReference
.of("org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken"),
TypeReference.of(
"org.springframework.security.oauth2.client.authentication.OAuth2AuthorizationCodeAuthenticationToken"),
TypeReference.of("org.springframework.security.oauth2.core.OAuth2AuthenticationException"));
}
}

View File

@@ -1,81 +0,0 @@
/*
* Copyright 2014-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.session.aot.hint.server;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.security.web.server.csrf.DefaultCsrfToken;
import org.springframework.util.ClassUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mockStatic;
/**
* Tests for {@link WebSessionSecurityRuntimeHints}
*
* @author Marcus Da Coregio
*/
class WebSessionSecurityRuntimeHintsTests {
private final RuntimeHints hints = new RuntimeHints();
private final WebSessionSecurityRuntimeHints webSessionSecurityRuntimeHints = new WebSessionSecurityRuntimeHints();
@Test
void defaultCsrfTokenHasHints() {
this.webSessionSecurityRuntimeHints.registerHints(this.hints, getClass().getClassLoader());
assertThat(RuntimeHintsPredicates.serialization().onType(DefaultCsrfToken.class)).accepts(this.hints);
}
@Test
void registerHintsWhenWebSessionMissingThenDoNotRegisterHints() {
try (MockedStatic<ClassUtils> classUtilsMock = mockStatic(ClassUtils.class)) {
classUtilsMock.when(() -> ClassUtils.isPresent(eq("org.springframework.web.server.WebSession"), any()))
.thenReturn(false);
this.webSessionSecurityRuntimeHints.registerHints(this.hints, getClass().getClassLoader());
assertThat(this.hints.serialization().javaSerializationHints()).isEmpty();
}
}
@Test
void registerHintsWhenDefaultCsrfTokenMissingThenDoNotRegisterHints() {
try (MockedStatic<ClassUtils> classUtilsMock = mockStatic(ClassUtils.class)) {
classUtilsMock
.when(() -> ClassUtils
.isPresent(eq("org.springframework.security.web.server.csrf.DefaultCsrfToken"), any()))
.thenReturn(false);
this.webSessionSecurityRuntimeHints.registerHints(this.hints, getClass().getClassLoader());
assertThat(this.hints.serialization().javaSerializationHints()).isEmpty();
}
}
@Test
void aotFactoriesContainsRegistrar() {
boolean match = SpringFactoriesLoader.forResourceLocation("META-INF/spring/aot.factories")
.load(RuntimeHintsRegistrar.class).stream()
.anyMatch((registrar) -> registrar instanceof WebSessionSecurityRuntimeHints);
assertThat(match).isTrue();
}
}

View File

@@ -1,98 +0,0 @@
/*
* Copyright 2014-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.session.aot.hint.servlet;
import java.util.Locale;
import java.util.TreeMap;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.MockedStatic;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.TypeReference;
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.csrf.DefaultCsrfToken;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
import org.springframework.security.web.savedrequest.SavedCookie;
import org.springframework.util.ClassUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mockStatic;
/**
* Tests for {@link HttpSessionSecurityRuntimeHints}
*
* @author Marcus Da Coregio
*/
class HttpSessionSecurityRuntimeHintsTests {
private final RuntimeHints hints = new RuntimeHints();
private final HttpSessionSecurityRuntimeHints httpSessionSecurityRuntimeHints = new HttpSessionSecurityRuntimeHints();
@ParameterizedTest
@MethodSource("getSerializationHintTypes")
void httpSessionHasHints(TypeReference typeReference) {
this.httpSessionSecurityRuntimeHints.registerHints(this.hints, getClass().getClassLoader());
assertThat(RuntimeHintsPredicates.serialization().onType(typeReference)).accepts(this.hints);
}
@Test
void registerHintsWhenHttpSessionMissingThenDoNotRegisterHints() {
try (MockedStatic<ClassUtils> classUtilsMock = mockStatic(ClassUtils.class)) {
classUtilsMock.when(() -> ClassUtils.isPresent(eq("jakarta.servlet.http.HttpSession"), any()))
.thenReturn(false);
this.httpSessionSecurityRuntimeHints.registerHints(this.hints, getClass().getClassLoader());
assertThat(this.hints.serialization().javaSerializationHints()).isEmpty();
}
}
@Test
void registerHintsWhenDefaultCsrfTokenMissingThenDoNotRegisterHints() {
try (MockedStatic<ClassUtils> classUtilsMock = mockStatic(ClassUtils.class)) {
classUtilsMock.when(
() -> ClassUtils.isPresent(eq("org.springframework.security.web.csrf.DefaultCsrfToken"), any()))
.thenReturn(false);
this.httpSessionSecurityRuntimeHints.registerHints(this.hints, getClass().getClassLoader());
assertThat(this.hints.serialization().javaSerializationHints()).isEmpty();
}
}
@Test
void aotFactoriesContainsRegistrar() {
boolean match = SpringFactoriesLoader.forResourceLocation("META-INF/spring/aot.factories")
.load(RuntimeHintsRegistrar.class).stream()
.anyMatch((registrar) -> registrar instanceof HttpSessionSecurityRuntimeHints);
assertThat(match).isTrue();
}
private static Stream<TypeReference> getSerializationHintTypes() {
return Stream.of(TypeReference.of(TreeMap.class), TypeReference.of(Locale.class),
TypeReference.of(DefaultSavedRequest.class), TypeReference.of(DefaultCsrfToken.class),
TypeReference.of(WebAuthenticationDetails.class), TypeReference.of(SavedCookie.class),
TypeReference.of("java.lang.String$CaseInsensitiveComparator"));
}
}

View File

@@ -19,10 +19,10 @@ package org.springframework.session.config.annotation.web.http;
import java.io.IOException;
import java.util.Collections;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

View File

@@ -18,7 +18,7 @@ package org.springframework.session.config.annotation.web.http;
import java.util.concurrent.ConcurrentHashMap;
import jakarta.servlet.ServletContext;
import javax.servlet.ServletContext;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.ReactiveMapSessionRepository;
import org.springframework.session.ReactiveSessionRepository;
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
@@ -106,7 +105,6 @@ class SpringWebSessionConfigurationTests {
/**
* A configuration with all the right parts.
*/
@Configuration(proxyBeanMethods = false)
@EnableSpringWebSession
static class GoodConfig {
@@ -124,13 +122,11 @@ class SpringWebSessionConfigurationTests {
/**
* A configuration where no {@link ReactiveSessionRepository} is defined. It's BAD!
*/
@Configuration(proxyBeanMethods = false)
@EnableSpringWebSession
static class BadConfig {
}
@Configuration(proxyBeanMethods = false)
@EnableSpringWebSession
static class OverrideSessionIdResolver {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,12 +24,12 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.MockitoAnnotations;
import org.springframework.security.core.AuthenticatedPrincipal;
import org.springframework.security.core.Authentication;
@@ -44,12 +44,10 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.mock;
import static org.mockito.BDDMockito.verify;
import static org.mockito.Mockito.withSettings;
/**
* Tests for {@link SpringSessionBackedSessionRegistry}.
*/
@ExtendWith(MockitoExtension.class)
class SpringSessionBackedSessionRegistryTest {
private static final String SESSION_ID = "sessionId";
@@ -68,6 +66,11 @@ class SpringSessionBackedSessionRegistryTest {
@InjectMocks
private SpringSessionBackedSessionRegistry<Session> sessionRegistry;
@BeforeEach
void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
void sessionInformationForExistingSession() {
Session session = createSession(SESSION_ID, USER_NAME, NOW);
@@ -154,7 +157,7 @@ class SpringSessionBackedSessionRegistryTest {
private Session createSession(String sessionId, String userName, Instant lastAccessed) {
MapSession session = new MapSession(sessionId);
session.setLastAccessedTime(lastAccessed);
Authentication authentication = mock(Authentication.class, withSettings().lenient());
Authentication authentication = mock(Authentication.class);
given(authentication.getName()).willReturn(userName);
SecurityContextImpl securityContext = new SecurityContextImpl();
securityContext.setAuthentication(authentication);

View File

@@ -16,9 +16,9 @@
package org.springframework.session.security.web.authentication;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.junit.jupiter.api.Test;

View File

@@ -19,7 +19,7 @@ package org.springframework.session.web.http;
import java.util.Base64;
import java.util.Collections;
import jakarta.servlet.http.Cookie;
import javax.servlet.http.Cookie;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

View File

@@ -23,7 +23,7 @@ import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import jakarta.servlet.http.Cookie;
import javax.servlet.http.Cookie;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,25 +21,23 @@ import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.MockitoAnnotations;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.verify;
@ExtendWith(MockitoExtension.class)
class OnCommittedResponseWrapperTests {
private static final String NL = "\r\n";
@Mock(lenient = true)
@Mock
HttpServletResponse delegate;
@Mock
@@ -54,6 +52,7 @@ class OnCommittedResponseWrapperTests {
@BeforeEach
void setup() throws Exception {
MockitoAnnotations.initMocks(this);
this.response = new OnCommittedResponseWrapper(this.delegate) {
@Override
protected void onResponseCommitted() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2021 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,12 +20,12 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import jakarta.servlet.DispatcherType;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import javax.servlet.DispatcherType;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,17 +19,16 @@ package org.springframework.session.web.http;
import java.util.Arrays;
import java.util.Collections;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.MockitoAnnotations;
import org.springframework.mock.web.MockServletContext;
import org.springframework.session.MapSession;
@@ -48,7 +47,6 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
* @author Rob Winch
* @since 1.1
*/
@ExtendWith(MockitoExtension.class)
class SessionEventHttpSessionListenerAdapterTests {
@Mock
@@ -71,6 +69,7 @@ class SessionEventHttpSessionListenerAdapterTests {
@BeforeEach
void setup() {
MockitoAnnotations.initMocks(this);
this.listener = new SessionEventHttpSessionListenerAdapter(Arrays.asList(this.listener1, this.listener2));
this.listener.setServletContext(new MockServletContext());

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,28 +24,29 @@ import java.util.Base64;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import jakarta.servlet.http.HttpSessionBindingEvent;
import jakarta.servlet.http.HttpSessionBindingListener;
import javax.servlet.FilterChain;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionContext;
import org.assertj.core.data.Offset;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.MockitoAnnotations;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
@@ -77,7 +78,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
/**
* Tests for {@link SessionRepositoryFilter}.
*/
@ExtendWith(MockitoExtension.class)
@SuppressWarnings("deprecation")
class SessionRepositoryFilterTests {
@Mock
@@ -97,6 +98,7 @@ class SessionRepositoryFilterTests {
@BeforeEach
void setup() {
MockitoAnnotations.initMocks(this);
this.sessions = new HashMap<>();
this.sessionRepository = new MapSessionRepository(this.sessions);
this.filter = new SessionRepositoryFilter<>(this.sessionRepository);
@@ -313,6 +315,52 @@ class SessionRepositoryFilterTests {
});
}
@Test
void doFilterValue() throws Exception {
final String ATTR = "ATTR";
final String VALUE = "VALUE";
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest) {
wrappedRequest.getSession().putValue(ATTR, VALUE);
assertThat(wrappedRequest.getSession().getValue(ATTR)).isEqualTo(VALUE);
assertThat(Arrays.asList(wrappedRequest.getSession().getValueNames())).containsOnly(ATTR);
}
});
nextRequest();
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest) {
assertThat(wrappedRequest.getSession().getValue(ATTR)).isEqualTo(VALUE);
assertThat(Arrays.asList(wrappedRequest.getSession().getValueNames())).containsOnly(ATTR);
}
});
nextRequest();
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest) {
assertThat(wrappedRequest.getSession().getValue(ATTR)).isEqualTo(VALUE);
wrappedRequest.getSession().removeValue(ATTR);
assertThat(wrappedRequest.getSession().getValue(ATTR)).isNull();
}
});
nextRequest();
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest) {
assertThat(wrappedRequest.getSession().getValue(ATTR)).isNull();
}
});
}
@Test
void doFilterIsNewTrue() throws Exception {
doFilter(new DoInFilter() {
@@ -588,6 +636,27 @@ class SessionRepositoryFilterTests {
assertThat(session.getSecure()).describedAs("Session Cookie should be marked as Secure").isTrue();
}
@Test
void doFilterSessionContext() throws Exception {
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest) {
HttpSessionContext sessionContext = wrappedRequest.getSession().getSessionContext();
assertThat(sessionContext).isNotNull();
assertThat(sessionContext.getSession("a")).isNull();
assertThat(sessionContext.getIds()).isNotNull();
assertThat(sessionContext.getIds().hasMoreElements()).isFalse();
try {
sessionContext.getIds().nextElement();
fail("Expected Exception");
}
catch (NoSuchElementException ignored) {
}
}
});
}
// --- saving
@Test
@@ -671,6 +740,23 @@ class SessionRepositoryFilterTests {
});
}
@Test
void doFilterInvalidateValueIllegalState() throws Exception {
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest) {
HttpSession session = wrappedRequest.getSession();
session.invalidate();
try {
session.getValue("attr");
fail("Expected Exception");
}
catch (IllegalStateException ignored) {
}
}
});
}
@Test
void doFilterInvalidateAttributeNamesIllegalState() throws Exception {
doFilter(new DoInFilter() {
@@ -688,6 +774,23 @@ class SessionRepositoryFilterTests {
});
}
@Test
void doFilterInvalidateValueNamesIllegalState() throws Exception {
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest) {
HttpSession session = wrappedRequest.getSession();
session.invalidate();
try {
session.getValueNames();
fail("Expected Exception");
}
catch (IllegalStateException ignored) {
}
}
});
}
@Test
void doFilterInvalidateSetAttributeIllegalState() throws Exception {
doFilter(new DoInFilter() {
@@ -705,6 +808,23 @@ class SessionRepositoryFilterTests {
});
}
@Test
void doFilterInvalidatePutValueIllegalState() throws Exception {
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest) {
HttpSession session = wrappedRequest.getSession();
session.invalidate();
try {
session.putValue("a", "b");
fail("Expected Exception");
}
catch (IllegalStateException ignored) {
}
}
});
}
@Test
void doFilterInvalidateRemoveAttributeIllegalState() throws Exception {
doFilter(new DoInFilter() {
@@ -722,6 +842,23 @@ class SessionRepositoryFilterTests {
});
}
@Test
void doFilterInvalidateRemoveValueIllegalState() throws Exception {
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest) {
HttpSession session = wrappedRequest.getSession();
session.invalidate();
try {
session.removeValue("name");
fail("Expected Exception");
}
catch (IllegalStateException ignored) {
}
}
});
}
@Test
void doFilterInvalidateNewIllegalState() throws Exception {
doFilter(new DoInFilter() {
@@ -783,6 +920,20 @@ class SessionRepositoryFilterTests {
});
}
@Test
void doFilterInvalidateSessionContext() throws Exception {
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest) {
HttpSession session = wrappedRequest.getSession();
session.invalidate();
// no exception
session.getSessionContext();
}
});
}
@Test
void doFilterInvalidateMaxInteractiveInterval() throws Exception {
doFilter(new DoInFilter() {
@@ -1175,8 +1326,8 @@ class SessionRepositoryFilterTests {
}
});
// 2 invocations expected: initial resolution, after invalidation
verify(sessionRepository, times(2)).findById(eq(session.getId()));
// 3 invocations expected: initial resolution, after invalidation, after commit
verify(sessionRepository, times(3)).findById(eq(session.getId()));
verify(sessionRepository).deleteById(eq(session.getId()));
verify(sessionRepository).createSession();
verify(sessionRepository).save(any());
@@ -1187,9 +1338,8 @@ class SessionRepositoryFilterTests {
@Test
void order() {
assertThat(
AnnotationAwareOrderComparator.INSTANCE.compare(this.filter, new SessionRepositoryFilterDefaultOrder()))
.isZero();
assertThat(AnnotationAwareOrderComparator.INSTANCE.compare(this.filter,
new SessionRepositoryFilterDefaultOrder()));
}
// We want the filter to work without any dependencies on Spring
@@ -1401,7 +1551,7 @@ class SessionRepositoryFilterTests {
}
private abstract static class DoInFilter {
private abstract class DoInFilter {
void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse)
throws ServletException, IOException {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,9 +23,8 @@ import java.util.Set;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.MockitoAnnotations;
import reactor.core.publisher.Mono;
import org.springframework.session.ReactiveSessionRepository;
@@ -44,10 +43,9 @@ import static org.mockito.Mockito.verify;
* @author Rob Winch
* @author Vedran Pavic
*/
@ExtendWith(MockitoExtension.class)
class SpringSessionWebSessionStoreTests<S extends Session> {
@Mock(lenient = true)
@Mock
private ReactiveSessionRepository<S> sessionRepository;
@Mock
@@ -60,6 +58,7 @@ class SpringSessionWebSessionStoreTests<S extends Session> {
@BeforeEach
void setup() {
MockitoAnnotations.initMocks(this);
this.webSessionStore = new SpringSessionWebSessionStore<>(this.sessionRepository);
given(this.sessionRepository.findById(any())).willReturn(Mono.just(this.findByIdSession));
given(this.sessionRepository.createSession()).willReturn(Mono.just(this.createSession));

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,11 +18,10 @@ package org.springframework.session.web.socket.handler;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.MockitoAnnotations;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
@@ -36,7 +35,6 @@ import static org.mockito.BDDMockito.willThrow;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.verify;
@ExtendWith(MockitoExtension.class)
class WebSocketConnectHandlerDecoratorFactoryTests {
@Mock
@@ -55,6 +53,7 @@ class WebSocketConnectHandlerDecoratorFactoryTests {
@BeforeEach
void setup() {
MockitoAnnotations.initMocks(this);
this.factory = new WebSocketConnectHandlerDecoratorFactory(this.eventPublisher);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,9 +22,8 @@ import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.MockitoAnnotations;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
@@ -45,16 +44,15 @@ import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@ExtendWith(MockitoExtension.class)
class WebSocketRegistryListenerTests {
@Mock(lenient = true)
@Mock
private WebSocketSession wsSession;
@Mock(lenient = true)
@Mock
private WebSocketSession wsSession2;
@Mock(lenient = true)
@Mock
private Message<byte[]> message;
@Mock
@@ -76,6 +74,7 @@ class WebSocketRegistryListenerTests {
@BeforeEach
void setup() {
MockitoAnnotations.initMocks(this);
String sessionId = "session-id";
MapSession session = new MapSession(sessionId);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,14 +23,13 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import jakarta.servlet.http.HttpSession;
import javax.servlet.http.HttpSession;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.MockitoAnnotations;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.messaging.Message;
@@ -52,10 +51,9 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@ExtendWith(MockitoExtension.class)
class SessionRepositoryMessageInterceptorTests {
@Mock(lenient = true)
@Mock
SessionRepository<Session> sessionRepository;
@Mock
@@ -72,6 +70,7 @@ class SessionRepositoryMessageInterceptorTests {
@BeforeEach
void setup() {
MockitoAnnotations.initMocks(this);
this.interceptor = new SessionRepositoryMessageInterceptor<>(this.sessionRepository);
this.headers = SimpMessageHeaderAccessor.create();
this.headers.setSessionId("session");

View File

@@ -18,8 +18,6 @@ dependencies {
optional "org.mongodb:mongodb-driver-core"
testImplementation "org.mongodb:mongodb-driver-sync"
testImplementation "org.mongodb:mongodb-driver-reactivestreams"
testImplementation 'jakarta.websocket:jakarta.websocket-api'
testImplementation 'jakarta.websocket:jakarta.websocket-client-api'
integrationTestCompile "org.testcontainers:mongodb"
// Everything else

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.session.data.mongo;
package org.springframework.session.data.mongo.integration;
import java.lang.reflect.Field;
@@ -25,6 +25,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.serializer.DefaultDeserializer;
import org.springframework.core.serializer.support.DeserializingConverter;
import org.springframework.session.data.mongo.AbstractMongoSessionConverter;
import org.springframework.session.data.mongo.Assert;
import org.springframework.session.data.mongo.JdkMongoSessionConverter;
import org.springframework.util.ReflectionUtils;
/**
@@ -46,7 +49,8 @@ public abstract class AbstractClassLoaderTest<T> extends AbstractITest {
Field mongoSessionConverterField = ReflectionUtils.findField(this.sessionRepository.getClass(),
"mongoSessionConverter");
ReflectionUtils.makeAccessible(mongoSessionConverterField);
ReflectionUtils.makeAccessible(
Assert.requireNonNull(mongoSessionConverterField, "mongoSessionConverter must not be null!"));
AbstractMongoSessionConverter sessionConverter = (AbstractMongoSessionConverter) ReflectionUtils
.getField(mongoSessionConverterField, this.sessionRepository);
@@ -66,7 +70,7 @@ public abstract class AbstractClassLoaderTest<T> extends AbstractITest {
private static Object extractField(Class<?> clazz, String fieldName, Object obj) {
Field field = ReflectionUtils.findField(clazz, fieldName);
ReflectionUtils.makeAccessible(field);
ReflectionUtils.makeAccessible(Assert.requireNonNull(field, fieldName + " must not be null!"));
return ReflectionUtils.getField(field, obj);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.session.data.mongo;
package org.springframework.session.data.mongo.integration;
import java.util.UUID;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.session.data.mongo;
package org.springframework.session.data.mongo.integration;
import java.time.Duration;
import java.time.Instant;
@@ -37,6 +37,8 @@ import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.Session;
import org.springframework.session.data.mongo.MongoIndexedSessionRepository;
import org.springframework.session.data.mongo.MongoSession;
import static org.assertj.core.api.Assertions.assertThat;
@@ -387,13 +389,11 @@ public abstract class AbstractMongoRepositoryITest extends AbstractITest {
protected static class BaseConfig {
private static final String DOCKER_IMAGE = "mongo:5.0.11";
private static final String DOCKER_IMAGE = "mongo:4.4.1";
@Bean
public MongoDBContainer mongoDbContainer() {
MongoDBContainer mongoDbContainer = new MongoDBContainer(DOCKER_IMAGE);
mongoDbContainer.start();
return mongoDbContainer;
@Bean(initMethod = "start", destroyMethod = "stop")
public MongoDBContainer mongoContainer() {
return new MongoDBContainer(DOCKER_IMAGE).withExposedPorts(27017);
}
@Bean

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.session.data.mongo;
package org.springframework.session.data.mongo.integration;
import java.net.URI;
@@ -41,6 +41,8 @@ import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.session.data.mongo.AbstractMongoSessionConverter;
import org.springframework.session.data.mongo.JacksonMongoSessionConverter;
import org.springframework.session.data.mongo.config.annotation.web.reactive.EnableMongoWebSession;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@@ -135,7 +137,6 @@ public class MongoDbDeleteJacksonSessionVerificationTest {
}
@Configuration(proxyBeanMethods = false)
@EnableWebFluxSecurity
static class SecurityConfig {
@@ -155,8 +156,9 @@ public class MongoDbDeleteJacksonSessionVerificationTest {
@Bean
MapReactiveUserDetailsService userDetailsService() {
return new MapReactiveUserDetailsService(User.withUsername("admin") //
.password("{noop}password") //
return new MapReactiveUserDetailsService(User.withDefaultPasswordEncoder() //
.username("admin") //
.password("password") //
.roles("USER,ADMIN") //
.build());
}
@@ -173,13 +175,11 @@ public class MongoDbDeleteJacksonSessionVerificationTest {
@EnableMongoWebSession
static class Config {
private static final String DOCKER_IMAGE = "mongo:5.0.11";
private static final String DOCKER_IMAGE = "mongo:4.4.1";
@Bean
MongoDBContainer mongoDbContainer() {
MongoDBContainer mongoDbContainer = new MongoDBContainer(DOCKER_IMAGE);
mongoDbContainer.start();
return mongoDbContainer;
@Bean(initMethod = "start", destroyMethod = "stop")
MongoDBContainer mongoContainer() {
return new MongoDBContainer(DOCKER_IMAGE).withExposedPorts(27017);
}
@Bean

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.session.data.mongo;
package org.springframework.session.data.mongo.integration;
import java.net.URI;
@@ -135,7 +135,6 @@ public class MongoDbLogoutVerificationTest {
}
@Configuration(proxyBeanMethods = false)
@EnableWebFluxSecurity
static class SecurityConfig {
@@ -157,8 +156,9 @@ public class MongoDbLogoutVerificationTest {
@Bean
MapReactiveUserDetailsService userDetailsService() {
return new MapReactiveUserDetailsService(User.withUsername("admin") //
.password("{noop}password") //
return new MapReactiveUserDetailsService(User.withDefaultPasswordEncoder() //
.username("admin") //
.password("password") //
.roles("USER,ADMIN") //
.build());
}
@@ -170,13 +170,11 @@ public class MongoDbLogoutVerificationTest {
@EnableMongoWebSession
static class Config {
private static final String DOCKER_IMAGE = "mongo:5.0.11";
private static final String DOCKER_IMAGE = "mongo:4.4.1";
@Bean
MongoDBContainer mongoDbContainer() {
MongoDBContainer mongoDbContainer = new MongoDBContainer(DOCKER_IMAGE);
mongoDbContainer.start();
return mongoDbContainer;
@Bean(initMethod = "start", destroyMethod = "stop")
MongoDBContainer mongoContainer() {
return new MongoDBContainer(DOCKER_IMAGE).withExposedPorts(27017);
}
@Bean

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.session.data.mongo;
package org.springframework.session.data.mongo.integration;
import java.util.Collections;
import java.util.Map;
@@ -25,6 +25,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.geo.GeoModule;
import org.springframework.session.data.mongo.AbstractMongoSessionConverter;
import org.springframework.session.data.mongo.JacksonMongoSessionConverter;
import org.springframework.session.data.mongo.MongoSession;
import org.springframework.session.data.mongo.config.annotation.web.http.EnableMongoHttpSession;
import org.springframework.test.context.ContextConfiguration;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.session.data.mongo;
package org.springframework.session.data.mongo.integration;
import java.time.Duration;
import java.util.Map;
@@ -23,6 +23,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.mongo.AbstractMongoSessionConverter;
import org.springframework.session.data.mongo.JdkMongoSessionConverter;
import org.springframework.session.data.mongo.MongoSession;
import org.springframework.session.data.mongo.config.annotation.web.http.EnableMongoHttpSession;
import org.springframework.test.context.ContextConfiguration;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,8 +36,6 @@ import org.springframework.session.DelegatingIndexResolver;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.IndexResolver;
import org.springframework.session.PrincipalNameIndexResolver;
import org.springframework.session.Session;
import org.springframework.util.Assert;
/**
* Base class for serializing and deserializing session objects. To create custom
@@ -56,7 +54,8 @@ public abstract class AbstractMongoSessionConverter implements GenericConverter
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
private IndexResolver<Session> indexResolver = new DelegatingIndexResolver<>(new PrincipalNameIndexResolver<>());
private IndexResolver<MongoSession> indexResolver = new DelegatingIndexResolver<>(
new PrincipalNameIndexResolver<>());
/**
* Returns query to be executed to return sessions based on a particular index.
@@ -123,9 +122,8 @@ public abstract class AbstractMongoSessionConverter implements GenericConverter
protected abstract MongoSession convert(Document sessionWrapper);
public void setIndexResolver(IndexResolver<Session> indexResolver) {
Assert.notNull(indexResolver, "indexResolver must not be null");
this.indexResolver = indexResolver;
public void setIndexResolver(IndexResolver<MongoSession> indexResolver) {
this.indexResolver = Assert.requireNonNull(indexResolver, "indexResolver must not be null!");
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.session.data.mongo;
import org.springframework.lang.Nullable;
/**
* Utility to verify non null fields.
*
* @author Greg Turnquist
*/
public final class Assert {
private Assert() {
}
public static <T> T requireNonNull(@Nullable T item, String message) {
if (item == null) {
throw new IllegalArgumentException(message);
}
return item;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import org.apache.commons.logging.Log;
@@ -168,18 +168,18 @@ public class JacksonMongoSessionConverter extends AbstractMongoSessionConverter
}
private static class MongoIdNamingStrategy extends PropertyNamingStrategies.NamingBase {
private static class MongoIdNamingStrategy extends PropertyNamingStrategy.PropertyNamingStrategyBase {
@Override
public String translate(String propertyName) {
switch (propertyName) {
case "id":
return "_id";
case "_id":
return "id";
default:
return propertyName;
case "id":
return "_id";
case "_id":
return "id";
default:
return propertyName;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import com.mongodb.DBObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bson.Document;
@@ -35,11 +34,9 @@ import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.index.IndexOperations;
import org.springframework.lang.Nullable;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.MapSession;
import org.springframework.session.events.SessionCreatedEvent;
import org.springframework.session.events.SessionDeletedEvent;
import org.springframework.session.events.SessionExpiredEvent;
import org.springframework.util.Assert;
/**
* Session repository implementation which stores sessions in Mongo. Uses
@@ -49,7 +46,6 @@ import org.springframework.util.Assert;
*
* @author Jakub Kubrynski
* @author Greg Turnquist
* @author Vedran Pavic
* @since 2.2.0
*/
public class MongoIndexedSessionRepository
@@ -57,11 +53,8 @@ public class MongoIndexedSessionRepository
/**
* The default time period in seconds in which a session will expire.
* @deprecated since 3.0.0 in favor of
* {@link MapSession#DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS}
*/
@Deprecated
public static final int DEFAULT_INACTIVE_INTERVAL = MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS;
public static final int DEFAULT_INACTIVE_INTERVAL = 1800;
/**
* the default collection name for storing session.
@@ -72,12 +65,12 @@ public class MongoIndexedSessionRepository
private final MongoOperations mongoOperations;
private Duration defaultMaxInactiveInterval = Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS);
private Integer maxInactiveIntervalInSeconds = DEFAULT_INACTIVE_INTERVAL;
private String collectionName = DEFAULT_COLLECTION_NAME;
private AbstractMongoSessionConverter mongoSessionConverter = new JdkMongoSessionConverter(
this.defaultMaxInactiveInterval);
Duration.ofSeconds(this.maxInactiveIntervalInSeconds));
private ApplicationEventPublisher eventPublisher;
@@ -90,7 +83,9 @@ public class MongoIndexedSessionRepository
MongoSession session = new MongoSession();
session.setMaxInactiveInterval(this.defaultMaxInactiveInterval);
if (this.maxInactiveIntervalInSeconds != null) {
session.setMaxInactiveInterval(Duration.ofSeconds(this.maxInactiveIntervalInSeconds));
}
publishEvent(new SessionCreatedEvent(this, session));
@@ -99,9 +94,9 @@ public class MongoIndexedSessionRepository
@Override
public void save(MongoSession session) {
DBObject dbObject = MongoSessionUtils.convertToDBObject(this.mongoSessionConverter, session);
Assert.notNull(dbObject, "dbObject must not be null");
this.mongoOperations.save(dbObject, this.collectionName);
this.mongoOperations
.save(Assert.requireNonNull(MongoSessionUtils.convertToDBObject(this.mongoSessionConverter, session),
"convertToDBObject must not null!"), this.collectionName);
}
@Override
@@ -183,29 +178,8 @@ public class MongoIndexedSessionRepository
}
}
/**
* Set the maximum inactive interval in seconds between requests before newly created
* sessions will be invalidated. A negative time indicates that the session will never
* time out. The default is 30 minutes.
* @param defaultMaxInactiveInterval the default maxInactiveInterval
*/
public void setDefaultMaxInactiveInterval(Duration defaultMaxInactiveInterval) {
org.springframework.util.Assert.notNull(defaultMaxInactiveInterval,
"defaultMaxInactiveInterval must not be null");
this.defaultMaxInactiveInterval = defaultMaxInactiveInterval;
}
/**
* Set the maximum inactive interval in seconds between requests before newly created
* sessions will be invalidated. A negative time indicates that the session will never
* time out. The default is 1800 (30 minutes).
* @param defaultMaxInactiveInterval the default maxInactiveInterval in seconds
* @deprecated since 3.0.0, in favor of
* {@link #setDefaultMaxInactiveInterval(Duration)}
*/
@Deprecated(since = "3.0.0")
public void setMaxInactiveIntervalInSeconds(Integer defaultMaxInactiveInterval) {
setDefaultMaxInactiveInterval(Duration.ofSeconds(defaultMaxInactiveInterval));
public void setMaxInactiveIntervalInSeconds(final Integer maxInactiveIntervalInSeconds) {
this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds;
}
public void setCollectionName(final String collectionName) {

Some files were not shown because too many files have changed in this diff Show More