diff --git a/rewrite-maven/src/main/java/org/openrewrite/maven/utilities/MavenArtifactDownloader.java b/rewrite-maven/src/main/java/org/openrewrite/maven/utilities/MavenArtifactDownloader.java index b77a04de99c..b675c991d7c 100644 --- a/rewrite-maven/src/main/java/org/openrewrite/maven/utilities/MavenArtifactDownloader.java +++ b/rewrite-maven/src/main/java/org/openrewrite/maven/utilities/MavenArtifactDownloader.java @@ -130,6 +130,7 @@ public MavenArtifactDownloader(MavenArtifactCache mavenArtifactCache, } private HttpSender.Request.Builder applyAuthentication(MavenRepository repository, HttpSender.Request.Builder request) { + String username, password; MavenSettings.Server authInfo = serverIdToServer.get(repository.getId()); if (authInfo != null) { if (authInfo.getConfiguration() != null && authInfo.getConfiguration().getHttpHeaders() != null) { @@ -137,9 +138,15 @@ private HttpSender.Request.Builder applyAuthentication(MavenRepository repositor request.withHeader(header.getName(), header.getValue()); } } - return request.withBasicAuthentication(authInfo.getUsername(), authInfo.getPassword()); - } else if (repository.getUsername() != null && repository.getPassword() != null) { - return request.withBasicAuthentication(repository.getUsername(), repository.getPassword()); + username = authInfo.getUsername(); + password = authInfo.getPassword(); + } else { + username = repository.getUsername(); + password = repository.getPassword(); + } + if (username != null && !username.contains("${") && + password != null && !password.contains("${")) { + return request.withBasicAuthentication(username, password); } return request; } diff --git a/rewrite-maven/src/test/java/org/openrewrite/maven/utilities/MavenArtifactDownloaderTest.java b/rewrite-maven/src/test/java/org/openrewrite/maven/utilities/MavenArtifactDownloaderTest.java index df5f9e5a2cb..a501181570f 100644 --- a/rewrite-maven/src/test/java/org/openrewrite/maven/utilities/MavenArtifactDownloaderTest.java +++ b/rewrite-maven/src/test/java/org/openrewrite/maven/utilities/MavenArtifactDownloaderTest.java @@ -15,21 +15,26 @@ */ package org.openrewrite.maven.utilities; +import okhttp3.mockwebserver.Dispatcher; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import org.openrewrite.ExecutionContext; import org.openrewrite.InMemoryExecutionContext; +import org.openrewrite.Parser; import org.openrewrite.SourceFile; import org.openrewrite.maven.MavenParser; +import org.openrewrite.maven.MavenSettings; import org.openrewrite.maven.cache.LocalMavenArtifactCache; import org.openrewrite.maven.cache.MavenArtifactCache; -import org.openrewrite.maven.tree.MavenResolutionResult; -import org.openrewrite.maven.tree.ResolvedDependency; -import org.openrewrite.maven.tree.ResolvedGroupArtifactVersion; -import org.openrewrite.maven.tree.Scope; +import org.openrewrite.maven.tree.*; +import java.io.ByteArrayInputStream; import java.nio.file.Path; import java.util.List; +import java.util.concurrent.atomic.AtomicReference; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -126,4 +131,59 @@ void downloadDependenciesWithClassifier(@TempDir Path tempDir) { } } } + + @Test + void fallsBackToAnonymousWhenCredentialsRejected(@TempDir Path tempDir) throws Exception { + byte[] jarBytes = {0x50, 0x4B, 0x03, 0x04}; // minimal ZIP magic bytes + + try (MockWebServer mockRepo = new MockWebServer()) { + mockRepo.setDispatcher(new Dispatcher() { + @Override + public MockResponse dispatch(RecordedRequest request) { + if (request.getHeader("Authorization") != null) { + return new MockResponse().setResponseCode(403); // Throw if used; it should not be called at all + } + return new MockResponse().setResponseCode(200) + .setBody(new okio.Buffer().write(jarBytes)); + } + }); + mockRepo.start(); + + String repoUrl = "http://" + mockRepo.getHostName() + ":" + mockRepo.getPort(); + MavenSettings settings = MavenSettings.parse(new Parser.Input( + Path.of("settings.xml"), () -> new ByteArrayInputStream( + //language=xml + """ + + + + mock-repo + ${placeholder} + ${placeholder} + + + + """.getBytes())), new InMemoryExecutionContext()); + + MavenArtifactCache artifactCache = new LocalMavenArtifactCache(tempDir); + AtomicReference error = new AtomicReference<>(); + MavenArtifactDownloader downloader = new MavenArtifactDownloader( + artifactCache, settings, error::set); + + MavenRepository repo = new MavenRepository( + "mock-repo", repoUrl, "true", "false", true, null, null, null, false); + GroupArtifactVersion gav = new GroupArtifactVersion("com.example", "test-lib", "1.0.0"); + ResolvedDependency dep = ResolvedDependency.builder() + .repository(repo) + .gav(new ResolvedGroupArtifactVersion(repoUrl, gav.getGroupId(), gav.getArtifactId(), gav.getVersion(), null)) + .requested(Dependency.builder().gav(gav).build()) + .build(); + + Path artifact = downloader.downloadArtifact(dep); + + assertThat(artifact).isNotNull(); + assertThat(error.get()).isNull(); + assertThat(mockRepo.getRequestCount()).isEqualTo(1); + } + } }