From 15e000f0f6c409ced21eb085611a42e3bb4dc4dc Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Mon, 2 Oct 2017 15:07:34 +0200 Subject: [PATCH] SONAR-9900 Support UTF-8 login and password in Java WS client --- .../sonarqube/ws/client/HttpConnector.java | 3 ++- .../ws/client/OkHttpClientBuilder.java | 3 ++- .../ws/client/HttpConnectorTest.java | 21 +++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpConnector.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpConnector.java index 9d4c7fdc1ea..b437151e79f 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpConnector.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpConnector.java @@ -42,6 +42,7 @@ import static com.google.common.base.Strings.nullToEmpty; import static java.lang.String.format; import static java.net.HttpURLConnection.HTTP_MOVED_PERM; import static java.net.HttpURLConnection.HTTP_MOVED_TEMP; +import static java.nio.charset.StandardCharsets.UTF_8; import static okhttp3.internal.http.StatusLine.HTTP_PERM_REDIRECT; import static okhttp3.internal.http.StatusLine.HTTP_TEMP_REDIRECT; @@ -74,7 +75,7 @@ public class HttpConnector implements WsConnector { if (!isNullOrEmpty(builder.login)) { // password is null when login represents an access token. In this case // the Basic credentials consider an empty password. - okHttpClientBuilder.setCredentials(Credentials.basic(builder.login, nullToEmpty(builder.password))); + okHttpClientBuilder.setCredentials(Credentials.basic(builder.login, nullToEmpty(builder.password), UTF_8)); } this.systemPassCode = builder.systemPassCode; okHttpClientBuilder.setProxy(builder.proxy); diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/OkHttpClientBuilder.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/OkHttpClientBuilder.java index 8737a68ea0c..46fa103656c 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/OkHttpClientBuilder.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/OkHttpClientBuilder.java @@ -48,6 +48,7 @@ import okhttp3.Request; import okhttp3.Response; import static com.google.common.base.Strings.nullToEmpty; +import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Arrays.asList; /** @@ -174,7 +175,7 @@ public class OkHttpClientBuilder { return null; } if (HttpURLConnection.HTTP_PROXY_AUTH == response.code()) { - String credential = Credentials.basic(proxyLogin, nullToEmpty(proxyPassword)); + String credential = Credentials.basic(proxyLogin, nullToEmpty(proxyPassword), UTF_8); return response.request().newBuilder().header(PROXY_AUTHORIZATION, credential).build(); } return null; diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/HttpConnectorTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/HttpConnectorTest.java index 4e1ca719ac4..f4d0f2a7521 100644 --- a/sonar-ws/src/test/java/org/sonarqube/ws/client/HttpConnectorTest.java +++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/HttpConnectorTest.java @@ -30,6 +30,7 @@ import okhttp3.ConnectionSpec; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; +import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.RandomStringUtils; @@ -42,6 +43,7 @@ import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonarqube.ws.MediaTypes; +import static java.nio.charset.StandardCharsets.UTF_8; import static okhttp3.Credentials.basic; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; @@ -168,6 +170,25 @@ public class HttpConnectorTest { assertThat(recordedRequest.getHeader("Authorization")).isEqualTo(basic("theLogin", "")); } + @Test + public void use_basic_authentication_with_utf8_login_and_password() throws Exception { + answerHelloWorld(); + String login = "我能"; + String password = "吞下"; + underTest = HttpConnector.newBuilder() + .url(serverUrl) + .credentials(login, password) + .build(); + + GetRequest request = new GetRequest("api/issues/search"); + underTest.call(request); + + RecordedRequest recordedRequest = server.takeRequest(); + // do not use OkHttp Credentials.basic() in order to not use the same code as the code under test + String expectedHeader = "Basic " + Base64.encodeBase64String((login + ":" + password).getBytes(UTF_8)); + assertThat(recordedRequest.getHeader("Authorization")).isEqualTo(expectedHeader); + } + /** * Access token replaces the couple {login,password} and is sent through * the login field -- 2.39.5