URL encode username in http and ssh schemes Also add a test to verify that username was correctly encoded. This change depends on change in gerrit core that marked DownloadConfig ctor public. Depends-On: https://gerrit-review.googlesource.com/c/gerrit/+/328279 Change-Id: Id7d24530607f6d05c5034bac1a91b3270c4cb698
diff --git a/BUILD b/BUILD index 95eda17..c864ea4 100644 --- a/BUILD +++ b/BUILD
@@ -1,4 +1,10 @@ -load("//tools/bzl:plugin.bzl", "gerrit_plugin") +load("//tools/bzl:junit.bzl", "junit_tests") +load( + "//tools/bzl:plugin.bzl", + "PLUGIN_DEPS", + "PLUGIN_TEST_DEPS", + "gerrit_plugin", +) gerrit_plugin( name = "download-commands", @@ -9,3 +15,13 @@ ], resources = glob(["src/main/resources/**/*"]), ) + +junit_tests( + name = "download-commands_tests", + size = "small", + srcs = glob(["src/test/java/**/*.java"]), + tags = ["download-commands"], + deps = PLUGIN_DEPS + PLUGIN_TEST_DEPS + [ + ":download-commands__plugin", + ], +)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/download/scheme/HttpScheme.java b/src/main/java/com/googlesource/gerrit/plugins/download/scheme/HttpScheme.java index 54d0322..85705c4 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/download/scheme/HttpScheme.java +++ b/src/main/java/com/googlesource/gerrit/plugins/download/scheme/HttpScheme.java
@@ -24,6 +24,9 @@ import com.google.gerrit.server.config.GerritServerConfig; import com.google.inject.Inject; import com.google.inject.Provider; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import org.eclipse.jgit.lib.Config; public class HttpScheme extends DownloadScheme { @@ -64,7 +67,13 @@ String host = base.substring(p + 3, s); r.append(base.substring(0, p + 3)); if (userProvider.get().getUserName().isPresent()) { - r.append(userProvider.get().getUserName().get()); + try { + r.append( + URLEncoder.encode( + userProvider.get().getUserName().get(), StandardCharsets.UTF_8.name())); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("No UTF-8 support", e); + } r.append("@"); } r.append(host);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/download/scheme/SshScheme.java b/src/main/java/com/googlesource/gerrit/plugins/download/scheme/SshScheme.java index 8478654..b39b953 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/download/scheme/SshScheme.java +++ b/src/main/java/com/googlesource/gerrit/plugins/download/scheme/SshScheme.java
@@ -24,8 +24,11 @@ import com.google.gerrit.server.ssh.SshAdvertisedAddresses; import com.google.inject.Inject; import com.google.inject.Provider; +import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Optional; @@ -92,7 +95,11 @@ StringBuilder r = new StringBuilder(); r.append("ssh://"); - r.append(username.get()); + try { + r.append(URLEncoder.encode(username.get(), StandardCharsets.UTF_8.name())); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("No UTF-8 support", e); + } r.append("@"); r.append(ensureSlash(sshdAddress)); r.append(project);
diff --git a/src/test/java/com/googlesource/gerrit/plugins/download/scheme/SchemeTest.java b/src/test/java/com/googlesource/gerrit/plugins/download/scheme/SchemeTest.java new file mode 100644 index 0000000..ad38898 --- /dev/null +++ b/src/test/java/com/googlesource/gerrit/plugins/download/scheme/SchemeTest.java
@@ -0,0 +1,87 @@ +// Copyright (C) 2022 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.googlesource.gerrit.plugins.download.scheme; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.gerrit.entities.Account; +import com.google.gerrit.server.CurrentUser; +import com.google.gerrit.server.account.GroupMembership; +import com.google.gerrit.server.config.DownloadConfig; +import com.google.inject.Provider; +import com.google.inject.util.Providers; +import java.util.List; +import java.util.Optional; +import org.eclipse.jgit.lib.Config; +import org.junit.Before; +import org.junit.Test; + +public class SchemeTest { + private HttpScheme httpScheme; + private SshScheme sshScheme; + + @Before + public void setUp() { + Config cfg = new Config(); + Provider<String> urlProvider = Providers.of("https://gerrit.company.com/"); + Provider<CurrentUser> userProvider = Providers.of(fakeUser()); + DownloadConfig downloadConfig = new DownloadConfig(cfg); + httpScheme = new HttpScheme(cfg, urlProvider, userProvider, downloadConfig); + sshScheme = + new SshScheme( + List.of("gerrit.company.com:29418"), urlProvider, userProvider, downloadConfig); + } + + @Test + public void ensureHttpSchemeEncodedInUrl() { + assertThat(httpScheme.getUrl("foo")) + .isEqualTo("https://john-doe%40company.com@gerrit.company.com/a/foo"); + } + + @Test + public void ensureSshSchemeEncodedInUrl() { + assertThat(sshScheme.getUrl("foo")) + .isEqualTo("ssh://john-doe%40company.com@gerrit.company.com:29418/foo"); + } + + private static CurrentUser fakeUser() { + return new CurrentUser() { + @Override + public Optional<String> getUserName() { + return Optional.of("john-doe@company.com"); + } + + @Override + public GroupMembership getEffectiveGroups() { + throw new UnsupportedOperationException("not implemented"); + } + + @Override + public Object getCacheKey() { + return new Object(); + } + + @Override + public boolean isIdentifiedUser() { + return true; + } + + @Override + public Account.Id getAccountId() { + return Account.id(1); + } + }; + } +}