From e77d8e16a26d4caff88457e256c519392e8886ee Mon Sep 17 00:00:00 2001 From: andreoss Date: Sun, 23 Aug 2020 07:53:59 -0400 Subject: [PATCH] (#215) Strip user info after Auth header was added --- .../com/jcabi/http/wire/BasicAuthWire.java | 25 +++++----- .../jcabi/http/wire/BasicAuthWireTest.java | 47 +++++++++++++++++++ 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/jcabi/http/wire/BasicAuthWire.java b/src/main/java/com/jcabi/http/wire/BasicAuthWire.java index c656f1bd..02843a5e 100644 --- a/src/main/java/com/jcabi/http/wire/BasicAuthWire.java +++ b/src/main/java/com/jcabi/http/wire/BasicAuthWire.java @@ -39,6 +39,7 @@ import java.io.InputStream; import java.net.URI; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.LinkedList; import java.util.Map; @@ -65,25 +66,16 @@ * * @since 0.10 * @see RFC 2617 "HTTP Authentication: Basic and Digest Access Authentication" - * @todo #97:30m Strip user info from URI after Auth header is added. - * Consider adding warnings about the wire applied for Request with header, and - * without user info. */ @Immutable @ToString(of = "origin") @EqualsAndHashCode(of = "origin") public final class BasicAuthWire implements Wire { - /** - * The encoding to use. - */ - private static final String ENCODING = "UTF-8"; - /** * The Charset to use. */ - private static final Charset CHARSET = - Charset.forName(BasicAuthWire.ENCODING); + private static final Charset CHARSET = StandardCharsets.UTF_8; /** * Original wire. @@ -111,6 +103,11 @@ public Response send(final Request req, final String home, boolean absent = true; for (final Map.Entry header : headers) { if (header.getKey().equals(HttpHeaders.AUTHORIZATION)) { + Logger.warn( + this, + "Request already contains %s header", + HttpHeaders.AUTHORIZATION + ); absent = false; } hdrs.add(header); @@ -135,7 +132,13 @@ public Response send(final Request req, final String home, ); } return this.origin.send( - req, home, method, hdrs, content, connect, read + req.uri().userInfo(null).back(), + home, + method, + hdrs, + content, + connect, + read ); } } diff --git a/src/test/java/com/jcabi/http/wire/BasicAuthWireTest.java b/src/test/java/com/jcabi/http/wire/BasicAuthWireTest.java index 660f7268..f31aef95 100644 --- a/src/test/java/com/jcabi/http/wire/BasicAuthWireTest.java +++ b/src/test/java/com/jcabi/http/wire/BasicAuthWireTest.java @@ -32,17 +32,22 @@ import com.jcabi.http.mock.MkAnswer; import com.jcabi.http.mock.MkContainer; import com.jcabi.http.mock.MkGrizzlyContainer; +import com.jcabi.http.mock.MkQueryMatchers; import com.jcabi.http.request.JdkRequest; import com.jcabi.http.response.RestResponse; import java.net.HttpURLConnection; import java.net.URI; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import javax.net.ssl.HttpsURLConnection; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.UriBuilder; import javax.xml.bind.DatatypeConverter; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -100,6 +105,48 @@ void testHeader( ); } + /** + * Tests if the wire strips user info from URI, after the header was added. + * + * @throws Exception If something goes wrong + */ + @Test + void shouldStripUserInfo() throws Exception { + final MkContainer container = new MkGrizzlyContainer().next( + new MkAnswer.Simple(HttpsURLConnection.HTTP_NOT_FOUND), + MkQueryMatchers.hasHeader( + "Authorization", Matchers.contains( + BasicAuthWireTest.expectHeader("foo", "bar") + ) + ) + ).start(); + final String userinfo = "foo:bar"; + final URI uri = UriBuilder.fromUri(container.home()).userInfo( + userinfo + ).build(); + MatcherAssert.assertThat( + Assertions.assertThrows( + AssertionError.class, + new Executable() { + @Override + public void execute() throws Throwable { + new JdkRequest(uri) + .through(BasicAuthWire.class) + .fetch() + .as(RestResponse.class) + .assertStatus(HttpURLConnection.HTTP_OK); + } + } + ), + Matchers.hasToString( + Matchers.not( + Matchers.containsString(userinfo) + ) + ) + ); + container.stop(); + } + /** * Creates the expected authorization header value for the * given username.