Skip to content

Commit 1106fc0

Browse files
committed
Merge branch 'main' into fix/datasource-validation
2 parents ef3bc34 + ce54a6d commit 1106fc0

File tree

54 files changed

+3985
-377
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+3985
-377
lines changed

.github/dependabot.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ updates:
103103
- dependency-name: '*'
104104
update-types:
105105
- version-update:semver-major
106-
- version-update:semver-minor
107106
- package-ecosystem: github-actions
108107
target-branch: 5.8.x
109108
directory: /
Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,52 @@
11
name: Merge Dependabot PR
22

3-
on:
4-
pull_request:
3+
on: pull_request_target
54

65
run-name: Merge Dependabot PR ${{ github.ref_name }}
76

7+
permissions: write-all
8+
89
jobs:
910
merge-dependabot-pr:
10-
permissions: write-all
11-
uses: spring-io/spring-github-workflows/.github/workflows/spring-merge-dependabot-pr.yml@1e8b0587a1f4f01697f9753fa3339c3e0d30f396
12-
with:
13-
mergeArguments: '--auto --rebase'
11+
runs-on: ubuntu-latest
12+
if: github.actor == 'dependabot[bot]'
13+
steps:
14+
15+
- uses: actions/checkout@v4
16+
with:
17+
show-progress: false
18+
ref: ${{ github.event.pull_request.head.sha }}
19+
20+
- uses: actions/setup-java@v4
21+
with:
22+
distribution: temurin
23+
java-version: 17
24+
25+
- name: Set Milestone to Dependabot Pull Request
26+
id: set-milestone
27+
run: |
28+
if test -f pom.xml
29+
then
30+
CURRENT_VERSION=$(mvn help:evaluate -Dexpression="project.version" -q -DforceStdout)
31+
else
32+
CURRENT_VERSION=$(cat gradle.properties | sed -n '/^version=/ { s/^version=//;p }')
33+
fi
34+
export CANDIDATE_VERSION=${CURRENT_VERSION/-SNAPSHOT}
35+
MILESTONE=$(gh api repos/$GITHUB_REPOSITORY/milestones --jq 'map(select(.due_on != null and (.title | startswith(env.CANDIDATE_VERSION)))) | .[0] | .title')
36+
37+
if [ -z $MILESTONE ]
38+
then
39+
gh run cancel ${{ github.run_id }}
40+
echo "::warning title=Cannot merge::No scheduled milestone for $CURRENT_VERSION version"
41+
else
42+
gh pr edit ${{ github.event.pull_request.number }} --milestone $MILESTONE
43+
echo mergeEnabled=true >> $GITHUB_OUTPUT
44+
fi
45+
env:
46+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
47+
48+
- name: Merge Dependabot pull request
49+
if: steps.set-milestone.outputs.mergeEnabled
50+
run: gh pr merge ${{ github.event.pull_request.number }} --auto --rebase
51+
env:
52+
GH_TOKEN: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}

.github/workflows/trigger-dependabot-auto-merge-forward.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
name: Trigger Dependabot Auto Merge Forward
22

33
on:
4-
pull_request:
5-
types: [closed]
4+
push:
5+
branches:
6+
- '*.x'
67

78
permissions: read-all
89

910
jobs:
1011
trigger-worflow:
1112
name: Trigger Workflow
1213
runs-on: ubuntu-latest
13-
if: ${{ github.event.pull_request.merged == true && github.actor == 'dependabot[bot]' && github.repository == 'spring-projects/spring-security' }}
14+
if: ${{ github.event.commits[0].author.username == 'dependabot[bot]' && github.repository == 'spring-projects/spring-security' }}
1415
steps:
1516
- name: Checkout
1617
id: checkout

.github/workflows/update-dependabot.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ name: Update dependabot.yml
22

33
on:
44
workflow_dispatch:
5-
schedule:
6-
- cron: '0 0 * * *' # Once per day at midnight UTC
75

86
permissions:
97
contents: read

aspects/src/test/java/org/springframework/security/authorization/method/aspectj/PostAuthorizeAspectTests.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -103,6 +103,13 @@ public void denyAllPreAuthorizeDeniesAccess() {
103103
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.prePostSecured::denyAllMethod);
104104
}
105105

106+
@Test
107+
public void nestedDenyAllPostAuthorizeDeniesAccess() {
108+
SecurityContextHolder.getContext().setAuthentication(this.anne);
109+
assertThatExceptionOfType(AccessDeniedException.class)
110+
.isThrownBy(() -> this.secured.myObject().denyAllMethod());
111+
}
112+
106113
interface SecuredInterface {
107114

108115
@PostAuthorize("hasRole('X')")
@@ -134,6 +141,10 @@ void publicCallsPrivate() {
134141
privateMethod();
135142
}
136143

144+
NestedObject myObject() {
145+
return new NestedObject();
146+
}
147+
137148
}
138149

139150
static class SecuredImplSubclass extends SecuredImpl {
@@ -157,4 +168,13 @@ void denyAllMethod() {
157168

158169
}
159170

171+
static class NestedObject {
172+
173+
@PostAuthorize("denyAll")
174+
void denyAllMethod() {
175+
176+
}
177+
178+
}
179+
160180
}

aspects/src/test/java/org/springframework/security/authorization/method/aspectj/PostFilterAspectTests.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -54,13 +54,31 @@ public void preFilterMethodWhenListThenFilters() {
5454
assertThat(this.prePostSecured.postFilterMethod(objects)).containsExactly("apple", "aubergine");
5555
}
5656

57+
@Test
58+
public void nestedDenyAllPostFilterDeniesAccess() {
59+
assertThat(this.prePostSecured.myObject().denyAllMethod()).isEmpty();
60+
}
61+
5762
static class PrePostSecured {
5863

5964
@PostFilter("filterObject.startsWith('a')")
6065
List<String> postFilterMethod(List<String> objects) {
6166
return objects;
6267
}
6368

69+
NestedObject myObject() {
70+
return new NestedObject();
71+
}
72+
73+
}
74+
75+
static class NestedObject {
76+
77+
@PostFilter("filterObject == null")
78+
List<String> denyAllMethod() {
79+
return new ArrayList<>(List.of("deny"));
80+
}
81+
6482
}
6583

6684
}

aspects/src/test/java/org/springframework/security/authorization/method/aspectj/PreAuthorizeAspectTests.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -103,6 +103,13 @@ public void denyAllPreAuthorizeDeniesAccess() {
103103
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.prePostSecured::denyAllMethod);
104104
}
105105

106+
@Test
107+
public void nestedDenyAllPreAuthorizeDeniesAccess() {
108+
SecurityContextHolder.getContext().setAuthentication(this.anne);
109+
assertThatExceptionOfType(AccessDeniedException.class)
110+
.isThrownBy(() -> this.secured.myObject().denyAllMethod());
111+
}
112+
106113
interface SecuredInterface {
107114

108115
@PreAuthorize("hasRole('X')")
@@ -134,6 +141,10 @@ void publicCallsPrivate() {
134141
privateMethod();
135142
}
136143

144+
NestedObject myObject() {
145+
return new NestedObject();
146+
}
147+
137148
}
138149

139150
static class SecuredImplSubclass extends SecuredImpl {
@@ -157,4 +168,13 @@ void denyAllMethod() {
157168

158169
}
159170

171+
static class NestedObject {
172+
173+
@PreAuthorize("denyAll")
174+
void denyAllMethod() {
175+
176+
}
177+
178+
}
179+
160180
}

aspects/src/test/java/org/springframework/security/authorization/method/aspectj/PreFilterAspectTests.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -54,13 +54,31 @@ public void preFilterMethodWhenListThenFilters() {
5454
assertThat(this.prePostSecured.preFilterMethod(objects)).containsExactly("apple", "aubergine");
5555
}
5656

57+
@Test
58+
public void nestedDenyAllPreFilterDeniesAccess() {
59+
assertThat(this.prePostSecured.myObject().denyAllMethod(new ArrayList<>(List.of("deny")))).isEmpty();
60+
}
61+
5762
static class PrePostSecured {
5863

5964
@PreFilter("filterObject.startsWith('a')")
6065
List<String> preFilterMethod(List<String> objects) {
6166
return objects;
6267
}
6368

69+
NestedObject myObject() {
70+
return new NestedObject();
71+
}
72+
73+
}
74+
75+
static class NestedObject {
76+
77+
@PreFilter("filterObject == null")
78+
List<String> denyAllMethod(List<String> list) {
79+
return list;
80+
}
81+
6482
}
6583

6684
}

aspects/src/test/java/org/springframework/security/authorization/method/aspectj/SecuredAspectTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright 2002-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.security.config.annotation.method.configuration;
18+
19+
import java.util.ArrayList;
20+
import java.util.List;
21+
22+
import org.aopalliance.intercept.MethodInterceptor;
23+
24+
import org.springframework.aop.framework.AopInfrastructureBean;
25+
import org.springframework.beans.factory.ObjectProvider;
26+
import org.springframework.beans.factory.config.BeanDefinition;
27+
import org.springframework.context.annotation.Bean;
28+
import org.springframework.context.annotation.Configuration;
29+
import org.springframework.context.annotation.Role;
30+
import org.springframework.security.authorization.AuthorizationAdvisorProxyFactory;
31+
import org.springframework.security.authorization.method.AuthorizationAdvisor;
32+
import org.springframework.security.authorization.method.AuthorizeReturnObjectMethodInterceptor;
33+
34+
@Configuration(proxyBeanMethods = false)
35+
final class AuthorizationProxyConfiguration implements AopInfrastructureBean {
36+
37+
@Bean
38+
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
39+
static AuthorizationAdvisorProxyFactory authorizationProxyFactory(ObjectProvider<AuthorizationAdvisor> provider) {
40+
List<AuthorizationAdvisor> advisors = new ArrayList<>();
41+
provider.forEach(advisors::add);
42+
AuthorizationAdvisorProxyFactory factory = new AuthorizationAdvisorProxyFactory();
43+
factory.setAdvisors(advisors);
44+
return factory;
45+
}
46+
47+
@Bean
48+
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
49+
static MethodInterceptor authorizeReturnObjectMethodInterceptor(ObjectProvider<AuthorizationAdvisor> provider,
50+
AuthorizationAdvisorProxyFactory authorizationProxyFactory) {
51+
AuthorizeReturnObjectMethodInterceptor interceptor = new AuthorizeReturnObjectMethodInterceptor(
52+
authorizationProxyFactory);
53+
List<AuthorizationAdvisor> advisors = new ArrayList<>();
54+
provider.forEach(advisors::add);
55+
advisors.add(interceptor);
56+
authorizationProxyFactory.setAdvisors(advisors);
57+
return interceptor;
58+
}
59+
60+
}

config/src/main/java/org/springframework/security/config/annotation/method/configuration/Jsr250MethodSecurityConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.aopalliance.intercept.MethodInterceptor;
2121
import org.aopalliance.intercept.MethodInvocation;
2222

23+
import org.springframework.aop.framework.AopInfrastructureBean;
2324
import org.springframework.beans.factory.ObjectProvider;
2425
import org.springframework.beans.factory.config.BeanDefinition;
2526
import org.springframework.context.annotation.Bean;
@@ -48,7 +49,7 @@
4849
*/
4950
@Configuration(proxyBeanMethods = false)
5051
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
51-
final class Jsr250MethodSecurityConfiguration implements ImportAware {
52+
final class Jsr250MethodSecurityConfiguration implements ImportAware, AopInfrastructureBean {
5253

5354
private int interceptorOrderOffset;
5455

config/src/main/java/org/springframework/security/config/annotation/method/configuration/MethodSecurityAdvisorRegistrar.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, B
3333
registerAsAdvisor("postAuthorizeAuthorization", registry);
3434
registerAsAdvisor("securedAuthorization", registry);
3535
registerAsAdvisor("jsr250Authorization", registry);
36+
registerAsAdvisor("authorizeReturnObject", registry);
3637
}
3738

3839
private void registerAsAdvisor(String prefix, BeanDefinitionRegistry registry) {

config/src/main/java/org/springframework/security/config/annotation/method/configuration/MethodSecuritySelector.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public String[] selectImports(@NonNull AnnotationMetadata importMetadata) {
5656
if (annotation.jsr250Enabled()) {
5757
imports.add(Jsr250MethodSecurityConfiguration.class.getName());
5858
}
59+
imports.add(AuthorizationProxyConfiguration.class.getName());
5960
return imports.toArray(new String[0]);
6061
}
6162

0 commit comments

Comments
 (0)