Compare commits
183 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8b9beb0e1f | |||
| 6230806d56 | |||
| 2159f3a93d | |||
| dc366cf8da | |||
| d32202bce3 | |||
| 349ac07c10 | |||
| 59be5553a1 | |||
| 2bfdb0c6cd | |||
| 2ed7b857c3 | |||
| a0b1d6317c | |||
| 731cd6131b | |||
| c2a589734c | |||
| e5e67f91e9 | |||
| ccb2f06d0d | |||
| fc658d10d3 | |||
| e0fc8f37b0 | |||
| 43ced5291b | |||
| 56c5fc281e | |||
| 7c3a6a567e | |||
| 07e0b1dc37 | |||
| 05d3c4b695 | |||
| 5f80cfc705 | |||
| 7011930305 | |||
| 8a75382b2d | |||
| ca10187fd1 | |||
| 56f486588f | |||
| 3f5f79d835 | |||
| 9985580534 | |||
| 24d4abe5fd | |||
| 16dc6be3c8 | |||
| c88aaedb48 | |||
| 9203567a20 | |||
| e058b559b8 | |||
| 33800c0124 | |||
| b71962e87d | |||
| b97c310aba | |||
| 59461d94b0 | |||
| fc007aa373 | |||
| eaaa813ede | |||
| 10b3a9b234 | |||
| e4cc0a4755 | |||
| ff71ef46b7 | |||
| 5593655bbf | |||
| 47812e506f | |||
| 89fd30f235 | |||
| c3c068376a | |||
| 6d68f403fc | |||
| 74d06f020d | |||
| e896b14046 | |||
| be11812fe4 | |||
| 9c44b700f5 | |||
| 40e8b20257 | |||
| c336ca49fb | |||
| c623303ca5 | |||
| a98baa7522 | |||
| bb0987db80 | |||
| d961307044 | |||
| 4ca54683ae | |||
| a7da9491d9 | |||
| 382cfd63ed | |||
| 7c98a39770 | |||
| 6afcc02ef3 | |||
| 773673ac2c | |||
| 7335c5745c | |||
| 52675c80b3 | |||
| b919ece045 | |||
| 11a21896dd | |||
| eff9814d7b | |||
| 058495d463 | |||
| ffd12ee3b9 | |||
| 3f64c6d745 | |||
| 2cd302fb1b | |||
| e8ec49b4c5 | |||
| 602d4189d1 | |||
| 884014c2fb | |||
| 47969ec7c9 | |||
| 6654479649 | |||
| bfc31bacab | |||
| ad2bea3350 | |||
| 5161712c35 | |||
| a6b872dcf3 | |||
| 70ad3bf749 | |||
| 19c4e427ee | |||
| 736f1c27cd | |||
| ec58bf0b28 | |||
| e4e31f2c90 | |||
| 49cd8ae217 | |||
| 81d91063a5 | |||
| 7f50bb5db1 | |||
| 7556df6ea7 | |||
| 71ceb5b80b | |||
| bd9643af44 | |||
| d46627b776 | |||
| 8c6b5e0efe | |||
| 3315775734 | |||
| cefcbdc819 | |||
| 0b25dc53cc | |||
| 766396aa7c | |||
| 64270f28e4 | |||
| ece5089cc8 | |||
| 448d23dd3e | |||
| 0108241049 | |||
| 88cfae4182 | |||
| b9836d618a | |||
| 2505c08e8f | |||
| 9e877c9bc6 | |||
| adef0f3f25 | |||
| a8eb565b05 | |||
| 64e2a2ff8b | |||
| 650692964e | |||
| e29ea47ff7 | |||
| 664ee9a206 | |||
| b67218c150 | |||
| ac04c2e675 | |||
| e63d7fd9e9 | |||
| 718c470910 | |||
| 700b711c4b | |||
| c614422f44 | |||
| 85e0783796 | |||
| 3656fa6e0c | |||
| 564a022ab6 | |||
| 779541b340 | |||
| 5b293d2116 | |||
| f026e29771 | |||
| 620e6e0c34 | |||
| 4ebfa2c804 | |||
| 3feb809b35 | |||
| 9b7a110704 | |||
| ce012a4661 | |||
| 96d1763fc4 | |||
| 8efbbb3eb5 | |||
| 612909ac4f | |||
| 28f98b3351 | |||
| ed96e2cddf | |||
| 7200f76ac1 | |||
| 094b71b329 | |||
| 491f0f647c | |||
| 1db8734101 | |||
| 4b44a2d924 | |||
| e8b9a35494 | |||
| 82e5f62079 | |||
| 30bc2634d7 | |||
| 13ca7ac4d4 | |||
| c4f061c63d | |||
| 2c6d053ceb | |||
| ff4745a461 | |||
| 38a7ffcc9b | |||
| 6f55fc60bb | |||
| d0491c07e9 | |||
| 486c5118d2 | |||
| d02ab50577 | |||
| 17d8293be1 | |||
| bb46a54270 | |||
| df239b6448 | |||
| a939f17890 | |||
| fe9bc26bdc | |||
| 7813a9ba26 | |||
| 7d58b9391a | |||
| dc3cb68c76 | |||
| 8555c100d7 | |||
| ae46531add | |||
| 0121b08a85 | |||
| 56292c9971 | |||
| 4fc938555e | |||
| e574415244 | |||
| c5da886310 | |||
| 3bef5fd3ed | |||
| b7a9a654f0 | |||
| e7201c48d1 | |||
| a642fdb004 | |||
| 991b398c55 | |||
| 40d61743b9 | |||
| 8895a66a2b | |||
| 80a5028f3f | |||
| c30bacac10 | |||
| a104dec30d | |||
| 488b6ea531 | |||
| ef04ea9d68 | |||
| b7be4c462c | |||
| aa8440e1ee | |||
| 6d3f1699c0 | |||
| bb72eed8d1 | |||
| 108075763b |
@@ -2,8 +2,8 @@ name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
branches-ignore:
|
||||
- "dependabot/**"
|
||||
schedule:
|
||||
- cron: '0 10 * * *' # Once per day at 10am UTC
|
||||
workflow_dispatch: # Manual trigger
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
runjobs: ${{ steps.continue.outputs.runjobs }}
|
||||
project_version: ${{ steps.continue.outputs.project_version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- id: continue
|
||||
name: Determine if should continue
|
||||
run: |
|
||||
@@ -49,15 +49,15 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
if: needs.prerequisites.outputs.runjobs
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'adopt'
|
||||
cache: 'gradle'
|
||||
- name: Set up Gradle
|
||||
uses: gradle/gradle-build-action@v2
|
||||
uses: gradle/gradle-build-action@v3
|
||||
- name: Set up gradle user name
|
||||
run: echo 'systemProp.user.name=spring-builds+github' >> gradle.properties
|
||||
- name: Build with Gradle
|
||||
@@ -72,9 +72,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: needs.prerequisites.outputs.runjobs
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up gradle
|
||||
uses: spring-io/spring-gradle-build-action@v1
|
||||
uses: spring-io/spring-gradle-build-action@v2
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'adopt'
|
||||
@@ -83,16 +83,16 @@ jobs:
|
||||
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
|
||||
./gradlew test --refresh-dependencies -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" -PforceMavenRepositories=snapshot -PisOverrideVersionCatalog -PspringFrameworkVersion='5.+' -PreactorVersion='2020.0.+' -PspringDataVersion='2021.2.+' -PlocksDisabled --stacktrace
|
||||
check_samples:
|
||||
name: Check Samples project
|
||||
needs: [prerequisites]
|
||||
runs-on: ubuntu-latest
|
||||
if: needs.prerequisites.outputs.runjobs
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up gradle
|
||||
uses: spring-io/spring-gradle-build-action@v1
|
||||
uses: spring-io/spring-gradle-build-action@v2
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'adopt'
|
||||
@@ -114,9 +114,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: needs.prerequisites.outputs.runjobs
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up gradle
|
||||
uses: spring-io/spring-gradle-build-action@v1
|
||||
uses: spring-io/spring-gradle-build-action@v2
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'adopt'
|
||||
@@ -131,9 +131,9 @@ jobs:
|
||||
needs: [build_jdk_11, snapshot_tests, check_samples, check_tangles]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up gradle
|
||||
uses: spring-io/spring-gradle-build-action@v1
|
||||
uses: spring-io/spring-gradle-build-action@v2
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'adopt'
|
||||
@@ -155,9 +155,9 @@ jobs:
|
||||
needs: [build_jdk_11, snapshot_tests, check_samples, check_tangles]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up gradle
|
||||
uses: spring-io/spring-gradle-build-action@v1
|
||||
uses: spring-io/spring-gradle-build-action@v2
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'adopt'
|
||||
@@ -176,9 +176,9 @@ jobs:
|
||||
needs: [build_jdk_11, snapshot_tests, check_samples, check_tangles]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up gradle
|
||||
uses: spring-io/spring-gradle-build-action@v1
|
||||
uses: spring-io/spring-gradle-build-action@v2
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'adopt'
|
||||
@@ -206,11 +206,11 @@ jobs:
|
||||
TOKEN: ${{ github.token }}
|
||||
VERSION: ${{ needs.prerequisites.outputs.project_version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
|
||||
- name: Set up gradle
|
||||
uses: spring-io/spring-gradle-build-action@v1
|
||||
uses: spring-io/spring-gradle-build-action@v2
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'adopt'
|
||||
@@ -243,7 +243,7 @@ jobs:
|
||||
./gradlew createGitHubRelease -PnextVersion=$VERSION -Pbranch=$BRANCH -PcreateRelease=true -PgitHubAccessToken=$TOKEN
|
||||
- name: Announce Release on Slack
|
||||
id: spring-security-announcing
|
||||
uses: slackapi/slack-github-action@v1.19.0
|
||||
uses: slackapi/slack-github-action@v1.25.0
|
||||
with:
|
||||
payload: |
|
||||
{
|
||||
@@ -287,9 +287,9 @@ jobs:
|
||||
TOKEN: ${{ github.token }}
|
||||
VERSION: ${{ needs.prerequisites.outputs.project_version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up gradle
|
||||
uses: spring-io/spring-gradle-build-action@v1
|
||||
uses: spring-io/spring-gradle-build-action@v2
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'adopt'
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
name: Deploy Docs
|
||||
on:
|
||||
push:
|
||||
branches-ignore: [ gh-pages ]
|
||||
branches-ignore:
|
||||
- "gh-pages"
|
||||
- "dependabot/**"
|
||||
tags: '**'
|
||||
repository_dispatch:
|
||||
types: request-build-reference # legacy
|
||||
@@ -15,7 +17,7 @@ jobs:
|
||||
if: github.repository_owner == 'spring-projects'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: docs-build
|
||||
fetch-depth: 1
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
name: Merge Dependabot PR
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
run-name: Merge Dependabot PR ${{ github.ref_name }}
|
||||
|
||||
jobs:
|
||||
merge-dependabot-pr:
|
||||
permissions: write-all
|
||||
uses: spring-io/spring-github-workflows/.github/workflows/spring-merge-dependabot-pr.yml@1e8b0587a1f4f01697f9753fa3339c3e0d30f396
|
||||
with:
|
||||
mergeArguments: '--auto --rebase'
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
actions: read
|
||||
steps:
|
||||
- name: Send Slack message
|
||||
uses: Gamesight/slack-workflow-status@v1.0.1
|
||||
uses: Gamesight/slack-workflow-status@v1.3.0
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
|
||||
@@ -2,6 +2,11 @@ name: PR Build
|
||||
|
||||
on: pull_request
|
||||
|
||||
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 }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
@@ -11,9 +16,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'spring-projects/spring-security' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up gradle
|
||||
uses: spring-io/spring-gradle-build-action@v1
|
||||
uses: spring-io/spring-gradle-build-action@v2
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'adopt'
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
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
|
||||
@@ -23,11 +23,11 @@ jobs:
|
||||
steps:
|
||||
- id: checkout-source
|
||||
name: Checkout Source Code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
|
||||
- name: Set up gradle
|
||||
uses: spring-io/spring-gradle-build-action@v1
|
||||
uses: spring-io/spring-gradle-build-action@v2
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'adopt'
|
||||
@@ -72,7 +72,7 @@ jobs:
|
||||
- id: send-slack-notification
|
||||
name: Send Slack message
|
||||
if: failure()
|
||||
uses: Gamesight/slack-workflow-status@v1.0.1
|
||||
uses: Gamesight/slack-workflow-status@v1.3.0
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ import org.springframework.util.Assert;
|
||||
public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
|
||||
|
||||
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||
.getContextHolderStrategy();
|
||||
.getContextHolderStrategy();
|
||||
|
||||
private final GrantedAuthority gaGeneralChanges;
|
||||
|
||||
|
||||
+2
-2
@@ -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)) {
|
||||
|
||||
+1
-1
@@ -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");
|
||||
|
||||
@@ -66,7 +66,7 @@ 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();
|
||||
.getContextHolderStrategy();
|
||||
|
||||
private boolean foreignKeysInDatabase = true;
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -85,7 +85,8 @@ 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));
|
||||
}
|
||||
|
||||
|
||||
+7
-6
@@ -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,7 +126,8 @@ 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));
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -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(
|
||||
|
||||
@@ -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,12 +246,14 @@ 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));
|
||||
@@ -292,7 +294,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();
|
||||
@@ -303,13 +305,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
|
||||
@@ -396,20 +398,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
|
||||
@@ -417,7 +419,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
|
||||
@@ -435,7 +437,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
|
||||
@@ -466,7 +468,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);
|
||||
|
||||
+11
-11
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -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,10 +47,12 @@ 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
|
||||
@@ -64,20 +66,23 @@ 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]");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -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
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+12
-12
@@ -168,7 +168,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 +196,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 +209,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 +266,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 +277,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 +297,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 +320,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
|
||||
@@ -392,7 +392,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);
|
||||
|
||||
+1
-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
-1
@@ -101,7 +101,7 @@ public class AnnotationSecurityAspectTests {
|
||||
@Test
|
||||
public void securedClassMethodDeniesUnauthenticatedAccess() {
|
||||
assertThatExceptionOfType(AuthenticationCredentialsNotFoundException.class)
|
||||
.isThrownBy(() -> this.secured.securedClassMethod());
|
||||
.isThrownBy(() -> this.secured.securedClassMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ public class PostAuthorizeAspectTests {
|
||||
@Test
|
||||
public void securedClassMethodDeniesUnauthenticatedAccess() {
|
||||
assertThatExceptionOfType(AuthenticationCredentialsNotFoundException.class)
|
||||
.isThrownBy(() -> this.secured.securedClassMethod());
|
||||
.isThrownBy(() -> this.secured.securedClassMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ public class PreAuthorizeAspectTests {
|
||||
@Test
|
||||
public void securedClassMethodDeniesUnauthenticatedAccess() {
|
||||
assertThatExceptionOfType(AuthenticationCredentialsNotFoundException.class)
|
||||
.isThrownBy(() -> this.secured.securedClassMethod());
|
||||
.isThrownBy(() -> this.secured.securedClassMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ public class SecuredAspectTests {
|
||||
@Test
|
||||
public void securedClassMethodDeniesUnauthenticatedAccess() {
|
||||
assertThatExceptionOfType(AuthenticationCredentialsNotFoundException.class)
|
||||
.isThrownBy(() -> this.secured.securedClassMethod());
|
||||
.isThrownBy(() -> this.secured.securedClassMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+9
-60
@@ -1,12 +1,13 @@
|
||||
import io.spring.gradle.IncludeRepoTask
|
||||
import trang.RncToXsd
|
||||
|
||||
buildscript {
|
||||
dependencies {
|
||||
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.5.1"
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
|
||||
classpath "com.netflix.nebula:nebula-project-plugin:8.2.0"
|
||||
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
|
||||
}
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
@@ -18,12 +19,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'
|
||||
|
||||
group = 'org.springframework.security'
|
||||
description = 'Spring Security'
|
||||
@@ -85,58 +86,6 @@ 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()
|
||||
alphaBetaVersions()
|
||||
snapshotVersions()
|
||||
addRule { components ->
|
||||
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.withModule("io.mockk:mockk") { selection ->
|
||||
ModuleComponentIdentifier candidate = selection.getCandidate();
|
||||
if (!candidate.getVersion().equals(selection.getCurrentVersion())) {
|
||||
selection.reject("mockk updates break tests");
|
||||
}
|
||||
}
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
plugins.withType(JavaPlugin) {
|
||||
project.sourceCompatibility='1.8'
|
||||
@@ -156,7 +105,7 @@ allprojects {
|
||||
pluginManager.withPlugin("io.spring.convention.checkstyle", { plugin ->
|
||||
configure(plugin) {
|
||||
dependencies {
|
||||
checkstyle "io.spring.javaformat:spring-javaformat-checkstyle:$springJavaformatVersion"
|
||||
checkstyle libs.io.spring.javaformat.spring.javaformat.checkstyle
|
||||
}
|
||||
checkstyle {
|
||||
toolVersion = '8.34'
|
||||
@@ -189,7 +138,7 @@ if (hasProperty('buildScan')) {
|
||||
|
||||
nohttp {
|
||||
source.exclude "buildSrc/build/**"
|
||||
|
||||
source.builtBy(project(':spring-security-config').tasks.withType(RncToXsd))
|
||||
}
|
||||
|
||||
tasks.register('cloneSamples', IncludeRepoTask) {
|
||||
|
||||
+29
-27
@@ -2,7 +2,6 @@ plugins {
|
||||
id "java-gradle-plugin"
|
||||
id "java"
|
||||
id "groovy"
|
||||
id 'com.apollographql.apollo' version '2.4.5'
|
||||
}
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
@@ -41,10 +40,6 @@ 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"
|
||||
@@ -69,6 +64,10 @@ gradlePlugin {
|
||||
id = "s101"
|
||||
implementationClass = "s101.S101Plugin"
|
||||
}
|
||||
verifyDependenciesVersions {
|
||||
id = "org.springframework.security.versions.verify-dependencies-versions"
|
||||
implementationClass = "org.springframework.security.convention.versions.VerifyDependenciesVersionsPlugin"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,34 +78,37 @@ configurations {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
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 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 localGroovy()
|
||||
|
||||
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'
|
||||
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
|
||||
|
||||
testImplementation platform('org.junit:junit-bom:5.9.3')
|
||||
testImplementation platform(libs.org.junit.junit.bom)
|
||||
testImplementation platform(libs.org.mockito.mockito.bom)
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-params"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-engine"
|
||||
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"
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
dependencyResolutionManagement {
|
||||
versionCatalogs {
|
||||
libs {
|
||||
from(files("../gradle/libs.versions.toml"))
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-4
@@ -34,6 +34,14 @@ 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 {
|
||||
@@ -67,12 +75,11 @@ 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/'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.JavaPlugin
|
||||
import org.gradle.api.tasks.bundling.Zip
|
||||
import org.springframework.gradle.xsd.CreateVersionlessXsdTask
|
||||
|
||||
public class SchemaZipPlugin implements Plugin<Project> {
|
||||
|
||||
@@ -15,7 +16,10 @@ public class SchemaZipPlugin implements Plugin<Project> {
|
||||
schemaZip.archiveClassifier = 'schema'
|
||||
schemaZip.description = "Builds -${schemaZip.archiveClassifier} archive containing all " +
|
||||
"XSDs for deployment at static.springframework.org/schema."
|
||||
|
||||
def versionlessXsd = project.tasks.create("versionlessXsd", CreateVersionlessXsdTask) {
|
||||
description = "Generates spring-security.xsd"
|
||||
versionlessXsdFile = project.layout.buildDirectory.file("versionlessXsd/spring-security.xsd")
|
||||
}
|
||||
project.rootProject.subprojects.each { module ->
|
||||
|
||||
module.getPlugins().withType(JavaPlugin.class).all {
|
||||
@@ -36,17 +40,14 @@ public class SchemaZipPlugin implements Plugin<Project> {
|
||||
duplicatesStrategy 'exclude'
|
||||
from xsdFile.path
|
||||
}
|
||||
}
|
||||
File symlink = module.sourceSets.main.resources.find {
|
||||
it.path.endsWith('org/springframework/security/config/spring-security.xsd')
|
||||
}
|
||||
if (symlink != null) {
|
||||
schemaZip.into('security') {
|
||||
duplicatesStrategy 'exclude'
|
||||
from symlink.path
|
||||
}
|
||||
versionlessXsd.getInputFiles().from(xsdFile.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
schemaZip.into("security") {
|
||||
from(versionlessXsd.getOutputs())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+12
-3
@@ -16,15 +16,21 @@
|
||||
|
||||
package org.springframework.gradle.sagan;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
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 {
|
||||
|
||||
private static final Pattern VERSION_PATTERN = Pattern.compile("^([0-9]+)\\.([0-9]+)\\.([0-9]+)(-.+)?$");
|
||||
|
||||
@Input
|
||||
private String gitHubAccessToken;
|
||||
@Input
|
||||
@@ -44,9 +50,12 @@ public class SaganCreateReleaseTask extends DefaultTask {
|
||||
// Antora reference docs URLs for snapshots do not contain -SNAPSHOT
|
||||
String referenceDocUrl = this.referenceDocUrl;
|
||||
if (this.version.endsWith("-SNAPSHOT")) {
|
||||
referenceDocUrl = this.referenceDocUrl
|
||||
.replace("{version}", this.version)
|
||||
.replace("-SNAPSHOT", "");
|
||||
Matcher versionMatcher = VERSION_PATTERN.matcher(this.version);
|
||||
Assert.isTrue(versionMatcher.matches(), "Version " + this.version + " does not match expected pattern");
|
||||
String majorVersion = versionMatcher.group(1);
|
||||
String minorVersion = versionMatcher.group(2);
|
||||
String majorMinorVersion = String.format("%s.%s-SNAPSHOT", majorVersion, minorVersion);
|
||||
referenceDocUrl = this.referenceDocUrl.replace("{version}", majorMinorVersion);
|
||||
}
|
||||
|
||||
SaganApi sagan = new SaganApi(user.getLogin(), this.gitHubAccessToken);
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright 2019-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.gradle.xsd;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.file.ConfigurableFileCollection;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.tasks.*;
|
||||
import org.gradle.work.DisableCachingByDefault;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Creates the spring-security.xsd automatically
|
||||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
@DisableCachingByDefault(because = "not worth it")
|
||||
public abstract class CreateVersionlessXsdTask extends DefaultTask {
|
||||
|
||||
@InputFiles
|
||||
public abstract ConfigurableFileCollection getInputFiles();
|
||||
|
||||
@OutputFile
|
||||
abstract RegularFileProperty getVersionlessXsdFile();
|
||||
|
||||
@TaskAction
|
||||
void createVersionlessXsd() throws IOException {
|
||||
XsdFileMajorMinorVersion largest = null;
|
||||
ConfigurableFileCollection inputFiles = getInputFiles();
|
||||
if (inputFiles.isEmpty()) {
|
||||
throw new IllegalStateException("No Inputs configured");
|
||||
}
|
||||
for (File file : inputFiles) {
|
||||
XsdFileMajorMinorVersion current = XsdFileMajorMinorVersion.create(file);
|
||||
if (current == null) {
|
||||
continue;
|
||||
}
|
||||
if (largest == null) {
|
||||
largest = current;
|
||||
}
|
||||
else if (current.getVersion().isGreaterThan(largest.getVersion())) {
|
||||
largest = current;
|
||||
}
|
||||
}
|
||||
if (largest == null) {
|
||||
throw new IllegalStateException("Could not create versionless xsd file because no files matching spring-security-<digit>.xsd were found in " + inputFiles.getFiles());
|
||||
}
|
||||
Path to = getVersionlessXsdFile().getAsFile().get().toPath();
|
||||
Path from = largest.getFile().toPath();
|
||||
Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
|
||||
}
|
||||
|
||||
static class XsdFileMajorMinorVersion {
|
||||
private final File file;
|
||||
|
||||
private final MajorMinorVersion version;
|
||||
|
||||
private XsdFileMajorMinorVersion(File file, MajorMinorVersion version) {
|
||||
this.file = file;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
private static final Pattern FILE_MAJOR_MINOR_VERSION_PATTERN = Pattern.compile("^spring-security-(\\d+)\\.(\\d+)\\.xsd$");
|
||||
|
||||
/**
|
||||
* If matches xsd with major minor version (e.g. spring-security-5.1.xsd returns it, otherwise null
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
static XsdFileMajorMinorVersion create(File file) {
|
||||
String fileName = file.getName();
|
||||
Matcher matcher = FILE_MAJOR_MINOR_VERSION_PATTERN.matcher(fileName);
|
||||
if (!matcher.find()) {
|
||||
return null;
|
||||
}
|
||||
int major = Integer.parseInt(matcher.group(1));
|
||||
int minor = Integer.parseInt(matcher.group(2));
|
||||
MajorMinorVersion version = new MajorMinorVersion(major, minor);
|
||||
return new XsdFileMajorMinorVersion(file, version);
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public MajorMinorVersion getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
||||
static class MajorMinorVersion {
|
||||
private final int major;
|
||||
|
||||
private final int minor;
|
||||
|
||||
MajorMinorVersion(int major, int minor) {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
}
|
||||
|
||||
public int getMajor() {
|
||||
return major;
|
||||
}
|
||||
|
||||
public int getMinor() {
|
||||
return minor;
|
||||
}
|
||||
|
||||
public boolean isGreaterThan(MajorMinorVersion version) {
|
||||
if (getMajor() > version.getMajor()) {
|
||||
return true;
|
||||
}
|
||||
if (getMajor() < version.getMajor()) {
|
||||
return false;
|
||||
}
|
||||
if (getMinor() > version.getMinor()) {
|
||||
return true;
|
||||
}
|
||||
if (getMinor() < version.getMinor()) {
|
||||
return false;
|
||||
}
|
||||
// they are equal
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.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());
|
||||
}
|
||||
}
|
||||
}
|
||||
-179
@@ -1,179 +0,0 @@
|
||||
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
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2020 the original author or authors.
|
||||
* 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.
|
||||
|
||||
-198
@@ -1,198 +0,0 @@
|
||||
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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
-244
@@ -1,244 +0,0 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+7
-7
@@ -125,27 +125,27 @@ public class RepositoryConventionPluginTests {
|
||||
|
||||
private void assertSnapshotRepository(RepositoryHandler repositories) {
|
||||
assertThat(repositories).extracting(ArtifactRepository::getName).hasSize(5);
|
||||
assertThat(((MavenArtifactRepository) repositories.get(0)).getUrl().toString())
|
||||
.isEqualTo("https://repo.maven.apache.org/maven2/");
|
||||
assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString())
|
||||
.isEqualTo("https://repo.spring.io/snapshot/");
|
||||
.isEqualTo("https://repo.maven.apache.org/maven2/");
|
||||
assertThat(((MavenArtifactRepository) repositories.get(2)).getUrl().toString())
|
||||
.isEqualTo("https://repo.spring.io/snapshot/");
|
||||
assertThat(((MavenArtifactRepository) repositories.get(3)).getUrl().toString())
|
||||
.isEqualTo("https://repo.spring.io/milestone/");
|
||||
}
|
||||
|
||||
private void assertMilestoneRepository(RepositoryHandler repositories) {
|
||||
assertThat(repositories).extracting(ArtifactRepository::getName).hasSize(4);
|
||||
assertThat(((MavenArtifactRepository) repositories.get(0)).getUrl().toString())
|
||||
.isEqualTo("https://repo.maven.apache.org/maven2/");
|
||||
assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString())
|
||||
.isEqualTo("https://repo.maven.apache.org/maven2/");
|
||||
assertThat(((MavenArtifactRepository) repositories.get(2)).getUrl().toString())
|
||||
.isEqualTo("https://repo.spring.io/milestone/");
|
||||
}
|
||||
|
||||
private void assertReleaseRepository(RepositoryHandler repositories) {
|
||||
assertThat(repositories).extracting(ArtifactRepository::getName).hasSize(3);
|
||||
assertThat(((MavenArtifactRepository) repositories.get(0)).getUrl().toString())
|
||||
.isEqualTo("https://repo.maven.apache.org/maven2/");
|
||||
assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString())
|
||||
.isEqualTo("https://repo.maven.apache.org/maven2/");
|
||||
assertThat(((MavenArtifactRepository) repositories.get(2)).getUrl().toString())
|
||||
.isEqualTo("https://repo.spring.io/release/");
|
||||
}
|
||||
|
||||
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2019-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.gradle.xsd;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.gradle.xsd.CreateVersionlessXsdTask.MajorMinorVersion;
|
||||
import org.springframework.gradle.xsd.CreateVersionlessXsdTask.XsdFileMajorMinorVersion;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class CreateVersionlessXsdTaskTests {
|
||||
|
||||
@Test
|
||||
void xsdCreateWhenValid() {
|
||||
File file = new File("spring-security-2.0.xsd");
|
||||
XsdFileMajorMinorVersion xsdFile = XsdFileMajorMinorVersion.create(file);
|
||||
assertThat(xsdFile).isNotNull();
|
||||
assertThat(xsdFile.getFile()).isEqualTo(file);
|
||||
assertThat(xsdFile.getVersion().getMajor()).isEqualTo(2);
|
||||
assertThat(xsdFile.getVersion().getMinor()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void xsdCreateWhenPatchReleaseThenNull() {
|
||||
File file = new File("spring-security-2.0.1.xsd");
|
||||
XsdFileMajorMinorVersion xsdFile = XsdFileMajorMinorVersion.create(file);
|
||||
assertThat(xsdFile).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void xsdCreateWhenNotXsdFileThenNull() {
|
||||
File file = new File("spring-security-2.0.txt");
|
||||
XsdFileMajorMinorVersion xsdFile = XsdFileMajorMinorVersion.create(file);
|
||||
assertThat(xsdFile).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void xsdCreateWhenNotStartWithSpringSecurityThenNull() {
|
||||
File file = new File("spring-securityNO-2.0.xsd");
|
||||
XsdFileMajorMinorVersion xsdFile = XsdFileMajorMinorVersion.create(file);
|
||||
assertThat(xsdFile).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isGreaterWhenMajorLarger() {
|
||||
MajorMinorVersion larger = new MajorMinorVersion(2,0);
|
||||
MajorMinorVersion smaller = new MajorMinorVersion(1,0);
|
||||
assertThat(larger.isGreaterThan(smaller)).isTrue();
|
||||
assertThat(smaller.isGreaterThan(larger)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isGreaterWhenMinorLarger() {
|
||||
MajorMinorVersion larger = new MajorMinorVersion(1,1);
|
||||
MajorMinorVersion smaller = new MajorMinorVersion(1,0);
|
||||
assertThat(larger.isGreaterThan(smaller)).isTrue();
|
||||
assertThat(smaller.isGreaterThan(larger)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isGreaterWhenMajorAndMinorLarger() {
|
||||
MajorMinorVersion larger = new MajorMinorVersion(2,1);
|
||||
MajorMinorVersion smaller = new MajorMinorVersion(1,0);
|
||||
assertThat(larger.isGreaterThan(smaller)).isTrue();
|
||||
assertThat(smaller.isGreaterThan(larger)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isGreaterWhenSame() {
|
||||
MajorMinorVersion first = new MajorMinorVersion(1,0);
|
||||
MajorMinorVersion second = new MajorMinorVersion(1,0);
|
||||
assertThat(first.isGreaterThan(second)).isFalse();
|
||||
assertThat(second.isGreaterThan(first)).isFalse();
|
||||
}
|
||||
}
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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 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");
|
||||
}
|
||||
}
|
||||
+1
-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;
|
||||
}
|
||||
|
||||
+6
-6
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+2
-2
@@ -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,
|
||||
|
||||
+4
-4
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-5
@@ -132,13 +132,14 @@ 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();
|
||||
}
|
||||
|
||||
@@ -174,7 +175,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);
|
||||
verifyNoMoreInteractions(successHandler);
|
||||
// validate for when the filterProcessUrl matches
|
||||
@@ -206,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());
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
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
|
||||
@@ -113,12 +111,35 @@ dependencies {
|
||||
testRuntimeOnly 'org.hsqldb:hsqldb'
|
||||
}
|
||||
|
||||
rncToXsd {
|
||||
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) })
|
||||
versionlessXsdFile = project.layout.buildDirectory.file("versionlessXsd/spring-security.xsd")
|
||||
}
|
||||
|
||||
tasks.named('processResources', ProcessResources).configure {
|
||||
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/'
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(KotlinCompile).configureEach {
|
||||
kotlinOptions {
|
||||
languageVersion = "1.3"
|
||||
@@ -128,8 +149,6 @@ tasks.withType(KotlinCompile).configureEach {
|
||||
}
|
||||
}
|
||||
|
||||
build.dependsOn rncToXsd
|
||||
|
||||
compileTestJava {
|
||||
exclude "org/springframework/security/config/annotation/web/configurers/saml2/**", "org/springframework/security/config/http/Saml2*"
|
||||
}
|
||||
|
||||
+12
-10
@@ -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,7 +103,8 @@ 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
|
||||
@@ -119,8 +120,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
|
||||
@@ -129,13 +130,14 @@ 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) {
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+7
-4
@@ -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,8 +137,11 @@ 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() {
|
||||
@@ -169,7 +172,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();
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
+10
-10
@@ -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;
|
||||
}
|
||||
|
||||
+11
-9
@@ -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,19 +80,21 @@ 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
|
||||
@@ -112,7 +114,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
|
||||
@@ -120,7 +122,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
|
||||
@@ -128,7 +130,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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+10
-10
@@ -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}"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -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");
|
||||
|
||||
+6
-6
@@ -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
|
||||
|
||||
+10
-7
@@ -85,17 +85,19 @@ 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.8. Please update your schema declarations to the 5.8 schema.",
|
||||
element);
|
||||
}
|
||||
String name = pc.getDelegate().getLocalName(element);
|
||||
BeanDefinitionParser parser = this.parsers.get(name);
|
||||
@@ -140,8 +142,9 @@ 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) {
|
||||
|
||||
+1
-1
@@ -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");
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* 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.
|
||||
@@ -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/site/docs/current/reference/htmlsingle/#user-schema"
|
||||
* "https://docs.spring.io/spring-security/reference/servlet/appendix/database-schema.html"
|
||||
* >User Schema</a> section of the reference for the default schema.
|
||||
* </p>
|
||||
* @return a {@link JdbcUserDetailsManagerConfigurer} to allow customization of the
|
||||
|
||||
+4
-3
@@ -184,8 +184,9 @@ 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);
|
||||
}
|
||||
}
|
||||
@@ -218,7 +219,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));
|
||||
}
|
||||
|
||||
-1
@@ -98,7 +98,6 @@ import org.springframework.security.config.annotation.web.servlet.configuration.
|
||||
* @see EnableWebMvcSecurity
|
||||
* @see EnableWebSecurity
|
||||
* @see EnableGlobalMethodSecurity
|
||||
*
|
||||
* @author Rob Winch
|
||||
*
|
||||
*/
|
||||
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
@@ -33,6 +33,7 @@ import org.springframework.security.access.prepost.PreFilter;
|
||||
|
||||
/**
|
||||
* Enables Spring Security Method Security.
|
||||
*
|
||||
* @author Evgeniy Cheban
|
||||
* @author Josh Cummings
|
||||
* @since 5.6
|
||||
|
||||
-1
@@ -29,7 +29,6 @@ import org.springframework.core.Ordered;
|
||||
import org.springframework.security.authorization.ReactiveAuthorizationManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 5.0
|
||||
*/
|
||||
|
||||
+4
-4
@@ -108,7 +108,7 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
|
||||
};
|
||||
|
||||
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||
.getContextHolderStrategy();
|
||||
.getContextHolderStrategy();
|
||||
|
||||
private DefaultMethodSecurityExpressionHandler defaultMethodExpressionHandler = new DefaultMethodSecurityExpressionHandler();
|
||||
|
||||
@@ -320,7 +320,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 +375,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 +403,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);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -51,7 +51,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()
|
||||
|
||||
+2
-2
@@ -44,13 +44,13 @@ final class Jsr250MethodSecurityConfiguration {
|
||||
private final Jsr250AuthorizationManager jsr250AuthorizationManager = new Jsr250AuthorizationManager();
|
||||
|
||||
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||
.getContextHolderStrategy();
|
||||
.getContextHolderStrategy();
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
MethodInterceptor jsr250AuthorizationMethodInterceptor() {
|
||||
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor
|
||||
.jsr250(this.jsr250AuthorizationManager);
|
||||
.jsr250(this.jsr250AuthorizationManager);
|
||||
interceptor.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
+4
@@ -36,6 +36,10 @@ class MethodSecurityAdvisorRegistrar implements ImportBeanDefinitionRegistrar {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
+2
-2
@@ -45,13 +45,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);
|
||||
|
||||
+2
-2
@@ -68,10 +68,10 @@ final class PrePostMethodSecurityConfiguration {
|
||||
PrePostMethodSecurityConfiguration(ApplicationContext context) {
|
||||
this.preAuthorizeAuthorizationManager.setExpressionHandler(this.expressionHandler);
|
||||
this.preAuthorizeAuthorizationMethodInterceptor = AuthorizationManagerBeforeMethodInterceptor
|
||||
.preAuthorize(this.preAuthorizeAuthorizationManager);
|
||||
.preAuthorize(this.preAuthorizeAuthorizationManager);
|
||||
this.postAuthorizeAuthorizationManager.setExpressionHandler(this.expressionHandler);
|
||||
this.postAuthorizeAuthorizaitonMethodInterceptor = AuthorizationManagerAfterMethodInterceptor
|
||||
.postAuthorize(this.postAuthorizeAuthorizationManager);
|
||||
.postAuthorize(this.postAuthorizeAuthorizationManager);
|
||||
this.preFilterAuthorizationMethodInterceptor.setExpressionHandler(this.expressionHandler);
|
||||
this.postFilterAuthorizationMethodInterceptor.setExpressionHandler(this.expressionHandler);
|
||||
this.expressionHandler.setApplicationContext(context);
|
||||
|
||||
+11
-8
@@ -43,6 +43,7 @@ import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
||||
* @since 5.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
class ReactiveMethodSecurityConfiguration implements ImportAware {
|
||||
|
||||
private int advisorOrder;
|
||||
@@ -51,16 +52,17 @@ class ReactiveMethodSecurityConfiguration implements ImportAware {
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
MethodSecurityMetadataSourceAdvisor methodSecurityInterceptor(AbstractMethodSecurityMetadataSource source) {
|
||||
static MethodSecurityMetadataSourceAdvisor methodSecurityInterceptor(AbstractMethodSecurityMetadataSource source,
|
||||
ReactiveMethodSecurityConfiguration configuration) {
|
||||
MethodSecurityMetadataSourceAdvisor advisor = new MethodSecurityMetadataSourceAdvisor(
|
||||
"securityMethodInterceptor", source, "methodMetadataSource");
|
||||
advisor.setOrder(this.advisorOrder);
|
||||
advisor.setOrder(configuration.advisorOrder);
|
||||
return advisor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
DelegatingMethodSecurityMetadataSource methodMetadataSource(
|
||||
static DelegatingMethodSecurityMetadataSource methodMetadataSource(
|
||||
MethodSecurityExpressionHandler methodSecurityExpressionHandler) {
|
||||
ExpressionBasedAnnotationAttributeFactory attributeFactory = new ExpressionBasedAnnotationAttributeFactory(
|
||||
methodSecurityExpressionHandler);
|
||||
@@ -70,7 +72,7 @@ class ReactiveMethodSecurityConfiguration implements ImportAware {
|
||||
}
|
||||
|
||||
@Bean
|
||||
PrePostAdviceReactiveMethodInterceptor securityMethodInterceptor(AbstractMethodSecurityMetadataSource source,
|
||||
static PrePostAdviceReactiveMethodInterceptor securityMethodInterceptor(AbstractMethodSecurityMetadataSource source,
|
||||
MethodSecurityExpressionHandler handler) {
|
||||
ExpressionBasedPostInvocationAdvice postAdvice = new ExpressionBasedPostInvocationAdvice(handler);
|
||||
ExpressionBasedPreInvocationAdvice preAdvice = new ExpressionBasedPreInvocationAdvice();
|
||||
@@ -80,10 +82,11 @@ class ReactiveMethodSecurityConfiguration implements ImportAware {
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler() {
|
||||
static DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler(
|
||||
ReactiveMethodSecurityConfiguration configuration) {
|
||||
DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
|
||||
if (this.grantedAuthorityDefaults != null) {
|
||||
handler.setDefaultRolePrefix(this.grantedAuthorityDefaults.getRolePrefix());
|
||||
if (configuration.grantedAuthorityDefaults != null) {
|
||||
handler.setDefaultRolePrefix(configuration.grantedAuthorityDefaults.getRolePrefix());
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
@@ -91,7 +94,7 @@ class ReactiveMethodSecurityConfiguration implements ImportAware {
|
||||
@Override
|
||||
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||
this.advisorOrder = (int) importMetadata.getAnnotationAttributes(EnableReactiveMethodSecurity.class.getName())
|
||||
.get("order");
|
||||
.get("order");
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
|
||||
+2
-1
@@ -42,7 +42,8 @@ class ReactiveMethodSecuritySelector implements ImportSelector {
|
||||
return new String[0];
|
||||
}
|
||||
EnableReactiveMethodSecurity annotation = importMetadata.getAnnotations()
|
||||
.get(EnableReactiveMethodSecurity.class).synthesize();
|
||||
.get(EnableReactiveMethodSecurity.class)
|
||||
.synthesize();
|
||||
List<String> imports = new ArrayList<>(Arrays.asList(this.autoProxy.selectImports(importMetadata)));
|
||||
if (annotation.useAuthorizationManager()) {
|
||||
imports.add(ReactiveAuthorizationManagerMethodSecurityConfiguration.class.getName());
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||
final class SecuredMethodSecurityConfiguration {
|
||||
|
||||
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||
.getContextHolderStrategy();
|
||||
.getContextHolderStrategy();
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
|
||||
+2
-2
@@ -351,7 +351,7 @@ public class RSocketSecurity {
|
||||
public class AuthorizePayloadsSpec {
|
||||
|
||||
private PayloadExchangeMatcherReactiveAuthorizationManager.Builder authzBuilder = PayloadExchangeMatcherReactiveAuthorizationManager
|
||||
.builder();
|
||||
.builder();
|
||||
|
||||
public Access setup() {
|
||||
return matcher(PayloadExchangeMatchers.setup());
|
||||
@@ -427,7 +427,7 @@ public class RSocketSecurity {
|
||||
public AuthorizePayloadsSpec access(
|
||||
ReactiveAuthorizationManager<PayloadExchangeAuthorizationContext> authorization) {
|
||||
AuthorizePayloadsSpec.this.authzBuilder
|
||||
.add(new PayloadExchangeMatcherEntry<>(this.matcher, authorization));
|
||||
.add(new PayloadExchangeMatcherEntry<>(this.matcher, authorization));
|
||||
return AuthorizePayloadsSpec.this;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ class SecuritySocketAcceptorInterceptorConfiguration {
|
||||
ObjectProvider<PayloadSocketAcceptorInterceptor> rsocketInterceptor,
|
||||
ObjectProvider<RSocketSecurity> rsocketSecurity) {
|
||||
PayloadSocketAcceptorInterceptor delegate = rsocketInterceptor
|
||||
.getIfAvailable(() -> defaultInterceptor(rsocketSecurity));
|
||||
.getIfAvailable(() -> defaultInterceptor(rsocketSecurity));
|
||||
return new SecuritySocketAcceptorInterceptor(delegate);
|
||||
}
|
||||
|
||||
|
||||
+269
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* 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.
|
||||
@@ -18,9 +18,20 @@ package org.springframework.security.config.annotation.web;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletRegistration;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -36,6 +47,7 @@ import org.springframework.security.web.util.matcher.RegexRequestMatcher;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
|
||||
|
||||
/**
|
||||
@@ -66,6 +78,8 @@ public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
AbstractRequestMatcherRegistry.class.getClassLoader());
|
||||
}
|
||||
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
protected final void setApplicationContext(ApplicationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
@@ -297,16 +311,160 @@ public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
* @since 5.8
|
||||
*/
|
||||
public C requestMatchers(HttpMethod method, String... patterns) {
|
||||
List<RequestMatcher> matchers = new ArrayList<>();
|
||||
if (mvcPresent) {
|
||||
matchers.addAll(createMvcMatchers(method, patterns));
|
||||
if (!mvcPresent) {
|
||||
return requestMatchers(RequestMatchers.antMatchersAsArray(method, patterns));
|
||||
}
|
||||
else {
|
||||
matchers.addAll(RequestMatchers.antMatchers(method, patterns));
|
||||
if (!(this.context instanceof WebApplicationContext)) {
|
||||
return requestMatchers(RequestMatchers.antMatchersAsArray(method, patterns));
|
||||
}
|
||||
WebApplicationContext context = (WebApplicationContext) this.context;
|
||||
ServletContext servletContext = context.getServletContext();
|
||||
if (servletContext == null) {
|
||||
return requestMatchers(RequestMatchers.antMatchersAsArray(method, patterns));
|
||||
}
|
||||
boolean isProgrammaticApiAvailable = isProgrammaticApiAvailable(servletContext);
|
||||
List<RequestMatcher> matchers = new ArrayList<>();
|
||||
for (String pattern : patterns) {
|
||||
AntPathRequestMatcher ant = new AntPathRequestMatcher(pattern, (method != null) ? method.name() : null);
|
||||
MvcRequestMatcher mvc = createMvcMatchers(method, pattern).get(0);
|
||||
if (isProgrammaticApiAvailable) {
|
||||
matchers.add(resolve(ant, mvc, servletContext));
|
||||
}
|
||||
else {
|
||||
this.logger
|
||||
.warn("The ServletRegistration API was not available at startup time. This may be due to a misconfiguration; "
|
||||
+ "if you are using AbstractSecurityWebApplicationInitializer, please double-check the recommendations outlined in "
|
||||
+ "https://docs.spring.io/spring-security/reference/servlet/configuration/java.html#abstractsecuritywebapplicationinitializer-with-spring-mvc");
|
||||
matchers.add(new DeferredRequestMatcher((request) -> resolve(ant, mvc, request.getServletContext()),
|
||||
mvc, ant));
|
||||
}
|
||||
}
|
||||
return requestMatchers(matchers.toArray(new RequestMatcher[0]));
|
||||
}
|
||||
|
||||
private static boolean isProgrammaticApiAvailable(ServletContext servletContext) {
|
||||
try {
|
||||
servletContext.getServletRegistrations();
|
||||
return true;
|
||||
}
|
||||
catch (UnsupportedOperationException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private RequestMatcher resolve(AntPathRequestMatcher ant, MvcRequestMatcher mvc, ServletContext servletContext) {
|
||||
Map<String, ? extends ServletRegistration> registrations = mappableServletRegistrations(servletContext);
|
||||
if (registrations.isEmpty()) {
|
||||
return ant;
|
||||
}
|
||||
if (!hasDispatcherServlet(registrations)) {
|
||||
return ant;
|
||||
}
|
||||
ServletRegistration dispatcherServlet = requireOneRootDispatcherServlet(registrations);
|
||||
if (dispatcherServlet != null) {
|
||||
if (registrations.size() == 1) {
|
||||
return mvc;
|
||||
}
|
||||
return new DispatcherServletDelegatingRequestMatcher(ant, mvc, servletContext);
|
||||
}
|
||||
dispatcherServlet = requireOnlyPathMappedDispatcherServlet(registrations);
|
||||
if (dispatcherServlet != null) {
|
||||
String mapping = dispatcherServlet.getMappings().iterator().next();
|
||||
mvc.setServletPath(mapping.substring(0, mapping.length() - 2));
|
||||
return mvc;
|
||||
}
|
||||
String errorMessage = computeErrorMessage(registrations.values());
|
||||
throw new IllegalArgumentException(errorMessage);
|
||||
}
|
||||
|
||||
private Map<String, ? extends ServletRegistration> mappableServletRegistrations(ServletContext servletContext) {
|
||||
Map<String, ServletRegistration> mappable = new LinkedHashMap<>();
|
||||
for (Map.Entry<String, ? extends ServletRegistration> entry : servletContext.getServletRegistrations()
|
||||
.entrySet()) {
|
||||
if (!entry.getValue().getMappings().isEmpty()) {
|
||||
mappable.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
return mappable;
|
||||
}
|
||||
|
||||
private boolean hasDispatcherServlet(Map<String, ? extends ServletRegistration> registrations) {
|
||||
if (registrations == null) {
|
||||
return false;
|
||||
}
|
||||
for (ServletRegistration registration : registrations.values()) {
|
||||
if (isDispatcherServlet(registration)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private ServletRegistration requireOneRootDispatcherServlet(
|
||||
Map<String, ? extends ServletRegistration> registrations) {
|
||||
ServletRegistration rootDispatcherServlet = null;
|
||||
for (ServletRegistration registration : registrations.values()) {
|
||||
if (!isDispatcherServlet(registration)) {
|
||||
continue;
|
||||
}
|
||||
if (registration.getMappings().size() > 1) {
|
||||
return null;
|
||||
}
|
||||
if (!"/".equals(registration.getMappings().iterator().next())) {
|
||||
return null;
|
||||
}
|
||||
rootDispatcherServlet = registration;
|
||||
}
|
||||
return rootDispatcherServlet;
|
||||
}
|
||||
|
||||
private ServletRegistration requireOnlyPathMappedDispatcherServlet(
|
||||
Map<String, ? extends ServletRegistration> registrations) {
|
||||
ServletRegistration pathDispatcherServlet = null;
|
||||
for (ServletRegistration registration : registrations.values()) {
|
||||
if (!isDispatcherServlet(registration)) {
|
||||
return null;
|
||||
}
|
||||
if (registration.getMappings().size() > 1) {
|
||||
return null;
|
||||
}
|
||||
String mapping = registration.getMappings().iterator().next();
|
||||
if (!mapping.startsWith("/") || !mapping.endsWith("/*")) {
|
||||
return null;
|
||||
}
|
||||
if (pathDispatcherServlet != null) {
|
||||
return null;
|
||||
}
|
||||
pathDispatcherServlet = registration;
|
||||
}
|
||||
return pathDispatcherServlet;
|
||||
}
|
||||
|
||||
private boolean isDispatcherServlet(ServletRegistration registration) {
|
||||
Class<?> dispatcherServlet = ClassUtils.resolveClassName("org.springframework.web.servlet.DispatcherServlet",
|
||||
null);
|
||||
try {
|
||||
Class<?> clazz = Class.forName(registration.getClassName());
|
||||
return dispatcherServlet.isAssignableFrom(clazz);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private String computeErrorMessage(Collection<? extends ServletRegistration> registrations) {
|
||||
String template = "This method cannot decide whether these patterns are Spring MVC patterns or not. "
|
||||
+ "If this endpoint is a Spring MVC endpoint, please use requestMatchers(MvcRequestMatcher); "
|
||||
+ "otherwise, please use requestMatchers(AntPathRequestMatcher).\n\n"
|
||||
+ "This is because there is more than one mappable servlet in your servlet context: %s.\n\n"
|
||||
+ "For each MvcRequestMatcher, call MvcRequestMatcher#setServletPath to indicate the servlet path.";
|
||||
Map<String, Collection<String>> mappings = new LinkedHashMap<>();
|
||||
for (ServletRegistration registration : registrations) {
|
||||
mappings.put(registration.getClassName(), registration.getMappings());
|
||||
}
|
||||
return String.format(template, mappings);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* If the {@link HandlerMappingIntrospector} is available in the classpath, maps to an
|
||||
@@ -380,12 +538,7 @@ public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
* @return a {@link List} of {@link AntPathRequestMatcher} instances
|
||||
*/
|
||||
static List<RequestMatcher> antMatchers(HttpMethod httpMethod, String... antPatterns) {
|
||||
String method = (httpMethod != null) ? httpMethod.toString() : null;
|
||||
List<RequestMatcher> matchers = new ArrayList<>();
|
||||
for (String pattern : antPatterns) {
|
||||
matchers.add(new AntPathRequestMatcher(pattern, method));
|
||||
}
|
||||
return matchers;
|
||||
return Arrays.asList(antMatchersAsArray(httpMethod, antPatterns));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -399,6 +552,15 @@ public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
return antMatchers(null, antPatterns);
|
||||
}
|
||||
|
||||
static RequestMatcher[] antMatchersAsArray(HttpMethod httpMethod, String... antPatterns) {
|
||||
String method = (httpMethod != null) ? httpMethod.toString() : null;
|
||||
RequestMatcher[] matchers = new RequestMatcher[antPatterns.length];
|
||||
for (int index = 0; index < antPatterns.length; index++) {
|
||||
matchers[index] = new AntPathRequestMatcher(antPatterns[index], method);
|
||||
}
|
||||
return matchers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link List} of {@link RegexRequestMatcher} instances.
|
||||
* @param httpMethod the {@link HttpMethod} to use or {@code null} for any
|
||||
@@ -429,4 +591,99 @@ public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
|
||||
}
|
||||
|
||||
static class DeferredRequestMatcher implements RequestMatcher {
|
||||
|
||||
final Function<HttpServletRequest, RequestMatcher> requestMatcherFactory;
|
||||
|
||||
final AtomicReference<String> description = new AtomicReference<>();
|
||||
|
||||
volatile RequestMatcher requestMatcher;
|
||||
|
||||
DeferredRequestMatcher(Function<HttpServletRequest, RequestMatcher> resolver, RequestMatcher... candidates) {
|
||||
this.requestMatcherFactory = (request) -> {
|
||||
if (this.requestMatcher == null) {
|
||||
synchronized (this) {
|
||||
if (this.requestMatcher == null) {
|
||||
this.requestMatcher = resolver.apply(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.requestMatcher;
|
||||
};
|
||||
this.description.set("Deferred " + Arrays.toString(candidates));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(HttpServletRequest request) {
|
||||
return this.requestMatcherFactory.apply(request).matches(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MatchResult matcher(HttpServletRequest request) {
|
||||
return this.requestMatcherFactory.apply(request).matcher(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.description.get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class DispatcherServletDelegatingRequestMatcher implements RequestMatcher {
|
||||
|
||||
private final AntPathRequestMatcher ant;
|
||||
|
||||
private final MvcRequestMatcher mvc;
|
||||
|
||||
private final ServletContext servletContext;
|
||||
|
||||
DispatcherServletDelegatingRequestMatcher(AntPathRequestMatcher ant, MvcRequestMatcher mvc,
|
||||
ServletContext servletContext) {
|
||||
this.ant = ant;
|
||||
this.mvc = mvc;
|
||||
this.servletContext = servletContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(HttpServletRequest request) {
|
||||
String name = request.getHttpServletMapping().getServletName();
|
||||
ServletRegistration registration = this.servletContext.getServletRegistration(name);
|
||||
Assert.notNull(registration, "Failed to find servlet [" + name + "] in the servlet context");
|
||||
if (isDispatcherServlet(registration)) {
|
||||
return this.mvc.matches(request);
|
||||
}
|
||||
return this.ant.matches(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MatchResult matcher(HttpServletRequest request) {
|
||||
String name = request.getHttpServletMapping().getServletName();
|
||||
ServletRegistration registration = this.servletContext.getServletRegistration(name);
|
||||
Assert.notNull(registration, "Failed to find servlet [" + name + "] in the servlet context");
|
||||
if (isDispatcherServlet(registration)) {
|
||||
return this.mvc.matcher(request);
|
||||
}
|
||||
return this.ant.matcher(request);
|
||||
}
|
||||
|
||||
private boolean isDispatcherServlet(ServletRegistration registration) {
|
||||
Class<?> dispatcherServlet = ClassUtils
|
||||
.resolveClassName("org.springframework.web.servlet.DispatcherServlet", null);
|
||||
try {
|
||||
Class<?> clazz = Class.forName(registration.getClassName());
|
||||
return dispatcherServlet.isAssignableFrom(clazz);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DispatcherServletDelegating [" + "ant = " + this.ant + ", mvc = " + this.mvc + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+19
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* 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.
|
||||
@@ -28,6 +28,7 @@ import org.springframework.security.openid.OpenIDAuthenticationFilter;
|
||||
import org.springframework.security.web.DefaultSecurityFilterChain;
|
||||
import org.springframework.security.web.access.ExceptionTranslationFilter;
|
||||
import org.springframework.security.web.access.channel.ChannelProcessingFilter;
|
||||
import org.springframework.security.web.access.intercept.AuthorizationFilter;
|
||||
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
|
||||
import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
@@ -38,7 +39,11 @@ import org.springframework.security.web.authentication.rememberme.RememberMeAuth
|
||||
import org.springframework.security.web.authentication.switchuser.SwitchUserFilter;
|
||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||
import org.springframework.security.web.authentication.www.DigestAuthenticationFilter;
|
||||
import org.springframework.security.web.context.SecurityContextHolderFilter;
|
||||
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
|
||||
import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter;
|
||||
import org.springframework.security.web.csrf.CsrfFilter;
|
||||
import org.springframework.security.web.header.HeaderWriterFilter;
|
||||
import org.springframework.security.web.jaasapi.JaasApiIntegrationFilter;
|
||||
import org.springframework.security.web.savedrequest.RequestCacheAwareFilter;
|
||||
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
|
||||
@@ -46,6 +51,7 @@ import org.springframework.security.web.session.ConcurrentSessionFilter;
|
||||
import org.springframework.security.web.session.DisableEncodeUrlFilter;
|
||||
import org.springframework.security.web.session.ForceEagerSessionCreationFilter;
|
||||
import org.springframework.security.web.session.SessionManagementFilter;
|
||||
import org.springframework.web.filter.CorsFilter;
|
||||
|
||||
/**
|
||||
* @param <H>
|
||||
@@ -127,15 +133,24 @@ public interface HttpSecurityBuilder<H extends HttpSecurityBuilder<H>>
|
||||
* The ordering of the Filters is:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link ForceEagerSessionCreationFilter}</li>
|
||||
* <li>{@link DisableEncodeUrlFilter}</li>
|
||||
* <li>{@link ForceEagerSessionCreationFilter}</li>
|
||||
* <li>{@link ChannelProcessingFilter}</li>
|
||||
* <li>{@link WebAsyncManagerIntegrationFilter}</li>
|
||||
* <li>{@link SecurityContextHolderFilter}</li>
|
||||
* <li>{@link SecurityContextPersistenceFilter}</li>
|
||||
* <li>{@link HeaderWriterFilter}</li>
|
||||
* <li>{@link CorsFilter}</li>
|
||||
* <li>{@link CsrfFilter}</li>
|
||||
* <li>{@link LogoutFilter}</li>
|
||||
* <li>{@link org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter}</li>
|
||||
* <li>{@link org.springframework.security.saml2.provider.service.web.Saml2WebSsoAuthenticationRequestFilter}</li>
|
||||
* <li>{@link X509AuthenticationFilter}</li>
|
||||
* <li>{@link AbstractPreAuthenticatedProcessingFilter}</li>
|
||||
* <li><a href="
|
||||
* {@docRoot}/org/springframework/security/cas/web/CasAuthenticationFilter.html">CasAuthenticationFilter</a></li>
|
||||
* <li>{@link org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter}</li>
|
||||
* <li>{@link org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter}</li>
|
||||
* <li>{@link UsernamePasswordAuthenticationFilter}</li>
|
||||
* <li>{@link OpenIDAuthenticationFilter}</li>
|
||||
* <li>{@link org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter}</li>
|
||||
@@ -149,9 +164,11 @@ public interface HttpSecurityBuilder<H extends HttpSecurityBuilder<H>>
|
||||
* <li>{@link JaasApiIntegrationFilter}</li>
|
||||
* <li>{@link RememberMeAuthenticationFilter}</li>
|
||||
* <li>{@link AnonymousAuthenticationFilter}</li>
|
||||
* <li>{@link org.springframework.security.oauth2.client.web.OAuth2AuthorizationCodeGrantFilter}</li>
|
||||
* <li>{@link SessionManagementFilter}</li>
|
||||
* <li>{@link ExceptionTranslationFilter}</li>
|
||||
* <li>{@link FilterSecurityInterceptor}</li>
|
||||
* <li>{@link AuthorizationFilter}</li>
|
||||
* <li>{@link SwitchUserFilter}</li>
|
||||
* </ul>
|
||||
* @param filter the {@link Filter} to add
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* 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.
|
||||
|
||||
+2
-2
@@ -1418,7 +1418,7 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
|
||||
throws Exception {
|
||||
ApplicationContext context = getContext();
|
||||
authorizeRequestsCustomizer
|
||||
.customize(getOrApply(new ExpressionUrlAuthorizationConfigurer<>(context)).getRegistry());
|
||||
.customize(getOrApply(new ExpressionUrlAuthorizationConfigurer<>(context)).getRegistry());
|
||||
return HttpSecurity.this;
|
||||
}
|
||||
|
||||
@@ -1647,7 +1647,7 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
|
||||
throws Exception {
|
||||
ApplicationContext context = getContext();
|
||||
authorizeHttpRequestsCustomizer
|
||||
.customize(getOrApply(new AuthorizeHttpRequestsConfigurer<>(context)).getRegistry());
|
||||
.customize(getOrApply(new AuthorizeHttpRequestsConfigurer<>(context)).getRegistry());
|
||||
return HttpSecurity.this;
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -307,13 +307,13 @@ public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter,
|
||||
SecurityFilterChain securityFilterChain = new DefaultSecurityFilterChain(ignoredRequest);
|
||||
securityFilterChains.add(securityFilterChain);
|
||||
requestMatcherPrivilegeEvaluatorsEntries
|
||||
.add(getRequestMatcherPrivilegeEvaluatorsEntry(securityFilterChain));
|
||||
.add(getRequestMatcherPrivilegeEvaluatorsEntry(securityFilterChain));
|
||||
}
|
||||
for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : this.securityFilterChainBuilders) {
|
||||
SecurityFilterChain securityFilterChain = securityFilterChainBuilder.build();
|
||||
securityFilterChains.add(securityFilterChain);
|
||||
requestMatcherPrivilegeEvaluatorsEntries
|
||||
.add(getRequestMatcherPrivilegeEvaluatorsEntry(securityFilterChain));
|
||||
.add(getRequestMatcherPrivilegeEvaluatorsEntry(securityFilterChain));
|
||||
}
|
||||
if (this.privilegeEvaluator == null) {
|
||||
this.privilegeEvaluator = new RequestMatcherDelegatingWebInvocationPrivilegeEvaluator(
|
||||
@@ -354,7 +354,7 @@ public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter,
|
||||
}
|
||||
if (filter instanceof AuthorizationFilter) {
|
||||
AuthorizationManager<HttpServletRequest> authorizationManager = ((AuthorizationFilter) filter)
|
||||
.getAuthorizationManager();
|
||||
.getAuthorizationManager();
|
||||
AuthorizationManagerWebInvocationPrivilegeEvaluator evaluator = new AuthorizationManagerWebInvocationPrivilegeEvaluator(
|
||||
authorizationManager);
|
||||
evaluator.setServletContext(this.servletContext);
|
||||
@@ -374,7 +374,7 @@ public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter,
|
||||
}
|
||||
try {
|
||||
this.defaultWebSecurityExpressionHandler
|
||||
.setPermissionEvaluator(applicationContext.getBean(PermissionEvaluator.class));
|
||||
.setPermissionEvaluator(applicationContext.getBean(PermissionEvaluator.class));
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
}
|
||||
|
||||
-1
@@ -76,7 +76,6 @@ import org.springframework.security.web.SecurityFilterChain;
|
||||
* </pre>
|
||||
*
|
||||
* @see WebSecurityConfigurer
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 3.2
|
||||
*/
|
||||
|
||||
+2
-2
@@ -65,7 +65,7 @@ class HttpSecurityConfiguration {
|
||||
private ApplicationContext context;
|
||||
|
||||
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||
.getContextHolderStrategy();
|
||||
.getContextHolderStrategy();
|
||||
|
||||
private ContentNegotiationStrategy contentNegotiationStrategy = new HeaderContentNegotiationStrategy();
|
||||
|
||||
@@ -143,7 +143,7 @@ class HttpSecurityConfiguration {
|
||||
private void applyDefaultConfigurers(HttpSecurity http) throws Exception {
|
||||
ClassLoader classLoader = this.context.getClassLoader();
|
||||
List<AbstractHttpConfigurer> defaultHttpConfigurers = SpringFactoriesLoader
|
||||
.loadFactories(AbstractHttpConfigurer.class, classLoader);
|
||||
.loadFactories(AbstractHttpConfigurer.class, classLoader);
|
||||
for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) {
|
||||
http.apply(configurer);
|
||||
}
|
||||
|
||||
+3
-3
@@ -48,11 +48,11 @@ final class OAuth2ImportSelector implements ImportSelector {
|
||||
Set<String> imports = new LinkedHashSet<>();
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
boolean oauth2ClientPresent = ClassUtils
|
||||
.isPresent("org.springframework.security.oauth2.client.registration.ClientRegistration", classLoader);
|
||||
.isPresent("org.springframework.security.oauth2.client.registration.ClientRegistration", classLoader);
|
||||
boolean webfluxPresent = ClassUtils
|
||||
.isPresent("org.springframework.web.reactive.function.client.ExchangeFilterFunction", classLoader);
|
||||
.isPresent("org.springframework.web.reactive.function.client.ExchangeFilterFunction", classLoader);
|
||||
boolean oauth2ResourceServerPresent = ClassUtils
|
||||
.isPresent("org.springframework.security.oauth2.server.resource.BearerTokenError", classLoader);
|
||||
.isPresent("org.springframework.security.oauth2.server.resource.BearerTokenError", classLoader);
|
||||
if (oauth2ClientPresent) {
|
||||
imports.add("org.springframework.security.config.annotation.web.configuration.OAuth2ClientConfiguration");
|
||||
}
|
||||
|
||||
+3
-3
@@ -66,7 +66,7 @@ import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
class SecurityReactorContextConfiguration {
|
||||
|
||||
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||
.getContextHolderStrategy();
|
||||
.getContextHolderStrategy();
|
||||
|
||||
@Bean
|
||||
SecurityReactorContextSubscriberRegistrar securityReactorContextSubscriberRegistrar() {
|
||||
@@ -88,7 +88,7 @@ class SecurityReactorContextConfiguration {
|
||||
private final Map<Object, Supplier<Object>> CONTEXT_ATTRIBUTE_VALUE_LOADERS = new HashMap<>();
|
||||
|
||||
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||
.getContextHolderStrategy();
|
||||
.getContextHolderStrategy();
|
||||
|
||||
SecurityReactorContextSubscriberRegistrar() {
|
||||
this.CONTEXT_ATTRIBUTE_VALUE_LOADERS.put(HttpServletRequest.class,
|
||||
@@ -101,7 +101,7 @@ class SecurityReactorContextConfiguration {
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Function<? super Publisher<Object>, ? extends Publisher<Object>> lifter = Operators
|
||||
.liftPublisher((pub, sub) -> createSubscriberIfNecessary(sub));
|
||||
.liftPublisher((pub, sub) -> createSubscriberIfNecessary(sub));
|
||||
Hooks.onLastOperator(SECURITY_REACTOR_CONTEXT_OPERATOR_KEY, lifter::apply);
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -39,8 +39,8 @@ import org.springframework.web.servlet.support.RequestDataValueProcessor;
|
||||
* Used to add a {@link RequestDataValueProcessor} for Spring MVC and Spring Security CSRF
|
||||
* integration. This configuration is added whenever {@link EnableWebMvc} is added by
|
||||
* <a href="
|
||||
* {@docRoot}/org/springframework/security/config/annotation/web/configuration/SpringWebMvcImportSelector.html">SpringWebMvcImportSelector</a>
|
||||
* and the DispatcherServlet is present on the classpath. It also adds the
|
||||
* {@docRoot}/org/springframework/security/config/annotation/web/configuration/SpringWebMvcImportSelector.html">SpringWebMvcImportSelector</a> and
|
||||
* the DispatcherServlet is present on the classpath. It also adds the
|
||||
* {@link AuthenticationPrincipalArgumentResolver} as a
|
||||
* {@link HandlerMethodArgumentResolver}.
|
||||
*
|
||||
@@ -53,7 +53,7 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
|
||||
private BeanResolver beanResolver;
|
||||
|
||||
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||
.getContextHolderStrategy();
|
||||
.getContextHolderStrategy();
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
@@ -63,7 +63,7 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
|
||||
authenticationPrincipalResolver.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
|
||||
argumentResolvers.add(authenticationPrincipalResolver);
|
||||
argumentResolvers
|
||||
.add(new org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver());
|
||||
.add(new org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver());
|
||||
CurrentSecurityContextArgumentResolver currentSecurityContextArgumentResolver = new CurrentSecurityContextArgumentResolver();
|
||||
currentSecurityContextArgumentResolver.setBeanResolver(this.beanResolver);
|
||||
currentSecurityContextArgumentResolver.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
|
||||
|
||||
+5
-4
@@ -106,8 +106,8 @@ public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAwa
|
||||
"Found WebSecurityConfigurerAdapter as well as SecurityFilterChain. Please select just one.");
|
||||
if (!hasConfigurers && !hasFilterChain) {
|
||||
WebSecurityConfigurerAdapter adapter = this.objectObjectPostProcessor
|
||||
.postProcess(new WebSecurityConfigurerAdapter() {
|
||||
});
|
||||
.postProcess(new WebSecurityConfigurerAdapter() {
|
||||
});
|
||||
this.webSecurity.apply(adapter);
|
||||
}
|
||||
for (SecurityFilterChain securityFilterChain : this.securityFilterChains) {
|
||||
@@ -154,7 +154,8 @@ public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAwa
|
||||
this.webSecurity.debug(this.debugEnabled);
|
||||
}
|
||||
List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers = new AutowiredWebSecurityConfigurersIgnoreParents(
|
||||
beanFactory).getWebSecurityConfigurers();
|
||||
beanFactory)
|
||||
.getWebSecurityConfigurers();
|
||||
webSecurityConfigurers.sort(AnnotationAwareOrderComparator.INSTANCE);
|
||||
Integer previousOrder = null;
|
||||
Object previousConfig = null;
|
||||
@@ -191,7 +192,7 @@ public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAwa
|
||||
@Override
|
||||
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||
Map<String, Object> enableWebSecurityAttrMap = importMetadata
|
||||
.getAnnotationAttributes(EnableWebSecurity.class.getName());
|
||||
.getAnnotationAttributes(EnableWebSecurity.class.getName());
|
||||
AnnotationAttributes enableWebSecurityAttrs = AnnotationAttributes.fromMap(enableWebSecurityAttrMap);
|
||||
this.debugEnabled = enableWebSecurityAttrs.getBoolean("debug");
|
||||
if (this.webSecurity != null) {
|
||||
|
||||
+1
-1
@@ -230,7 +230,7 @@ public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigu
|
||||
applyDefaultConfiguration(this.http);
|
||||
ClassLoader classLoader = this.context.getClassLoader();
|
||||
List<AbstractHttpConfigurer> defaultHttpConfigurers = SpringFactoriesLoader
|
||||
.loadFactories(AbstractHttpConfigurer.class, classLoader);
|
||||
.loadFactories(AbstractHttpConfigurer.class, classLoader);
|
||||
for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) {
|
||||
this.http.apply(configurer);
|
||||
}
|
||||
|
||||
+2
-2
@@ -285,7 +285,7 @@ public abstract class AbstractAuthenticationFilterConfigurer<B extends HttpSecur
|
||||
this.authFilter.setAuthenticationDetailsSource(this.authenticationDetailsSource);
|
||||
}
|
||||
SessionAuthenticationStrategy sessionAuthenticationStrategy = http
|
||||
.getSharedObject(SessionAuthenticationStrategy.class);
|
||||
.getSharedObject(SessionAuthenticationStrategy.class);
|
||||
if (sessionAuthenticationStrategy != null) {
|
||||
this.authFilter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy);
|
||||
}
|
||||
@@ -296,7 +296,7 @@ public abstract class AbstractAuthenticationFilterConfigurer<B extends HttpSecur
|
||||
SecurityContextConfigurer securityContextConfigurer = http.getConfigurer(SecurityContextConfigurer.class);
|
||||
if (securityContextConfigurer != null && securityContextConfigurer.isRequireExplicitSave()) {
|
||||
SecurityContextRepository securityContextRepository = securityContextConfigurer
|
||||
.getSecurityContextRepository();
|
||||
.getSecurityContextRepository();
|
||||
this.authFilter.setSecurityContextRepository(securityContextRepository);
|
||||
}
|
||||
this.authFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ public final class AuthorizeHttpRequestsConfigurer<H extends HttpSecurityBuilder
|
||||
extends AbstractRequestMatcherRegistry<AuthorizedUrl> {
|
||||
|
||||
private final RequestMatcherDelegatingAuthorizationManager.Builder managerBuilder = RequestMatcherDelegatingAuthorizationManager
|
||||
.builder();
|
||||
.builder();
|
||||
|
||||
private List<RequestMatcher> unmappedMatchers;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user