From 69799754440a1acf93acd40bc5be413ce65b117a Mon Sep 17 00:00:00 2001 From: aboyko Date: Fri, 17 Feb 2023 19:12:48 -0500 Subject: [PATCH] Security switch to DSL syntax problem markers (no fix proposals) --- .../boot/java/Boot2JavaProblemType.java | 7 +- .../rewrite/BootCodeActionRepository.java | 8 +- .../HttpSecurityLamdaDslCodeAction.java | 83 +++++++++++++++++++ ...ServerHttpSecurityLambdaDslCodeAction.java | 82 ++++++++++++++++++ .../src/main/resources/problem-types.json | 6 ++ .../vscode-spring-boot/package.json | 12 +++ 6 files changed, 194 insertions(+), 4 deletions(-) create mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/HttpSecurityLamdaDslCodeAction.java create mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/ServerHttpSecurityLambdaDslCodeAction.java diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/Boot2JavaProblemType.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/Boot2JavaProblemType.java index ba8610119..da650557f 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/Boot2JavaProblemType.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/Boot2JavaProblemType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 VMware, Inc. + * Copyright (c) 2022, 2023 VMware, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,6 +11,7 @@ package org.springframework.ide.vscode.boot.java; import static org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity.IGNORE; +import static org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity.INFO; import static org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity.HINT; import static org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity.WARNING; @@ -31,7 +32,9 @@ public enum Boot2JavaProblemType implements ProblemType { JAVA_PRECISE_REQUEST_MAPPING(HINT, "Use precise mapping annotation, i.e. '@GetMapping', '@PostMapping', etc.", "Use precise mapping annotation, i.e. '@GetMapping', '@PostMapping', etc."), - JAVA_REPOSITORY(WARNING, "Unnecessary `@Repository`", "Unnecessary `@Repository`"); + JAVA_REPOSITORY(WARNING, "Unnecessary `@Repository`", "Unnecessary `@Repository`"), + + JAVA_LAMBDA_DSL(INFO, "Consider switching to Lambda DSL syntax", "Switch to Lambda DSL syntax"); private final ProblemSeverity defaultSeverity; private String description; diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/BootCodeActionRepository.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/BootCodeActionRepository.java index 51b9f9d87..506564f0a 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/BootCodeActionRepository.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/BootCodeActionRepository.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 VMware, Inc. + * Copyright (c) 2022, 2023 VMware, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -16,11 +16,13 @@ import org.springframework.ide.vscode.boot.java.rewrite.reconcile.AutowiredField import org.springframework.ide.vscode.boot.java.rewrite.reconcile.BeanMethodNotPublicProblem; import org.springframework.ide.vscode.boot.java.rewrite.reconcile.BeanPostProcessingIgnoreInAotProblem; import org.springframework.ide.vscode.boot.java.rewrite.reconcile.Boot3NotSupportedTypeProblem; +import org.springframework.ide.vscode.boot.java.rewrite.reconcile.HttpSecurityLamdaDslCodeAction; import org.springframework.ide.vscode.boot.java.rewrite.reconcile.NoAutowiredOnConstructorProblem; import org.springframework.ide.vscode.boot.java.rewrite.reconcile.NoRepoAnnotationProblem; import org.springframework.ide.vscode.boot.java.rewrite.reconcile.NoRequestMappingAnnotationCodeAction; import org.springframework.ide.vscode.boot.java.rewrite.reconcile.NotRegisteredBeansProblem; import org.springframework.ide.vscode.boot.java.rewrite.reconcile.PreciseBeanTypeProblem; +import org.springframework.ide.vscode.boot.java.rewrite.reconcile.ServerHttpSecurityLambdaDslCodeAction; import org.springframework.ide.vscode.boot.java.rewrite.reconcile.UnnecessarySpringExtensionProblem; import org.springframework.ide.vscode.commons.rewrite.config.CodeActionRepository; import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor; @@ -39,7 +41,9 @@ public class BootCodeActionRepository extends CodeActionRepository { new Boot3NotSupportedTypeProblem(), new NoRequestMappingAnnotationCodeAction(), new AutowiredFieldIntoConstructorParameterCodeAction(), - new NoRepoAnnotationProblem() + new NoRepoAnnotationProblem(), + new HttpSecurityLamdaDslCodeAction(), + new ServerHttpSecurityLambdaDslCodeAction() ); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/HttpSecurityLamdaDslCodeAction.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/HttpSecurityLamdaDslCodeAction.java new file mode 100644 index 000000000..c5c7f9d3e --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/HttpSecurityLamdaDslCodeAction.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2023 VMware, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.boot.java.rewrite.reconcile; + +import java.util.Set; + +import org.openrewrite.ExecutionContext; +import org.openrewrite.Tree; +import org.openrewrite.java.JavaVisitor; +import org.openrewrite.java.tree.J; +import org.openrewrite.java.tree.J.MethodInvocation; +import org.openrewrite.java.tree.JavaType.FullyQualified; +import org.openrewrite.java.tree.JavaType.Method; +import org.springframework.context.ApplicationContext; +import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType; +import org.springframework.ide.vscode.commons.java.IJavaProject; +import org.springframework.ide.vscode.commons.java.SpringProjectUtil; +import org.springframework.ide.vscode.commons.java.Version; +import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType; +import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor; +import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker; +import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor; + +public class HttpSecurityLamdaDslCodeAction implements RecipeCodeActionDescriptor { + + private static final Version SECURITY_VERSION = new Version(5, 2, 0, null); + + private static final String FQN_HTTP_SECURITY = "org.springframework.security.config.annotation.web.builders.HttpSecurity"; + + private static final Set APPLICABLE_METHOD_NAMES = Set.of( + "anonymous", "authorizeRequests", "cors", "csrf", "exceptionHandling", "formLogin", + "headers", "httpBasic", "jee", "logout", "oauth2Client", "oauth2Login", "oauth2ResourceServer", + "openidLogin", "portMapper", "rememberMe", "requestCache", "requestMatchers", "requiresChannel", + "saml2Login", "securityContext", "servletApi", "sessionManagement", "x509" + ); + + @Override + public JavaVisitor getMarkerVisitor(ApplicationContext applicationContext) { + return new JavaMarkerVisitor() { + + @Override + public MethodInvocation visitMethodInvocation(MethodInvocation method, ExecutionContext p) { + MethodInvocation m = super.visitMethodInvocation(method, p); + Method type = method.getMethodType(); + if (type != null) { + FullyQualified declaringType = type.getDeclaringType(); + if (declaringType != null && FQN_HTTP_SECURITY.equals(declaringType.getFullyQualifiedName()) + && type.getParameterTypes().isEmpty() && APPLICABLE_METHOD_NAMES.contains(m.getSimpleName()) + && getCursor().getParent(2) != null && getCursor().getParent(2).getValue() instanceof J.MethodInvocation) { + + J.MethodInvocation parentInvocation = getCursor().getParent(2).getValue(); + if (!declaringType.equals(parentInvocation.getType())) { + FixAssistMarker marker = new FixAssistMarker(Tree.randomId(), getId()).withLabel("Consider switching to Lambda DSL syntax"); + m = m.withName(m.getName().withMarkers(m.getName().getMarkers().add(marker))); + } + } + } + return m; + } + + }; + } + + @Override + public boolean isApplicable(IJavaProject project) { + Version version = SpringProjectUtil.getDependencyVersion(project, "spring-security-config"); + return version != null && version.compareTo(SECURITY_VERSION) >= 0; + } + + @Override + public ProblemType getProblemType() { + return Boot2JavaProblemType.JAVA_LAMBDA_DSL; + } + +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/ServerHttpSecurityLambdaDslCodeAction.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/ServerHttpSecurityLambdaDslCodeAction.java new file mode 100644 index 000000000..ad9d84cdf --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/ServerHttpSecurityLambdaDslCodeAction.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2023 VMware, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.boot.java.rewrite.reconcile; + +import java.util.Set; + +import org.openrewrite.ExecutionContext; +import org.openrewrite.Tree; +import org.openrewrite.java.JavaVisitor; +import org.openrewrite.java.tree.J; +import org.openrewrite.java.tree.J.MethodInvocation; +import org.openrewrite.java.tree.JavaType.FullyQualified; +import org.openrewrite.java.tree.JavaType.Method; +import org.springframework.context.ApplicationContext; +import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType; +import org.springframework.ide.vscode.commons.java.IJavaProject; +import org.springframework.ide.vscode.commons.java.SpringProjectUtil; +import org.springframework.ide.vscode.commons.java.Version; +import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType; +import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor; +import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker; +import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor; + +public class ServerHttpSecurityLambdaDslCodeAction implements RecipeCodeActionDescriptor { + + private static final Version SECURITY_VERSION = new Version(5, 2, 0, null); + + private static final String FQN_SERVER_HTTP_SECURITY = "org.springframework.security.config.web.server.ServerHttpSecurity"; + + private static final Set APPLICABLE_METHOD_NAMES = Set.of( + "anonymous", "authorizeExchange", "cors", "csrf", "exceptionHandling", "formLogin", + "headers", "httpBasic", "logout", "oauth2Client", "oauth2Login", "oauth2ResourceServer", + "redirectToHttps", "requestCache", "x509" + ); + + @Override + public JavaVisitor getMarkerVisitor(ApplicationContext applicationContext) { + return new JavaMarkerVisitor() { + + @Override + public MethodInvocation visitMethodInvocation(MethodInvocation method, ExecutionContext p) { + MethodInvocation m = super.visitMethodInvocation(method, p); + Method type = method.getMethodType(); + if (type != null) { + FullyQualified declaringType = type.getDeclaringType(); + if (declaringType != null && FQN_SERVER_HTTP_SECURITY.equals(declaringType.getFullyQualifiedName()) + && type.getParameterTypes().isEmpty() && APPLICABLE_METHOD_NAMES.contains(m.getSimpleName()) + && getCursor().getParent(2) != null && getCursor().getParent(2).getValue() instanceof J.MethodInvocation) { + + J.MethodInvocation parentInvocation = getCursor().getParent(2).getValue(); + if (!declaringType.equals(parentInvocation.getType())) { + FixAssistMarker marker = new FixAssistMarker(Tree.randomId(), getId()).withLabel("Consider switching to Lambda DSL syntax"); + m = m.withName(m.getName().withMarkers(m.getName().getMarkers().add(marker))); + } + } + } + return m; + } + + }; + } + + @Override + public boolean isApplicable(IJavaProject project) { + Version version = SpringProjectUtil.getDependencyVersion(project, "spring-security-config"); + return version != null && version.compareTo(SECURITY_VERSION) >= 0; + } + + @Override + public ProblemType getProblemType() { + return Boot2JavaProblemType.JAVA_LAMBDA_DSL; + } + +} diff --git a/headless-services/spring-boot-language-server/src/main/resources/problem-types.json b/headless-services/spring-boot-language-server/src/main/resources/problem-types.json index 9dbb2d1d9..4876aa21f 100644 --- a/headless-services/spring-boot-language-server/src/main/resources/problem-types.json +++ b/headless-services/spring-boot-language-server/src/main/resources/problem-types.json @@ -49,6 +49,12 @@ "label": "Unnecessary `@Repository`", "description": "Unnecessary `@Repository`", "defaultSeverity": "WARNING" + }, + { + "code": "JAVA_LAMBDA_DSL", + "label": "Switch to Lambda DSL syntax", + "description": "Consider switching to Lambda DSL syntax", + "defaultSeverity": "INFO" } ] }, diff --git a/vscode-extensions/vscode-spring-boot/package.json b/vscode-extensions/vscode-spring-boot/package.json index 38abb0b3c..c9a0e59b5 100644 --- a/vscode-extensions/vscode-spring-boot/package.json +++ b/vscode-extensions/vscode-spring-boot/package.json @@ -402,6 +402,18 @@ "HINT", "ERROR" ] + }, + "spring-boot.ls.problem.boot2.JAVA_LAMBDA_DSL": { + "type": "string", + "default": "INFO", + "description": "Consider switching to Lambda DSL syntax", + "enum": [ + "IGNORE", + "INFO", + "WARNING", + "HINT", + "ERROR" + ] } } },