Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions plugin-modernizer-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,11 @@
<artifactId>ssh-slaves</artifactId>
<version>3.1021.va_cc11b_de26a_e</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>jenkins-core</artifactId>
<version>2.497</version>
</dependency>
</artifactItems>
</configuration>
</execution>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package io.jenkins.tools.pluginmodernizer.core.recipes;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.java.ChangeMethodName;
import org.openrewrite.java.ChangePackage;
import org.openrewrite.java.ChangeType;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JLeftPadded;
import org.openrewrite.java.tree.Space;
import org.openrewrite.marker.Markers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MigrateAcegiSecurityToSpringSecurity extends Recipe {
/**
* Logger
*/
private static final Logger LOG = LoggerFactory.getLogger(MigrateAcegiSecurityToSpringSecurity.class);

@Override
public String getDisplayName() {
return "Migrate Acegi Security to Spring Security";
}

@Override
public String getDescription() {
return "Migrate acegi security to spring security.";
}

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new JavaIsoVisitor<>() {
@Override
public J.CompilationUnit visitCompilationUnit(J.CompilationUnit cu, ExecutionContext ctx) {
// ChangePackage will take care for the most of the migration so don't need to add separate migrations
// For those import statements that ChangePackage will not account correctly, add separate logic
cu = (J.CompilationUnit)
new ChangePackage("org.acegisecurity", "org.springframework.security.core", false)
.getVisitor()
.visitNonNull(cu, ctx);

cu = (J.CompilationUnit) new ChangeType(
"org.springframework.security.core.GrantedAuthorityImpl",
"org.springframework.security.core.authority.SimpleGrantedAuthority",
null)
.getVisitor()
.visitNonNull(cu, ctx);

// Authentication classes
cu = (J.CompilationUnit) new ChangeType(
"org.acegisecurity.providers.AbstractAuthenticationToken",
"org.springframework.security.authentication.AbstractAuthenticationToken",
null)
.getVisitor()
.visitNonNull(cu, ctx);

List<J.Import> originalImports = cu.getImports();

cu = (J.CompilationUnit) new ChangeType(
"org.springframework.security.core.AuthenticationManager",
" org.springframework.security.authentication.AuthenticationManager",
null)
.getVisitor()
.visitNonNull(cu, ctx);
if (!cu.getImports().equals(originalImports)) {
cu = addImportIfNotExists(
cu, "AuthenticationManager", "org.springframework.security.authentication");
}
originalImports = cu.getImports();
cu = (J.CompilationUnit) new ChangeType(
"org.springframework.security.core.BadCredentialsException",
"org.springframework.security.authentication.BadCredentialsException",
null)
.getVisitor()
.visitNonNull(cu, ctx);

if (!cu.getImports().equals(originalImports)) {
cu = addImportIfNotExists(
cu, "BadCredentialsException", "org.springframework.security.authentication");
}

return super.visitCompilationUnit(cu, ctx);
}

@Override
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
method = (J.MethodInvocation) new ChangeMethodName(
"jenkins.model.Jenkins getAuthentication()", "getAuthentication2", null, null)
.getVisitor()
.visitNonNull(method, ctx);
// Migrate fireAuthenticated to fireAuthenticated2
if (method.getSimpleName().equals("fireAuthenticated")) {
method = method.withName(method.getName().withSimpleName("fireAuthenticated2"));
}
return super.visitMethodInvocation(method, ctx);
}

private J.CompilationUnit addImportIfNotExists(J.CompilationUnit cu, String className, String packageName) {
boolean importExists = cu.getImports().stream().anyMatch(anImport -> (packageName + "." + className)
.equals(anImport.getQualid().toString()));
if (!importExists) {
J.Identifier identifier = new J.Identifier(
UUID.randomUUID(),
Space.EMPTY,
Markers.EMPTY,
Collections.emptyList(),
className,
null,
null);

J.Identifier packageIdentifier = new J.Identifier(
UUID.randomUUID(),
Space.SINGLE_SPACE,
Markers.EMPTY,
Collections.emptyList(),
packageName,
null,
null);

J.FieldAccess fieldAccess = new J.FieldAccess(
UUID.randomUUID(),
Space.EMPTY,
Markers.EMPTY,
packageIdentifier,
JLeftPadded.build(identifier),
null);

J.Import newImport = new J.Import(
UUID.randomUUID(),
Space.format("\n"), // Ensure the import appears on a new line
Markers.EMPTY,
JLeftPadded.build(false), // static: false
fieldAccess,
null);

List<J.Import> modifiedImports = new ArrayList<>(cu.getImports());
modifiedImports.add(newImport);

return cu.withImports(modifiedImports);
}

return cu;
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public TreeVisitor<?, ExecutionContext> getVisitor(Set<String> acc) {
@Override
public J.CompilationUnit visitCompilationUnit(J.CompilationUnit cu, ExecutionContext ctx) {
if (acc.isEmpty()) {
cu = (J.CompilationUnit) new ChangePackage("javax.servlet", "jakarta.servlet", false)
cu = (J.CompilationUnit) new ChangePackage("javax.servlet", "jakarta.servlet", true)
.getVisitor()
.visitNonNull(cu, ctx);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ recipeList:
- io.jenkins.tools.pluginmodernizer.core.recipes.UpgradeJenkinsTestHarnessVersion:
jenkinsVersion: 2.479.1
- io.jenkins.tools.pluginmodernizer.core.recipes.MigrateStaplerAndJavaxToJakarta
- io.jenkins.tools.pluginmodernizer.core.recipes.MigrateAcegiSecurityToSpringSecurity
- io.jenkins.tools.pluginmodernizer.RemoveDevelopersTag
- io.jenkins.tools.pluginmodernizer.RemoveDependencyVersionOverride
- io.jenkins.tools.pluginmodernizer.RemoveExtraMavenProperties
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1852,11 +1852,25 @@ void upgradeNextMajorParentVersionTest() {
import org.kohsuke.stapler.Stapler;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.acegisecurity.Authentication;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.providers.AbstractAuthenticationToken;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.AuthenticationManager;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import jenkins.model.Jenkins;
import jenkins.security.SecurityListener;

public class Foo {
public void foo() {
StaplerRequest req = Stapler.getCurrentRequest();
StaplerResponse response = Stapler.getCurrentResponse();
Authentication auth = Jenkins.getAuthentication();
}
}
""",
Expand All @@ -1865,11 +1879,24 @@ public void foo() {
import org.kohsuke.stapler.Stapler;
import org.kohsuke.stapler.StaplerRequest2;
import org.kohsuke.stapler.StaplerResponse2;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import jenkins.model.Jenkins;
import jenkins.security.SecurityListener;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;

public class Foo {
public void foo() {
StaplerRequest2 req = Stapler.getCurrentRequest2();
StaplerResponse2 response = Stapler.getCurrentResponse2();
Authentication auth = Jenkins.getAuthentication2();
}
}
""")));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package io.jenkins.tools.pluginmodernizer.core.recipes;

import static io.jenkins.tools.pluginmodernizer.core.recipes.DeclarativeRecipesTest.collectRewriteTestDependencies;
import static org.openrewrite.java.Assertions.java;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;
import org.openrewrite.java.JavaParser;
import org.openrewrite.test.RewriteTest;

/**
* Test for {@link MigrateAcegiSecurityToSpringSecurity}.
*/
@Execution(ExecutionMode.CONCURRENT)
public class MigrateAcegiSecurityToSpringSecurityTest implements RewriteTest {

@Test
void migrateAcegiToSpringSecurity() {
rewriteRun(
spec -> {
var parser = JavaParser.fromJavaVersion().logCompilationWarningsAndErrors(true);
collectRewriteTestDependencies().forEach(parser::addClasspathEntry);
spec.recipe(new MigrateAcegiSecurityToSpringSecurity()).parser(parser);
},
java(
"""
import org.acegisecurity.Authentication;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.providers.AbstractAuthenticationToken;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.AuthenticationManager;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import jenkins.model.Jenkins;
import jenkins.security.SecurityListener;

public class Foo implements UserDetails {
@Override
public GrantedAuthority[] getAuthorities() {
return new GrantedAuthority[] {
new GrantedAuthorityImpl("ROLE_USER")
};
}

@Override
public String getPassword() {
return "password123";
}

@Override
public String getUsername() {
return "testUser";
}

@Override
public boolean isAccountNonExpired() {
return true;
}

@Override
public boolean isAccountNonLocked() {
return true;
}

@Override
public boolean isCredentialsNonExpired() {
return true;
}

@Override
public boolean isEnabled() {
return true;
}
public UserDetails loadUserByUsername(String username) {
return new Foo();
}
public void foo() {
Authentication auth = Jenkins.getAuthentication();
Foo userDetails = new Foo();
SecurityListener.fireAuthenticated(userDetails);
}
}
""",
"""
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import jenkins.model.Jenkins;
import jenkins.security.SecurityListener;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;

public class Foo implements UserDetails {
@Override
public GrantedAuthority[] getAuthorities() {
return new GrantedAuthority[] {
new SimpleGrantedAuthority("ROLE_USER")
};
}

@Override
public String getPassword() {
return "password123";
}

@Override
public String getUsername() {
return "testUser";
}

@Override
public boolean isAccountNonExpired() {
return true;
}

@Override
public boolean isAccountNonLocked() {
return true;
}

@Override
public boolean isCredentialsNonExpired() {
return true;
}

@Override
public boolean isEnabled() {
return true;
}
public UserDetails loadUserByUsername(String username) {
return new Foo();
}
public void foo() {
Authentication auth = Jenkins.getAuthentication2();
Foo userDetails = new Foo();
SecurityListener.fireAuthenticated2(userDetails);
}
}
"""));
}
}
Loading