From d9c8412a131e04fedb06dfe8db4b84b26cae719b Mon Sep 17 00:00:00 2001 From: Denis Rosca Date: Wed, 28 Jun 2023 16:52:38 +0300 Subject: [PATCH 1/3] Fix basic HTTP authentication when resolving dependencies --- smithy-cli/build.gradle | 2 + .../amazon/smithy/cli/MavenResolverTest.java | 50 +++++++++++++-- .../cli/projects/maven-auth/smithy-build.json | 3 +- .../dependencies/MavenDependencyResolver.java | 61 +++---------------- 4 files changed, 55 insertions(+), 61 deletions(-) diff --git a/smithy-cli/build.gradle b/smithy-cli/build.gradle index dcf31372a6e..df4bd77d0ca 100644 --- a/smithy-cli/build.gradle +++ b/smithy-cli/build.gradle @@ -55,6 +55,8 @@ dependencies { implementation "org.apache.maven.resolver:maven-resolver-transport-file:1.9.2" implementation "org.apache.maven.resolver:maven-resolver-transport-http:1.9.2" implementation "org.slf4j:slf4j-jdk14:1.7.36" // Route slf4j used by Maven through JUL like the rest of Smithy. + + testImplementation "org.mock-server:mockserver-netty:3.10.8" } // ------ Shade Maven dependency resolvers into the JAR. ------- diff --git a/smithy-cli/src/it/java/software/amazon/smithy/cli/MavenResolverTest.java b/smithy-cli/src/it/java/software/amazon/smithy/cli/MavenResolverTest.java index a395a5ee4f7..8eaad258b33 100644 --- a/smithy-cli/src/it/java/software/amazon/smithy/cli/MavenResolverTest.java +++ b/smithy-cli/src/it/java/software/amazon/smithy/cli/MavenResolverTest.java @@ -5,6 +5,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; +import static org.mockserver.integration.ClientAndServer.startClientAndServer; import java.io.File; import java.io.IOException; @@ -12,6 +13,9 @@ import java.nio.file.Files; import java.util.Collections; import org.junit.jupiter.api.Test; +import org.mockserver.integration.ClientAndServer; +import org.mockserver.model.HttpRequest; +import org.mockserver.model.HttpResponse; import software.amazon.smithy.model.node.Node; import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.utils.ListUtils; @@ -61,14 +65,48 @@ public void failsWhenBadVersionRequested() { }); } - // TODO: This test could be better and actually test that auth works somehow. @Test public void usesCustomRepoWithAuth() { - IntegUtils.runWithEmptyCache("maven-auth", ListUtils.of("validate", "--debug"), - Collections.emptyMap(), result -> { - assertThat(result.getExitCode(), equalTo(1)); - assertThat(result.getOutput(), containsString("with xxx=****")); - }); + ClientAndServer mockServer = null; + try { + mockServer = startClientAndServer(1234); + mockServer.when( + HttpRequest + .request() + .withMethod("GET") + .withHeader("Authorization", "Basic eHh4Onl5eQ==") + .withPath("/maven/not/there/software/amazon/smithy/smithy-aws-iam-traits/.*\\." + "jar") + ).respond( + HttpResponse + .response() + .withStatusCode(200) + .withBody("FAKE JAR CONTENT") + ); + mockServer.when( + HttpRequest + .request() + .withMethod("GET") + .withPath("/maven/not/there/software/amazon/smithy/smithy-aws-iam-traits/.*") + ).respond( + HttpResponse + .response() + .withStatusCode(401) + .withHeader("WWW-Authenticate", "Basic realm=\"Artifactory Realm\"") + ); + + IntegUtils.runWithEmptyCache("maven-auth", ListUtils.of("validate", "--debug"), + Collections.emptyMap(), result -> { + assertThat(result.getExitCode(), equalTo(1)); + assertThat(result.getOutput(), containsString("HttpAuthenticator - Selected authentication options: [BASIC [complete=true]]")); + assertThat(result.getOutput(), containsString("HttpAuthenticator - Authentication succeeded")); + + System.err.println(result.getOutput()); + }); + } finally { + if(mockServer!=null) { + mockServer.stop(); + } + } } @Test diff --git a/smithy-cli/src/it/resources/software/amazon/smithy/cli/projects/maven-auth/smithy-build.json b/smithy-cli/src/it/resources/software/amazon/smithy/cli/projects/maven-auth/smithy-build.json index 47f6fcc8a16..e2c189f6590 100644 --- a/smithy-cli/src/it/resources/software/amazon/smithy/cli/projects/maven-auth/smithy-build.json +++ b/smithy-cli/src/it/resources/software/amazon/smithy/cli/projects/maven-auth/smithy-build.json @@ -3,7 +3,8 @@ "maven": { "repositories": [ { - "url": "https://localhost:1234/maven/not/there", + // Use HTTP instead of HTTPS because we're running a mock server during tests + "url": "http://localhost:1234/maven/not/there", "httpCredentials": "xxx:yyy" } ], diff --git a/smithy-cli/src/main/java/software/amazon/smithy/cli/dependencies/MavenDependencyResolver.java b/smithy-cli/src/main/java/software/amazon/smithy/cli/dependencies/MavenDependencyResolver.java index 95c49e07739..08061dce90b 100644 --- a/smithy-cli/src/main/java/software/amazon/smithy/cli/dependencies/MavenDependencyResolver.java +++ b/smithy-cli/src/main/java/software/amazon/smithy/cli/dependencies/MavenDependencyResolver.java @@ -23,8 +23,6 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.Objects; import java.util.logging.Logger; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; import org.eclipse.aether.DefaultRepositorySystemSession; @@ -36,9 +34,6 @@ import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.graph.DependencyFilter; import org.eclipse.aether.impl.DefaultServiceLocator; -import org.eclipse.aether.repository.Authentication; -import org.eclipse.aether.repository.AuthenticationContext; -import org.eclipse.aether.repository.AuthenticationDigest; import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.resolution.ArtifactResult; @@ -49,8 +44,8 @@ import org.eclipse.aether.transport.file.FileTransporterFactory; import org.eclipse.aether.transport.http.HttpTransporterFactory; import org.eclipse.aether.util.filter.DependencyFilterUtils; +import org.eclipse.aether.util.repository.AuthenticationBuilder; import software.amazon.smithy.build.model.MavenRepository; -import software.amazon.smithy.utils.StringUtils; /** * Resolves Maven dependencies for the Smithy CLI using Maven resolvers. @@ -121,7 +116,12 @@ private void addUserInfoAuth(URI uri, String userInfo, RemoteRepository.Builder if (parts.length != 2) { throw new DependencyResolverException("Invalid credentials provided for " + uri); } - builder.setAuthentication(new MavenAuth(parts[0], parts[1])); + builder.setAuthentication( + new AuthenticationBuilder() + .addUsername(parts[0]) + .addPassword(parts[1]) + .build() + ); } @Override @@ -190,51 +190,4 @@ private List resolveMavenArtifacts() { throw new DependencyResolverException(e); } } - - /** - * Based on Maven's StringAuthentication. There doesn't appear to be another way to do this. - */ - private static final class MavenAuth implements Authentication { - private final String key; - private final String value; - - private MavenAuth(String key, String value) { - if (StringUtils.isEmpty(key)) { - throw new IllegalArgumentException("Authentication key must be provided"); - } - this.key = key; - this.value = value; - } - - @Override - public void fill(AuthenticationContext context, String key, Map data) { - context.put(this.key, value); - } - - @Override - public void digest(AuthenticationDigest digest) { - digest.update(key, value); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } else if (obj == null || !getClass().equals(obj.getClass())) { - return false; - } - MavenAuth that = (MavenAuth) obj; - return Objects.equals(key, that.key) && Objects.equals(value, that.value); - } - - @Override - public int hashCode() { - return Objects.hash(key, value); - } - - @Override - public String toString() { - return key + "=****"; - } - } } From 33979edec7317894891359c5cb9e1ea4d4e9774a Mon Sep 17 00:00:00 2001 From: Denis Rosca Date: Wed, 28 Jun 2023 17:19:16 +0300 Subject: [PATCH 2/3] Clean-up --- .../it/java/software/amazon/smithy/cli/MavenResolverTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/smithy-cli/src/it/java/software/amazon/smithy/cli/MavenResolverTest.java b/smithy-cli/src/it/java/software/amazon/smithy/cli/MavenResolverTest.java index 8eaad258b33..064865815c6 100644 --- a/smithy-cli/src/it/java/software/amazon/smithy/cli/MavenResolverTest.java +++ b/smithy-cli/src/it/java/software/amazon/smithy/cli/MavenResolverTest.java @@ -75,7 +75,7 @@ public void usesCustomRepoWithAuth() { .request() .withMethod("GET") .withHeader("Authorization", "Basic eHh4Onl5eQ==") - .withPath("/maven/not/there/software/amazon/smithy/smithy-aws-iam-traits/.*\\." + "jar") + .withPath("/maven/not/there/software/amazon/smithy/smithy-aws-iam-traits/.*\\.jar") ).respond( HttpResponse .response() @@ -99,8 +99,6 @@ public void usesCustomRepoWithAuth() { assertThat(result.getExitCode(), equalTo(1)); assertThat(result.getOutput(), containsString("HttpAuthenticator - Selected authentication options: [BASIC [complete=true]]")); assertThat(result.getOutput(), containsString("HttpAuthenticator - Authentication succeeded")); - - System.err.println(result.getOutput()); }); } finally { if(mockServer!=null) { From 494504a986313d31ba85d6f9a80952df56d79618 Mon Sep 17 00:00:00 2001 From: Denis Rosca Date: Wed, 28 Jun 2023 17:19:47 +0300 Subject: [PATCH 3/3] Fix failing test --- .../it/java/software/amazon/smithy/cli/MavenResolverTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smithy-cli/src/it/java/software/amazon/smithy/cli/MavenResolverTest.java b/smithy-cli/src/it/java/software/amazon/smithy/cli/MavenResolverTest.java index 064865815c6..37bc7f8a707 100644 --- a/smithy-cli/src/it/java/software/amazon/smithy/cli/MavenResolverTest.java +++ b/smithy-cli/src/it/java/software/amazon/smithy/cli/MavenResolverTest.java @@ -229,7 +229,7 @@ public void setSetMavenRepoWithEnvUsingAuth() { ListUtils.of("validate", "--debug", "model"), MapUtils.of(EnvironmentVariable.SMITHY_MAVEN_REPOS.toString(), repo), result -> { - assertThat(result.getOutput(), containsString("with xxx=****")); + assertThat(result.getOutput(), containsString("username=xxx, password=***")); assertThat(result.getExitCode(), equalTo(1)); }); }