From 8bbe02c900ad0c32cbdd922f2c2b7608c91b4164 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Thu, 27 Jul 2023 19:07:16 +0200 Subject: [PATCH 1/6] UseNewRequestMatchers should also replace with 5.7 on classpath --- .../security5/UseNewRequestMatchers.java | 78 +++++++---------- .../security5/UseNewRequestMatchersTest.java | 84 ++++++------------- 2 files changed, 55 insertions(+), 107 deletions(-) rename src/{testWithSpringSecurity_5_7 => testWithSpringSecurity_5_8}/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java (84%) diff --git a/src/main/java/org/openrewrite/java/spring/security5/UseNewRequestMatchers.java b/src/main/java/org/openrewrite/java/spring/security5/UseNewRequestMatchers.java index d8dfe097..b7e356c8 100644 --- a/src/main/java/org/openrewrite/java/spring/security5/UseNewRequestMatchers.java +++ b/src/main/java/org/openrewrite/java/spring/security5/UseNewRequestMatchers.java @@ -22,24 +22,26 @@ import org.openrewrite.Recipe; import org.openrewrite.TreeVisitor; import org.openrewrite.java.JavaIsoVisitor; +import org.openrewrite.java.JavaParser; +import org.openrewrite.java.JavaTemplate; import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.search.UsesMethod; +import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; -import org.openrewrite.java.tree.JavaType; -import org.openrewrite.java.tree.TypeUtils; +import java.util.ArrayList; import java.util.List; -import java.util.Optional; -import static java.util.Objects.requireNonNull; +import static java.util.stream.Collectors.joining; @Value @EqualsAndHashCode(callSuper = false) public class UseNewRequestMatchers extends Recipe { - private static final MethodMatcher ANT_MATCHERS = new MethodMatcher("org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry antMatchers(..)"); - private static final MethodMatcher MVC_MATCHERS = new MethodMatcher("org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry mvcMatchers(..)", true); - private static final MethodMatcher REGEX_MATCHERS = new MethodMatcher("org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry regexMatchers(..)"); + private static final String CLAZZ = "org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry"; + private static final MethodMatcher ANT_MATCHERS = new MethodMatcher(CLAZZ + " antMatchers(..)"); + private static final MethodMatcher MVC_MATCHERS = new MethodMatcher(CLAZZ + " mvcMatchers(..)", true); + private static final MethodMatcher REGEX_MATCHERS = new MethodMatcher(CLAZZ + " regexMatchers(..)"); @Override @@ -57,46 +59,26 @@ public String getDescription() { @Override public TreeVisitor getVisitor() { return Preconditions.check(Preconditions.or( - new UsesMethod<>(ANT_MATCHERS), - new UsesMethod<>(MVC_MATCHERS), - new UsesMethod<>(REGEX_MATCHERS)), new JavaIsoVisitor() { - - @Override - public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { - J.MethodInvocation mi = super.visitMethodInvocation(method, ctx); - if (ANT_MATCHERS.matches(mi) || MVC_MATCHERS.matches(mi) || REGEX_MATCHERS.matches(mi)) { - mi = maybeChangeMethodInvocation(mi); - } - return mi; - } - }); - - } - - private J.MethodInvocation maybeChangeMethodInvocation(J.MethodInvocation mi) { - return findRequestMatchersMethodWithMatchingParameterTypes(mi) - .map(requestMatchersMethod -> mi - .withMethodType(requestMatchersMethod) - .withName(mi.getName().withSimpleName("requestMatchers"))) - .orElse(mi); - } - - private Optional findRequestMatchersMethodWithMatchingParameterTypes(J.MethodInvocation mi) { - JavaType.Method methodType = mi.getMethodType(); - if (methodType == null) { - return Optional.empty(); - } - List parameterTypes = methodType.getParameterTypes(); - List methods; - boolean isOverride = TypeUtils.isOverride(mi.getMethodType()); - if (isOverride) { - methods = requireNonNull(methodType.getDeclaringType().getSupertype(), "superType").getMethods(); - } else { - methods = methodType.getDeclaringType().getMethods(); - } - return methods.stream() - .filter(m -> m.getName().equals("requestMatchers")) - .filter(m -> m.getParameterTypes().equals(parameterTypes)) - .findFirst(); + new UsesMethod<>(ANT_MATCHERS), + new UsesMethod<>(MVC_MATCHERS), + new UsesMethod<>(REGEX_MATCHERS)), + new JavaIsoVisitor() { + @Override + public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { + J.MethodInvocation mi = super.visitMethodInvocation(method, ctx); + if ((ANT_MATCHERS.matches(mi) || MVC_MATCHERS.matches(mi) || REGEX_MATCHERS.matches(mi)) + && mi.getSelect() != null) { + String parametersTemplate = mi.getArguments().stream().map(arg -> "#{any()}").collect(joining(", ")); + List parameters = new ArrayList<>(); + parameters.add(mi.getSelect()); + parameters.addAll(mi.getArguments()); + JavaTemplate template = JavaTemplate.builder(String.format("#{any()}\n.requestMatchers(%s)", parametersTemplate)) + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "spring-security-config-5.8")) + .build(); + return template.apply(getCursor(), mi.getCoordinates().replace(), parameters.toArray()); + } + return mi; + } + }); } } diff --git a/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java b/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java similarity index 84% rename from src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java rename to src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java index 6da3a2dc..4b742f95 100644 --- a/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java +++ b/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java @@ -22,6 +22,7 @@ import org.openrewrite.java.spring.security5.UseNewRequestMatchers; import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; +import org.openrewrite.test.TypeValidation; import static org.openrewrite.java.Assertions.java; @@ -30,6 +31,7 @@ class UseNewRequestMatchersTest implements RewriteTest { @Override public void defaults(RecipeSpec spec) { spec.recipe(new UseNewRequestMatchers()) + .typeValidationOptions(TypeValidation.builder().methodInvocations(false).build()) .parser(JavaParser.fromJavaVersion() .logCompilationWarningsAndErrors(true) .classpathFromResources(new InMemoryExecutionContext(),"spring-context-5.3.+", "spring-beans-5.3.+", "spring-web-5.3.+", "spring-security-web-5.8.+", "spring-security-config-5.8.+")); @@ -55,10 +57,7 @@ void migratesMvcMatchersWithMvcPatterns() { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http - .authorizeHttpRequests((authz) -> authz - .mvcMatchers("/static/**").permitAll() - ); + http.authorizeHttpRequests(authz -> authz.mvcMatchers("/static/**").permitAll()); return http.build(); } } @@ -78,10 +77,8 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http - .authorizeHttpRequests((authz) -> authz - .requestMatchers("/static/**").permitAll() - ); + http.authorizeHttpRequests(authz -> authz + .requestMatchers("/static/**").permitAll()); return http.build(); } } @@ -110,10 +107,7 @@ void migratesMvcMatchersWithMvcPatternsAndHttpMethod() { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http - .authorizeHttpRequests((authz) -> authz - .mvcMatchers(HttpMethod.GET, "/static/**").permitAll() - ); + http.authorizeHttpRequests(authz -> authz.mvcMatchers(HttpMethod.GET, "/static/**").permitAll()); return http.build(); } } @@ -134,10 +128,8 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http - .authorizeHttpRequests((authz) -> authz - .requestMatchers(HttpMethod.GET, "/static/**").permitAll() - ); + http.authorizeHttpRequests(authz -> authz + .requestMatchers(HttpMethod.GET, "/static/**").permitAll()); return http.build(); } } @@ -165,10 +157,7 @@ void migratesRegexMatchersWithRegexPatterns() { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http - .authorizeHttpRequests((authz) -> authz - .regexMatchers("/static/**").permitAll() - ); + http.authorizeHttpRequests(authz -> authz.regexMatchers("/static/**").permitAll()); return http.build(); } } @@ -188,10 +177,8 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http - .authorizeHttpRequests((authz) -> authz - .requestMatchers("/static/**").permitAll() - ); + http.authorizeHttpRequests(authz -> authz + .requestMatchers("/static/**").permitAll()); return http.build(); } } @@ -220,10 +207,7 @@ void migratesRegexMatchersWithRegexPatternsAndHttpMethod() { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http - .authorizeHttpRequests((authz) -> authz - .regexMatchers(HttpMethod.GET, "/static/**").permitAll() - ); + http.authorizeHttpRequests(authz -> authz.regexMatchers(HttpMethod.GET, "/static/**").permitAll()); return http.build(); } } @@ -244,10 +228,8 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http - .authorizeHttpRequests((authz) -> authz - .requestMatchers(HttpMethod.GET, "/static/**").permitAll() - ); + http.authorizeHttpRequests(authz -> authz + .requestMatchers(HttpMethod.GET, "/static/**").permitAll()); return http.build(); } } @@ -275,10 +257,7 @@ void migratesAntMatchersWithAntPatterns() { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http - .authorizeHttpRequests((authz) -> authz - .antMatchers("/static/**").permitAll() - ); + http.authorizeHttpRequests(authz -> authz.antMatchers("/static/**").permitAll()); return http.build(); } } @@ -298,10 +277,8 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http - .authorizeHttpRequests((authz) -> authz - .requestMatchers("/static/**").permitAll() - ); + http.authorizeHttpRequests(authz -> authz + .requestMatchers("/static/**").permitAll()); return http.build(); } } @@ -330,10 +307,7 @@ void migratesAntMatchersWithHttpMethod() { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http - .authorizeHttpRequests((authz) -> authz - .antMatchers(HttpMethod.GET).permitAll() - ); + http.authorizeHttpRequests(authz -> authz.antMatchers(HttpMethod.GET).permitAll()); return http.build(); } } @@ -354,10 +328,8 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http - .authorizeHttpRequests((authz) -> authz - .requestMatchers(HttpMethod.GET).permitAll() - ); + http.authorizeHttpRequests(authz -> authz + .requestMatchers(HttpMethod.GET).permitAll()); return http.build(); } } @@ -386,10 +358,7 @@ void migratesAntMatchersWithAntPatternsAndHttpMethod() { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http - .authorizeHttpRequests((authz) -> authz - .antMatchers(HttpMethod.GET, "/static/**").permitAll() - ); + http.authorizeHttpRequests(authz -> authz.antMatchers(HttpMethod.GET, "/static/**").permitAll()); return http.build(); } } @@ -410,10 +379,8 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http - .authorizeHttpRequests((authz) -> authz - .requestMatchers(HttpMethod.GET, "/static/**").permitAll() - ); + http.authorizeHttpRequests(authz -> authz + .requestMatchers(HttpMethod.GET, "/static/**").permitAll()); return http.build(); } } @@ -443,8 +410,7 @@ class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { http - .authorizeHttpRequests((authz) -> authz - .regexMatchers("/api/admin/**").hasRole("ADMIN") + .authorizeHttpRequests(authz -> authz.regexMatchers("/api/admin/**").hasRole("ADMIN") .antMatchers(HttpMethod.GET, "/api/user/**").hasRole("USER") .mvcMatchers(HttpMethod.PATCH).denyAll() .anyRequest().authenticated() @@ -470,7 +436,7 @@ class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { http - .authorizeHttpRequests((authz) -> authz + .authorizeHttpRequests(authz -> authz .requestMatchers("/api/admin/**").hasRole("ADMIN") .requestMatchers(HttpMethod.GET, "/api/user/**").hasRole("USER") .requestMatchers(HttpMethod.PATCH).denyAll() From dad84cbe48166e28f96e80fd4395b250741ec188 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Thu, 27 Jul 2023 19:35:07 +0200 Subject: [PATCH 2/6] Also migrate ignoringAntMatchers to ignoringRequestMatchers --- .../java/spring/security5/UseNewRequestMatchers.java | 7 +++++-- .../spring/security5/UseNewRequestMatchersTest.java | 9 +++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/openrewrite/java/spring/security5/UseNewRequestMatchers.java b/src/main/java/org/openrewrite/java/spring/security5/UseNewRequestMatchers.java index b7e356c8..10253603 100644 --- a/src/main/java/org/openrewrite/java/spring/security5/UseNewRequestMatchers.java +++ b/src/main/java/org/openrewrite/java/spring/security5/UseNewRequestMatchers.java @@ -42,6 +42,7 @@ public class UseNewRequestMatchers extends Recipe { private static final MethodMatcher ANT_MATCHERS = new MethodMatcher(CLAZZ + " antMatchers(..)"); private static final MethodMatcher MVC_MATCHERS = new MethodMatcher(CLAZZ + " mvcMatchers(..)", true); private static final MethodMatcher REGEX_MATCHERS = new MethodMatcher(CLAZZ + " regexMatchers(..)"); + private static final MethodMatcher CSRF_MATCHERS = new MethodMatcher("org.springframework.security.config.annotation.web.configurers.CsrfConfigurer ignoringAntMatchers(..)"); @Override @@ -66,13 +67,15 @@ public TreeVisitor getVisitor() { @Override public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { J.MethodInvocation mi = super.visitMethodInvocation(method, ctx); - if ((ANT_MATCHERS.matches(mi) || MVC_MATCHERS.matches(mi) || REGEX_MATCHERS.matches(mi)) + boolean isCsrfMatcher = CSRF_MATCHERS.matches(mi); + if ((ANT_MATCHERS.matches(mi) || MVC_MATCHERS.matches(mi) || REGEX_MATCHERS.matches(mi) || isCsrfMatcher) && mi.getSelect() != null) { String parametersTemplate = mi.getArguments().stream().map(arg -> "#{any()}").collect(joining(", ")); List parameters = new ArrayList<>(); parameters.add(mi.getSelect()); parameters.addAll(mi.getArguments()); - JavaTemplate template = JavaTemplate.builder(String.format("#{any()}\n.requestMatchers(%s)", parametersTemplate)) + String replacementMethodName = isCsrfMatcher ? "ignoringRequestMatchers" : "requestMatchers"; + JavaTemplate template = JavaTemplate.builder(String.format("#{any()}\n." + replacementMethodName + "(%s)", parametersTemplate)) .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "spring-security-config-5.8")) .build(); return template.apply(getCursor(), mi.getCoordinates().replace(), parameters.toArray()); diff --git a/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java b/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java index 4b742f95..8bc99fec 100644 --- a/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java +++ b/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java @@ -413,8 +413,8 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { .authorizeHttpRequests(authz -> authz.regexMatchers("/api/admin/**").hasRole("ADMIN") .antMatchers(HttpMethod.GET, "/api/user/**").hasRole("USER") .mvcMatchers(HttpMethod.PATCH).denyAll() - .anyRequest().authenticated() - ); + .anyRequest().authenticated()) + .csrf().ignoringAntMatchers("/admin/**"); return http.build(); } } @@ -440,8 +440,9 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { .requestMatchers("/api/admin/**").hasRole("ADMIN") .requestMatchers(HttpMethod.GET, "/api/user/**").hasRole("USER") .requestMatchers(HttpMethod.PATCH).denyAll() - .anyRequest().authenticated() - ); + .anyRequest().authenticated()) + .csrf() + .ignoringRequestMatchers("/admin/**"); return http.build(); } } From aee9455a24757dc6cdacd5dfeef633480484d6e9 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Thu, 27 Jul 2023 19:37:16 +0200 Subject: [PATCH 3/6] Ignore type validation issues on combined test --- .../spring/security5/UseNewSecurityMatchersTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewSecurityMatchersTest.java b/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewSecurityMatchersTest.java index 91398749..3592c390 100644 --- a/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewSecurityMatchersTest.java +++ b/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewSecurityMatchersTest.java @@ -28,6 +28,7 @@ import org.openrewrite.java.tree.J; import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; +import org.openrewrite.test.TypeValidation; import static org.openrewrite.java.Assertions.java; import static org.openrewrite.test.RewriteTest.toRecipe; @@ -110,7 +111,8 @@ void togetherWithRequestMatchers() { tree = new UseNewSecurityMatchers().getVisitor().visit(tree, ctx); return (J) tree; } - })), + })) + .typeValidationOptions(TypeValidation.builder().methodInvocations(false).build()), java( """ package com.example; From 33998c617b7c62ddcbb0e153d508cc171ae23887 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Fri, 28 Jul 2023 09:26:16 +0200 Subject: [PATCH 4/6] Use getCoordinates().replaceMethod() --- .../security5/UseNewRequestMatchers.java | 12 +--- .../security5/UseNewSecurityMatchersTest.java | 68 ++++++++++++++++--- .../security5/UseNewRequestMatchersTest.java | 42 ++++-------- 3 files changed, 76 insertions(+), 46 deletions(-) diff --git a/src/main/java/org/openrewrite/java/spring/security5/UseNewRequestMatchers.java b/src/main/java/org/openrewrite/java/spring/security5/UseNewRequestMatchers.java index 10253603..6397b467 100644 --- a/src/main/java/org/openrewrite/java/spring/security5/UseNewRequestMatchers.java +++ b/src/main/java/org/openrewrite/java/spring/security5/UseNewRequestMatchers.java @@ -26,12 +26,8 @@ import org.openrewrite.java.JavaTemplate; import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.search.UsesMethod; -import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; -import java.util.ArrayList; -import java.util.List; - import static java.util.stream.Collectors.joining; @Value @@ -71,14 +67,12 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu if ((ANT_MATCHERS.matches(mi) || MVC_MATCHERS.matches(mi) || REGEX_MATCHERS.matches(mi) || isCsrfMatcher) && mi.getSelect() != null) { String parametersTemplate = mi.getArguments().stream().map(arg -> "#{any()}").collect(joining(", ")); - List parameters = new ArrayList<>(); - parameters.add(mi.getSelect()); - parameters.addAll(mi.getArguments()); String replacementMethodName = isCsrfMatcher ? "ignoringRequestMatchers" : "requestMatchers"; - JavaTemplate template = JavaTemplate.builder(String.format("#{any()}\n." + replacementMethodName + "(%s)", parametersTemplate)) + JavaTemplate template = JavaTemplate.builder(String.format(replacementMethodName + "(%s)", parametersTemplate)) .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "spring-security-config-5.8")) .build(); - return template.apply(getCursor(), mi.getCoordinates().replace(), parameters.toArray()); + J.MethodInvocation apply = template.apply(getCursor(), mi.getCoordinates().replaceMethod(), mi.getArguments().toArray()); + return apply.withSelect(mi.getSelect()); } return mi; } diff --git a/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewSecurityMatchersTest.java b/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewSecurityMatchersTest.java index 3592c390..c5313916 100644 --- a/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewSecurityMatchersTest.java +++ b/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewSecurityMatchersTest.java @@ -16,10 +16,10 @@ package org.openrewrite.spring.security5; import org.junit.jupiter.api.Test; +import org.openrewrite.DocumentExample; import org.openrewrite.ExecutionContext; import org.openrewrite.InMemoryExecutionContext; import org.openrewrite.Tree; -import org.openrewrite.DocumentExample; import org.openrewrite.internal.lang.Nullable; import org.openrewrite.java.JavaParser; import org.openrewrite.java.JavaVisitor; @@ -40,7 +40,7 @@ public void defaults(RecipeSpec spec) { spec.recipe(new UseNewSecurityMatchers()) .parser(JavaParser.fromJavaVersion() .logCompilationWarningsAndErrors(true) - .classpathFromResources(new InMemoryExecutionContext(),"spring-context-5.3.+", "spring-beans-5.3.+", "spring-web-5.3.+", "spring-security-web-5.8.+", "spring-security-config-5.8.+")); + .classpathFromResources(new InMemoryExecutionContext(), "spring-context-5.3.+", "spring-beans-5.3.+", "spring-web-5.3.+", "spring-security-web-5.8.+", "spring-security-config-5.8.+")); } @DocumentExample @@ -100,18 +100,68 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { ); } + @Test + void chainedCalls() { + rewriteRun( + //language=java + java(""" + package com.example.demo; + + import org.springframework.context.annotation.Bean; + import org.springframework.context.annotation.Configuration; + import org.springframework.http.HttpMethod; + import org.springframework.security.config.annotation.web.builders.HttpSecurity; + import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; + import org.springframework.security.web.SecurityFilterChain; + + @Configuration + @EnableWebSecurity + class SecurityConfig { + @Bean + SecurityFilterChain securityFilterChain(HttpSecurity http) { + http.antMatcher("/**").authorizeRequests() + .antMatchers(HttpMethod.POST, "/verify").access("hasRole('ROLE_USER')") + .anyRequest().authenticated(); + return http.build(); + } + } + """,""" + package com.example.demo; + + import org.springframework.context.annotation.Bean; + import org.springframework.context.annotation.Configuration; + import org.springframework.http.HttpMethod; + import org.springframework.security.config.annotation.web.builders.HttpSecurity; + import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; + import org.springframework.security.web.SecurityFilterChain; + + @Configuration + @EnableWebSecurity + class SecurityConfig { + @Bean + SecurityFilterChain securityFilterChain(HttpSecurity http) { + http.securityMatcher("/**").authorizeRequests() + .antMatchers(HttpMethod.POST, "/verify").access("hasRole('ROLE_USER')") + .anyRequest().authenticated(); + return http.build(); + } + } + """) + ); + } + @Test void togetherWithRequestMatchers() { //language=java rewriteRun( spec -> spec.recipe(toRecipe(() -> new JavaVisitor<>() { - @Override - public @Nullable J visit(@Nullable Tree tree, ExecutionContext ctx) { - tree = new UseNewRequestMatchers().getVisitor().visit(tree, ctx); - tree = new UseNewSecurityMatchers().getVisitor().visit(tree, ctx); - return (J) tree; - } - })) + @Override + public @Nullable J visit(@Nullable Tree tree, ExecutionContext ctx) { + tree = new UseNewRequestMatchers().getVisitor().visit(tree, ctx); + tree = new UseNewSecurityMatchers().getVisitor().visit(tree, ctx); + return (J) tree; + } + })) .typeValidationOptions(TypeValidation.builder().methodInvocations(false).build()), java( """ diff --git a/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java b/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java index 8bc99fec..078222f6 100644 --- a/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java +++ b/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java @@ -16,8 +16,8 @@ package org.openrewrite.spring.security5; import org.junit.jupiter.api.Test; -import org.openrewrite.InMemoryExecutionContext; import org.openrewrite.DocumentExample; +import org.openrewrite.InMemoryExecutionContext; import org.openrewrite.java.JavaParser; import org.openrewrite.java.spring.security5.UseNewRequestMatchers; import org.openrewrite.test.RecipeSpec; @@ -34,7 +34,7 @@ public void defaults(RecipeSpec spec) { .typeValidationOptions(TypeValidation.builder().methodInvocations(false).build()) .parser(JavaParser.fromJavaVersion() .logCompilationWarningsAndErrors(true) - .classpathFromResources(new InMemoryExecutionContext(),"spring-context-5.3.+", "spring-beans-5.3.+", "spring-web-5.3.+", "spring-security-web-5.8.+", "spring-security-config-5.8.+")); + .classpathFromResources(new InMemoryExecutionContext(), "spring-context-5.3.+", "spring-beans-5.3.+", "spring-web-5.3.+", "spring-security-web-5.8.+", "spring-security-config-5.8.+")); } @DocumentExample @@ -61,8 +61,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { return http.build(); } } - """ - , + """, """ package com.example; @@ -77,8 +76,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http.authorizeHttpRequests(authz -> authz - .requestMatchers("/static/**").permitAll()); + http.authorizeHttpRequests(authz -> authz.requestMatchers("/static/**").permitAll()); return http.build(); } } @@ -128,8 +126,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http.authorizeHttpRequests(authz -> authz - .requestMatchers(HttpMethod.GET, "/static/**").permitAll()); + http.authorizeHttpRequests(authz -> authz.requestMatchers(HttpMethod.GET, "/static/**").permitAll()); return http.build(); } } @@ -177,8 +174,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http.authorizeHttpRequests(authz -> authz - .requestMatchers("/static/**").permitAll()); + http.authorizeHttpRequests(authz -> authz.requestMatchers("/static/**").permitAll()); return http.build(); } } @@ -228,8 +224,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http.authorizeHttpRequests(authz -> authz - .requestMatchers(HttpMethod.GET, "/static/**").permitAll()); + http.authorizeHttpRequests(authz -> authz.requestMatchers(HttpMethod.GET, "/static/**").permitAll()); return http.build(); } } @@ -277,8 +272,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http.authorizeHttpRequests(authz -> authz - .requestMatchers("/static/**").permitAll()); + http.authorizeHttpRequests(authz -> authz.requestMatchers("/static/**").permitAll()); return http.build(); } } @@ -328,8 +322,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http.authorizeHttpRequests(authz -> authz - .requestMatchers(HttpMethod.GET).permitAll()); + http.authorizeHttpRequests(authz -> authz.requestMatchers(HttpMethod.GET).permitAll()); return http.build(); } } @@ -379,8 +372,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http.authorizeHttpRequests(authz -> authz - .requestMatchers(HttpMethod.GET, "/static/**").permitAll()); + http.authorizeHttpRequests(authz -> authz.requestMatchers(HttpMethod.GET, "/static/**").permitAll()); return http.build(); } } @@ -409,12 +401,10 @@ void migratesAllTypesOfMatchers() { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http - .authorizeHttpRequests(authz -> authz.regexMatchers("/api/admin/**").hasRole("ADMIN") + http.authorizeHttpRequests(authz -> authz.regexMatchers("/api/admin/**").hasRole("ADMIN") .antMatchers(HttpMethod.GET, "/api/user/**").hasRole("USER") .mvcMatchers(HttpMethod.PATCH).denyAll() - .anyRequest().authenticated()) - .csrf().ignoringAntMatchers("/admin/**"); + .anyRequest().authenticated()).csrf().ignoringAntMatchers("/admin/**"); return http.build(); } } @@ -435,14 +425,10 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) { class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) { - http - .authorizeHttpRequests(authz -> authz - .requestMatchers("/api/admin/**").hasRole("ADMIN") + http.authorizeHttpRequests(authz -> authz.requestMatchers("/api/admin/**").hasRole("ADMIN") .requestMatchers(HttpMethod.GET, "/api/user/**").hasRole("USER") .requestMatchers(HttpMethod.PATCH).denyAll() - .anyRequest().authenticated()) - .csrf() - .ignoringRequestMatchers("/admin/**"); + .anyRequest().authenticated()).csrf().ignoringRequestMatchers("/admin/**"); return http.build(); } } From 6ef8cd9c7340bbe271da05a8cd5eeff9f57f419c Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Fri, 28 Jul 2023 09:29:29 +0200 Subject: [PATCH 5/6] Update name to remove need for typeValidationOptions --- .../java/spring/security5/UseNewRequestMatchers.java | 3 ++- .../spring/security5/UseNewSecurityMatchersTest.java | 3 +-- .../spring/security5/UseNewRequestMatchersTest.java | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/openrewrite/java/spring/security5/UseNewRequestMatchers.java b/src/main/java/org/openrewrite/java/spring/security5/UseNewRequestMatchers.java index 6397b467..fa3b3134 100644 --- a/src/main/java/org/openrewrite/java/spring/security5/UseNewRequestMatchers.java +++ b/src/main/java/org/openrewrite/java/spring/security5/UseNewRequestMatchers.java @@ -72,7 +72,8 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "spring-security-config-5.8")) .build(); J.MethodInvocation apply = template.apply(getCursor(), mi.getCoordinates().replaceMethod(), mi.getArguments().toArray()); - return apply.withSelect(mi.getSelect()); + return apply.withSelect(mi.getSelect()) + .withName(mi.getName().withSimpleName(replacementMethodName)); } return mi; } diff --git a/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewSecurityMatchersTest.java b/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewSecurityMatchersTest.java index c5313916..ff5bcd71 100644 --- a/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewSecurityMatchersTest.java +++ b/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewSecurityMatchersTest.java @@ -161,8 +161,7 @@ void togetherWithRequestMatchers() { tree = new UseNewSecurityMatchers().getVisitor().visit(tree, ctx); return (J) tree; } - })) - .typeValidationOptions(TypeValidation.builder().methodInvocations(false).build()), + })), java( """ package com.example; diff --git a/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java b/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java index 078222f6..b30eca67 100644 --- a/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java +++ b/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java @@ -31,7 +31,6 @@ class UseNewRequestMatchersTest implements RewriteTest { @Override public void defaults(RecipeSpec spec) { spec.recipe(new UseNewRequestMatchers()) - .typeValidationOptions(TypeValidation.builder().methodInvocations(false).build()) .parser(JavaParser.fromJavaVersion() .logCompilationWarningsAndErrors(true) .classpathFromResources(new InMemoryExecutionContext(), "spring-context-5.3.+", "spring-beans-5.3.+", "spring-web-5.3.+", "spring-security-web-5.8.+", "spring-security-config-5.8.+")); From 2935560d3578afcb5030d5fca8377a66d94c8282 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Fri, 28 Jul 2023 09:30:09 +0200 Subject: [PATCH 6/6] Remove unused imports --- .../openrewrite/spring/security5/UseNewSecurityMatchersTest.java | 1 - .../openrewrite/spring/security5/UseNewRequestMatchersTest.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewSecurityMatchersTest.java b/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewSecurityMatchersTest.java index ff5bcd71..92021df6 100644 --- a/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewSecurityMatchersTest.java +++ b/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/UseNewSecurityMatchersTest.java @@ -28,7 +28,6 @@ import org.openrewrite.java.tree.J; import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; -import org.openrewrite.test.TypeValidation; import static org.openrewrite.java.Assertions.java; import static org.openrewrite.test.RewriteTest.toRecipe; diff --git a/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java b/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java index b30eca67..427e347a 100644 --- a/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java +++ b/src/testWithSpringSecurity_5_8/java/org/openrewrite/spring/security5/UseNewRequestMatchersTest.java @@ -22,7 +22,6 @@ import org.openrewrite.java.spring.security5.UseNewRequestMatchers; import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; -import org.openrewrite.test.TypeValidation; import static org.openrewrite.java.Assertions.java;