1
0
mirror of synced 2026-07-14 15:15:11 +00:00

Compare commits

..

7 Commits

Author SHA1 Message Date
github-actions[bot] d0b2b33dce Release 5.7.14 2024-11-18 16:36:56 +00:00
Joe Grandja 0eaffb37e7 Require Locale argument for toLower/toUpperCase usage 2024-11-15 11:01:23 -05:00
Rob Winch e86d88d0cf Support ServerExchangeRejectedHandler @Bean
Closes gh-15975
2024-11-08 14:48:40 -06:00
Rob Winch e48d6b039b Support ServerWebExchangeFirewall @Bean
Closes gh-15974
2024-10-22 18:25:28 -05:00
github-actions[bot] dd3c6892e9 Next development version 2024-10-21 17:58:56 +00:00
github-actions[bot] c552366a78 Release 5.7.13 2024-10-21 17:23:29 +00:00
Steve Riesenberg 7215c72373 Migrate slack notifications to GChat
Issue gh-15503

[skip ci]
2024-10-21 11:24:40 -05:00
1642 changed files with 13176 additions and 55332 deletions
@@ -2,14 +2,16 @@ name: CI
on:
push:
branches-ignore:
- "dependabot/**"
branches:
- '**'
schedule:
- cron: '0 10 * * *' # Once per day at 10am UTC
workflow_dispatch: # Manual trigger
env:
DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }}
GRADLE_ENTERPRISE_CACHE_USER: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USER }}
GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }}
GRADLE_ENTERPRISE_SECRET_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }}
COMMIT_OWNER: ${{ github.event.pusher.name }}
COMMIT_SHA: ${{ github.sha }}
STRUCTURE101_LICENSEID: ${{ secrets.STRUCTURE101_LICENSEID }}
@@ -28,7 +30,7 @@ jobs:
runjobs: ${{ steps.continue.outputs.runjobs }}
project_version: ${{ steps.continue.outputs.project_version }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- id: continue
name: Determine if should continue
run: |
@@ -46,18 +48,22 @@ jobs:
runs-on: ${{ matrix.os }}
if: needs.prerequisites.outputs.runjobs
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v4
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'adopt'
cache: 'gradle'
- name: Set up Gradle
uses: gradle/gradle-build-action@v3
uses: gradle/gradle-build-action@v2
- name: Set up gradle user name
run: echo 'systemProp.user.name=spring-builds+github' >> gradle.properties
- name: Build with Gradle
env:
GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USER }}
GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }}
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }}
run: ./gradlew clean build --continue -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD"
snapshot_tests:
name: Test against snapshots
@@ -65,23 +71,27 @@ jobs:
runs-on: ubuntu-latest
if: needs.prerequisites.outputs.runjobs
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v2
uses: spring-io/spring-gradle-build-action@v1
with:
java-version: '11'
distribution: 'adopt'
- name: Snapshot Tests
run: ./gradlew test --refresh-dependencies -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" -PforceMavenRepositories=snapshot -PisOverrideVersionCatalog -PspringFrameworkVersion='5.+' -PreactorVersion='2020.0.+' -PspringDataVersion='2021.2.+' -PlocksDisabled --stacktrace
run: |
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
./gradlew test --refresh-dependencies -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" -PforceMavenRepositories=snapshot -PspringVersion='5.+' -PreactorVersion='20+' -PspringDataVersion='Neumann-BUILD-SNAPSHOT' -PrsocketVersion=1.1.0-SNAPSHOT -PspringBootVersion=2.4.0-SNAPSHOT -PlocksDisabled --stacktrace
check_samples:
name: Check Samples project
needs: [prerequisites]
runs-on: ubuntu-latest
if: needs.prerequisites.outputs.runjobs
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v2
uses: spring-io/spring-gradle-build-action@v1
with:
java-version: '11'
distribution: 'adopt'
@@ -91,6 +101,9 @@ jobs:
SAMPLES_DIR: ../spring-security-samples
VERSION: ${{ needs.prerequisites.outputs.project_version }}
run: |
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
./gradlew publishMavenJavaPublicationToLocalRepository
./gradlew cloneSamples -PcloneOutputDirectory="$SAMPLES_DIR"
./gradlew --project-dir "$SAMPLES_DIR" --init-script spring-security-ci.gradle -PlocalRepositoryPath="$LOCAL_REPOSITORY_PATH" -PspringSecurityVersion="$VERSION" :runAllTests
@@ -100,27 +113,35 @@ jobs:
runs-on: ubuntu-latest
if: needs.prerequisites.outputs.runjobs
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v2
uses: spring-io/spring-gradle-build-action@v1
with:
java-version: '11'
distribution: 'adopt'
- name: Check for package tangles
run: ./gradlew check s101 -Ps101.licenseId="$STRUCTURE101_LICENSEID" --stacktrace
run: |
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
./gradlew check s101 -Ps101.licenseId="$STRUCTURE101_LICENSEID" --stacktrace
deploy_artifacts:
name: Deploy Artifacts
needs: [build_jdk_11, snapshot_tests, check_samples, check_tangles]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v2
uses: spring-io/spring-gradle-build-action@v1
with:
java-version: '11'
distribution: 'adopt'
- name: Deploy artifacts
run: ./gradlew publishArtifacts finalizeDeployArtifacts -PossrhUsername="$OSSRH_TOKEN_USERNAME" -PossrhPassword="$OSSRH_TOKEN_PASSWORD" -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" --stacktrace
run: |
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
./gradlew publishArtifacts finalizeDeployArtifacts -PossrhUsername="$OSSRH_TOKEN_USERNAME" -PossrhPassword="$OSSRH_TOKEN_PASSWORD" -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" --stacktrace
env:
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.GPG_PRIVATE_KEY }}
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.GPG_PASSPHRASE }}
@@ -133,14 +154,18 @@ jobs:
needs: [build_jdk_11, snapshot_tests, check_samples, check_tangles]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v2
uses: spring-io/spring-gradle-build-action@v1
with:
java-version: '11'
distribution: 'adopt'
- name: Deploy Docs
run: ./gradlew deployDocs -PdeployDocsSshKey="$DOCS_SSH_KEY" -PdeployDocsSshUsername="$DOCS_USERNAME" -PdeployDocsHost="$DOCS_HOST" --stacktrace
run: |
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
./gradlew deployDocs -PdeployDocsSshKey="$DOCS_SSH_KEY" -PdeployDocsSshUsername="$DOCS_USERNAME" -PdeployDocsHost="$DOCS_HOST" --stacktrace
env:
DOCS_USERNAME: ${{ secrets.DOCS_USERNAME }}
DOCS_SSH_KEY: ${{ secrets.DOCS_SSH_KEY }}
@@ -150,14 +175,18 @@ jobs:
needs: [build_jdk_11, snapshot_tests, check_samples, check_tangles]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v2
uses: spring-io/spring-gradle-build-action@v1
with:
java-version: '11'
distribution: 'adopt'
- name: Deploy Schema
run: ./gradlew deploySchema -PdeployDocsSshKey="$DOCS_SSH_KEY" -PdeployDocsSshUsername="$DOCS_USERNAME" -PdeployDocsHost="$DOCS_HOST" --stacktrace --info
run: |
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
./gradlew deploySchema -PdeployDocsSshKey="$DOCS_SSH_KEY" -PdeployDocsSshUsername="$DOCS_USERNAME" -PdeployDocsHost="$DOCS_HOST" --stacktrace --info
env:
DOCS_USERNAME: ${{ secrets.DOCS_USERNAME }}
DOCS_SSH_KEY: ${{ secrets.DOCS_SSH_KEY }}
@@ -176,11 +205,11 @@ jobs:
TOKEN: ${{ github.token }}
VERSION: ${{ needs.prerequisites.outputs.project_version }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
with:
token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v2
uses: spring-io/spring-gradle-build-action@v1
with:
java-version: '11'
distribution: 'adopt'
@@ -206,6 +235,9 @@ jobs:
echo "Artifacts for $REPO@$VERSION have been released to Maven Central."
- name: Create GitHub Release
run: |
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
echo "Tagging and publishing $REPO@$VERSION release on GitHub."
./gradlew createGitHubRelease -PnextVersion=$VERSION -Pbranch=$BRANCH -PcreateRelease=true -PgitHubAccessToken=$TOKEN
- name: Announce Release on GChat
@@ -219,6 +251,9 @@ jobs:
git config user.email 'github-actions[bot]@users.noreply.github.com'
- name: Update to next Snapshot Version
run: |
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
echo "Updating $REPO@$VERSION to next snapshot version."
./gradlew :updateToSnapshotVersion
git commit -am "Next development version"
@@ -236,9 +271,9 @@ jobs:
TOKEN: ${{ github.token }}
VERSION: ${{ needs.prerequisites.outputs.project_version }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v2
uses: spring-io/spring-gradle-build-action@v1
with:
java-version: '11'
distribution: 'adopt'
+2 -4
View File
@@ -1,9 +1,7 @@
name: Deploy Docs
on:
push:
branches-ignore:
- "gh-pages"
- "dependabot/**"
branches-ignore: [ gh-pages ]
tags: '**'
repository_dispatch:
types: request-build-reference # legacy
@@ -17,7 +15,7 @@ jobs:
if: github.repository_owner == 'spring-projects'
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v3
with:
ref: docs-build
fetch-depth: 1
@@ -1,45 +0,0 @@
name: Mark Duplicate Dependabot PRs
on:
pull_request:
types: [closed]
jobs:
check_duplicate_prs:
runs-on: ubuntu-latest
if: github.event.pull_request.merged == true && github.event.pull_request.user.login == 'dependabot[bot]'
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Extract Dependency Name from PR Title
id: extract
run: |
PR_TITLE="${{ github.event.pull_request.title }}"
DEPENDENCY_NAME=$(echo "$PR_TITLE" | awk -F ' from ' '{print $1}')
echo "dependency_name=$DEPENDENCY_NAME" >> $GITHUB_OUTPUT
- name: Find PRs
id: find_duplicates
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PRS=$(gh pr list --search 'milestone:${{ github.event.pull_request.milestone.title }} is:merged in:title "${{ steps.extract.outputs.dependency_name }}"' --json number --jq 'map(.number) | join(",")')
echo "prs=$PRS" >> $GITHUB_OUTPUT
- name: Label Duplicate PRs
if: steps.find_duplicates.outputs.prs != ''
env:
PRS: ${{ steps.find_duplicates.outputs.prs }}
CURRENT_PR_NUMBER: ${{ github.event.pull_request.number }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash
run: |
for i in ${PRS//,/ }
do
if [ ! $i -eq "$CURRENT_PR_NUMBER" ]; then
echo "Marking PR $i as duplicate"
gh pr edit "$i" --add-label "status: duplicate"
gh pr comment "$i" --body "Duplicate of #$CURRENT_PR_NUMBER"
fi
done
-63
View File
@@ -1,63 +0,0 @@
name: Merge Dependabot PR
on: pull_request_target
run-name: Merge Dependabot PR ${{ github.ref_name }}
permissions: write-all
jobs:
merge-dependabot-pr:
name: Merge Dependabot PR
runs-on: ubuntu-latest
if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' && github.repository == 'spring-projects/spring-security' }}
steps:
- uses: actions/checkout@v4
with:
show-progress: false
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- name: Set Milestone to Dependabot Pull Request
id: set-milestone
run: |
if test -f pom.xml
then
CURRENT_VERSION=$(mvn help:evaluate -Dexpression="project.version" -q -DforceStdout)
else
CURRENT_VERSION=$(cat gradle.properties | sed -n '/^version=/ { s/^version=//;p }')
fi
export CANDIDATE_VERSION=${CURRENT_VERSION/-SNAPSHOT}
MILESTONE=$(gh api repos/$GITHUB_REPOSITORY/milestones --jq 'map(select(.due_on != null and (.title | startswith(env.CANDIDATE_VERSION)))) | .[0] | .title')
if [ -z $MILESTONE ]
then
gh run cancel ${{ github.run_id }}
echo "::warning title=Cannot merge::No scheduled milestone for $CURRENT_VERSION version"
else
gh pr edit ${{ github.event.pull_request.number }} --milestone $MILESTONE
echo mergeEnabled=true >> $GITHUB_OUTPUT
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Merge Dependabot pull request
if: steps.set-milestone.outputs.mergeEnabled
run: gh pr merge ${{ github.event.pull_request.number }} --auto --rebase
env:
GH_TOKEN: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
send-notification:
name: Send Notification
needs: [ merge-dependabot-pr ]
if: ${{ failure() || cancelled() }}
runs-on: ubuntu-latest
steps:
- name: Send Notification
uses: spring-io/spring-security-release-tools/.github/actions/send-notification@v1
with:
webhook-url: ${{ secrets.SPRING_SECURITY_CI_GCHAT_WEBHOOK_URL }}
@@ -23,13 +23,18 @@ jobs:
export TOOL_VERSION=0.1.1
wget "https://repo.maven.apache.org/maven2/io/spring/releasetrain/spring-release-train-tools/$TOOL_VERSION/spring-release-train-tools-$TOOL_VERSION.jar"
java -cp "spring-release-train-tools-$TOOL_VERSION.jar" io.spring.releasetrain.CheckMilestoneDueOnMain --dueOn "$DUE_ON" --expectedDayOfWeek MONDAY --expectedMondayCount 3
send-notification:
name: Send Notification
needs: [ spring-releasetrain-checks ]
if: ${{ failure() || cancelled() }}
notify_result:
name: Check for failures
needs: [spring-releasetrain-checks]
if: failure()
runs-on: ubuntu-latest
permissions:
actions: read
steps:
- name: Send Notification
uses: spring-io/spring-security-release-tools/.github/actions/send-notification@v1
- name: Send Slack message
uses: Gamesight/slack-workflow-status@v1.0.1
with:
webhook-url: ${{ secrets.SPRING_SECURITY_CI_GCHAT_WEBHOOK_URL }}
repo_token: ${{ secrets.GITHUB_TOKEN }}
slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
channel: '#spring-security-ci'
name: 'CI Notifier'
+3 -36
View File
@@ -2,9 +2,6 @@ name: PR Build
on: pull_request
env:
DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }}
permissions:
contents: read
@@ -14,41 +11,11 @@ jobs:
runs-on: ubuntu-latest
if: ${{ github.repository == 'spring-projects/spring-security' }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v2
uses: spring-io/spring-gradle-build-action@v1
with:
java-version: '11'
distribution: 'adopt'
- name: Build with Gradle
run: ./gradlew clean build -PskipCheckExpectedBranchVersion --continue
generate-docs:
name: Generate Docs
runs-on: ubuntu-latest
if: ${{ github.repository == 'spring-projects/spring-security' }}
steps:
- uses: actions/checkout@v4
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v2
with:
java-version: '11'
distribution: 'adopt'
- name: Run Antora
run: ./gradlew -PbuildSrc.skipTests=true :spring-security-docs:antora
- name: Upload Docs
id: upload
uses: actions/upload-artifact@v4
with:
name: docs
path: docs/build/site
overwrite: true
send-notification:
name: Send Notification
needs: [ build, generate-docs ]
if: ${{ failure() && github.event.pull_request.user.login == 'dependabot[bot]' && github.repository == 'spring-projects/spring-security' }}
runs-on: ubuntu-latest
steps:
- name: Send Notification
uses: spring-io/spring-security-release-tools/.github/actions/send-notification@v1
with:
webhook-url: ${{ secrets.SPRING_SECURITY_CI_GCHAT_WEBHOOK_URL }}
run: ./gradlew clean build --continue --scan
@@ -1,22 +0,0 @@
name: Trigger Dependabot Auto Merge Forward
on:
push:
branches:
- '*.x'
permissions: read-all
jobs:
trigger-worflow:
name: Trigger Workflow
runs-on: ubuntu-latest
if: ${{ github.event.commits[0].author.username == 'dependabot[bot]' && github.repository == 'spring-projects/spring-security' }}
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
- id: trigger
env:
GH_TOKEN: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
run: gh workflow run dependabot-auto-merge-forward.yml -r main
@@ -4,7 +4,10 @@ on:
workflow_dispatch: # Manual trigger only. Triggered by release-scheduler.yml on main.
env:
DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
GRADLE_ENTERPRISE_CACHE_USER: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USER }}
GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }}
GRADLE_ENTERPRISE_SECRET_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }}
permissions:
contents: read
@@ -20,23 +23,29 @@ jobs:
steps:
- id: checkout-source
name: Checkout Source Code
uses: actions/checkout@v4
uses: actions/checkout@v3
with:
token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v2
uses: spring-io/spring-gradle-build-action@v1
with:
java-version: '11'
distribution: 'adopt'
- id: check-release-due
name: Check Release Due
run: |
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
./gradlew gitHubCheckNextVersionDueToday
echo "is_due_today=$(cat build/github/milestones/is-due-today)" >>$GITHUB_OUTPUT
- id: check-open-issues
name: Check for open issues
if: steps.check-release-due.outputs.is_due_today == 'true'
run: |
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
./gradlew gitHubCheckMilestoneHasNoOpenIssues
echo "is_open_issues=$(cat build/github/milestones/is-open-issues)" >>$GITHUB_OUTPUT
- id: validate-release-state
@@ -49,6 +58,9 @@ jobs:
name: Update version and push
if: steps.check-release-due.outputs.is_due_today == 'true' && steps.check-open-issues.outputs.is_open_issues == 'false'
run: |
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
git config user.name 'github-actions[bot]'
git config user.email 'github-actions[bot]@users.noreply.github.com'
./gradlew :updateProjectVersion
@@ -57,13 +69,12 @@ jobs:
git tag $updatedVersion
git push
git push origin $updatedVersion
send-notification:
name: Send Notification
needs: [ update_scheduled_release_version ]
if: ${{ failure() || cancelled() }}
runs-on: ubuntu-latest
steps:
- name: Send Notification
uses: spring-io/spring-security-release-tools/.github/actions/send-notification@v1
- id: send-slack-notification
name: Send Slack message
if: failure()
uses: Gamesight/slack-workflow-status@v1.0.1
with:
webhook-url: ${{ secrets.SPRING_SECURITY_CI_GCHAT_WEBHOOK_URL }}
repo_token: ${{ secrets.GITHUB_TOKEN }}
slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
channel: '#spring-security-ci'
name: 'CI Notifier'
@@ -27,9 +27,7 @@ import org.springframework.security.acls.model.SidRetrievalStrategy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.util.Assert;
/**
@@ -48,9 +46,6 @@ import org.springframework.util.Assert;
*/
public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
private final GrantedAuthority gaGeneralChanges;
private final GrantedAuthority gaModifyAuditing;
@@ -86,12 +81,12 @@ public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
@Override
public void securityCheck(Acl acl, int changeType) {
SecurityContext context = this.securityContextHolderStrategy.getContext();
if ((context == null) || (context.getAuthentication() == null)
|| !context.getAuthentication().isAuthenticated()) {
if ((SecurityContextHolder.getContext() == null)
|| (SecurityContextHolder.getContext().getAuthentication() == null)
|| !SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) {
throw new AccessDeniedException("Authenticated principal required to operate with ACLs");
}
Authentication authentication = context.getAuthentication();
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
// Check if authorized by virtue of ACL ownership
Sid currentUser = createCurrentUser(authentication);
if (currentUser.equals(acl.getOwner())
@@ -151,15 +146,4 @@ public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
this.sidRetrievalStrategy = sidRetrievalStrategy;
}
/**
* Sets the {@link SecurityContextHolderStrategy} to use. The default action is to use
* the {@link SecurityContextHolderStrategy} stored in {@link SecurityContextHolder}.
*
* @since 5.8
*/
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
Assert.notNull(securityContextHolderStrategy, "securityContextHolderStrategy cannot be null");
this.securityContextHolderStrategy = securityContextHolderStrategy;
}
}
@@ -110,9 +110,9 @@ public class EhCacheBasedAclCache implements AclCache {
if (this.aclAuthorizationStrategy == null) {
if (acl instanceof AclImpl) {
this.aclAuthorizationStrategy = (AclAuthorizationStrategy) FieldUtils
.getProtectedFieldValue("aclAuthorizationStrategy", acl);
.getProtectedFieldValue("aclAuthorizationStrategy", acl);
this.permissionGrantingStrategy = (PermissionGrantingStrategy) FieldUtils
.getProtectedFieldValue("permissionGrantingStrategy", acl);
.getProtectedFieldValue("permissionGrantingStrategy", acl);
}
}
if ((acl.getParentAcl() != null) && (acl.getParentAcl() instanceof MutableAcl)) {
@@ -54,7 +54,7 @@ public class SidRetrievalStrategyImpl implements SidRetrievalStrategy {
@Override
public List<Sid> getSids(Authentication authentication) {
Collection<? extends GrantedAuthority> authorities = this.roleHierarchy
.getReachableGrantedAuthorities(authentication.getAuthorities());
.getReachableGrantedAuthorities(authentication.getAuthorities());
List<Sid> sids = new ArrayList<>(authorities.size() + 1);
sids.add(new PrincipalSid(authentication));
for (GrantedAuthority authority : authorities) {
@@ -579,7 +579,7 @@ public class BasicLookupStrategy implements LookupStrategy {
Serializable identifier = (Serializable) rs.getObject("object_id_identity");
identifier = BasicLookupStrategy.this.aclClassIdUtils.identifierFrom(identifier, rs);
ObjectIdentity objectIdentity = BasicLookupStrategy.this.objectIdentityGenerator
.createObjectIdentity(identifier, rs.getString("class"));
.createObjectIdentity(identifier, rs.getString("class"));
Acl parentAcl = null;
long parentAclId = rs.getLong("parent_object");
@@ -40,7 +40,6 @@ import org.springframework.security.acls.model.ObjectIdentity;
import org.springframework.security.acls.model.Sid;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
@@ -65,9 +64,6 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
private static final String DEFAULT_INSERT_INTO_ACL_CLASS_WITH_ID = "insert into acl_class (class, class_id_type) values (?, ?)";
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
private boolean foreignKeysInDatabase = true;
private final AclCache aclCache;
@@ -119,7 +115,7 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
// Need to retrieve the current principal, in order to know who "owns" this ACL
// (can be changed later on)
Authentication auth = this.securityContextHolderStrategy.getContext().getAuthentication();
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
PrincipalSid sid = new PrincipalSid(auth);
// Create the acl_object_identity row
@@ -477,15 +473,4 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
}
}
/**
* Sets the {@link SecurityContextHolderStrategy} to use. The default action is to use
* the {@link SecurityContextHolderStrategy} stored in {@link SecurityContextHolder}.
*
* @since 5.8
*/
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
Assert.notNull(securityContextHolderStrategy, "securityContextHolderStrategy cannot be null");
this.securityContextHolderStrategy = securityContextHolderStrategy;
}
}
@@ -37,7 +37,7 @@ public class AclFormattingUtilsTests {
assertThatIllegalArgumentException().isThrownBy(() -> AclFormattingUtils.demergePatterns(null, "SOME STRING"));
assertThatIllegalArgumentException().isThrownBy(() -> AclFormattingUtils.demergePatterns("SOME STRING", null));
assertThatIllegalArgumentException()
.isThrownBy(() -> AclFormattingUtils.demergePatterns("SOME STRING", "LONGER SOME STRING"));
.isThrownBy(() -> AclFormattingUtils.demergePatterns("SOME STRING", "LONGER SOME STRING"));
assertThatNoException().isThrownBy(() -> AclFormattingUtils.demergePatterns("SOME STRING", "SAME LENGTH"));
}
@@ -46,7 +46,7 @@ public class AclFormattingUtilsTests {
String original = "...........................A...R";
String removeBits = "...............................R";
assertThat(AclFormattingUtils.demergePatterns(original, removeBits))
.isEqualTo("...........................A....");
.isEqualTo("...........................A....");
assertThat(AclFormattingUtils.demergePatterns("ABCDEF", "......")).isEqualTo("ABCDEF");
assertThat(AclFormattingUtils.demergePatterns("ABCDEF", "GHIJKL")).isEqualTo("......");
}
@@ -56,7 +56,7 @@ public class AclFormattingUtilsTests {
assertThatIllegalArgumentException().isThrownBy(() -> AclFormattingUtils.mergePatterns(null, "SOME STRING"));
assertThatIllegalArgumentException().isThrownBy(() -> AclFormattingUtils.mergePatterns("SOME STRING", null));
assertThatIllegalArgumentException()
.isThrownBy(() -> AclFormattingUtils.mergePatterns("SOME STRING", "LONGER SOME STRING"));
.isThrownBy(() -> AclFormattingUtils.mergePatterns("SOME STRING", "LONGER SOME STRING"));
assertThatNoException().isThrownBy(() -> AclFormattingUtils.mergePatterns("SOME STRING", "SAME LENGTH"));
}
@@ -73,9 +73,9 @@ public class AclFormattingUtilsTests {
public final void testBinaryPrints() {
assertThat(AclFormattingUtils.printBinary(15)).isEqualTo("............................****");
assertThatIllegalArgumentException()
.isThrownBy(() -> AclFormattingUtils.printBinary(15, Permission.RESERVED_ON));
.isThrownBy(() -> AclFormattingUtils.printBinary(15, Permission.RESERVED_ON));
assertThatIllegalArgumentException()
.isThrownBy(() -> AclFormattingUtils.printBinary(15, Permission.RESERVED_OFF));
.isThrownBy(() -> AclFormattingUtils.printBinary(15, Permission.RESERVED_OFF));
assertThat(AclFormattingUtils.printBinary(15, 'x')).isEqualTo("............................xxxx");
}
@@ -34,7 +34,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* @author Luke Taylor
@@ -68,7 +68,7 @@ public class AclPermissionCacheOptimizerTests {
pco.setObjectIdentityRetrievalStrategy(oids);
pco.setSidRetrievalStrategy(sids);
pco.cachePermissionsFor(mock(Authentication.class), Collections.emptyList());
verifyNoMoreInteractions(service, sids, oids);
verifyZeroInteractions(service, sids, oids);
}
}
@@ -85,8 +85,7 @@ public class AclEntryAfterInvocationCollectionFilteringProviderTests {
AclEntryAfterInvocationCollectionFilteringProvider provider = new AclEntryAfterInvocationCollectionFilteringProvider(
service, Arrays.asList(mock(Permission.class)));
assertThat(provider.decide(mock(Authentication.class), new Object(),
SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), null))
.isNull();
SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), null)).isNull();
verify(service, never()).readAclById(any(ObjectIdentity.class), any(List.class));
}
@@ -54,7 +54,7 @@ public class AclEntryAfterInvocationProviderTests {
@Test
public void rejectsMissingPermissions() {
assertThatIllegalArgumentException()
.isThrownBy(() -> new AclEntryAfterInvocationProvider(mock(AclService.class), null));
.isThrownBy(() -> new AclEntryAfterInvocationProvider(mock(AclService.class), null));
assertThatIllegalArgumentException().isThrownBy(
() -> new AclEntryAfterInvocationProvider(mock(AclService.class), Collections.<Permission>emptyList()));
}
@@ -112,12 +112,12 @@ public class AclEntryAfterInvocationProviderTests {
provider.setProcessDomainObjectClass(Object.class);
provider.setSidRetrievalStrategy(mock(SidRetrievalStrategy.class));
assertThatExceptionOfType(AccessDeniedException.class)
.isThrownBy(() -> provider.decide(mock(Authentication.class), new Object(),
SecurityConfig.createList("UNSUPPORTED", "MY_ATTRIBUTE"), new Object()));
.isThrownBy(() -> provider.decide(mock(Authentication.class), new Object(),
SecurityConfig.createList("UNSUPPORTED", "MY_ATTRIBUTE"), new Object()));
// Second scenario with no acls found
assertThatExceptionOfType(AccessDeniedException.class)
.isThrownBy(() -> provider.decide(mock(Authentication.class), new Object(),
SecurityConfig.createList("UNSUPPORTED", "MY_ATTRIBUTE"), new Object()));
.isThrownBy(() -> provider.decide(mock(Authentication.class), new Object(),
SecurityConfig.createList("UNSUPPORTED", "MY_ATTRIBUTE"), new Object()));
}
@Test
@@ -126,8 +126,7 @@ public class AclEntryAfterInvocationProviderTests {
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(service,
Arrays.asList(mock(Permission.class)));
assertThat(provider.decide(mock(Authentication.class), new Object(),
SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), null))
.isNull();
SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), null)).isNull();
verify(service, never()).readAclById(any(ObjectIdentity.class), any(List.class));
}
@@ -77,14 +77,14 @@ public class AccessControlImplEntryTests {
assertThat(ace).isNotNull();
assertThat(ace).isNotEqualTo(100L);
assertThat(ace).isEqualTo(ace);
assertThat(ace)
.isEqualTo(new AccessControlEntryImpl(1L, mockAcl, sid, BasePermission.ADMINISTRATION, true, true, true));
assertThat(ace).isEqualTo(
new AccessControlEntryImpl(1L, mockAcl, sid, BasePermission.ADMINISTRATION, true, true, true));
assertThat(ace).isNotEqualTo(
new AccessControlEntryImpl(2L, mockAcl, sid, BasePermission.ADMINISTRATION, true, true, true));
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(1L, mockAcl, new PrincipalSid("scott"),
BasePermission.ADMINISTRATION, true, true, true));
assertThat(ace)
.isNotEqualTo(new AccessControlEntryImpl(1L, mockAcl, sid, BasePermission.WRITE, true, true, true));
.isNotEqualTo(new AccessControlEntryImpl(1L, mockAcl, sid, BasePermission.WRITE, true, true, true));
assertThat(ace).isNotEqualTo(
new AccessControlEntryImpl(1L, mockAcl, sid, BasePermission.ADMINISTRATION, false, true, true));
assertThat(ace).isNotEqualTo(
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-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,13 +29,9 @@ import org.springframework.security.acls.model.Acl;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.core.context.SecurityContextImpl;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.verify;
/**
* @author Rob Winch
@@ -44,14 +40,9 @@ import static org.mockito.Mockito.verify;
@ExtendWith(MockitoExtension.class)
public class AclAuthorizationStrategyImplTests {
SecurityContext context;
@Mock
Acl acl;
@Mock
SecurityContextHolderStrategy securityContextHolderStrategy;
GrantedAuthority authority;
AclAuthorizationStrategyImpl strategy;
@@ -62,8 +53,7 @@ public class AclAuthorizationStrategyImplTests {
TestingAuthenticationToken authentication = new TestingAuthenticationToken("foo", "bar",
Arrays.asList(this.authority));
authentication.setAuthenticated(true);
this.context = new SecurityContextImpl(authentication);
SecurityContextHolder.setContext(this.context);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
@AfterEach
@@ -86,16 +76,6 @@ public class AclAuthorizationStrategyImplTests {
this.strategy.securityCheck(this.acl, AclAuthorizationStrategy.CHANGE_GENERAL);
}
@Test
public void securityCheckWhenCustomSecurityContextHolderStrategyThenUses() {
given(this.securityContextHolderStrategy.getContext()).willReturn(this.context);
given(this.acl.getOwner()).willReturn(new GrantedAuthoritySid("ROLE_AUTH"));
this.strategy = new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_SYSTEM_ADMIN"));
this.strategy.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
this.strategy.securityCheck(this.acl, AclAuthorizationStrategy.CHANGE_GENERAL);
verify(this.securityContextHolderStrategy).getContext();
}
@SuppressWarnings("serial")
class CustomAuthority implements GrantedAuthority {
@@ -103,7 +103,7 @@ public class AclImplTests {
assertThatIllegalArgumentException().isThrownBy(
() -> new AclImpl(null, 1, this.authzStrategy, this.pgs, null, null, true, new PrincipalSid("joe")));
assertThatIllegalArgumentException()
.isThrownBy(() -> new AclImpl(null, 1, this.authzStrategy, this.mockAuditLogger));
.isThrownBy(() -> new AclImpl(null, 1, this.authzStrategy, this.mockAuditLogger));
}
@Test
@@ -111,7 +111,7 @@ public class AclImplTests {
assertThatIllegalArgumentException().isThrownBy(() -> new AclImpl(this.objectIdentity, null, this.authzStrategy,
this.pgs, null, null, true, new PrincipalSid("joe")));
assertThatIllegalArgumentException()
.isThrownBy(() -> new AclImpl(this.objectIdentity, null, this.authzStrategy, this.mockAuditLogger));
.isThrownBy(() -> new AclImpl(this.objectIdentity, null, this.authzStrategy, this.mockAuditLogger));
}
@Test
@@ -120,7 +120,7 @@ public class AclImplTests {
new DefaultPermissionGrantingStrategy(this.mockAuditLogger), null, null, true,
new PrincipalSid("joe")));
assertThatIllegalArgumentException()
.isThrownBy(() -> new AclImpl(this.objectIdentity, 1, null, this.mockAuditLogger));
.isThrownBy(() -> new AclImpl(this.objectIdentity, 1, null, this.mockAuditLogger));
}
@Test
@@ -128,7 +128,7 @@ public class AclImplTests {
MutableAcl acl = new AclImpl(this.objectIdentity, 1, this.authzStrategy, this.pgs, null, null, true,
new PrincipalSid("joe"));
assertThatIllegalArgumentException()
.isThrownBy(() -> acl.insertAce(0, null, new GrantedAuthoritySid("ROLE_IGNORED"), true));
.isThrownBy(() -> acl.insertAce(0, null, new GrantedAuthoritySid("ROLE_IGNORED"), true));
assertThatIllegalArgumentException().isThrownBy(() -> acl.insertAce(0, BasePermission.READ, null, true));
}
@@ -175,7 +175,7 @@ public class AclImplTests {
acl.insertAce(0, BasePermission.READ, new GrantedAuthoritySid("ROLE_TEST1"), true);
service.updateAcl(acl);
assertThatExceptionOfType(NotFoundException.class)
.isThrownBy(() -> acl.insertAce(55, BasePermission.READ, new GrantedAuthoritySid("ROLE_TEST2"), true));
.isThrownBy(() -> acl.insertAce(55, BasePermission.READ, new GrantedAuthoritySid("ROLE_TEST2"), true));
}
@Test
@@ -223,7 +223,7 @@ public class AclImplTests {
new PrincipalSid("joe"));
Sid ben = new PrincipalSid("ben");
assertThatIllegalArgumentException()
.isThrownBy(() -> acl.isGranted(new ArrayList<>(0), Arrays.asList(ben), false));
.isThrownBy(() -> acl.isGranted(new ArrayList<>(0), Arrays.asList(ben), false));
assertThatIllegalArgumentException().isThrownBy(() -> acl.isGranted(READ, new ArrayList<>(0), false));
}
@@ -246,14 +246,12 @@ public class AclImplTests {
List<Sid> sids = Arrays.asList(new PrincipalSid("ben"), new GrantedAuthoritySid("ROLE_GUEST"));
assertThat(rootAcl.isGranted(permissions, sids, false)).isFalse();
assertThatExceptionOfType(NotFoundException.class)
.isThrownBy(() -> rootAcl.isGranted(permissions, SCOTT, false));
.isThrownBy(() -> rootAcl.isGranted(permissions, SCOTT, false));
assertThat(rootAcl.isGranted(WRITE, SCOTT, false)).isTrue();
assertThat(rootAcl.isGranted(WRITE,
Arrays.asList(new PrincipalSid("rod"), new GrantedAuthoritySid("WRITE_ACCESS_ROLE")), false))
.isFalse();
Arrays.asList(new PrincipalSid("rod"), new GrantedAuthoritySid("WRITE_ACCESS_ROLE")), false)).isFalse();
assertThat(rootAcl.isGranted(WRITE,
Arrays.asList(new GrantedAuthoritySid("WRITE_ACCESS_ROLE"), new PrincipalSid("rod")), false))
.isTrue();
Arrays.asList(new GrantedAuthoritySid("WRITE_ACCESS_ROLE"), new PrincipalSid("rod")), false)).isTrue();
// Change the type of the Sid and check the granting process
assertThatExceptionOfType(NotFoundException.class).isThrownBy(() -> rootAcl.isGranted(WRITE,
Arrays.asList(new GrantedAuthoritySid("rod"), new PrincipalSid("WRITE_ACCESS_ROLE")), false));
@@ -294,7 +292,7 @@ public class AclImplTests {
// Check granting process for parent1
assertThat(parentAcl1.isGranted(READ, SCOTT, false)).isTrue();
assertThat(parentAcl1.isGranted(READ, Arrays.asList((Sid) new GrantedAuthoritySid("ROLE_USER_READ")), false))
.isTrue();
.isTrue();
assertThat(parentAcl1.isGranted(WRITE, BEN, false)).isTrue();
assertThat(parentAcl1.isGranted(DELETE, BEN, false)).isFalse();
assertThat(parentAcl1.isGranted(DELETE, SCOTT, false)).isFalse();
@@ -305,13 +303,13 @@ public class AclImplTests {
// Check granting process for child1
assertThat(childAcl1.isGranted(CREATE, SCOTT, false)).isTrue();
assertThat(childAcl1.isGranted(READ, Arrays.asList((Sid) new GrantedAuthoritySid("ROLE_USER_READ")), false))
.isTrue();
.isTrue();
assertThat(childAcl1.isGranted(DELETE, BEN, false)).isFalse();
// Check granting process for child2 (doesn't inherit the permissions from its
// parent)
assertThatExceptionOfType(NotFoundException.class).isThrownBy(() -> childAcl2.isGranted(CREATE, SCOTT, false));
assertThatExceptionOfType(NotFoundException.class)
.isThrownBy(() -> childAcl2.isGranted(CREATE, Arrays.asList((Sid) new PrincipalSid("joe")), false));
.isThrownBy(() -> childAcl2.isGranted(CREATE, Arrays.asList((Sid) new PrincipalSid("joe")), false));
}
@Test
@@ -398,20 +396,20 @@ public class AclImplTests {
new PrincipalSid("joe"));
assertThat(acl.isSidLoaded(loadedSids)).isTrue();
assertThat(acl.isSidLoaded(Arrays.asList(new GrantedAuthoritySid("ROLE_IGNORED"), new PrincipalSid("ben"))))
.isTrue();
.isTrue();
assertThat(acl.isSidLoaded(Arrays.asList((Sid) new GrantedAuthoritySid("ROLE_IGNORED")))).isTrue();
assertThat(acl.isSidLoaded(BEN)).isTrue();
assertThat(acl.isSidLoaded(null)).isTrue();
assertThat(acl.isSidLoaded(new ArrayList<>(0))).isTrue();
assertThat(acl.isSidLoaded(
Arrays.asList(new GrantedAuthoritySid("ROLE_IGNORED"), new GrantedAuthoritySid("ROLE_IGNORED"))))
.isTrue();
.isTrue();
assertThat(acl.isSidLoaded(
Arrays.asList(new GrantedAuthoritySid("ROLE_GENERAL"), new GrantedAuthoritySid("ROLE_IGNORED"))))
.isFalse();
.isFalse();
assertThat(acl.isSidLoaded(
Arrays.asList(new GrantedAuthoritySid("ROLE_IGNORED"), new GrantedAuthoritySid("ROLE_GENERAL"))))
.isFalse();
.isFalse();
}
@Test
@@ -419,7 +417,7 @@ public class AclImplTests {
AclImpl acl = new AclImpl(this.objectIdentity, 1, this.authzStrategy, this.pgs, null, null, true,
new PrincipalSid("joe"));
assertThatExceptionOfType(NotFoundException.class)
.isThrownBy(() -> acl.insertAce(-1, mock(Permission.class), mock(Sid.class), true));
.isThrownBy(() -> acl.insertAce(-1, mock(Permission.class), mock(Sid.class), true));
}
@Test
@@ -437,7 +435,7 @@ public class AclImplTests {
acl.insertAce(0, mock(Permission.class), mock(Sid.class), true);
// Size is now 1
assertThatExceptionOfType(NotFoundException.class)
.isThrownBy(() -> acl.insertAce(2, mock(Permission.class), mock(Sid.class), true));
.isThrownBy(() -> acl.insertAce(2, mock(Permission.class), mock(Sid.class), true));
}
// SEC-1151
@@ -468,7 +466,7 @@ public class AclImplTests {
AclImpl acl = new AclImpl(this.objectIdentity, 1, this.authzStrategy, maskPgs, null, null, true,
new PrincipalSid("joe"));
Permission permission = this.permissionFactory
.buildFromMask(BasePermission.READ.getMask() | BasePermission.WRITE.getMask());
.buildFromMask(BasePermission.READ.getMask() | BasePermission.WRITE.getMask());
Sid sid = new PrincipalSid("ben");
acl.insertAce(0, permission, sid, true);
service.updateAcl(acl);
@@ -73,12 +73,12 @@ public class AclImplementationSecurityCheckTests {
new SimpleGrantedAuthority("ROLE_THREE"));
Acl acl2 = new AclImpl(identity, 1L, aclAuthorizationStrategy2, new ConsoleAuditLogger());
// Check access in case the principal has no authorization rights
assertThatExceptionOfType(NotFoundException.class)
.isThrownBy(() -> aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_GENERAL));
assertThatExceptionOfType(NotFoundException.class)
.isThrownBy(() -> aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_AUDITING));
assertThatExceptionOfType(NotFoundException.class)
.isThrownBy(() -> aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_OWNERSHIP));
assertThatExceptionOfType(NotFoundException.class).isThrownBy(
() -> aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_GENERAL));
assertThatExceptionOfType(NotFoundException.class).isThrownBy(
() -> aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_AUDITING));
assertThatExceptionOfType(NotFoundException.class).isThrownBy(
() -> aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_OWNERSHIP));
}
@Test
@@ -181,11 +181,11 @@ public class AclImplementationSecurityCheckTests {
new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()), null, null, false,
new PrincipalSid(auth));
assertThatNoException()
.isThrownBy(() -> aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_GENERAL));
assertThatExceptionOfType(NotFoundException.class)
.isThrownBy(() -> aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_AUDITING));
assertThatNoException()
.isThrownBy(() -> aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_OWNERSHIP));
.isThrownBy(() -> aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_GENERAL));
assertThatExceptionOfType(NotFoundException.class).isThrownBy(
() -> aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_AUDITING));
assertThatNoException().isThrownBy(
() -> aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_OWNERSHIP));
}
}
@@ -60,7 +60,7 @@ public class ObjectIdentityImplTests {
public void testGetIdMethodConstraints() {
// Check the getId() method is present
assertThatExceptionOfType(IdentityUnavailableException.class)
.isThrownBy(() -> new ObjectIdentityImpl("A_STRING_OBJECT"));
.isThrownBy(() -> new ObjectIdentityImpl("A_STRING_OBJECT"));
// getId() should return a non-null value
MockIdDomainObject mockId = new MockIdDomainObject();
assertThatIllegalArgumentException().isThrownBy(() -> new ObjectIdentityImpl(mockId));
@@ -47,12 +47,10 @@ public class PermissionTests {
public void expectedIntegerValues() {
assertThat(BasePermission.READ.getMask()).isEqualTo(1);
assertThat(BasePermission.ADMINISTRATION.getMask()).isEqualTo(16);
assertThat(new CumulativePermission().set(BasePermission.READ)
.set(BasePermission.WRITE)
.set(BasePermission.CREATE)
.getMask()).isEqualTo(7);
assertThat(new CumulativePermission().set(BasePermission.READ).set(BasePermission.WRITE)
.set(BasePermission.CREATE).getMask()).isEqualTo(7);
assertThat(new CumulativePermission().set(BasePermission.READ).set(BasePermission.ADMINISTRATION).getMask())
.isEqualTo(17);
.isEqualTo(17);
}
@Test
@@ -66,23 +64,20 @@ public class PermissionTests {
this.permissionFactory.registerPublicPermissions(SpecialPermission.class);
assertThat(BasePermission.READ.toString()).isEqualTo("BasePermission[...............................R=1]");
assertThat(BasePermission.ADMINISTRATION.toString())
.isEqualTo("BasePermission[...........................A....=16]");
.isEqualTo("BasePermission[...........................A....=16]");
assertThat(new CumulativePermission().set(BasePermission.READ).toString())
.isEqualTo("CumulativePermission[...............................R=1]");
.isEqualTo("CumulativePermission[...............................R=1]");
assertThat(
new CumulativePermission().set(SpecialPermission.ENTER).set(BasePermission.ADMINISTRATION).toString())
.isEqualTo("CumulativePermission[..........................EA....=48]");
.isEqualTo("CumulativePermission[..........................EA....=48]");
assertThat(new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ).toString())
.isEqualTo("CumulativePermission[...........................A...R=17]");
assertThat(new CumulativePermission().set(BasePermission.ADMINISTRATION)
.set(BasePermission.READ)
.clear(BasePermission.ADMINISTRATION)
.toString()).isEqualTo("CumulativePermission[...............................R=1]");
assertThat(new CumulativePermission().set(BasePermission.ADMINISTRATION)
.set(BasePermission.READ)
.clear(BasePermission.ADMINISTRATION)
.clear(BasePermission.READ)
.toString()).isEqualTo("CumulativePermission[................................=0]");
.isEqualTo("CumulativePermission[...........................A...R=17]");
assertThat(new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ)
.clear(BasePermission.ADMINISTRATION).toString())
.isEqualTo("CumulativePermission[...............................R=1]");
assertThat(new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ)
.clear(BasePermission.ADMINISTRATION).clear(BasePermission.READ).toString())
.isEqualTo("CumulativePermission[................................=0]");
}
}
@@ -147,7 +147,7 @@ public abstract class AbstractBasicLookupStrategyTests {
// Deliberately use an integer for the child, to reproduce bug report in SEC-819
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, 102);
Map<ObjectIdentity, Acl> map = this.strategy
.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
checkEntries(topParentOid, middleParentOid, childOid, map);
}
@@ -161,7 +161,7 @@ public abstract class AbstractBasicLookupStrategyTests {
// Let's empty the database to force acls retrieval from cache
emptyDatabase();
Map<ObjectIdentity, Acl> map = this.strategy
.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
checkEntries(topParentOid, middleParentOid, childOid, map);
}
@@ -174,7 +174,7 @@ public abstract class AbstractBasicLookupStrategyTests {
// acls
this.strategy.setBatchSize(1);
Map<ObjectIdentity, Acl> map = this.strategy
.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
checkEntries(topParentOid, middleParentOid, childOid, map);
}
@@ -301,7 +301,7 @@ public abstract class AbstractBasicLookupStrategyTests {
getJdbcTemplate().execute(query);
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, 104L);
assertThatIllegalArgumentException()
.isThrownBy(() -> this.strategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID)));
.isThrownBy(() -> this.strategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID)));
}
@Test
@@ -116,7 +116,7 @@ public class BasicLookupStrategyWithAclClassTypeTests extends AbstractBasicLooku
public void testReadObjectIdentityUsingNonUuidInDatabase() {
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID, OBJECT_IDENTITY_LONG_AS_UUID);
assertThatExceptionOfType(ConversionFailedException.class)
.isThrownBy(() -> this.uuidEnabledStrategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID)));
.isThrownBy(() -> this.uuidEnabledStrategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID)));
}
}
@@ -101,7 +101,7 @@ public class JdbcAclServiceTests {
ObjectIdentity objectIdentity = new ObjectIdentityImpl(Object.class, 1);
List<Sid> sids = Arrays.<Sid>asList(new PrincipalSid("user"));
assertThatExceptionOfType(NotFoundException.class)
.isThrownBy(() -> this.aclService.readAclById(objectIdentity, sids));
.isThrownBy(() -> this.aclService.readAclById(objectIdentity, sids));
}
@Test
@@ -168,20 +168,20 @@ public class JdbcAclServiceTests {
assertThat(objectIdentities.size()).isEqualTo(1);
assertThat(objectIdentities.get(0).getType()).isEqualTo("costcenter");
assertThat(objectIdentities.get(0).getIdentifier())
.isEqualTo(UUID.fromString("25d93b3f-c3aa-4814-9d5e-c7c96ced7762"));
.isEqualTo(UUID.fromString("25d93b3f-c3aa-4814-9d5e-c7c96ced7762"));
}
@Test
public void setObjectIdentityGeneratorWhenNullThenThrowsIllegalArgumentException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> this.aclServiceIntegration.setObjectIdentityGenerator(null))
.withMessage("objectIdentityGenerator cannot be null");
.isThrownBy(() -> this.aclServiceIntegration.setObjectIdentityGenerator(null))
.withMessage("objectIdentityGenerator cannot be null");
}
@Test
public void findChildrenWhenObjectIdentityGeneratorSetThenUsed() {
this.aclServiceIntegration
.setObjectIdentityGenerator((id, type) -> new ObjectIdentityImpl(type, "prefix:" + id));
.setObjectIdentityGenerator((id, type) -> new ObjectIdentityImpl(type, "prefix:" + id));
ObjectIdentity objectIdentity = new ObjectIdentityImpl("location", "US");
this.aclServiceIntegration.setAclClassIdSupported(true);
@@ -48,10 +48,7 @@ import org.springframework.security.acls.model.Sid;
import org.springframework.security.acls.sid.CustomSid;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.transaction.AfterTransaction;
@@ -62,9 +59,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
/**
* Integration tests the ACL system using an in-memory database.
@@ -168,7 +163,7 @@ public class JdbcMutableAclServiceTests {
this.jdbcMutableAclService.updateAcl(child);
// Let's check if we can read them back correctly
Map<ObjectIdentity, Acl> map = this.jdbcMutableAclService
.readAclsById(Arrays.asList(getTopParentOid(), getMiddleParentOid(), getChildOid()));
.readAclsById(Arrays.asList(getTopParentOid(), getMiddleParentOid(), getChildOid()));
assertThat(map).hasSize(3);
// Get the retrieved versions
MutableAcl retrievedTopParent = (MutableAcl) map.get(getTopParentOid());
@@ -196,7 +191,7 @@ public class JdbcMutableAclServiceTests {
assertThat(retrievedMiddleParent.isGranted(delete, pSid, false)).isTrue();
assertThat(retrievedChild.isGranted(delete, pSid, false)).isFalse();
assertThatExceptionOfType(NotFoundException.class)
.isThrownBy(() -> retrievedChild.isGranted(Arrays.asList(BasePermission.ADMINISTRATION), pSid, false));
.isThrownBy(() -> retrievedChild.isGranted(Arrays.asList(BasePermission.ADMINISTRATION), pSid, false));
// Now check the inherited rights (when not explicitly overridden) also look OK
assertThat(retrievedChild.isGranted(read, pSid, false)).isTrue();
assertThat(retrievedChild.isGranted(write, pSid, false)).isFalse();
@@ -209,9 +204,9 @@ public class JdbcMutableAclServiceTests {
// Check the child permissions no longer inherit
assertThat(nonInheritingChild.isGranted(delete, pSid, true)).isFalse();
assertThatExceptionOfType(NotFoundException.class)
.isThrownBy(() -> nonInheritingChild.isGranted(read, pSid, true));
.isThrownBy(() -> nonInheritingChild.isGranted(read, pSid, true));
assertThatExceptionOfType(NotFoundException.class)
.isThrownBy(() -> nonInheritingChild.isGranted(write, pSid, true));
.isThrownBy(() -> nonInheritingChild.isGranted(write, pSid, true));
// Let's add an identical permission to the child, but it'll appear AFTER the
// current permission, so has no impact
nonInheritingChild.insertAce(1, BasePermission.DELETE, new PrincipalSid(this.auth), true);
@@ -266,9 +261,9 @@ public class JdbcMutableAclServiceTests {
// Delete the mid-parent and test if the child was deleted, as well
this.jdbcMutableAclService.deleteAcl(getMiddleParentOid(), true);
assertThatExceptionOfType(NotFoundException.class)
.isThrownBy(() -> this.jdbcMutableAclService.readAclById(getMiddleParentOid()));
.isThrownBy(() -> this.jdbcMutableAclService.readAclById(getMiddleParentOid()));
assertThatExceptionOfType(NotFoundException.class)
.isThrownBy(() -> this.jdbcMutableAclService.readAclById(getChildOid()));
.isThrownBy(() -> this.jdbcMutableAclService.readAclById(getChildOid()));
Acl acl = this.jdbcMutableAclService.readAclById(getTopParentOid());
assertThat(acl).isNotNull();
assertThat(getTopParentOid()).isEqualTo(acl.getObjectIdentity());
@@ -277,11 +272,11 @@ public class JdbcMutableAclServiceTests {
@Test
public void constructorRejectsNullParameters() {
assertThatIllegalArgumentException()
.isThrownBy(() -> new JdbcMutableAclService(null, this.lookupStrategy, this.aclCache));
.isThrownBy(() -> new JdbcMutableAclService(null, this.lookupStrategy, this.aclCache));
assertThatIllegalArgumentException()
.isThrownBy(() -> new JdbcMutableAclService(this.dataSource, null, this.aclCache));
.isThrownBy(() -> new JdbcMutableAclService(this.dataSource, null, this.aclCache));
assertThatIllegalArgumentException()
.isThrownBy(() -> new JdbcMutableAclService(this.dataSource, this.lookupStrategy, null));
.isThrownBy(() -> new JdbcMutableAclService(this.dataSource, this.lookupStrategy, null));
}
@Test
@@ -297,7 +292,7 @@ public class JdbcMutableAclServiceTests {
this.jdbcMutableAclService.createAcl(duplicateOid);
// Try to add the same object second time
assertThatExceptionOfType(AlreadyExistsException.class)
.isThrownBy(() -> this.jdbcMutableAclService.createAcl(duplicateOid));
.isThrownBy(() -> this.jdbcMutableAclService.createAcl(duplicateOid));
}
@Test
@@ -320,7 +315,7 @@ public class JdbcMutableAclServiceTests {
try {
// checking in the class, not database
assertThatExceptionOfType(ChildrenExistException.class)
.isThrownBy(() -> this.jdbcMutableAclService.deleteAcl(getTopParentOid(), false));
.isThrownBy(() -> this.jdbcMutableAclService.deleteAcl(getTopParentOid(), false));
}
finally {
// restore to the default
@@ -355,19 +350,6 @@ public class JdbcMutableAclServiceTests {
assertThat(this.jdbcMutableAclService.readAclById(new ObjectIdentityImpl(TARGET_CLASS, 101L))).isNotNull();
}
@Test
@Transactional
public void createAclWhenCustomSecurityContextHolderStrategyThenUses() {
SecurityContextHolderStrategy securityContextHolderStrategy = mock(SecurityContextHolderStrategy.class);
SecurityContext context = new SecurityContextImpl(this.auth);
given(securityContextHolderStrategy.getContext()).willReturn(context);
JdbcMutableAclService service = new JdbcMutableAclService(this.dataSource, this.lookupStrategy, this.aclCache);
service.setSecurityContextHolderStrategy(securityContextHolderStrategy);
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, 101);
service.createAcl(oid);
verify(securityContextHolderStrategy).getContext();
}
/**
* SEC-655
*/
@@ -392,7 +374,7 @@ public class JdbcMutableAclServiceTests {
child = (MutableAcl) this.jdbcMutableAclService.readAclById(childOid);
parent = (MutableAcl) child.getParentAcl();
assertThat(parent.getEntries()).hasSize(2)
.withFailMessage("Fails because child has a stale reference to its parent");
.withFailMessage("Fails because child has a stale reference to its parent");
assertThat(parent.getEntries().get(0).getPermission().getMask()).isEqualTo(1);
assertThat(parent.getEntries().get(0).getSid()).isEqualTo(new PrincipalSid("ben"));
assertThat(parent.getEntries().get(1).getPermission().getMask()).isEqualTo(1);
@@ -79,7 +79,7 @@ public class JdbcMutableAclServiceTestsWithAclClassId extends JdbcMutableAclServ
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID, id);
getJdbcMutableAclService().createAcl(oid);
assertThat(getJdbcMutableAclService().readAclById(new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID, id)))
.isNotNull();
.isNotNull();
}
}
@@ -46,9 +46,9 @@ public class SidTests {
// Check one Authentication-argument constructor
assertThatIllegalArgumentException().isThrownBy(() -> new PrincipalSid((Authentication) null));
assertThatIllegalArgumentException()
.isThrownBy(() -> new PrincipalSid(new TestingAuthenticationToken(null, "password")));
.isThrownBy(() -> new PrincipalSid(new TestingAuthenticationToken(null, "password")));
assertThatNoException()
.isThrownBy(() -> new PrincipalSid(new TestingAuthenticationToken("johndoe", "password")));
.isThrownBy(() -> new PrincipalSid(new TestingAuthenticationToken("johndoe", "password")));
}
@Test
@@ -60,7 +60,7 @@ public class SidTests {
// Check one GrantedAuthority-argument constructor
assertThatIllegalArgumentException().isThrownBy(() -> new GrantedAuthoritySid((GrantedAuthority) null));
assertThatIllegalArgumentException()
.isThrownBy(() -> new GrantedAuthoritySid(new SimpleGrantedAuthority(null)));
.isThrownBy(() -> new GrantedAuthoritySid(new SimpleGrantedAuthority(null)));
assertThatNoException().isThrownBy(() -> new GrantedAuthoritySid(new SimpleGrantedAuthority("ROLE_TEST")));
}
@@ -100,7 +100,7 @@ public class SidTests {
assertThat(principalSid.hashCode()).isEqualTo(new PrincipalSid("johndoe").hashCode());
assertThat(principalSid.hashCode()).isNotEqualTo(new PrincipalSid("scott").hashCode());
assertThat(principalSid.hashCode())
.isNotEqualTo(new PrincipalSid(new TestingAuthenticationToken("scott", "password")).hashCode());
.isNotEqualTo(new PrincipalSid(new TestingAuthenticationToken("scott", "password")).hashCode());
}
@Test
@@ -111,7 +111,7 @@ public class SidTests {
assertThat(gaSid.hashCode()).isEqualTo(new GrantedAuthoritySid("ROLE_TEST").hashCode());
assertThat(gaSid.hashCode()).isNotEqualTo(new GrantedAuthoritySid("ROLE_TEST_2").hashCode());
assertThat(gaSid.hashCode())
.isNotEqualTo(new GrantedAuthoritySid(new SimpleGrantedAuthority("ROLE_TEST_2")).hashCode());
.isNotEqualTo(new GrantedAuthoritySid(new SimpleGrantedAuthority("ROLE_TEST_2")).hashCode());
}
@Test
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-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.
@@ -37,9 +37,7 @@ import org.springframework.security.access.prepost.PreFilter;
* @author Mike Wiesner
* @author Luke Taylor
* @since 3.1
* @deprecated Use aspects in {@link org.springframework.security.authorization.method.aspectj} instead
*/
@Deprecated
public aspect AnnotationSecurityAspect implements InitializingBean {
/**
@@ -1,61 +0,0 @@
/*
* Copyright 2002-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.security.authorization.method.aspectj;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.access.prepost.PostAuthorize;
/**
* Abstract AspectJ aspect for adapting a {@link MethodInvocation}
*
* @author Josh Cummings
* @since 5.8
*/
abstract aspect AbstractMethodInterceptorAspect {
protected abstract pointcut executionOfAnnotatedMethod();
private MethodInterceptor securityInterceptor;
Object around(): executionOfAnnotatedMethod() {
if (this.securityInterceptor == null) {
return proceed();
}
MethodInvocation invocation = new JoinPointMethodInvocation(thisJoinPoint, () -> proceed());
try {
return this.securityInterceptor.invoke(invocation);
} catch (Throwable t) {
throwUnchecked(t);
throw new IllegalStateException("Code unexpectedly reached", t);
}
}
public void setSecurityInterceptor(MethodInterceptor securityInterceptor) {
this.securityInterceptor = securityInterceptor;
}
private static void throwUnchecked(Throwable ex) {
AbstractMethodInterceptorAspect.<RuntimeException>throwAny(ex);
}
@SuppressWarnings("unchecked")
private static <E extends Throwable> void throwAny(Throwable ex) throws E {
throw (E) ex;
}
}
@@ -1,98 +0,0 @@
/*
* Copyright 2002-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.security.authorization.method.aspectj;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import java.util.function.Supplier;
import org.aopalliance.intercept.MethodInvocation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.CodeSignature;
import org.springframework.util.Assert;
class JoinPointMethodInvocation implements MethodInvocation {
private final JoinPoint jp;
private final Method method;
private final Object target;
private final Supplier<Object> proceed;
JoinPointMethodInvocation(JoinPoint jp, Supplier<Object> proceed) {
this.jp = jp;
if (jp.getTarget() != null) {
this.target = jp.getTarget();
}
else {
// SEC-1295: target may be null if an ITD is in use
this.target = jp.getSignature().getDeclaringType();
}
String targetMethodName = jp.getStaticPart().getSignature().getName();
Class<?>[] types = ((CodeSignature) jp.getStaticPart().getSignature()).getParameterTypes();
Class<?> declaringType = jp.getStaticPart().getSignature().getDeclaringType();
this.method = findMethod(targetMethodName, declaringType, types);
Assert.notNull(this.method, () -> "Could not obtain target method from JoinPoint: '" + jp + "'");
this.proceed = proceed;
}
private Method findMethod(String name, Class<?> declaringType, Class<?>[] params) {
Method method = null;
try {
method = declaringType.getMethod(name, params);
}
catch (NoSuchMethodException ignored) {
}
if (method == null) {
try {
method = declaringType.getDeclaredMethod(name, params);
}
catch (NoSuchMethodException ignored) {
}
}
return method;
}
@Override
public Method getMethod() {
return this.method;
}
@Override
public Object[] getArguments() {
return this.jp.getArgs();
}
@Override
public AccessibleObject getStaticPart() {
return this.method;
}
@Override
public Object getThis() {
return this.target;
}
@Override
public Object proceed() throws Throwable {
return this.proceed.get();
}
}
@@ -1,44 +0,0 @@
/*
* Copyright 2002-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.security.authorization.method.aspectj;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.access.prepost.PostAuthorize;
/**
* Concrete AspectJ aspect using Spring Security @PostAuthorize annotation.
*
* <p>
* When using this aspect, you <i>must</i> annotate the implementation class
* (and/or methods within that class), <i>not</i> the interface (if any) that
* the class implements. AspectJ follows Java's rule that annotations on
* interfaces are <i>not</i> inherited. This will vary from Spring AOP.
*
* @author Mike Wiesner
* @author Luke Taylor
* @author Josh Cummings
* @since 5.8
*/
public aspect PostAuthorizeAspect extends AbstractMethodInterceptorAspect {
/**
* Matches the execution of any method with a PostAuthorize annotation.
*/
protected pointcut executionOfAnnotatedMethod() : execution(* *(..)) && @annotation(PostAuthorize);
}
@@ -1,45 +0,0 @@
/*
* Copyright 2002-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.security.authorization.method.aspectj;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.access.prepost.PostFilter;
/**
* Concrete AspectJ aspect using Spring Security @PostFilter annotation.
*
* <p>
* When using this aspect, you <i>must</i> annotate the implementation class
* (and/or methods within that class), <i>not</i> the interface (if any) that
* the class implements. AspectJ follows Java's rule that annotations on
* interfaces are <i>not</i> inherited. This will vary from Spring AOP.
*
* @author Mike Wiesner
* @author Luke Taylor
* @author Josh Cummings
* @since 5.8
*/
public aspect PostFilterAspect extends AbstractMethodInterceptorAspect {
/**
* Matches the execution of any method with a PostFilter annotation.
*/
protected pointcut executionOfAnnotatedMethod() : execution(* *(..)) && @annotation(PostFilter);
}
@@ -1,44 +0,0 @@
/*
* Copyright 2002-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.security.authorization.method.aspectj;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.access.prepost.PreAuthorize;
/**
* Concrete AspectJ aspect using Spring Security @PreAuthorize annotation.
*
* <p>
* When using this aspect, you <i>must</i> annotate the implementation class
* (and/or methods within that class), <i>not</i> the interface (if any) that
* the class implements. AspectJ follows Java's rule that annotations on
* interfaces are <i>not</i> inherited. This will vary from Spring AOP.
*
* @author Mike Wiesner
* @author Luke Taylor
* @author Josh Cummings
* @since 5.8
*/
public aspect PreAuthorizeAspect extends AbstractMethodInterceptorAspect {
/**
* Matches the execution of any method with a PreAuthorize annotation.
*/
protected pointcut executionOfAnnotatedMethod() : execution(* *(..)) && @annotation(PreAuthorize);
}
@@ -1,45 +0,0 @@
/*
* Copyright 2002-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.security.authorization.method.aspectj;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.access.prepost.PreFilter;
/**
* Concrete AspectJ aspect using Spring Security @PreFilter annotation.
*
* <p>
* When using this aspect, you <i>must</i> annotate the implementation class
* (and/or methods within that class), <i>not</i> the interface (if any) that
* the class implements. AspectJ follows Java's rule that annotations on
* interfaces are <i>not</i> inherited. This will vary from Spring AOP.
*
* @author Mike Wiesner
* @author Luke Taylor
* @author Josh Cummings
* @since 5.8
*/
public aspect PreFilterAspect extends AbstractMethodInterceptorAspect {
/**
* Matches the execution of any method with a PreFilter annotation.
*/
protected pointcut executionOfAnnotatedMethod() : execution(* *(..)) && @annotation(PreFilter);
}
@@ -1,56 +0,0 @@
/*
* Copyright 2002-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.security.authorization.method.aspectj;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.access.annotation.Secured;
/**
* Concrete AspectJ aspect using Spring Security @Secured annotation.
*
* <p>
* When using this aspect, you <i>must</i> annotate the implementation class
* (and/or methods within that class), <i>not</i> the interface (if any) that
* the class implements. AspectJ follows Java's rule that annotations on
* interfaces are <i>not</i> inherited. This will vary from Spring AOP.
*
* @author Mike Wiesner
* @author Luke Taylor
* @author Josh Cummings
* @since 5.8
*/
public aspect SecuredAspect extends AbstractMethodInterceptorAspect {
/**
* Matches the execution of any public method in a type with the Secured
* annotation, or any subtype of a type with the Secured annotation.
*/
private pointcut executionOfAnyPublicMethodInAtSecuredType() :
execution(public * ((@Secured *)+).*(..)) && @this(Secured);
/**
* Matches the execution of any method with the Secured annotation.
*/
private pointcut executionOfSecuredMethod() :
execution(* *(..)) && @annotation(Secured);
protected pointcut executionOfAnnotatedMethod() :
executionOfAnyPublicMethodInAtSecuredType() ||
executionOfSecuredMethod();
}
@@ -101,7 +101,7 @@ public class AnnotationSecurityAspectTests {
@Test
public void securedClassMethodDeniesUnauthenticatedAccess() {
assertThatExceptionOfType(AuthenticationCredentialsNotFoundException.class)
.isThrownBy(() -> this.secured.securedClassMethod());
.isThrownBy(() -> this.secured.securedClassMethod());
}
@Test
@@ -1,160 +0,0 @@
/*
* Copyright 2002-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.security.authorization.method.aspectj;
import org.aopalliance.intercept.MethodInterceptor;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.authorization.method.AuthorizationManagerAfterMethodInterceptor;
import org.springframework.security.core.context.SecurityContextHolder;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Luke Taylor
* @since 3.0.3
*/
public class PostAuthorizeAspectTests {
private TestingAuthenticationToken anne = new TestingAuthenticationToken("anne", "", "ROLE_A");
private MethodInterceptor interceptor;
private SecuredImpl secured = new SecuredImpl();
private SecuredImplSubclass securedSub = new SecuredImplSubclass();
private PrePostSecured prePostSecured = new PrePostSecured();
@BeforeEach
public final void setUp() {
MockitoAnnotations.initMocks(this);
this.interceptor = AuthorizationManagerAfterMethodInterceptor.postAuthorize();
PostAuthorizeAspect secAspect = PostAuthorizeAspect.aspectOf();
secAspect.setSecurityInterceptor(this.interceptor);
}
@AfterEach
public void clearContext() {
SecurityContextHolder.clearContext();
}
@Test
public void securedInterfaceMethodAllowsAllAccess() {
this.secured.securedMethod();
}
@Test
public void securedClassMethodDeniesUnauthenticatedAccess() {
assertThatExceptionOfType(AuthenticationCredentialsNotFoundException.class)
.isThrownBy(() -> this.secured.securedClassMethod());
}
@Test
public void securedClassMethodAllowsAccessToRoleA() {
SecurityContextHolder.getContext().setAuthentication(this.anne);
this.secured.securedClassMethod();
}
@Test
public void internalPrivateCallIsIntercepted() {
SecurityContextHolder.getContext().setAuthentication(this.anne);
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(() -> this.secured.publicCallsPrivate());
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(() -> this.securedSub.publicCallsPrivate());
}
@Test
public void protectedMethodIsIntercepted() {
SecurityContextHolder.getContext().setAuthentication(this.anne);
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(() -> this.secured.protectedMethod());
}
@Test
public void overriddenProtectedMethodIsNotIntercepted() {
// AspectJ doesn't inherit annotations
this.securedSub.protectedMethod();
}
// SEC-1262
@Test
public void denyAllPreAuthorizeDeniesAccess() {
SecurityContextHolder.getContext().setAuthentication(this.anne);
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.prePostSecured::denyAllMethod);
}
interface SecuredInterface {
@PostAuthorize("hasRole('X')")
void securedMethod();
}
static class SecuredImpl implements SecuredInterface {
// Not really secured because AspectJ doesn't inherit annotations from interfaces
@Override
public void securedMethod() {
}
@PostAuthorize("hasRole('A')")
void securedClassMethod() {
}
@PostAuthorize("hasRole('X')")
private void privateMethod() {
}
@PostAuthorize("hasRole('X')")
protected void protectedMethod() {
}
@PostAuthorize("hasRole('X')")
void publicCallsPrivate() {
privateMethod();
}
}
static class SecuredImplSubclass extends SecuredImpl {
@Override
protected void protectedMethod() {
}
@Override
public void publicCallsPrivate() {
super.publicCallsPrivate();
}
}
static class PrePostSecured {
@PostAuthorize("denyAll")
void denyAllMethod() {
}
}
}
@@ -1,66 +0,0 @@
/*
* Copyright 2002-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.security.authorization.method.aspectj;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.aopalliance.intercept.MethodInterceptor;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.authorization.method.PostFilterAuthorizationMethodInterceptor;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Luke Taylor
* @since 3.0.3
*/
public class PostFilterAspectTests {
private MethodInterceptor interceptor;
private PrePostSecured prePostSecured = new PrePostSecured();
@BeforeEach
public final void setUp() {
MockitoAnnotations.initMocks(this);
this.interceptor = new PostFilterAuthorizationMethodInterceptor();
PostFilterAspect secAspect = PostFilterAspect.aspectOf();
secAspect.setSecurityInterceptor(this.interceptor);
}
@Test
public void preFilterMethodWhenListThenFilters() {
List<String> objects = new ArrayList<>(Arrays.asList("apple", "banana", "aubergine", "orange"));
assertThat(this.prePostSecured.postFilterMethod(objects)).containsExactly("apple", "aubergine");
}
static class PrePostSecured {
@PostFilter("filterObject.startsWith('a')")
List<String> postFilterMethod(List<String> objects) {
return objects;
}
}
}
@@ -1,160 +0,0 @@
/*
* Copyright 2002-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.security.authorization.method.aspectj;
import org.aopalliance.intercept.MethodInterceptor;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
import org.springframework.security.core.context.SecurityContextHolder;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Luke Taylor
* @since 3.0.3
*/
public class PreAuthorizeAspectTests {
private TestingAuthenticationToken anne = new TestingAuthenticationToken("anne", "", "ROLE_A");
private MethodInterceptor interceptor;
private SecuredImpl secured = new SecuredImpl();
private SecuredImplSubclass securedSub = new SecuredImplSubclass();
private PrePostSecured prePostSecured = new PrePostSecured();
@BeforeEach
public final void setUp() {
MockitoAnnotations.initMocks(this);
this.interceptor = AuthorizationManagerBeforeMethodInterceptor.preAuthorize();
PreAuthorizeAspect secAspect = PreAuthorizeAspect.aspectOf();
secAspect.setSecurityInterceptor(this.interceptor);
}
@AfterEach
public void clearContext() {
SecurityContextHolder.clearContext();
}
@Test
public void securedInterfaceMethodAllowsAllAccess() {
this.secured.securedMethod();
}
@Test
public void securedClassMethodDeniesUnauthenticatedAccess() {
assertThatExceptionOfType(AuthenticationCredentialsNotFoundException.class)
.isThrownBy(() -> this.secured.securedClassMethod());
}
@Test
public void securedClassMethodAllowsAccessToRoleA() {
SecurityContextHolder.getContext().setAuthentication(this.anne);
this.secured.securedClassMethod();
}
@Test
public void internalPrivateCallIsIntercepted() {
SecurityContextHolder.getContext().setAuthentication(this.anne);
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(() -> this.secured.publicCallsPrivate());
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(() -> this.securedSub.publicCallsPrivate());
}
@Test
public void protectedMethodIsIntercepted() {
SecurityContextHolder.getContext().setAuthentication(this.anne);
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(() -> this.secured.protectedMethod());
}
@Test
public void overriddenProtectedMethodIsNotIntercepted() {
// AspectJ doesn't inherit annotations
this.securedSub.protectedMethod();
}
// SEC-1262
@Test
public void denyAllPreAuthorizeDeniesAccess() {
SecurityContextHolder.getContext().setAuthentication(this.anne);
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.prePostSecured::denyAllMethod);
}
interface SecuredInterface {
@PreAuthorize("hasRole('X')")
void securedMethod();
}
static class SecuredImpl implements SecuredInterface {
// Not really secured because AspectJ doesn't inherit annotations from interfaces
@Override
public void securedMethod() {
}
@PreAuthorize("hasRole('A')")
void securedClassMethod() {
}
@PreAuthorize("hasRole('X')")
private void privateMethod() {
}
@PreAuthorize("hasRole('X')")
protected void protectedMethod() {
}
@PreAuthorize("hasRole('X')")
void publicCallsPrivate() {
privateMethod();
}
}
static class SecuredImplSubclass extends SecuredImpl {
@Override
protected void protectedMethod() {
}
@Override
public void publicCallsPrivate() {
super.publicCallsPrivate();
}
}
static class PrePostSecured {
@PreAuthorize("denyAll")
void denyAllMethod() {
}
}
}
@@ -1,66 +0,0 @@
/*
* Copyright 2002-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.security.authorization.method.aspectj;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.aopalliance.intercept.MethodInterceptor;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.security.access.prepost.PreFilter;
import org.springframework.security.authorization.method.PreFilterAuthorizationMethodInterceptor;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Luke Taylor
* @since 3.0.3
*/
public class PreFilterAspectTests {
private MethodInterceptor interceptor;
private PrePostSecured prePostSecured = new PrePostSecured();
@BeforeEach
public final void setUp() {
MockitoAnnotations.initMocks(this);
this.interceptor = new PreFilterAuthorizationMethodInterceptor();
PreFilterAspect secAspect = PreFilterAspect.aspectOf();
secAspect.setSecurityInterceptor(this.interceptor);
}
@Test
public void preFilterMethodWhenListThenFilters() {
List<String> objects = new ArrayList<>(Arrays.asList("apple", "banana", "aubergine", "orange"));
assertThat(this.prePostSecured.preFilterMethod(objects)).containsExactly("apple", "aubergine");
}
static class PrePostSecured {
@PreFilter("filterObject.startsWith('a')")
List<String> preFilterMethod(List<String> objects) {
return objects;
}
}
}
@@ -1,143 +0,0 @@
/*
* Copyright 2002-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.security.authorization.method.aspectj;
import org.aopalliance.intercept.MethodInterceptor;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
import org.springframework.security.core.context.SecurityContextHolder;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Luke Taylor
* @since 3.0.3
*/
public class SecuredAspectTests {
private TestingAuthenticationToken anne = new TestingAuthenticationToken("anne", "", "ROLE_A");
private MethodInterceptor interceptor;
private SecuredImpl secured = new SecuredImpl();
private SecuredImplSubclass securedSub = new SecuredImplSubclass();
@BeforeEach
public final void setUp() {
MockitoAnnotations.initMocks(this);
this.interceptor = AuthorizationManagerBeforeMethodInterceptor.secured();
SecuredAspect secAspect = SecuredAspect.aspectOf();
secAspect.setSecurityInterceptor(this.interceptor);
}
@AfterEach
public void clearContext() {
SecurityContextHolder.clearContext();
}
@Test
public void securedInterfaceMethodAllowsAllAccess() {
this.secured.securedMethod();
}
@Test
public void securedClassMethodDeniesUnauthenticatedAccess() {
assertThatExceptionOfType(AuthenticationCredentialsNotFoundException.class)
.isThrownBy(() -> this.secured.securedClassMethod());
}
@Test
public void securedClassMethodAllowsAccessToRoleA() {
SecurityContextHolder.getContext().setAuthentication(this.anne);
this.secured.securedClassMethod();
}
@Test
public void internalPrivateCallIsIntercepted() {
SecurityContextHolder.getContext().setAuthentication(this.anne);
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(() -> this.secured.publicCallsPrivate());
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(() -> this.securedSub.publicCallsPrivate());
}
@Test
public void protectedMethodIsIntercepted() {
SecurityContextHolder.getContext().setAuthentication(this.anne);
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(() -> this.secured.protectedMethod());
}
@Test
public void overriddenProtectedMethodIsNotIntercepted() {
// AspectJ doesn't inherit annotations
this.securedSub.protectedMethod();
}
interface SecuredInterface {
@Secured("ROLE_X")
void securedMethod();
}
static class SecuredImpl implements SecuredInterface {
// Not really secured because AspectJ doesn't inherit annotations from interfaces
@Override
public void securedMethod() {
}
@Secured("ROLE_A")
void securedClassMethod() {
}
@Secured("ROLE_X")
private void privateMethod() {
}
@Secured("ROLE_X")
protected void protectedMethod() {
}
@Secured("ROLE_X")
void publicCallsPrivate() {
privateMethod();
}
}
static class SecuredImplSubclass extends SecuredImpl {
@Override
protected void protectedMethod() {
}
@Override
public void publicCallsPrivate() {
super.publicCallsPrivate();
}
}
}
+77 -20
View File
@@ -1,13 +1,12 @@
import io.spring.gradle.IncludeRepoTask
import trang.RncToXsd
buildscript {
dependencies {
classpath libs.io.spring.javaformat.spring.javaformat.gradle.plugin
classpath libs.io.spring.nohttp.nohttp.gradle
classpath libs.io.freefair.gradle.aspectj.plugin
classpath libs.org.jetbrains.kotlin.kotlin.gradle.plugin
classpath libs.com.netflix.nebula.nebula.project.plugin
classpath "io.spring.javaformat:spring-javaformat-gradle-plugin:$springJavaformatVersion"
classpath 'io.spring.nohttp:nohttp-gradle:0.0.11'
classpath "io.freefair.gradle:aspectj-plugin:6.4.3.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath "com.netflix.nebula:nebula-project-plugin:8.2.0"
}
repositories {
gradlePluginPortal()
@@ -19,13 +18,12 @@ apply plugin: 'locks'
apply plugin: 's101'
apply plugin: 'io.spring.convention.root'
apply plugin: 'org.jetbrains.kotlin.jvm'
apply plugin: 'org.springframework.security.update-dependencies'
apply plugin: 'org.springframework.security.update-version'
apply plugin: 'org.springframework.security.sagan'
apply plugin: 'org.springframework.github.milestone'
apply plugin: 'org.springframework.github.changelog'
apply plugin: 'org.springframework.github.release'
apply plugin: 'org.springframework.security.versions.verify-dependencies-versions'
apply plugin: 'org.springframework.security.check-expected-branch-version'
group = 'org.springframework.security'
description = 'Spring Security'
@@ -87,6 +85,71 @@ tasks.named("dispatchGitHubWorkflow") {
}
}
tasks.named("updateDependencies") {
// we aren't Gradle 7 compatible yet
checkForGradleUpdate = false
}
updateDependenciesSettings {
gitHub {
organization = "spring-projects"
repository = "spring-security"
}
addFiles({
return [
project.file("buildSrc/src/main/groovy/io/spring/gradle/convention/CheckstylePlugin.groovy")
]
})
dependencyExcludes {
majorVersionBump()
minorVersionBump()
releaseCandidatesVersions()
milestoneVersions()
alphaBetaVersions()
snapshotVersions()
addRule { components ->
components.withModule("commons-codec:commons-codec") { selection ->
ModuleComponentIdentifier candidate = selection.getCandidate();
if (!candidate.getVersion().equals(selection.getCurrentVersion())) {
selection.reject("commons-codec updates break saml tests");
}
}
components.withModule("org.python:jython") { selection ->
ModuleComponentIdentifier candidate = selection.getCandidate();
if (!candidate.getVersion().equals(selection.getCurrentVersion())) {
selection.reject("jython updates break integration tests");
}
}
components.withModule("com.nimbusds:nimbus-jose-jwt") { selection ->
ModuleComponentIdentifier candidate = selection.getCandidate();
if (!candidate.getVersion().equals(selection.getCurrentVersion())) {
selection.reject("nimbus-jose-jwt gets updated when oauth2-oidc-sdk is updated to ensure consistency");
}
}
components.all { selection ->
ModuleComponentIdentifier candidate = selection.getCandidate();
// Do not compare version due to multiple versions existing
// will cause opensaml 3.x to be updated to 4.x
if (candidate.getGroup().equals("org.opensaml")) {
selection.reject("org.opensaml maintains two different versions, so it must be updated manually");
}
}
components.withModule("io.spring.javaformat:spring-javaformat-gradle-plugin") { selection ->
ModuleComponentIdentifier candidate = selection.getCandidate();
if (!candidate.getVersion().equals(selection.getCurrentVersion())) {
selection.reject("spring-javaformat-gradle-plugin updates break checkstyle");
}
}
components.withModule("io.spring.javaformat:spring-javaformat-checkstyle") { selection ->
ModuleComponentIdentifier candidate = selection.getCandidate();
if (!candidate.getVersion().equals(selection.getCurrentVersion())) {
selection.reject("spring-javaformat-checkstyle updates break checkstyle");
}
}
}
}
}
subprojects {
plugins.withType(JavaPlugin) {
project.sourceCompatibility='1.8'
@@ -94,6 +157,7 @@ subprojects {
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
options.compilerArgs.add("-parameters")
options.release = 8
}
}
@@ -106,7 +170,7 @@ allprojects {
pluginManager.withPlugin("io.spring.convention.checkstyle", { plugin ->
configure(plugin) {
dependencies {
checkstyle libs.io.spring.javaformat.spring.javaformat.checkstyle
checkstyle "io.spring.javaformat:spring-javaformat-checkstyle:$springJavaformatVersion"
}
checkstyle {
toolVersion = '8.34'
@@ -122,24 +186,18 @@ allprojects {
}
}
}
tasks.withType(JavaCompile).configureEach {
javaCompiler = javaToolchains.compilerFor {
languageVersion = JavaLanguageVersion.of(8)
}
}
}
develocity {
if (hasProperty('buildScan')) {
buildScan {
termsOfUseUrl = 'https://gradle.com/help/legal-terms-of-use'
termsOfUseAgree = 'yes'
termsOfServiceUrl = 'https://gradle.com/terms-of-service'
termsOfServiceAgree = 'yes'
}
}
nohttp {
source.exclude "buildSrc/build/**"
source.builtBy(project(':spring-security-config').tasks.withType(RncToXsd))
}
tasks.register('cloneSamples', IncludeRepoTask) {
@@ -149,6 +207,5 @@ tasks.register('cloneSamples', IncludeRepoTask) {
}
s101 {
repository = 'https://structure101.com/binaries/latest'
configurationDirectory = project.file("etc/s101")
}
+27 -33
View File
@@ -2,6 +2,7 @@ plugins {
id "java-gradle-plugin"
id "java"
id "groovy"
id 'com.apollographql.apollo' version '2.4.5'
}
sourceCompatibility = 1.8
@@ -40,6 +41,10 @@ gradlePlugin {
id = "io.spring.convention.management-configuration"
implementationClass = "io.spring.gradle.convention.ManagementConfigurationPlugin"
}
updateDependencies {
id = "org.springframework.security.update-dependencies"
implementationClass = "org.springframework.security.convention.versions.UpdateDependenciesPlugin"
}
updateProjectVersion {
id = "org.springframework.security.update-version"
implementationClass = "org.springframework.security.convention.versions.UpdateProjectVersionPlugin"
@@ -64,14 +69,6 @@ gradlePlugin {
id = "s101"
implementationClass = "s101.S101Plugin"
}
verifyDependenciesVersions {
id = "org.springframework.security.versions.verify-dependencies-versions"
implementationClass = "org.springframework.security.convention.versions.VerifyDependenciesVersionsPlugin"
}
checkExpectedBranchVersion {
id = "org.springframework.security.check-expected-branch-version"
implementationClass = "org.springframework.security.CheckExpectedBranchVersionPlugin"
}
}
}
@@ -82,37 +79,34 @@ configurations {
}
dependencies {
implementation platform(libs.io.projectreactor.reactor.bom)
implementation libs.com.google.code.gson.gson
implementation libs.com.thaiopensource.trag
implementation libs.net.sourceforge.saxon.saxon
implementation libs.org.yaml.snakeyaml
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.thaiopensource:trang:20091111'
implementation 'net.sourceforge.saxon:saxon:9.1.0.8'
implementation 'org.yaml:snakeyaml:1.30'
implementation localGroovy()
implementation libs.io.github.gradle.nexus.publish.plugin
implementation 'io.projectreactor:reactor-core'
implementation libs.org.gretty.gretty
implementation libs.com.github.ben.manes.gradle.versions.plugin
implementation libs.com.github.spullara.mustache.java.compiler
implementation libs.io.spring.javaformat.spring.javaformat.gradle.plugin
implementation libs.io.spring.nohttp.nohttp.gradle
implementation libs.net.sourceforge.htmlunit
implementation libs.org.hidetake.gradle.ssh.plugin
implementation libs.org.jfrog.buildinfo.build.info.extractor.gradle
implementation libs.org.sonarsource.scanner.gradle.sonarqube.gradle.plugin
implementation libs.com.squareup.okhttp3.okhttp
implementation 'io.github.gradle-nexus:publish-plugin:1.1.0'
implementation 'io.projectreactor:reactor-core:3.5.0'
implementation 'org.gretty:gretty:3.0.9'
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.4'
implementation 'io.spring.javaformat:spring-javaformat-gradle-plugin:0.0.15'
implementation 'io.spring.nohttp:nohttp-gradle:0.0.11'
implementation 'net.sourceforge.htmlunit:htmlunit:2.37.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'
testImplementation platform(libs.org.junit.junit.bom)
testImplementation platform(libs.org.mockito.mockito.bom)
testImplementation platform('org.junit:junit-bom:5.8.2')
testImplementation "org.junit.jupiter:junit-jupiter-api"
testImplementation "org.junit.jupiter:junit-jupiter-params"
testImplementation "org.junit.jupiter:junit-jupiter-engine"
testImplementation libs.org.apache.commons.commons.io
testImplementation libs.org.assertj.assertj.core
testImplementation 'org.mockito:mockito-core'
testImplementation 'org.mockito:mockito-junit-jupiter'
testImplementation libs.com.squareup.okhttp3.mockwebserver
testImplementation 'org.apache.commons:commons-io:1.3.2'
testImplementation 'org.assertj:assertj-core:3.13.2'
testImplementation 'org.mockito:mockito-core:3.12.4'
testImplementation 'org.mockito:mockito-junit-jupiter:3.12.4'
testImplementation "com.squareup.okhttp3:mockwebserver:3.14.9"
}
-7
View File
@@ -1,7 +0,0 @@
dependencyResolutionManagement {
versionCatalogs {
libs {
from(files("../gradle/libs.versions.toml"))
}
}
}
@@ -34,14 +34,6 @@ class RepositoryConventionPlugin implements Plugin<Project> {
if (forceMavenRepositories?.contains('local')) {
mavenLocal()
}
maven {
name = 'shibboleth'
url = 'https://build.shibboleth.net/nexus/content/repositories/releases/'
content {
includeGroupByRegex('org\\.opensaml.*')
includeGroupByRegex('net\\.shibboleth.*')
}
}
mavenCentral()
if (isSnapshot) {
maven {
@@ -75,11 +67,12 @@ class RepositoryConventionPlugin implements Plugin<Project> {
password project.artifactoryPassword
}
}
content {
excludeGroup('net.minidev')
}
url = 'https://repo.spring.io/release/'
}
maven {
name = 'shibboleth'
url = 'https://build.shibboleth.net/nexus/content/repositories/releases/'
}
}
}
@@ -19,13 +19,13 @@ package org.springframework.gradle.sagan;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.Assert;
import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.TaskAction;
import org.springframework.gradle.github.user.GitHubUserApi;
import org.springframework.gradle.github.user.User;
import org.springframework.util.Assert;
public class SaganCreateReleaseTask extends DefaultTask {
@@ -1,85 +0,0 @@
/*
* Copyright 2002-2024 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.security;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.gradle.api.DefaultTask;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.plugins.JavaBasePlugin;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.TaskProvider;
/**
* @author Marcus da Coregio
*/
public class CheckExpectedBranchVersionPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
TaskProvider<CheckExpectedBranchVersionTask> checkExpectedBranchVersionTask = project.getTasks().register("checkExpectedBranchVersion", CheckExpectedBranchVersionTask.class, (task) -> {
task.setGroup("Build");
task.setDescription("Check if the project version matches the branch version");
});
project.getTasks().named(JavaBasePlugin.CHECK_TASK_NAME, checkTask -> checkTask.dependsOn(checkExpectedBranchVersionTask));
}
public static class CheckExpectedBranchVersionTask extends DefaultTask {
@TaskAction
public void run() throws IOException {
Project project = getProject();
if (project.hasProperty("skipCheckExpectedBranchVersion")) {
return;
}
String version = (String) project.getVersion();
String branchVersion = getBranchVersion(project);
if (!branchVersion.matches("^[0-9]+\\.[0-9]+\\.x$")) {
System.out.println("Branch version does not match *.x, ignoring");
return;
}
if (!versionsMatch(version, branchVersion)) {
throw new IllegalStateException(String.format("Project version [%s] does not match branch version [%s]. " +
"Please verify that the branch contains the right version.", version, branchVersion));
}
}
private static String getBranchVersion(Project project) throws IOException {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
project.exec((exec) -> {
exec.commandLine("git", "symbolic-ref", "--short", "HEAD");
exec.setErrorOutput(System.err);
exec.setStandardOutput(baos);
});
return baos.toString();
}
}
private boolean versionsMatch(String projectVersion, String branchVersion) {
String[] projectVersionParts = projectVersion.split("\\.");
String[] branchVersionParts = branchVersion.split("\\.");
if (projectVersionParts.length < 2 || branchVersionParts.length < 2) {
return false;
}
return projectVersionParts[0].equals(branchVersionParts[0]) && projectVersionParts[1].equals(branchVersionParts[1]);
}
}
}
@@ -0,0 +1,49 @@
/*
* 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.security.convention.versions;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Scanner;
class CommandLineUtils {
static void runCommand(File dir, String... args) {
try {
Process process = new ProcessBuilder()
.directory(dir)
.command(args)
.start();
writeLinesTo(process.getInputStream(), System.out);
writeLinesTo(process.getErrorStream(), System.out);
if (process.waitFor() != 0) {
new RuntimeException("Failed to run " + Arrays.toString(args));
}
} catch (IOException | InterruptedException e) {
throw new RuntimeException("Failed to run " + Arrays.toString(args), e);
}
}
private static void writeLinesTo(InputStream input, PrintStream out) {
Scanner scanner = new Scanner(input);
while(scanner.hasNextLine()) {
out.println(scanner.nextLine());
}
}
}
@@ -0,0 +1,179 @@
package org.springframework.security.convention.versions;
import com.apollographql.apollo.ApolloCall;
import com.apollographql.apollo.ApolloClient;
import com.apollographql.apollo.api.Input;
import com.apollographql.apollo.api.Response;
import com.apollographql.apollo.exception.ApolloException;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import org.jetbrains.annotations.NotNull;
import reactor.core.publisher.Mono;
import reactor.util.retry.Retry;
import reactor.util.retry.RetrySpec;
import java.io.IOException;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class GitHubApi {
private final ApolloClient apolloClient;
public GitHubApi(String githubToken) {
if (githubToken == null) {
throw new IllegalArgumentException("githubToken is required. You can set it using -PgitHubAccessToken=");
}
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
clientBuilder.addInterceptor(new AuthorizationInterceptor(githubToken));
this.apolloClient = ApolloClient.builder()
.serverUrl("https://api.github.com/graphql")
.okHttpClient(clientBuilder.build())
.build();
}
public Mono<FindCreateIssueResult> findCreateIssueInput(String owner, String name, String milestone) {
String label = "\"type: dependency-upgrade\"";
FindCreateIssueInputQuery findCreateIssueInputQuery = new FindCreateIssueInputQuery(owner, name, Input.optional(label), Input.optional(milestone));
return Mono.create( sink -> this.apolloClient.query(findCreateIssueInputQuery)
.enqueue(new ApolloCall.Callback<FindCreateIssueInputQuery.Data>() {
@Override
public void onResponse(@NotNull Response<FindCreateIssueInputQuery.Data> response) {
if (response.hasErrors()) {
sink.error(new RuntimeException(response.getErrors().stream().map(e -> e.getMessage()).collect(Collectors.joining(" "))));
} else {
FindCreateIssueInputQuery.Data data = response.getData();
FindCreateIssueInputQuery.Repository repository = data.repository();
List<String> labels = repository.labels().nodes().stream().map(FindCreateIssueInputQuery.Node::id).collect(Collectors.toList());
if (labels.isEmpty()) {
sink.error(new IllegalArgumentException("Could not find label for " + label));
return;
}
Optional<String> firstMilestoneId = repository.milestones().nodes().stream().map(FindCreateIssueInputQuery.Node1::id).findFirst();
if (!firstMilestoneId.isPresent()) {
sink.error(new IllegalArgumentException("Could not find OPEN milestone id for " + milestone));
return;
}
String milestoneId = firstMilestoneId.get();
String repositoryId = repository.id();
String assigneeId = data.viewer().id();
sink.success(new FindCreateIssueResult(repositoryId, labels, milestoneId, assigneeId));
}
}
@Override
public void onFailure(@NotNull ApolloException e) {
sink.error(e);
}
}));
}
public static class FindCreateIssueResult {
private final String repositoryId;
private final List<String> labelIds;
private final String milestoneId;
private final String assigneeId;
public FindCreateIssueResult(String repositoryId, List<String> labelIds, String milestoneId, String assigneeId) {
this.repositoryId = repositoryId;
this.labelIds = labelIds;
this.milestoneId = milestoneId;
this.assigneeId = assigneeId;
}
public String getRepositoryId() {
return repositoryId;
}
public List<String> getLabelIds() {
return labelIds;
}
public String getMilestoneId() {
return milestoneId;
}
public String getAssigneeId() {
return assigneeId;
}
}
public Mono<RateLimitQuery.RateLimit> findRateLimit() {
return Mono.create( sink -> this.apolloClient.query(new RateLimitQuery())
.enqueue(new ApolloCall.Callback<RateLimitQuery.Data>() {
@Override
public void onResponse(@NotNull Response<RateLimitQuery.Data> response) {
if (response.hasErrors()) {
sink.error(new RuntimeException(response.getErrors().stream().map(e -> e.getMessage()).collect(Collectors.joining(" "))));
} else {
sink.success(response.getData().rateLimit());
}
}
@Override
public void onFailure(@NotNull ApolloException e) {
sink.error(e);
}
}));
}
public Mono<Integer> createIssue(String repositoryId, String title, List<String> labelIds, String milestoneId, String assigneeId) {
CreateIssueInputMutation createIssue = new CreateIssueInputMutation.Builder()
.repositoryId(repositoryId)
.title(title)
.labelIds(labelIds)
.milestoneId(milestoneId)
.assigneeId(assigneeId)
.build();
return Mono.create( sink -> this.apolloClient.mutate(createIssue)
.enqueue(new ApolloCall.Callback<CreateIssueInputMutation.Data>() {
@Override
public void onResponse(@NotNull Response<CreateIssueInputMutation.Data> response) {
if (response.hasErrors()) {
String message = response.getErrors().stream().map(e -> e.getMessage() + " " + e.getCustomAttributes() + " " + e.getLocations()).collect(Collectors.joining(" "));
if (message.contains("was submitted too quickly")) {
sink.error(new SubmittedTooQuick(message));
} else {
sink.error(new RuntimeException(message));
}
} else {
sink.success(response.getData().createIssue().issue().number());
}
}
@Override
public void onFailure(@NotNull ApolloException e) {
sink.error(e);
}
}))
.retryWhen(
RetrySpec.fixedDelay(3, Duration.ofMinutes(1))
.filter(SubmittedTooQuick.class::isInstance)
.doBeforeRetry(r -> System.out.println("Pausing for 1 minute and then retrying due to receiving \"submitted too quickly\" error from GitHub API"))
)
.cast(Integer.class);
}
public static class SubmittedTooQuick extends RuntimeException {
public SubmittedTooQuick(String message) {
super(message);
}
}
private static class AuthorizationInterceptor implements Interceptor {
private final String token;
public AuthorizationInterceptor(String token) {
this.token = token;
}
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder()
.addHeader("Authorization", "Bearer " + this.token).build();
return chain.proceed(request);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2019-2020 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.
@@ -0,0 +1,198 @@
package org.springframework.security.convention.versions;
import com.github.benmanes.gradle.versions.updates.resolutionstrategy.ComponentSelectionRulesWithCurrent;
import com.github.benmanes.gradle.versions.updates.resolutionstrategy.ComponentSelectionWithCurrent;
import com.github.benmanes.gradle.versions.updates.resolutionstrategy.ResolutionStrategyWithCurrent;
import org.gradle.api.Action;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import java.util.regex.Pattern;
public class UpdateDependenciesExtension {
private Supplier<List<File>> files;
private UpdateMode updateMode = UpdateMode.COMMIT;
private DependencyExcludes dependencyExcludes = new DependencyExcludes();
private GitHub gitHub = new GitHub();
public UpdateDependenciesExtension(Supplier<List<File>> files) {
this.files = files;
}
public void setUpdateMode(UpdateMode updateMode) {
this.updateMode = updateMode;
}
public UpdateMode getUpdateMode() {
return updateMode;
}
GitHub getGitHub() {
return this.gitHub;
}
DependencyExcludes getExcludes() {
return dependencyExcludes;
}
Supplier<List<File>> getFiles() {
return files;
}
public void setFiles(Supplier<List<File>> files) {
this.files = files;
}
public void addFiles(Supplier<List<File>> files) {
Supplier<List<File>> original = this.files;
setFiles(() -> {
List<File> result = new ArrayList<>(original.get());
result.addAll(files.get());
return result;
});
}
public void dependencyExcludes(Action<DependencyExcludes> excludes) {
excludes.execute(this.dependencyExcludes);
}
public void gitHub(Action<GitHub> gitHub) {
gitHub.execute(this.gitHub);
}
public enum UpdateMode {
COMMIT,
GITHUB_ISSUE
}
public class GitHub {
private String organization;
private String repository;
private String accessToken;
private String milestone;
public String getOrganization() {
return organization;
}
public void setOrganization(String organization) {
this.organization = organization;
}
public String getRepository() {
return repository;
}
public void setRepository(String repository) {
this.repository = repository;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getMilestone() {
return milestone;
}
public void setMilestone(String milestone) {
this.milestone = milestone;
}
}
/**
* Consider creating some Predicates instead since they are composible
*/
public class DependencyExcludes {
private List<Action<ComponentSelectionWithCurrent>> actions = new ArrayList<>();
private List<Action<ComponentSelectionRulesWithCurrent>> components = new ArrayList<>();
List<Action<ComponentSelectionWithCurrent>> getActions() {
return actions;
}
public List<Action<ComponentSelectionRulesWithCurrent>> getComponents() {
return components;
}
public DependencyExcludes alphaBetaVersions() {
this.actions.add(excludeVersionWithRegex("(?i).*?(alpha|beta).*", "an alpha or beta version"));
return this;
}
public DependencyExcludes majorVersionBump() {
this.actions.add((selection) -> {
String currentVersion = selection.getCurrentVersion();
int separator = currentVersion.indexOf(".");
String major = separator > 0 ? currentVersion.substring(0, separator) : currentVersion;
String candidateVersion = selection.getCandidate().getVersion();
Pattern calVerPattern = Pattern.compile("\\d\\d\\d\\d.*");
boolean isCalVer = calVerPattern.matcher(candidateVersion).matches();
if (!isCalVer && !candidateVersion.startsWith(major)) {
selection.reject("Cannot upgrade to new Major Version");
}
});
return this;
}
public DependencyExcludes minorVersionBump() {
this.actions.add(createExcludeMinorVersionBump());
return this;
}
public Action<ComponentSelectionWithCurrent> createExcludeMinorVersionBump() {
return (selection) -> {
String currentVersion = selection.getCurrentVersion();
int majorSeparator = currentVersion.indexOf(".");
int separator = currentVersion.indexOf(".", majorSeparator + 1);
String majorMinor = separator > 0 ? currentVersion.substring(0, separator) : currentVersion;
String candidateVersion = selection.getCandidate().getVersion();
if (!candidateVersion.startsWith(majorMinor)) {
selection.reject("Cannot upgrade to new Minor Version");
}
};
}
public DependencyExcludes releaseCandidatesVersions() {
this.actions.add(excludeVersionWithRegex("(?i).*?rc.*", "a release candidate version"));
return this;
}
public DependencyExcludes milestoneVersions() {
this.actions.add(excludeVersionWithRegex("(?i).*?m\\d+.*", "a milestone version"));
return this;
}
public DependencyExcludes snapshotVersions() {
this.actions.add(excludeVersionWithRegex(".*?-SNAPSHOT.*", "a SNAPSHOT version"));
return this;
}
public DependencyExcludes addRule(Action<ComponentSelectionRulesWithCurrent> rule) {
this.components.add(rule);
return this;
}
private Action<ComponentSelectionWithCurrent> excludeVersionWithRegex(String regex, String reason) {
Pattern pattern = Pattern.compile(regex);
return (selection) -> {
String candidateVersion = selection.getCandidate().getVersion();
if (pattern.matcher(candidateVersion).matches()) {
selection.reject(candidateVersion + " is not allowed because it is " + reason);
}
};
}
}
}
@@ -0,0 +1,244 @@
/*
* Copyright 2019-2020 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.security.convention.versions;
import com.github.benmanes.gradle.versions.reporter.result.Dependency;
import com.github.benmanes.gradle.versions.reporter.result.DependencyOutdated;
import com.github.benmanes.gradle.versions.reporter.result.Result;
import com.github.benmanes.gradle.versions.reporter.result.VersionAvailable;
import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask;
import com.github.benmanes.gradle.versions.updates.gradle.GradleUpdateResult;
import com.github.benmanes.gradle.versions.updates.resolutionstrategy.ComponentSelectionRulesWithCurrent;
import com.github.benmanes.gradle.versions.updates.resolutionstrategy.ComponentSelectionWithCurrent;
import com.github.benmanes.gradle.versions.updates.resolutionstrategy.ResolutionStrategyWithCurrent;
import groovy.lang.Closure;
import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
import reactor.core.publisher.Mono;
import java.io.File;
import java.time.Duration;
import java.util.*;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.springframework.security.convention.versions.TransitiveDependencyLookupUtils.NIMBUS_JOSE_JWT_NAME;
import static org.springframework.security.convention.versions.TransitiveDependencyLookupUtils.OIDC_SDK_NAME;
public class UpdateDependenciesPlugin implements Plugin<Project> {
private GitHubApi gitHubApi;
@Override
public void apply(Project project) {
UpdateDependenciesExtension updateDependenciesSettings = project.getExtensions().create("updateDependenciesSettings", UpdateDependenciesExtension.class, defaultFiles(project));
if (project.hasProperty("updateMode")) {
String updateMode = String.valueOf(project.findProperty("updateMode"));
updateDependenciesSettings.setUpdateMode(UpdateDependenciesExtension.UpdateMode.valueOf(updateMode));
}
if (project.hasProperty("nextVersion")) {
String nextVersion = String.valueOf(project.findProperty("nextVersion"));
updateDependenciesSettings.getGitHub().setMilestone(nextVersion);
}
if (project.hasProperty("gitHubAccessToken")) {
String gitHubAccessToken = String.valueOf(project.findProperty("gitHubAccessToken"));
updateDependenciesSettings.getGitHub().setAccessToken(gitHubAccessToken);
}
project.getTasks().register("updateDependencies", DependencyUpdatesTask.class, new Action<DependencyUpdatesTask>() {
@Override
public void execute(DependencyUpdatesTask updateDependencies) {
updateDependencies.setDescription("Update the dependencies");
updateDependencies.setCheckConstraints(true);
updateDependencies.setOutputFormatter(new Closure<Void>(null) {
@Override
public Void call(Object argument) {
Result result = (Result) argument;
if (gitHubApi == null && updateDependenciesSettings.getUpdateMode() != UpdateDependenciesExtension.UpdateMode.COMMIT) {
gitHubApi = new GitHubApi(updateDependenciesSettings.getGitHub().getAccessToken());
}
updateDependencies(result, project, updateDependenciesSettings);
updateGradleVersion(result, project, updateDependenciesSettings);
return null;
}
});
updateDependencies.resolutionStrategy(new Action<ResolutionStrategyWithCurrent>() {
@Override
public void execute(ResolutionStrategyWithCurrent resolution) {
resolution.componentSelection(new Action<ComponentSelectionRulesWithCurrent>() {
@Override
public void execute(ComponentSelectionRulesWithCurrent components) {
updateDependenciesSettings.getExcludes().getActions().forEach((action) -> {
components.all(action);
});
updateDependenciesSettings.getExcludes().getComponents().forEach((action) -> {
action.execute(components);
});
components.all((selection) -> {
ModuleComponentIdentifier candidate = selection.getCandidate();
if (candidate.getGroup().startsWith("org.apache.directory.") && !candidate.getVersion().equals(selection.getCurrentVersion())) {
selection.reject("org.apache.directory.* has breaking changes in newer versions");
}
});
String jaxbBetaRegex = ".*?b\\d+.*";
components.withModule("javax.xml.bind:jaxb-api", excludeWithRegex(jaxbBetaRegex, "Reject jaxb-api beta versions"));
components.withModule("com.sun.xml.bind:jaxb-impl", excludeWithRegex(jaxbBetaRegex, "Reject jaxb-api beta versions"));
components.withModule("commons-collections:commons-collections", excludeWithRegex("^\\d{3,}.*", "Reject commons-collections date based releases"));
}
});
}
});
}
});
}
private void updateDependencies(Result result, Project project, UpdateDependenciesExtension updateDependenciesSettings) {
SortedSet<DependencyOutdated> dependencies = result.getOutdated().getDependencies();
if (dependencies.isEmpty()) {
return;
}
Map<String, List<DependencyOutdated>> groups = new LinkedHashMap<>();
dependencies.forEach(outdated -> {
groups.computeIfAbsent(outdated.getGroup(), (key) -> new ArrayList<>()).add(outdated);
});
List<DependencyOutdated> nimbusds = groups.getOrDefault("com.nimbusds", new ArrayList<>());
DependencyOutdated oidcSdc = nimbusds.stream().filter(d -> d.getName().equals(OIDC_SDK_NAME)).findFirst().orElseGet(() -> null);
if(oidcSdc != null) {
String oidcVersion = updatedVersion(oidcSdc);
String jwtVersion = TransitiveDependencyLookupUtils.lookupJwtVersion(oidcVersion);
Dependency nimbusJoseJwtDependency = result.getCurrent().getDependencies().stream().filter(d -> d.getName().equals(NIMBUS_JOSE_JWT_NAME)).findFirst().get();
DependencyOutdated outdatedJwt = new DependencyOutdated();
outdatedJwt.setVersion(nimbusJoseJwtDependency.getVersion());
outdatedJwt.setGroup(oidcSdc.getGroup());
outdatedJwt.setName(NIMBUS_JOSE_JWT_NAME);
VersionAvailable available = new VersionAvailable();
available.setRelease(jwtVersion);
outdatedJwt.setAvailable(available);
nimbusds.add(outdatedJwt);
}
File gradlePropertiesFile = project.getRootProject().file(Project.GRADLE_PROPERTIES);
Mono<GitHubApi.FindCreateIssueResult> createIssueResult = createIssueResultMono(updateDependenciesSettings);
List<File> filesWithDependencies = updateDependenciesSettings.getFiles().get();
groups.forEach((group, outdated) -> {
outdated.forEach((dependency) -> {
String ga = dependency.getGroup() + ":" + dependency.getName() + ":";
String originalDependency = ga + dependency.getVersion();
String replacementDependency = ga + updatedVersion(dependency);
System.out.println("Update " + originalDependency + " to " + replacementDependency);
filesWithDependencies.forEach((fileWithDependency) -> {
updateDependencyInlineVersion(fileWithDependency, dependency);
updateDependencyWithVersionVariable(fileWithDependency, gradlePropertiesFile, dependency);
});
});
// commit
DependencyOutdated firstDependency = outdated.get(0);
String updatedVersion = updatedVersion(firstDependency);
String title = outdated.size() == 1 ? "Update " + firstDependency.getName() + " to " + updatedVersion : "Update " + firstDependency.getGroup() + " to " + updatedVersion;
afterGroup(updateDependenciesSettings, project.getRootDir(), title, createIssueResult);
});
}
private void afterGroup(UpdateDependenciesExtension updateDependenciesExtension, File rootDir, String title, Mono<GitHubApi.FindCreateIssueResult> createIssueResultMono) {
String commitMessage = title;
if (updateDependenciesExtension.getUpdateMode() == UpdateDependenciesExtension.UpdateMode.GITHUB_ISSUE) {
GitHubApi.FindCreateIssueResult createIssueResult = createIssueResultMono.block();
Integer issueNumber = gitHubApi.createIssue(createIssueResult.getRepositoryId(), title, createIssueResult.getLabelIds(), createIssueResult.getMilestoneId(), createIssueResult.getAssigneeId()).delayElement(Duration.ofSeconds(1)).block();
commitMessage += "\n\nCloses gh-" + issueNumber;
}
CommandLineUtils.runCommand(rootDir, "git", "commit", "-am", commitMessage);
}
private Mono<GitHubApi.FindCreateIssueResult> createIssueResultMono(UpdateDependenciesExtension updateDependenciesExtension) {
return Mono.defer(() -> {
UpdateDependenciesExtension.GitHub gitHub = updateDependenciesExtension.getGitHub();
return gitHubApi.findCreateIssueInput(gitHub.getOrganization(), gitHub.getRepository(), gitHub.getMilestone()).cache();
});
}
private void updateGradleVersion(Result result, Project project, UpdateDependenciesExtension updateDependenciesSettings) {
if (!result.getGradle().isEnabled()) {
return;
}
GradleUpdateResult current = result.getGradle().getCurrent();
GradleUpdateResult running = result.getGradle().getRunning();
if (current.compareTo(running) > 0) {
String title = "Update Gradle to " + current.getVersion();
System.out.println(title);
CommandLineUtils.runCommand(project.getRootDir(), "./gradlew", "wrapper", "--gradle-version", current.getVersion(), "--no-daemon");
afterGroup(updateDependenciesSettings, project.getRootDir(), title, createIssueResultMono(updateDependenciesSettings));
}
}
private static Supplier<List<File>> defaultFiles(Project project) {
return () -> {
List<File> result = new ArrayList<>();
result.add(project.getBuildFile());
project.getChildProjects().values().forEach((childProject) ->
result.add(childProject.getBuildFile())
);
result.add(project.getRootProject().file("buildSrc/build.gradle"));
return result;
};
}
static Action<ComponentSelectionWithCurrent> excludeWithRegex(String regex, String reason) {
Pattern pattern = Pattern.compile(regex);
return (selection) -> {
String candidateVersion = selection.getCandidate().getVersion();
if (pattern.matcher(candidateVersion).matches()) {
selection.reject(candidateVersion + " is not allowed because it is " + reason);
}
};
}
static void updateDependencyInlineVersion(File buildFile, DependencyOutdated dependency){
String ga = dependency.getGroup() + ":" + dependency.getName() + ":";
String originalDependency = ga + dependency.getVersion();
String replacementDependency = ga + updatedVersion(dependency);
FileUtils.replaceFileText(buildFile, buildFileText -> buildFileText.replace(originalDependency, replacementDependency));
}
static void updateDependencyWithVersionVariable(File scanFile, File gradlePropertiesFile, DependencyOutdated dependency) {
if (!gradlePropertiesFile.exists()) {
return;
}
FileUtils.replaceFileText(gradlePropertiesFile, (gradlePropertiesText) -> {
String ga = dependency.getGroup() + ":" + dependency.getName() + ":";
Pattern pattern = Pattern.compile("\"" + ga + "\\$\\{?([^'\"]+?)\\}?\"");
String buildFileText = FileUtils.readString(scanFile);
Matcher matcher = pattern.matcher(buildFileText);
while (matcher.find()) {
String versionVariable = matcher.group(1);
gradlePropertiesText = gradlePropertiesText.replace(versionVariable + "=" + dependency.getVersion(), versionVariable + "=" + updatedVersion(dependency));
}
return gradlePropertiesText;
});
}
private static String updatedVersion(DependencyOutdated dependency) {
VersionAvailable available = dependency.getAvailable();
String release = available.getRelease();
if (release != null) {
return release;
}
return available.getMilestone();
}
}
@@ -1,70 +0,0 @@
/*
* Copyright 2002-2023 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.security.convention.versions;
import org.gradle.api.DefaultTask;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.MinimalExternalModuleDependency;
import org.gradle.api.artifacts.VersionCatalog;
import org.gradle.api.artifacts.VersionCatalogsExtension;
import org.gradle.api.plugins.JavaBasePlugin;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.TaskProvider;
public class VerifyDependenciesVersionsPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
TaskProvider<VerifyDependenciesVersionsTask> verifyDependenciesVersionsTaskProvider = project.getTasks().register("verifyDependenciesVersions", VerifyDependenciesVersionsTask.class, (task) -> {
task.setGroup("Verification");
task.setDescription("Verify that specific dependencies are using the same version");
VersionCatalog versionCatalog = project.getExtensions().getByType(VersionCatalogsExtension.class).named("libs");
MinimalExternalModuleDependency oauth2OidcSdk = versionCatalog.findLibrary("com-nimbusds-oauth2-oidc-sdk").get().get();
MinimalExternalModuleDependency nimbusJoseJwt = versionCatalog.findLibrary("com-nimbusds-nimbus-jose-jwt").get().get();
task.setOauth2OidcSdkVersion(oauth2OidcSdk.getVersionConstraint().getDisplayName());
task.setExpectedNimbusJoseJwtVersion(nimbusJoseJwt.getVersionConstraint().getDisplayName());
});
project.getTasks().named(JavaBasePlugin.CHECK_TASK_NAME, checkTask -> checkTask.dependsOn(verifyDependenciesVersionsTaskProvider));
}
public static class VerifyDependenciesVersionsTask extends DefaultTask {
private String oauth2OidcSdkVersion;
private String expectedNimbusJoseJwtVersion;
public void setOauth2OidcSdkVersion(String oauth2OidcSdkVersion) {
this.oauth2OidcSdkVersion = oauth2OidcSdkVersion;
}
public void setExpectedNimbusJoseJwtVersion(String expectedNimbusJoseJwtVersion) {
this.expectedNimbusJoseJwtVersion = expectedNimbusJoseJwtVersion;
}
@TaskAction
public void verify() {
String transitiveNimbusJoseJwtVersion = TransitiveDependencyLookupUtils.lookupJwtVersion(this.oauth2OidcSdkVersion);
if (!transitiveNimbusJoseJwtVersion.equals(this.expectedNimbusJoseJwtVersion)) {
String message = String.format("Found transitive nimbus-jose-jwt:%s in oauth2-oidc-sdk:%s, but the project contains a different version of nimbus-jose-jwt [%s]. Please align the versions.", transitiveNimbusJoseJwtVersion, this.oauth2OidcSdkVersion, this.expectedNimbusJoseJwtVersion);
throw new IllegalStateException(message);
}
}
}
}
+46 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-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.
@@ -17,6 +17,7 @@
package s101;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -33,11 +34,18 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.github.mustachejava.DefaultMustacheFactory;
import com.github.mustachejava.Mustache;
import com.github.mustachejava.MustacheFactory;
@@ -63,10 +71,6 @@ public class S101Configurer {
private final Path licenseDirectory;
private final String repository;
private final String version;
private final Project project;
private final Logger logger;
@@ -86,9 +90,6 @@ public class S101Configurer {
throw new UncheckedIOException(ex);
}
this.licenseDirectory = new File(System.getProperty("user.home") + "/.Structure101/java").toPath();
S101PluginExtension extension = project.getExtensions().getByType(S101PluginExtension.class);
this.repository = extension.getRepository().get();
this.version = extension.getVersion().get();
}
public void license(String licenseId) {
@@ -128,7 +129,25 @@ public class S101Configurer {
public void configure(File installationDirectory, File configurationDirectory) {
deleteDirectory(configurationDirectory);
configureProject(this.version, configurationDirectory);
String version = computeVersionFromInstallation(installationDirectory);
configureProject(version, configurationDirectory);
}
private String computeVersionFromInstallation(File installationDirectory) {
File buildJar = new File(installationDirectory, "structure101-java-build.jar");
try (JarInputStream input = new JarInputStream(new FileInputStream(buildJar))) {
JarEntry entry;
while ((entry = input.getNextJarEntry()) != null) {
if (entry.getName().contains("structure101-build.properties")) {
Properties properties = new Properties();
properties.load(input);
return properties.getProperty("s101-build");
}
}
} catch (Exception ex) {
throw new RuntimeException(ex);
}
throw new IllegalStateException("Unable to determine Structure101 version");
}
private boolean deleteDirectory(File directoryToBeDeleted) {
@@ -142,8 +161,24 @@ public class S101Configurer {
}
private String installBuildTool(File installationDirectory, File configurationDirectory) {
copyZipToFilesystem(this.repository, installationDirectory, "structure101-build-java-all-" + this.version);
return this.version;
String source = "https://structure101.com/binaries/v6";
try (final WebClient webClient = new WebClient()) {
HtmlPage page = webClient.getPage(source);
Matcher matcher = null;
for (HtmlAnchor anchor : page.getAnchors()) {
Matcher candidate = Pattern.compile("(structure101-build-java-all-)(.*).zip").matcher(anchor.getHrefAttribute());
if (candidate.find()) {
matcher = candidate;
}
}
if (matcher == null) {
return null;
}
copyZipToFilesystem(source, installationDirectory, matcher.group(1) + matcher.group(2));
return matcher.group(2);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
private void copyZipToFilesystem(String source, File destination, String name) {
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-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.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-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.
@@ -17,12 +17,7 @@
package s101;
import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import org.gradle.api.Project;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
@@ -30,11 +25,6 @@ import org.gradle.api.tasks.InputDirectory;
public class S101PluginExtension {
private final Property<String> licenseId;
private final Property<String> repository;
private final Property<String> version;
private final Property<File> installationDirectory;
private final Property<File> configurationDirectory;
private final Property<String> label;
@@ -75,24 +65,6 @@ public class S101PluginExtension {
this.label.set(label);
}
@Input
public Property<String> getRepository() {
return repository;
}
public void setRepository(String repository) {
this.repository.set(repository);
}
@Input
public Property<String> getVersion() {
return this.version;
}
public void setVersion(String version) {
this.version.set(version);
}
public S101PluginExtension(Project project) {
this.licenseId = project.getObjects().property(String.class);
if (project.hasProperty("s101.licenseId")) {
@@ -106,31 +78,5 @@ public class S101PluginExtension {
if (project.hasProperty("s101.label")) {
setLabel((String) project.findProperty("s101.label"));
}
this.repository = project.getObjects().property(String.class);
if (project.hasProperty("s101.repository")) {
setRepository((String) project.findProperty("s101.repository"));
} else {
setRepository("https://structure101.com/binaries/v6");
}
this.version = project.getObjects().property(String.class);
if (project.hasProperty("s101.version")) {
setVersion((String) project.findProperty("s101.version"));
} else {
try (final WebClient webClient = new WebClient()) {
HtmlPage page = webClient.getPage(getRepository().get());
Matcher matcher = null;
for (HtmlAnchor anchor : page.getAnchors()) {
Matcher candidate = Pattern.compile("(structure101-build-java-all-)(.*).zip").matcher(anchor.getHrefAttribute());
if (candidate.find()) {
matcher = candidate;
}
}
if (matcher != null) {
setVersion(matcher.group(2));
}
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
}
@@ -125,27 +125,27 @@ public class RepositoryConventionPluginTests {
private void assertSnapshotRepository(RepositoryHandler repositories) {
assertThat(repositories).extracting(ArtifactRepository::getName).hasSize(5);
assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString())
assertThat(((MavenArtifactRepository) repositories.get(0)).getUrl().toString())
.isEqualTo("https://repo.maven.apache.org/maven2/");
assertThat(((MavenArtifactRepository) repositories.get(2)).getUrl().toString())
assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString())
.isEqualTo("https://repo.spring.io/snapshot/");
assertThat(((MavenArtifactRepository) repositories.get(3)).getUrl().toString())
assertThat(((MavenArtifactRepository) repositories.get(2)).getUrl().toString())
.isEqualTo("https://repo.spring.io/milestone/");
}
private void assertMilestoneRepository(RepositoryHandler repositories) {
assertThat(repositories).extracting(ArtifactRepository::getName).hasSize(4);
assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString())
assertThat(((MavenArtifactRepository) repositories.get(0)).getUrl().toString())
.isEqualTo("https://repo.maven.apache.org/maven2/");
assertThat(((MavenArtifactRepository) repositories.get(2)).getUrl().toString())
assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString())
.isEqualTo("https://repo.spring.io/milestone/");
}
private void assertReleaseRepository(RepositoryHandler repositories) {
assertThat(repositories).extracting(ArtifactRepository::getName).hasSize(3);
assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString())
assertThat(((MavenArtifactRepository) repositories.get(0)).getUrl().toString())
.isEqualTo("https://repo.maven.apache.org/maven2/");
assertThat(((MavenArtifactRepository) repositories.get(2)).getUrl().toString())
assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString())
.isEqualTo("https://repo.spring.io/release/");
}
@@ -0,0 +1,86 @@
/*
* Copyright 2019-2020 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.security.convention.versions;
import com.github.benmanes.gradle.versions.updates.resolutionstrategy.ComponentSelectionWithCurrent;
import org.gradle.api.Action;
import org.gradle.api.artifacts.ComponentSelection;
import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
import org.junit.jupiter.api.Test;
import java.util.Collections;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.*;
public class DependencyExcludesTests {
@Test
public void createExcludeMinorVersionBumpWhenMajorVersionBumpThenReject() {
ComponentSelection componentSelection = executeCreateExcludeMinorVersionBump("1.0.0", "2.0.0");
verify(componentSelection).reject(any());
}
@Test
public void createExcludeMinorVersionBumpWhenMajorCalVersionBumpThenReject() {
ComponentSelection componentSelection = executeCreateExcludeMinorVersionBump("2000.0.0", "2001.0.0");
verify(componentSelection).reject(any());
}
@Test
public void createExcludeMinorVersionBumpWhenMinorVersionBumpThenReject() {
ComponentSelection componentSelection = executeCreateExcludeMinorVersionBump("1.0.0", "1.1.0");
verify(componentSelection).reject(any());
}
@Test
public void createExcludeMinorVersionBumpWhenMinorCalVersionBumpThenReject() {
ComponentSelection componentSelection = executeCreateExcludeMinorVersionBump("2000.0.0", "2000.1.0");
verify(componentSelection).reject(any());
}
@Test
public void createExcludeMinorVersionBumpWhenMinorAndPatchVersionBumpThenReject() {
ComponentSelection componentSelection = executeCreateExcludeMinorVersionBump("1.0.0", "1.1.1");
verify(componentSelection).reject(any());
}
@Test
public void createExcludeMinorVersionBumpWhenPatchVersionBumpThenDoesNotReject() {
ComponentSelection componentSelection = executeCreateExcludeMinorVersionBump("1.0.0", "1.0.1");
verify(componentSelection, times(0)).reject(any());
}
private ComponentSelection executeCreateExcludeMinorVersionBump(String currentVersion, String candidateVersion) {
ComponentSelection componentSelection = mock(ComponentSelection.class);
UpdateDependenciesExtension.DependencyExcludes excludes = new UpdateDependenciesExtension(() -> Collections.emptyList()).new DependencyExcludes();
Action<ComponentSelectionWithCurrent> excludeMinorVersionBump = excludes.createExcludeMinorVersionBump();
ComponentSelectionWithCurrent selection = currentVersionAndCandidateVersion(componentSelection, currentVersion, candidateVersion);
excludeMinorVersionBump.execute(selection);
return componentSelection;
}
private ComponentSelectionWithCurrent currentVersionAndCandidateVersion(ComponentSelection componentSelection, String currentVersion, String candidateVersion) {
ModuleComponentIdentifier candidate = mock(ModuleComponentIdentifier.class);
given(componentSelection.getCandidate()).willReturn(candidate);
ComponentSelectionWithCurrent selection = new ComponentSelectionWithCurrent(currentVersion, componentSelection);
given(candidate.getVersion()).willReturn(candidateVersion);
given(componentSelection.getCandidate()).willReturn(candidate);
return selection;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2019-2020 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,19 +14,18 @@
* limitations under the License.
*/
package org.springframework.security.oauth2.client.web;
package org.springframework.security.convention.versions;
/**
* @author Steve Riesenberg
* @since 5.8
*/
class InvalidClientRegistrationIdException extends IllegalArgumentException {
/**
* @param message the exception message
*/
InvalidClientRegistrationIdException(String message) {
super(message);
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class TransitiveDependencyLookupUtilsTest {
@Test
public void lookupJwtVersionWhen93Then961() {
String s = TransitiveDependencyLookupUtils.lookupJwtVersion("9.3");
assertThat(s).isEqualTo("9.6.1");
}
}
@@ -98,7 +98,7 @@ public class CasAuthenticationProvider implements AuthenticationProvider, Initia
if (authentication instanceof UsernamePasswordAuthenticationToken
&& (!CasAuthenticationFilter.CAS_STATEFUL_IDENTIFIER.equals(authentication.getPrincipal().toString())
&& !CasAuthenticationFilter.CAS_STATELESS_IDENTIFIER
.equals(authentication.getPrincipal().toString()))) {
.equals(authentication.getPrincipal().toString()))) {
// UsernamePasswordAuthenticationToken not CAS related
return null;
}
@@ -18,6 +18,7 @@ package org.springframework.security.cas.userdetails;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.jasig.cas.client.validation.Assertion;
@@ -73,7 +74,8 @@ public final class GrantedAuthorityFromAssertionAttributesUserDetailsService
}
private SimpleGrantedAuthority createSimpleGrantedAuthority(Object o) {
return new SimpleGrantedAuthority(this.convertToUpperCase ? o.toString().toUpperCase() : o.toString());
return new SimpleGrantedAuthority(
this.convertToUpperCase ? o.toString().toUpperCase(Locale.ROOT) : o.toString());
}
/**
@@ -88,7 +88,7 @@ public class CasAuthenticationProviderTests {
cap.setTicketValidator(new MockTicketValidator(true));
cap.afterPropertiesSet();
UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken
.unauthenticated(CasAuthenticationFilter.CAS_STATEFUL_IDENTIFIER, "ST-123");
.unauthenticated(CasAuthenticationFilter.CAS_STATEFUL_IDENTIFIER, "ST-123");
token.setDetails("details");
Authentication result = cap.authenticate(token);
// Confirm ST-123 was NOT added to the cache
@@ -121,7 +121,7 @@ public class CasAuthenticationProviderTests {
cap.setServiceProperties(makeServiceProperties());
cap.afterPropertiesSet();
UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken
.unauthenticated(CasAuthenticationFilter.CAS_STATELESS_IDENTIFIER, "ST-456");
.unauthenticated(CasAuthenticationFilter.CAS_STATELESS_IDENTIFIER, "ST-456");
token.setDetails("details");
Authentication result = cap.authenticate(token);
// Confirm ST-456 was added to the cache
@@ -158,7 +158,7 @@ public class CasAuthenticationProviderTests {
cap.afterPropertiesSet();
String ticket = "ST-456";
UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken
.unauthenticated(CasAuthenticationFilter.CAS_STATELESS_IDENTIFIER, ticket);
.unauthenticated(CasAuthenticationFilter.CAS_STATELESS_IDENTIFIER, ticket);
Authentication result = cap.authenticate(token);
}
@@ -179,7 +179,7 @@ public class CasAuthenticationProviderTests {
cap.afterPropertiesSet();
String ticket = "ST-456";
UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken
.unauthenticated(CasAuthenticationFilter.CAS_STATELESS_IDENTIFIER, ticket);
.unauthenticated(CasAuthenticationFilter.CAS_STATELESS_IDENTIFIER, ticket);
Authentication result = cap.authenticate(token);
verify(validator).validate(ticket, serviceProperties.getService());
serviceProperties.setAuthenticateAllArtifacts(true);
@@ -212,7 +212,7 @@ public class CasAuthenticationProviderTests {
cap.setServiceProperties(makeServiceProperties());
cap.afterPropertiesSet();
UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken
.unauthenticated(CasAuthenticationFilter.CAS_STATEFUL_IDENTIFIER, "");
.unauthenticated(CasAuthenticationFilter.CAS_STATEFUL_IDENTIFIER, "");
assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> cap.authenticate(token));
}
@@ -315,7 +315,7 @@ public class CasAuthenticationProviderTests {
cap.setServiceProperties(makeServiceProperties());
cap.afterPropertiesSet();
UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken
.authenticated("some_normal_user", "password", AuthorityUtils.createAuthorityList("ROLE_A"));
.authenticated("some_normal_user", "password", AuthorityUtils.createAuthorityList("ROLE_A"));
assertThat(cap.authenticate(token)).isNull();
}
@@ -103,7 +103,7 @@ public class CasAuthenticationTokenTests {
@Test
public void testNoArgConstructorDoesntExist() {
assertThatExceptionOfType(NoSuchMethodException.class)
.isThrownBy(() -> CasAuthenticationToken.class.getDeclaredConstructor((Class[]) null));
.isThrownBy(() -> CasAuthenticationToken.class.getDeclaredConstructor((Class[]) null));
}
@Test
@@ -132,7 +132,7 @@ public class CasAuthenticationTokenMixinTests {
assertThat(token.getAssertion()).isNotNull().isInstanceOf(AssertionImpl.class);
assertThat(token.getKeyHash()).isEqualTo(KEY.hashCode());
assertThat(token.getUserDetails().getAuthorities()).extracting(GrantedAuthority::getAuthority)
.containsOnly("ROLE_USER");
.containsOnly("ROLE_USER");
assertThat(token.getAssertion().getAuthenticationDate()).isEqualTo(START_DATE);
assertThat(token.getAssertion().getValidFromDate()).isEqualTo(START_DATE);
assertThat(token.getAssertion().getValidUntilDate()).isEqualTo(END_DATE);
@@ -143,7 +143,7 @@ public class CasAuthenticationTokenMixinTests {
private CasAuthenticationToken createCasAuthenticationToken() {
User principal = new User("admin", "1234", Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER")));
Collection<? extends GrantedAuthority> authorities = Collections
.singletonList(new SimpleGrantedAuthority("ROLE_USER"));
.singletonList(new SimpleGrantedAuthority("ROLE_USER"));
Assertion assertion = new AssertionImpl(new AttributePrincipalImpl("assertName"), START_DATE, END_DATE,
START_DATE, Collections.<String, Object>emptyMap());
return new CasAuthenticationToken(KEY, principal, principal.getPassword(), authorities,
@@ -39,7 +39,7 @@ public class CasAuthenticationEntryPointTests {
CasAuthenticationEntryPoint ep = new CasAuthenticationEntryPoint();
ep.setServiceProperties(new ServiceProperties());
assertThatIllegalArgumentException().isThrownBy(ep::afterPropertiesSet)
.withMessage("loginUrl must be specified");
.withMessage("loginUrl must be specified");
}
@Test
@@ -47,7 +47,7 @@ public class CasAuthenticationEntryPointTests {
CasAuthenticationEntryPoint ep = new CasAuthenticationEntryPoint();
ep.setLoginUrl("https://cas/login");
assertThatIllegalArgumentException().isThrownBy(ep::afterPropertiesSet)
.withMessage("serviceProperties must be specified");
.withMessage("serviceProperties must be specified");
}
@Test
@@ -74,7 +74,7 @@ public class CasAuthenticationEntryPointTests {
ep.commence(request, response, null);
assertThat(
"https://cas/login?service=" + URLEncoder.encode("https://mycompany.com/bigWebApp/login/cas", "UTF-8"))
.isEqualTo(response.getRedirectedUrl());
.isEqualTo(response.getRedirectedUrl());
}
@Test
@@ -92,7 +92,7 @@ public class CasAuthenticationEntryPointTests {
ep.commence(request, response, null);
assertThat("https://cas/login?service="
+ URLEncoder.encode("https://mycompany.com/bigWebApp/login/cas", "UTF-8") + "&renew=true")
.isEqualTo(response.getRedirectedUrl());
.isEqualTo(response.getRedirectedUrl());
}
}
@@ -46,6 +46,7 @@ import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Tests {@link CasAuthenticationFilter}.
@@ -132,14 +133,13 @@ public class CasAuthenticationFilterTests {
assertThat(filter.requiresAuthentication(request, response)).isFalse();
request.setParameter(properties.getArtifactParameter(), "value");
assertThat(filter.requiresAuthentication(request, response)).isTrue();
SecurityContextHolder.getContext()
.setAuthentication(new AnonymousAuthenticationToken("key", "principal",
AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS")));
SecurityContextHolder.getContext().setAuthentication(new AnonymousAuthenticationToken("key", "principal",
AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS")));
assertThat(filter.requiresAuthentication(request, response)).isTrue();
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("un", "principal"));
assertThat(filter.requiresAuthentication(request, response)).isTrue();
SecurityContextHolder.getContext()
.setAuthentication(new TestingAuthenticationToken("un", "principal", "ROLE_ANONYMOUS"));
.setAuthentication(new TestingAuthenticationToken("un", "principal", "ROLE_ANONYMOUS"));
assertThat(filter.requiresAuthentication(request, response)).isFalse();
}
@@ -175,9 +175,9 @@ public class CasAuthenticationFilterTests {
filter.afterPropertiesSet();
filter.doFilter(request, response, chain);
assertThat(SecurityContextHolder.getContext().getAuthentication()).isNotNull()
.withFailMessage("Authentication should not be null");
.withFailMessage("Authentication should not be null");
verify(chain).doFilter(request, response);
verifyNoMoreInteractions(successHandler);
verifyZeroInteractions(successHandler);
// validate for when the filterProcessUrl matches
filter.setFilterProcessesUrl(request.getServletPath());
SecurityContextHolder.clearContext();
@@ -207,7 +207,7 @@ public class CasAuthenticationFilterTests {
filter.afterPropertiesSet();
filter.doFilter(request, response, chain);
assertThat(SecurityContextHolder.getContext().getAuthentication()).isNotNull()
.withFailMessage("Authentication should not be null");
.withFailMessage("Authentication should not be null");
verify(chain).doFilter(request, response);
// validate for when the filterProcessUrl matches
filter.setFilterProcessesUrl(request.getServletPath());
@@ -229,7 +229,7 @@ public class CasAuthenticationFilterTests {
filter.setProxyGrantingTicketStorage(mock(ProxyGrantingTicketStorage.class));
filter.setProxyReceptorUrl(request.getServletPath());
filter.doFilter(request, response, chain);
verifyNoMoreInteractions(chain);
verifyZeroInteractions(chain);
}
}
@@ -54,7 +54,7 @@ public class DefaultServiceAuthenticationDetailsTests {
this.request.setServerPort(8443);
this.request.setRequestURI("/cas-sample/secure/");
this.artifactPattern = DefaultServiceAuthenticationDetails
.createArtifactPattern(ServiceProperties.DEFAULT_CAS_ARTIFACT_PARAMETER);
.createArtifactPattern(ServiceProperties.DEFAULT_CAS_ARTIFACT_PARAMETER);
}
@AfterEach
+12 -53
View File
@@ -1,11 +1,14 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.springframework.gradle.xsd.CreateVersionlessXsdTask
import trang.RncToXsd
apply plugin: 'io.spring.convention.spring-module'
apply plugin: 'trang'
apply plugin: 'kotlin'
repositories {
maven { url "https://build.shibboleth.net/nexus/content/repositories/releases/" }
}
dependencies {
management platform(project(":spring-security-dependencies"))
// NB: Don't add other compile time dependencies to the config module as this breaks tooling
@@ -111,33 +114,21 @@ dependencies {
testRuntimeOnly 'org.hsqldb:hsqldb'
}
def rncToXsd = tasks.named('rncToXsd', RncToXsd)
rncToXsd.configure {
rncDir = file('src/main/resources/org/springframework/security/config/')
xsdDir = rncDir
xslFile = new File(rncDir, 'spring-security.xsl')
}
def versionlessXsd = tasks.register("versionlessXsd", CreateVersionlessXsdTask) {
inputFiles.from(rncToXsd.map { task -> project.fileTree(task.xsdDir) })
def versionlessXsd = project.tasks.create("versionlessXsd", CreateVersionlessXsdTask) {
inputFiles.from(project.sourceSets.main.resources)
versionlessXsdFile = project.layout.buildDirectory.file("versionlessXsd/spring-security.xsd")
}
tasks.named('processResources', ProcessResources).configure {
processResources {
from(versionlessXsd) {
into 'org/springframework/security/config/'
}
from(rncToXsd) {
duplicatesStrategy DuplicatesStrategy.EXCLUDE
into 'org/springframework/security/config/'
}
}
tasks.named('sourcesJar', Jar).configure {
from(rncToXsd) {
duplicatesStrategy DuplicatesStrategy.EXCLUDE
into 'org/springframework/security/config/'
}
rncToXsd {
rncDir = file('src/main/resources/org/springframework/security/config/')
xsdDir = rncDir
xslFile = new File(rncDir, 'spring-security.xsl')
}
tasks.withType(KotlinCompile).configureEach {
@@ -149,36 +140,4 @@ tasks.withType(KotlinCompile).configureEach {
}
}
compileTestJava {
exclude "org/springframework/security/config/annotation/web/configurers/saml2/**", "org/springframework/security/config/http/Saml2*"
}
task compileSaml2TestJava(type: JavaCompile) {
javaCompiler = javaToolchains.compilerFor {
languageVersion = JavaLanguageVersion.of(11)
}
source = sourceSets.test.java.srcDirs
include "org/springframework/security/config/annotation/web/configurers/saml2/**", "org/springframework/security/config/http/Saml2*"
classpath = sourceSets.test.compileClasspath
destinationDirectory = new File("${buildDir}/classes/java/test")
options.sourcepath = sourceSets.test.java.getSourceDirectories()
}
task saml2Tests(type: Test) {
javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(11)
}
filter {
includeTestsMatching "org.springframework.security.config.annotation.web.configurers.saml2.*"
}
useJUnitPlatform()
dependsOn compileSaml2TestJava
}
test {
shouldRunAfter saml2Tests
}
tasks.named('check') {
dependsOn saml2Tests
}
build.dependsOn rncToXsd
@@ -74,8 +74,8 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
assertThat(authoritiesPopulator).hasFieldOrPropertyWithValue("groupRoleAttribute", "cn");
assertThat(authoritiesPopulator).hasFieldOrPropertyWithValue("groupSearchBase", "");
assertThat(authoritiesPopulator).hasFieldOrPropertyWithValue("groupSearchFilter", "(uniqueMember={0})");
assertThat(authoritiesPopulator).extracting("searchControls")
.hasFieldOrPropertyWithValue("searchScope", SearchControls.ONELEVEL_SCOPE);
assertThat(authoritiesPopulator).extracting("searchControls").hasFieldOrPropertyWithValue("searchScope",
SearchControls.ONELEVEL_SCOPE);
assertThat(ReflectionTestUtils.getField(getAuthoritiesMapper(provider), "prefix")).isEqualTo("ROLE_");
}
@@ -85,7 +85,7 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
LdapAuthenticationProvider provider = ldapProvider();
assertThat(ReflectionTestUtils.getField(getAuthoritiesPopulator(provider), "groupRoleAttribute"))
.isEqualTo("group");
.isEqualTo("group");
}
@Test
@@ -94,7 +94,7 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
LdapAuthenticationProvider provider = ldapProvider();
assertThat(ReflectionTestUtils.getField(getAuthoritiesPopulator(provider), "groupSearchFilter"))
.isEqualTo("ou=groupName");
.isEqualTo("ou=groupName");
}
@Test
@@ -103,8 +103,7 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
LdapAuthenticationProvider provider = ldapProvider();
assertThat(ReflectionTestUtils.getField(getAuthoritiesPopulator(provider), "searchControls"))
.extracting("searchScope")
.isEqualTo(SearchControls.SUBTREE_SCOPE);
.extracting("searchScope").isEqualTo(SearchControls.SUBTREE_SCOPE);
}
@Test
@@ -120,8 +119,8 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
this.spring.register(BindAuthenticationConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(authenticated().withUsername("bob")
.withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))));
.andExpect(authenticated().withUsername("bob")
.withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))));
}
// SEC-2472
@@ -130,14 +129,13 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
this.spring.register(PasswordEncoderConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bcrypt").password("password"))
.andExpect(authenticated().withUsername("bcrypt")
.withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))));
.andExpect(authenticated().withUsername("bcrypt")
.withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))));
}
private LdapAuthenticationProvider ldapProvider() {
return ((List<LdapAuthenticationProvider>) ReflectionTestUtils.getField(this.authenticationManager,
"providers"))
.get(0);
"providers")).get(0);
}
private LdapAuthoritiesPopulator getAuthoritiesPopulator(LdapAuthenticationProvider provider) {
@@ -51,7 +51,7 @@ public class LdapAuthenticationProviderConfigurerTests {
this.spring.register(MultiLdapAuthenticationProvidersConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(authenticated().withUsername("bob"));
.andExpect(authenticated().withUsername("bob"));
}
@Test
@@ -122,7 +122,7 @@ public class JwtITests {
@Test
public void routeWhenAuthenticationBearerThenAuthorized() {
MimeType authenticationMimeType = MimeTypeUtils
.parseMimeType(WellKnownMimeType.MESSAGE_RSOCKET_AUTHENTICATION.getString());
.parseMimeType(WellKnownMimeType.MESSAGE_RSOCKET_AUTHENTICATION.getString());
BearerTokenMetadata credentials = new BearerTokenMetadata("token");
given(this.decoder.decode(any())).willReturn(Mono.just(jwt()));
// @formatter:off
@@ -137,11 +137,8 @@ public class JwtITests {
}
private Jwt jwt() {
return TestJwts.jwt()
.claim(IdTokenClaimNames.ISS, "https://issuer.example.com")
.claim(IdTokenClaimNames.SUB, "rob")
.claim(IdTokenClaimNames.AUD, Arrays.asList("client-id"))
.build();
return TestJwts.jwt().claim(IdTokenClaimNames.ISS, "https://issuer.example.com")
.claim(IdTokenClaimNames.SUB, "rob").claim(IdTokenClaimNames.AUD, Arrays.asList("client-id")).build();
}
private RSocketRequester.Builder requester() {
@@ -172,7 +169,7 @@ public class JwtITests {
@Bean
PayloadSocketAcceptorInterceptor rsocketInterceptor(RSocketSecurity rsocket) {
rsocket.authorizePayload((authorize) -> authorize.anyRequest().authenticated().anyExchange().permitAll())
.jwt(Customizer.withDefaults());
.jwt(Customizer.withDefaults());
return rsocket.build();
}
@@ -195,7 +195,7 @@ public class RSocketMessageHandlerITests {
String data = "a";
assertThatExceptionOfType(ApplicationErrorException.class).isThrownBy(
() -> this.requester.route("secure.hello").data(data).retrieveFlux(String.class).collectList().block())
.withMessageContaining("Access Denied");
.withMessageContaining("Access Denied");
assertThat(this.controller.payloads).isEmpty();
}
@@ -117,7 +117,7 @@ public class SimpleAuthenticationITests {
@Test
public void retrieveMonoWhenAuthorizedThenGranted() {
MimeType authenticationMimeType = MimeTypeUtils
.parseMimeType(WellKnownMimeType.MESSAGE_RSOCKET_AUTHENTICATION.getString());
.parseMimeType(WellKnownMimeType.MESSAGE_RSOCKET_AUTHENTICATION.getString());
UsernamePasswordMetadata credentials = new UsernamePasswordMetadata("rob", "password");
// @formatter:off
this.requester = RSocketRequester.builder()
@@ -161,7 +161,7 @@ public class SimpleAuthenticationITests {
@Bean
PayloadSocketAcceptorInterceptor rsocketInterceptor(RSocketSecurity rsocket) {
rsocket.authorizePayload((authorize) -> authorize.anyRequest().authenticated().anyExchange().permitAll())
.simpleAuthentication(Customizer.withDefaults());
.simpleAuthentication(Customizer.withDefaults());
return rsocket.build();
}
@@ -47,7 +47,7 @@ public class EmbeddedLdapServerContextSourceFactoryBeanITests {
this.spring.register(FromEmbeddedLdapServerConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(authenticated().withUsername("bob"));
.andExpect(authenticated().withUsername("bob"));
}
@Test
@@ -55,7 +55,7 @@ public class EmbeddedLdapServerContextSourceFactoryBeanITests {
this.spring.register(PortZeroConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(authenticated().withUsername("bob"));
.andExpect(authenticated().withUsername("bob"));
}
@Test
@@ -70,15 +70,15 @@ public class EmbeddedLdapServerContextSourceFactoryBeanITests {
this.spring.register(CustomManagerDnConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(authenticated().withUsername("bob"));
.andExpect(authenticated().withUsername("bob"));
}
@Test
public void contextSourceFactoryBeanWhenManagerDnAndNoPasswordThenException() {
assertThatExceptionOfType(UnsatisfiedDependencyException.class)
.isThrownBy(() -> this.spring.register(CustomManagerDnNoPasswordConfig.class).autowire())
.withRootCauseInstanceOf(IllegalStateException.class)
.withMessageContaining("managerPassword is required if managerDn is supplied");
.isThrownBy(() -> this.spring.register(CustomManagerDnNoPasswordConfig.class).autowire())
.withRootCauseInstanceOf(IllegalStateException.class)
.withMessageContaining("managerPassword is required if managerDn is supplied");
}
@EnableWebSecurity
@@ -104,7 +104,7 @@ public class EmbeddedLdapServerContextSourceFactoryBeanITests {
@Bean
EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
EmbeddedLdapServerContextSourceFactoryBean factoryBean = EmbeddedLdapServerContextSourceFactoryBean
.fromEmbeddedLdapServer();
.fromEmbeddedLdapServer();
factoryBean.setPort(0);
return factoryBean;
}
@@ -124,7 +124,7 @@ public class EmbeddedLdapServerContextSourceFactoryBeanITests {
@Bean
EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
EmbeddedLdapServerContextSourceFactoryBean factoryBean = EmbeddedLdapServerContextSourceFactoryBean
.fromEmbeddedLdapServer();
.fromEmbeddedLdapServer();
factoryBean.setLdif("classpath*:test-server2.xldif");
factoryBean.setRoot("dc=monkeymachine,dc=co,dc=uk");
return factoryBean;
@@ -145,7 +145,7 @@ public class EmbeddedLdapServerContextSourceFactoryBeanITests {
@Bean
EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
EmbeddedLdapServerContextSourceFactoryBean factoryBean = EmbeddedLdapServerContextSourceFactoryBean
.fromEmbeddedLdapServer();
.fromEmbeddedLdapServer();
factoryBean.setManagerDn("uid=admin,ou=system");
factoryBean.setManagerPassword("secret");
return factoryBean;
@@ -167,7 +167,7 @@ public class EmbeddedLdapServerContextSourceFactoryBeanITests {
@Bean
EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
EmbeddedLdapServerContextSourceFactoryBean factoryBean = EmbeddedLdapServerContextSourceFactoryBean
.fromEmbeddedLdapServer();
.fromEmbeddedLdapServer();
factoryBean.setManagerDn("uid=admin,ou=system");
return factoryBean;
}
@@ -65,7 +65,7 @@ public class LdapBindAuthenticationManagerFactoryITests {
this.spring.register(FromContextSourceConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(authenticated().withUsername("bob"));
.andExpect(authenticated().withUsername("bob"));
}
@Test
@@ -80,21 +80,19 @@ public class LdapBindAuthenticationManagerFactoryITests {
this.spring.register(CustomAuthoritiesPopulatorConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(
authenticated().withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_EXTRA"))));
this.mockMvc.perform(formLogin().user("bob").password("bobspassword")).andExpect(
authenticated().withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_EXTRA"))));
}
@Test
public void authenticationManagerFactoryWhenCustomAuthoritiesMapperThenUsed() throws Exception {
CustomAuthoritiesMapperConfig.AUTHORITIES_MAPPER = ((authorities) -> AuthorityUtils
.createAuthorityList("ROLE_CUSTOM"));
.createAuthorityList("ROLE_CUSTOM"));
this.spring.register(CustomAuthoritiesMapperConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(
authenticated().withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_CUSTOM"))));
this.mockMvc.perform(formLogin().user("bob").password("bobspassword")).andExpect(
authenticated().withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_CUSTOM"))));
}
@Test
@@ -114,7 +112,7 @@ public class LdapBindAuthenticationManagerFactoryITests {
this.spring.register(CustomUserDetailsContextMapperConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(authenticated().withUsername("other"));
.andExpect(authenticated().withUsername("other"));
}
@Test
@@ -122,7 +120,7 @@ public class LdapBindAuthenticationManagerFactoryITests {
this.spring.register(CustomUserDnPatternsConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(authenticated().withUsername("bob"));
.andExpect(authenticated().withUsername("bob"));
}
@Test
@@ -130,7 +128,7 @@ public class LdapBindAuthenticationManagerFactoryITests {
this.spring.register(CustomUserSearchConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(authenticated().withUsername("bob"));
.andExpect(authenticated().withUsername("bob"));
}
@EnableWebSecurity
@@ -49,7 +49,7 @@ public class LdapPasswordComparisonAuthenticationManagerFactoryITests {
this.spring.register(CustomPasswordEncoderConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bcrypt").password("password"))
.andExpect(authenticated().withUsername("bcrypt"));
.andExpect(authenticated().withUsername("bcrypt"));
}
@Test
@@ -56,7 +56,7 @@ public class LdapProviderBeanDefinitionParserTests {
AuthenticationManager authenticationManager = this.appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER,
AuthenticationManager.class);
Authentication auth = authenticationManager
.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("ben", "benspassword"));
.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("ben", "benspassword"));
UserDetails ben = (UserDetails) auth.getPrincipal();
assertThat(ben.getAuthorities()).hasSize(3);
}
@@ -71,7 +71,7 @@ public class LdapProviderBeanDefinitionParserTests {
ProviderManager providerManager = this.appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER, ProviderManager.class);
assertThat(providerManager.getProviders()).hasSize(2);
assertThat(providerManager.getProviders()).extracting("authoritiesPopulator.groupSearchFilter")
.containsExactly("member={0}", "uniqueMember={0}");
.containsExactly("member={0}", "uniqueMember={0}");
}
@Test
@@ -89,7 +89,7 @@ public class LdapProviderBeanDefinitionParserTests {
AuthenticationManager authenticationManager = this.appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER,
AuthenticationManager.class);
Authentication auth = authenticationManager
.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("ben", "benspassword"));
.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("ben", "benspassword"));
assertThat(auth).isNotNull();
}
@@ -105,7 +105,7 @@ public class LdapProviderBeanDefinitionParserTests {
AuthenticationManager authenticationManager = this.appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER,
AuthenticationManager.class);
Authentication auth = authenticationManager
.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("ben", "ben"));
.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("ben", "ben"));
assertThat(auth).isNotNull();
}
@@ -122,7 +122,7 @@ public class LdapProviderBeanDefinitionParserTests {
AuthenticationManager authenticationManager = this.appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER,
AuthenticationManager.class);
Authentication auth = authenticationManager
.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("bcrypt", "password"));
.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("bcrypt", "password"));
assertThat(auth).isNotNull();
}
@@ -137,8 +137,8 @@ public class LdapProviderBeanDefinitionParserTests {
ProviderManager providerManager = this.appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER, ProviderManager.class);
assertThat(providerManager.getProviders()).hasSize(1);
assertThat(providerManager.getProviders()).extracting("userDetailsContextMapper")
.allSatisfy((contextMapper) -> assertThat(contextMapper).isInstanceOf(InetOrgPersonContextMapper.class));
assertThat(providerManager.getProviders()).extracting("userDetailsContextMapper").allSatisfy(
(contextMapper) -> assertThat(contextMapper).isInstanceOf(InetOrgPersonContextMapper.class));
}
@Test
@@ -155,10 +155,10 @@ public class LdapProviderBeanDefinitionParserTests {
AuthenticationProvider authenticationProvider = providerManager.getProviders().get(0);
assertThat(authenticationProvider).extracting("authenticator.userDnFormat")
.satisfies((messageFormats) -> assertThat(messageFormats)
.isEqualTo(new MessageFormat[] { new MessageFormat("uid={0},ou=people") }));
.satisfies((messageFormats) -> assertThat(messageFormats)
.isEqualTo(new MessageFormat[] { new MessageFormat("uid={0},ou=people") }));
assertThat(authenticationProvider).extracting("authoritiesPopulator.groupSearchFilter")
.satisfies((searchFilter) -> assertThat(searchFilter).isEqualTo("member={0}"));
.satisfies((searchFilter) -> assertThat(searchFilter).isEqualTo("member={0}"));
}
}
@@ -52,7 +52,7 @@ public class LdapServerBeanDefinitionParserTests {
this.appCtx = new InMemoryXmlApplicationContext("<ldap-server ldif='classpath:test-server.ldif' port='0'/>");
DefaultSpringSecurityContextSource contextSource = (DefaultSpringSecurityContextSource) this.appCtx
.getBean(BeanIds.CONTEXT_SOURCE);
.getBean(BeanIds.CONTEXT_SOURCE);
// Check data is loaded
LdapTemplate template = new LdapTemplate(contextSource);
@@ -71,7 +71,7 @@ public class LdapServerBeanDefinitionParserTests {
this.appCtx.getBean(BeanIds.CONTEXT_SOURCE);
DefaultSpringSecurityContextSource contextSource = (DefaultSpringSecurityContextSource) this.appCtx
.getBean("blah");
.getBean("blah");
// Check data is loaded as before
LdapTemplate template = new LdapTemplate(contextSource);
@@ -83,7 +83,7 @@ public class LdapServerBeanDefinitionParserTests {
this.appCtx = new InMemoryXmlApplicationContext(
"<ldap-server ldif='classpath*:test-server2.xldif' root='dc=monkeymachine,dc=co,dc=uk' port='0'/>");
DefaultSpringSecurityContextSource contextSource = (DefaultSpringSecurityContextSource) this.appCtx
.getBean(BeanIds.CONTEXT_SOURCE);
.getBean(BeanIds.CONTEXT_SOURCE);
LdapTemplate template = new LdapTemplate(contextSource);
template.lookup("uid=pg,ou=gorillas");
@@ -58,17 +58,17 @@ public class LdapUserServiceBeanDefinitionParserTests {
@Test
public void beanClassNamesAreCorrect() {
assertThat(FilterBasedLdapUserSearch.class.getName())
.isEqualTo(LdapUserServiceBeanDefinitionParser.LDAP_SEARCH_CLASS);
.isEqualTo(LdapUserServiceBeanDefinitionParser.LDAP_SEARCH_CLASS);
assertThat(PersonContextMapper.class.getName())
.isEqualTo(LdapUserServiceBeanDefinitionParser.PERSON_MAPPER_CLASS);
.isEqualTo(LdapUserServiceBeanDefinitionParser.PERSON_MAPPER_CLASS);
assertThat(InetOrgPersonContextMapper.class.getName())
.isEqualTo(LdapUserServiceBeanDefinitionParser.INET_ORG_PERSON_MAPPER_CLASS);
.isEqualTo(LdapUserServiceBeanDefinitionParser.INET_ORG_PERSON_MAPPER_CLASS);
assertThat(LdapUserDetailsMapper.class.getName())
.isEqualTo(LdapUserServiceBeanDefinitionParser.LDAP_USER_MAPPER_CLASS);
.isEqualTo(LdapUserServiceBeanDefinitionParser.LDAP_USER_MAPPER_CLASS);
assertThat(DefaultLdapAuthoritiesPopulator.class.getName())
.isEqualTo(LdapUserServiceBeanDefinitionParser.LDAP_AUTHORITIES_POPULATOR_CLASS);
.isEqualTo(LdapUserServiceBeanDefinitionParser.LDAP_AUTHORITIES_POPULATOR_CLASS);
assertThat(new LdapUserServiceBeanDefinitionParser().getBeanClassName(mock(Element.class)))
.isEqualTo(LdapUserDetailsService.class.getName());
.isEqualTo(LdapUserDetailsService.class.getName());
}
@Test
@@ -85,19 +85,17 @@ public final class SecurityNamespaceHandler implements NamespaceHandler {
String version = pkg.getImplementationVersion();
this.logger.info("Spring Security 'config' module version is " + version);
if (version.compareTo(coreVersion) != 0) {
this.logger
.error("You are running with different versions of the Spring Security 'core' and 'config' modules");
this.logger.error(
"You are running with different versions of the Spring Security 'core' and 'config' modules");
}
}
@Override
public BeanDefinition parse(Element element, ParserContext pc) {
if (!namespaceMatchesVersion(element)) {
pc.getReaderContext()
.fatal("You cannot use a spring-security-2.0.xsd or spring-security-3.0.xsd or "
+ "spring-security-3.1.xsd schema or spring-security-3.2.xsd schema or spring-security-4.0.xsd schema "
+ "with Spring Security 5.8. Please update your schema declarations to the 5.8 schema.",
element);
pc.getReaderContext().fatal("You cannot use a spring-security-2.0.xsd or spring-security-3.0.xsd or "
+ "spring-security-3.1.xsd schema or spring-security-3.2.xsd schema or spring-security-4.0.xsd schema "
+ "with Spring Security 5.7. Please update your schema declarations to the 5.7 schema.", element);
}
String name = pc.getDelegate().getLocalName(element);
BeanDefinitionParser parser = this.parsers.get(name);
@@ -142,9 +140,8 @@ public final class SecurityNamespaceHandler implements NamespaceHandler {
}
private void reportUnsupportedNodeType(String name, ParserContext pc, Node node) {
pc.getReaderContext()
.fatal("Security namespace does not support decoration of "
+ ((node instanceof Element) ? "element" : "attribute") + " [" + name + "]", node);
pc.getReaderContext().fatal("Security namespace does not support decoration of "
+ ((node instanceof Element) ? "element" : "attribute") + " [" + name + "]", node);
}
private void reportMissingWebClasses(String nodeName, ParserContext pc, Node node) {
@@ -221,7 +218,7 @@ public final class SecurityNamespaceHandler implements NamespaceHandler {
private boolean matchesVersionInternal(Element element) {
String schemaLocation = element.getAttributeNS("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation");
return schemaLocation.matches("(?m).*spring-security-5\\.8.*.xsd.*")
return schemaLocation.matches("(?m).*spring-security-5\\.7.*.xsd.*")
|| schemaLocation.matches("(?m).*spring-security.xsd.*")
|| !schemaLocation.matches("(?m).*spring-security.*");
}
@@ -176,7 +176,7 @@ public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBui
private <C extends SecurityConfigurer<O, B>> void add(C configurer) {
Assert.notNull(configurer, "configurer cannot be null");
Class<? extends SecurityConfigurer<O, B>> clazz = (Class<? extends SecurityConfigurer<O, B>>) configurer
.getClass();
.getClass();
synchronized (this.configurers) {
if (this.buildState.isConfigured()) {
throw new IllegalStateException("Cannot apply " + configurer + " to already built object");
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2013 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.
@@ -149,7 +149,7 @@ public class AuthenticationManagerBuilder
* {@link #getDefaultUserDetailsService()} method. Note that additional
* {@link UserDetailsService}'s may override this {@link UserDetailsService} as the
* default. See the <a href=
* "https://docs.spring.io/spring-security/reference/servlet/appendix/database-schema.html"
* "https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#user-schema"
* >User Schema</a> section of the reference for the default schema.
* </p>
* @return a {@link JdbcUserDetailsManagerConfigurer} to allow customization of the
@@ -184,9 +184,8 @@ public class AuthenticationConfiguration {
return Collections.emptyList();
}
for (String beanName : beanNamesForType) {
if (((ConfigurableApplicationContext) this.applicationContext).getBeanFactory()
.getBeanDefinition(beanName)
.isPrimary()) {
if (((ConfigurableApplicationContext) this.applicationContext).getBeanFactory().getBeanDefinition(beanName)
.isPrimary()) {
list.add(beanName);
}
}
@@ -219,7 +218,7 @@ public class AuthenticationConfiguration {
@Override
public void init(AuthenticationManagerBuilder auth) {
Map<String, Object> beansWithAnnotation = this.context
.getBeansWithAnnotation(EnableGlobalAuthentication.class);
.getBeansWithAnnotation(EnableGlobalAuthentication.class);
if (logger.isTraceEnabled()) {
logger.trace(LogMessage.format("Eagerly initializing %s", beansWithAnnotation));
}
@@ -98,6 +98,7 @@ import org.springframework.security.config.annotation.web.servlet.configuration.
* @see EnableWebMvcSecurity
* @see EnableWebSecurity
* @see EnableGlobalMethodSecurity
*
* @author Rob Winch
*
*/
@@ -67,7 +67,7 @@ class InitializeAuthenticationProviderBeanManagerConfigurer extends GlobalAuthen
*/
private <T> T getBeanOrNull(Class<T> type) {
String[] beanNames = InitializeAuthenticationProviderBeanManagerConfigurer.this.context
.getBeanNamesForType(type);
.getBeanNamesForType(type);
if (beanNames.length != 1) {
return null;
}
@@ -387,7 +387,7 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
*/
public PasswordCompareConfigurer passwordCompare() {
return new PasswordCompareConfigurer().passwordAttribute("password")
.passwordEncoder(NoOpPasswordEncoder.getInstance());
.passwordEncoder(NoOpPasswordEncoder.getInstance());
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2013 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.
@@ -43,9 +43,7 @@ import org.springframework.security.config.annotation.authentication.configurati
*
* @author Rob Winch
* @since 3.2
* @deprecated Use {@link EnableMethodSecurity} instead
*/
@Deprecated
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@@ -33,7 +33,6 @@ import org.springframework.security.access.prepost.PreFilter;
/**
* Enables Spring Security Method Security.
*
* @author Evgeniy Cheban
* @author Josh Cummings
* @since 5.6
@@ -26,9 +26,9 @@ import org.springframework.context.annotation.AdviceMode;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.Ordered;
import org.springframework.security.authorization.ReactiveAuthorizationManager;
/**
*
* @author Rob Winch
* @since 5.0
*/
@@ -69,11 +69,4 @@ public @interface EnableReactiveMethodSecurity {
*/
int order() default Ordered.LOWEST_PRECEDENCE;
/**
* Indicate whether {@link ReactiveAuthorizationManager} based Method Security to be
* used.
* @since 5.8
*/
boolean useAuthorizationManager() default false;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2013 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,9 +36,7 @@ import org.springframework.core.type.AnnotationMetadata;
*
* @author Rob Winch
* @since 3.2
* @deprecated Use {@link EnableMethodSecurity} instead
*/
@Deprecated
class GlobalMethodSecurityAspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-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.
@@ -73,8 +73,6 @@ import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.core.GrantedAuthorityDefaults;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.util.Assert;
/**
@@ -86,11 +84,7 @@ import org.springframework.util.Assert;
* @author Eddú Meléndez
* @since 3.2
* @see EnableGlobalMethodSecurity
* @deprecated Use {@link PrePostMethodSecurityConfiguration},
* {@link SecuredMethodSecurityConfiguration}, or
* {@link Jsr250MethodSecurityConfiguration} instead
*/
@Deprecated
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInitializingSingleton, BeanFactoryAware {
@@ -107,9 +101,6 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
};
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
private DefaultMethodSecurityExpressionHandler defaultMethodExpressionHandler = new DefaultMethodSecurityExpressionHandler();
private AuthenticationManager authenticationManager;
@@ -152,7 +143,6 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
this.methodSecurityInterceptor.setAccessDecisionManager(accessDecisionManager());
this.methodSecurityInterceptor.setAfterInvocationManager(afterInvocationManager());
this.methodSecurityInterceptor.setSecurityMetadataSource(methodSecurityMetadataSource);
this.methodSecurityInterceptor.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
RunAsManager runAsManager = runAsManager();
if (runAsManager != null) {
this.methodSecurityInterceptor.setRunAsManager(runAsManager);
@@ -320,7 +310,7 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
protected AuthenticationManager authenticationManager() throws Exception {
if (this.authenticationManager == null) {
DefaultAuthenticationEventPublisher eventPublisher = this.objectPostProcessor
.postProcess(new DefaultAuthenticationEventPublisher());
.postProcess(new DefaultAuthenticationEventPublisher());
this.auth = new AuthenticationManagerBuilder(this.objectPostProcessor);
this.auth.authenticationEventPublisher(eventPublisher);
configure(this.auth);
@@ -375,7 +365,7 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
if (isJsr250Enabled) {
GrantedAuthorityDefaults grantedAuthorityDefaults = getSingleBeanOrNull(GrantedAuthorityDefaults.class);
Jsr250MethodSecurityMetadataSource jsr250MethodSecurityMetadataSource = this.context
.getBean(Jsr250MethodSecurityMetadataSource.class);
.getBean(Jsr250MethodSecurityMetadataSource.class);
if (grantedAuthorityDefaults != null) {
jsr250MethodSecurityMetadataSource.setDefaultRolePrefix(grantedAuthorityDefaults.getRolePrefix());
}
@@ -403,7 +393,7 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
@Override
public final void setImportMetadata(AnnotationMetadata importMetadata) {
Map<String, Object> annotationAttributes = importMetadata
.getAnnotationAttributes(EnableGlobalMethodSecurity.class.getName());
.getAnnotationAttributes(EnableGlobalMethodSecurity.class.getName());
this.enableMethodSecurity = AnnotationAttributes.fromMap(annotationAttributes);
}
@@ -421,12 +411,6 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
this.expressionHandler = handlers.get(0);
}
@Autowired(required = false)
void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
Assert.notNull(securityContextHolderStrategy, "securityContextHolderStrategy cannot be null");
this.securityContextHolderStrategy = securityContextHolderStrategy;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.context = beanFactory;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-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.
@@ -34,9 +34,7 @@ import org.springframework.util.ClassUtils;
*
* @author Rob Winch
* @since 3.2
* @deprecated Use {@link MethodSecuritySelector} instead
*/
@Deprecated
final class GlobalMethodSecuritySelector implements ImportSelector {
@Override
@@ -51,7 +49,7 @@ final class GlobalMethodSecuritySelector implements ImportSelector {
Class<?> importingClass = ClassUtils.resolveClassName(importingClassMetadata.getClassName(),
ClassUtils.getDefaultClassLoader());
boolean skipMethodSecurityConfiguration = GlobalMethodSecurityConfiguration.class
.isAssignableFrom(importingClass);
.isAssignableFrom(importingClass);
AdviceMode mode = attributes.getEnum("mode");
boolean isProxy = AdviceMode.PROXY == mode;
String autoProxyClassName = isProxy ? AutoProxyRegistrar.class.getName()
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-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.springframework.security.access.annotation.Jsr250MethodSecurityMetada
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Deprecated
class Jsr250MetadataSourceConfiguration {
@Bean
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-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.
@@ -16,8 +16,7 @@
package org.springframework.security.config.annotation.method.configuration;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.Advisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
@@ -26,8 +25,6 @@ import org.springframework.context.annotation.Role;
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
import org.springframework.security.authorization.method.Jsr250AuthorizationManager;
import org.springframework.security.config.core.GrantedAuthorityDefaults;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
/**
* {@link Configuration} for enabling JSR-250 Spring Security Method Security.
@@ -43,16 +40,10 @@ final class Jsr250MethodSecurityConfiguration {
private final Jsr250AuthorizationManager jsr250AuthorizationManager = new Jsr250AuthorizationManager();
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
MethodInterceptor jsr250AuthorizationMethodInterceptor() {
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor
.jsr250(this.jsr250AuthorizationManager);
interceptor.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
return interceptor;
Advisor jsr250AuthorizationMethodInterceptor() {
return AuthorizationManagerBeforeMethodInterceptor.jsr250(this.jsr250AuthorizationManager);
}
@Autowired(required = false)
@@ -60,9 +51,4 @@ final class Jsr250MethodSecurityConfiguration {
this.jsr250AuthorizationManager.setRolePrefix(grantedAuthorityDefaults.getRolePrefix());
}
@Autowired(required = false)
void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
this.securityContextHolderStrategy = securityContextHolderStrategy;
}
}
@@ -1,56 +0,0 @@
/*
* Copyright 2002-2023 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.security.config.annotation.method.configuration;
import org.springframework.aop.Advisor;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
class MethodSecurityAdvisorRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
registerAsAdvisor("preFilterAuthorization", registry);
registerAsAdvisor("preAuthorizeAuthorization", registry);
registerAsAdvisor("postFilterAuthorization", registry);
registerAsAdvisor("postAuthorizeAuthorization", registry);
registerAsAdvisor("securedAuthorization", registry);
registerAsAdvisor("jsr250Authorization", registry);
}
private void registerAsAdvisor(String prefix, BeanDefinitionRegistry registry) {
String advisorName = prefix + "Advisor";
if (registry.containsBeanDefinition(advisorName)) {
return;
}
String interceptorName = prefix + "MethodInterceptor";
if (!registry.containsBeanDefinition(interceptorName)) {
return;
}
BeanDefinition definition = registry.getBeanDefinition(interceptorName);
if (!(definition instanceof RootBeanDefinition)) {
return;
}
RootBeanDefinition advisor = new RootBeanDefinition((RootBeanDefinition) definition);
advisor.setTargetType(Advisor.class);
registry.registerBeanDefinition(prefix + "Advisor", advisor);
}
}
@@ -1,78 +0,0 @@
/*
* Copyright 2002-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.security.config.annotation.method.configuration;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
/**
* Registers an
* {@link org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
* AnnotationAwareAspectJAutoProxyCreator} against the current
* {@link BeanDefinitionRegistry} as appropriate based on a given @
* {@link EnableMethodSecurity} annotation.
*
* <p>
* Note: This class is necessary because AspectJAutoProxyRegistrar only supports
* EnableAspectJAutoProxy.
* </p>
*
* @author Josh Cummings
* @since 5.8
*/
class MethodSecurityAspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableMethodSecurity#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
registerBeanDefinition("preFilterAuthorizationMethodInterceptor",
"org.springframework.security.authorization.method.aspectj.PreFilterAspect", "preFilterAspect$0",
registry);
registerBeanDefinition("postFilterAuthorizationMethodInterceptor",
"org.springframework.security.authorization.method.aspectj.PostFilterAspect", "postFilterAspect$0",
registry);
registerBeanDefinition("preAuthorizeAuthorizationMethodInterceptor",
"org.springframework.security.authorization.method.aspectj.PreAuthorizeAspect", "preAuthorizeAspect$0",
registry);
registerBeanDefinition("postAuthorizeAuthorizationMethodInterceptor",
"org.springframework.security.authorization.method.aspectj.PostAuthorizeAspect",
"postAuthorizeAspect$0", registry);
registerBeanDefinition("securedAuthorizationMethodInterceptor",
"org.springframework.security.authorization.method.aspectj.SecuredAspect", "securedAspect$0", registry);
}
private void registerBeanDefinition(String beanName, String aspectClassName, String aspectBeanName,
BeanDefinitionRegistry registry) {
if (!registry.containsBeanDefinition(beanName)) {
return;
}
BeanDefinition interceptor = registry.getBeanDefinition(beanName);
BeanDefinitionBuilder aspect = BeanDefinitionBuilder.rootBeanDefinition(aspectClassName);
aspect.setFactoryMethod("aspectOf");
aspect.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
aspect.addPropertyValue("securityInterceptor", interceptor);
registry.registerBeanDefinition(aspectBeanName, aspect.getBeanDefinition());
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-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.
@@ -32,9 +32,7 @@ import org.springframework.util.MultiValueMap;
* @author Rob Winch
* @since 4.0.2
* @see GlobalMethodSecuritySelector
* @deprecated Use {@link MethodSecuritySelector} instead
*/
@Deprecated
class MethodSecurityMetadataSourceAdvisorRegistrar implements ImportBeanDefinitionRegistrar {
/**
@@ -45,13 +43,13 @@ class MethodSecurityMetadataSourceAdvisorRegistrar implements ImportBeanDefiniti
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder advisor = BeanDefinitionBuilder
.rootBeanDefinition(MethodSecurityMetadataSourceAdvisor.class);
.rootBeanDefinition(MethodSecurityMetadataSourceAdvisor.class);
advisor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
advisor.addConstructorArgValue("methodSecurityInterceptor");
advisor.addConstructorArgReference("methodSecurityMetadataSource");
advisor.addConstructorArgValue("methodSecurityMetadataSource");
MultiValueMap<String, Object> attributes = importingClassMetadata
.getAllAnnotationAttributes(EnableGlobalMethodSecurity.class.getName());
.getAllAnnotationAttributes(EnableGlobalMethodSecurity.class.getName());
Integer order = (Integer) attributes.getFirst("order");
if (order != null) {
advisor.addPropertyValue("order", order);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-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.
@@ -60,20 +60,13 @@ final class MethodSecuritySelector implements ImportSelector {
private static final class AutoProxyRegistrarSelector extends AdviceModeImportSelector<EnableMethodSecurity> {
private static final String[] IMPORTS = new String[] { AutoProxyRegistrar.class.getName(),
MethodSecurityAdvisorRegistrar.class.getName() };
private static final String[] ASPECTJ_IMPORTS = new String[] {
MethodSecurityAspectJAutoProxyRegistrar.class.getName() };
private static final String[] IMPORTS = new String[] { AutoProxyRegistrar.class.getName() };
@Override
protected String[] selectImports(@NonNull AdviceMode adviceMode) {
if (adviceMode == AdviceMode.PROXY) {
return IMPORTS;
}
if (adviceMode == AdviceMode.ASPECTJ) {
return ASPECTJ_IMPORTS;
}
throw new IllegalStateException("AdviceMode '" + adviceMode + "' is not supported");
}

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