Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51ca6c329e | ||
|
|
bd81ee5a49 | ||
|
|
ec6fd8a902 | ||
|
|
0320e60cf0 | ||
|
|
90d0c1d778 | ||
|
|
058ae80419 | ||
|
|
89fb210f18 |
6
.gitattributes
vendored
6
.gitattributes
vendored
@@ -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
20
.github/actions/algolia-config.json
vendored
Normal 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
20
.github/actions/algolia-deploy.sh
vendored
Executable 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
21
.github/actions/algolia-docsearch-scraper.sh
vendored
Executable 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
5
.github/actions/dispatch.sh
vendored
Executable 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
16
.github/workflows/algolia-index.yml
vendored
Normal 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
31
.github/workflows/antora-generate.yml
vendored
Normal 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"
|
||||
@@ -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
|
||||
|
||||
30
.github/workflows/deploy-docs.yml
vendored
30
.github/workflows/deploy-docs.yml
vendored
@@ -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
33
.github/workflows/deploy-reference.yml
vendored
Normal 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 }}"
|
||||
2
.github/workflows/pr-build-workflow.yml
vendored
2
.github/workflows/pr-build-workflow.yml
vendored
@@ -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
|
||||
|
||||
20
.github/workflows/rebuild-search-index.yml
vendored
20
.github/workflows/rebuild-search-index.yml
vendored
@@ -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
2
.gitignore
vendored
@@ -14,5 +14,3 @@ out
|
||||
!etc/eclipse/.checkstyle
|
||||
!**/src/**/build
|
||||
.DS_Store
|
||||
spring-session-docs/package-lock.json
|
||||
spring-session-docs/node_modules/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
12
RELEASE.adoc
12
RELEASE.adoc
@@ -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+`.
|
||||
|
||||
|
||||
@@ -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/**"
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
|
||||
BIN
buildSrc/gradle/wrapper/gradle-wrapper.jar
vendored
BIN
buildSrc/gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public class SpringSampleWarPlugin extends SpringSamplePlugin {
|
||||
pluginManager.apply("org.gretty");
|
||||
|
||||
project.gretty {
|
||||
servletContainer = 'tomcat10'
|
||||
servletContainer = 'tomcat85'
|
||||
contextPath = '/'
|
||||
fileLogEnabled = false
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -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
6
gradlew
vendored
@@ -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
180
gradlew.bat
vendored
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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"))));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user