From c0feea3328042ef6ae2c421389fa45ba5fa297aa Mon Sep 17 00:00:00 2001 From: Sven Strittmatter Date: Mon, 4 Sep 2023 16:07:00 +0200 Subject: [PATCH 01/10] #36 Add tests for auth header generation Signed-off-by: Sven Strittmatter --- .../persistence/defectdojo/config/Config.java | 10 +++ .../persistence/defectdojo/http/Foo.java | 26 ++++--- .../service/GenericDefectDojoService.java | 5 +- .../service/ImportScanService2.java | 5 +- .../persistence/defectdojo/http/FooTest.java | 69 +++++++++++++++++++ 5 files changed, 103 insertions(+), 12 deletions(-) create mode 100644 src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/config/Config.java b/src/main/java/io/securecodebox/persistence/defectdojo/config/Config.java index 1ba06f6c..f5546357 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/config/Config.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/config/Config.java @@ -52,6 +52,16 @@ public final class Config { */ private final int maxPageCountForGets; + /** + * Convenience constructor which sets {@link #DEFAULT_MAX_PAGE_COUNT_FOR_GETS} + * + * @param url not {@code null} + * @param apiKey not {@code null} + */ + public Config(final @NonNull String url, final @NonNull String apiKey) { + this(url, apiKey, DEFAULT_MAX_PAGE_COUNT_FOR_GETS); + } + /** * Dedicated constructor * diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java index f185ee99..ddd62bab 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java @@ -26,27 +26,37 @@ */ public final class Foo { private final Config config; + private final ProxyConfig proxyConfig; - public Foo(@NonNull final Config config) { + public Foo(@NonNull final Config config, @NonNull final ProxyConfig proxyConfig) { super(); this.config = config; + this.proxyConfig = proxyConfig; } - public HttpHeaders getDefectDojoAuthorizationHeaders() { + /** + * This method generates appropriate authorization headers + * + * @return never {@code null} + */ + public HttpHeaders generateAuthorizationHeaders() { HttpHeaders headers = new HttpHeaders(); - headers.set("Authorization", "Token " + this.config.getApiKey()); + headers.set(HttpHeaders.AUTHORIZATION, "Token " + this.config.getApiKey()); - String username = System.getProperty("http.proxyUser", ""); - String password = System.getProperty("http.proxyPassword", ""); - - if (!username.isEmpty() || !password.isEmpty()) { + if (proxyConfig.isComplete()) { + // FIXME: System.out logging is a real bad code smell. Standard loging should be used. System.out.println("Setting Proxy Auth Header..."); - headers.set(HttpHeaders.PROXY_AUTHORIZATION, "Basic " + Base64.getEncoder().encodeToString((username + ':' + password).getBytes(StandardCharsets.UTF_8))); + headers.set(HttpHeaders.PROXY_AUTHORIZATION, "Basic " + encodeProxyCredentials(proxyConfig)); } return headers; } + static String encodeProxyCredentials(@NonNull final ProxyConfig cfg) { + final var credential = String.format("%s:%s", cfg.getUser(), cfg.getPassword()); + return Base64.getEncoder().encodeToString(credential.getBytes(StandardCharsets.UTF_8)); + } + public RestTemplate setupRestTemplate() { RestTemplate restTemplate; diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/service/GenericDefectDojoService.java b/src/main/java/io/securecodebox/persistence/defectdojo/service/GenericDefectDojoService.java index 084c0b64..902ef4fe 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/service/GenericDefectDojoService.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/service/GenericDefectDojoService.java @@ -13,6 +13,7 @@ import io.securecodebox.persistence.defectdojo.config.Config; import io.securecodebox.persistence.defectdojo.exception.LoopException; import io.securecodebox.persistence.defectdojo.http.Foo; +import io.securecodebox.persistence.defectdojo.http.ProxyConfigFactory; import io.securecodebox.persistence.defectdojo.model.BaseModel; import io.securecodebox.persistence.defectdojo.model.Engagement; import io.securecodebox.persistence.defectdojo.model.Response; @@ -66,11 +67,11 @@ public GenericDefectDojoService(Config config) { * @return The DefectDojo Authentication Header */ private HttpHeaders getDefectDojoAuthorizationHeaders() { - return new Foo(config).getDefectDojoAuthorizationHeaders(); + return new Foo(config, new ProxyConfigFactory().create()).generateAuthorizationHeaders(); } private RestTemplate setupRestTemplate() { - RestTemplate restTemplate = new Foo(config).setupRestTemplate(); + RestTemplate restTemplate = new Foo(config, new ProxyConfigFactory().create()).setupRestTemplate(); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setObjectMapper(this.objectMapper); restTemplate.setMessageConverters(List.of( diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/service/ImportScanService2.java b/src/main/java/io/securecodebox/persistence/defectdojo/service/ImportScanService2.java index 36c660be..85676d27 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/service/ImportScanService2.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/service/ImportScanService2.java @@ -9,6 +9,7 @@ import io.securecodebox.persistence.defectdojo.config.Config; import io.securecodebox.persistence.defectdojo.exception.PersistenceException; import io.securecodebox.persistence.defectdojo.http.Foo; +import io.securecodebox.persistence.defectdojo.http.ProxyConfigFactory; import io.securecodebox.persistence.defectdojo.model.ScanFile; import lombok.Data; import org.springframework.core.io.ByteArrayResource; @@ -49,11 +50,11 @@ public ImportScanService2(Config config) { * @return The DefectDojo Authentication Header */ private HttpHeaders getDefectDojoAuthorizationHeaders() { - return new Foo(config).getDefectDojoAuthorizationHeaders(); + return new Foo(config, new ProxyConfigFactory().create()).generateAuthorizationHeaders(); } protected RestTemplate setupRestTemplate() { - return new Foo(config).setupRestTemplate(); + return new Foo(config, new ProxyConfigFactory().create()).setupRestTemplate(); } /** diff --git a/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java b/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java new file mode 100644 index 00000000..6e97b9a0 --- /dev/null +++ b/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java @@ -0,0 +1,69 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +package io.securecodebox.persistence.defectdojo.http; + +import io.securecodebox.persistence.defectdojo.config.Config; +import lombok.NonNull; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpHeaders; + +import static org.junit.jupiter.api.Assertions.*; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +/** + * Tests for {@link Foo} + */ +class FooTest { + private final Config config = new Config("url", "apikey"); + + @Test + void generateAuthorizationHeaders_withoutProxyAuth() { + final var incompleteProxyConfig = ProxyConfig.NULL; + + final var sut = new Foo(config, incompleteProxyConfig); + + assertAll( + () -> assertThat( + sut.generateAuthorizationHeaders().get(HttpHeaders.AUTHORIZATION), + contains("Token apikey")), + () -> assertThat( + sut.generateAuthorizationHeaders().get(HttpHeaders.PROXY_AUTHORIZATION), + not(contains("Basic dXNlcjpwdw=="))) + ); + } + + @Test + void generateAuthorizationHeaders_withProxyAuth() { + final var completeProxyConfig = ProxyConfig.builder() + .user("user") + .password("pw") + .host("host") + .port(42) + .build(); + + final var sut = new Foo(config, completeProxyConfig); + + assertAll( + () -> assertThat( + sut.generateAuthorizationHeaders().get(HttpHeaders.AUTHORIZATION), + contains("Token apikey")), + () -> assertThat( + sut.generateAuthorizationHeaders().get(HttpHeaders.PROXY_AUTHORIZATION), + contains("Basic dXNlcjpwdw==")) + ); + } + + @Test + void encodeProxyCredentials() { + final var proxyConfig = ProxyConfig.builder() + .user("bärtram") + .password("gohze8Ae") + .build(); + + assertThat(Foo.encodeProxyCredentials(proxyConfig), is("YsOkcnRyYW06Z29oemU4QWU=")); + } +} From cb4352df53a3a11f996e6da7fdec80376612102d Mon Sep 17 00:00:00 2001 From: Sven Strittmatter Date: Mon, 4 Sep 2023 16:08:56 +0200 Subject: [PATCH 02/10] #36 USe better name forfacotry method Signed-off-by: Sven Strittmatter --- .../java/io/securecodebox/persistence/defectdojo/http/Foo.java | 2 +- .../defectdojo/service/GenericDefectDojoService.java | 2 +- .../persistence/defectdojo/service/ImportScanService2.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java index ddd62bab..07560c53 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java @@ -57,7 +57,7 @@ static String encodeProxyCredentials(@NonNull final ProxyConfig cfg) { return Base64.getEncoder().encodeToString(credential.getBytes(StandardCharsets.UTF_8)); } - public RestTemplate setupRestTemplate() { + public RestTemplate createRestTemplate() { RestTemplate restTemplate; if (System.getProperty("http.proxyUser") != null && System.getProperty("http.proxyPassword") != null) { diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/service/GenericDefectDojoService.java b/src/main/java/io/securecodebox/persistence/defectdojo/service/GenericDefectDojoService.java index 902ef4fe..84d384a2 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/service/GenericDefectDojoService.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/service/GenericDefectDojoService.java @@ -71,7 +71,7 @@ private HttpHeaders getDefectDojoAuthorizationHeaders() { } private RestTemplate setupRestTemplate() { - RestTemplate restTemplate = new Foo(config, new ProxyConfigFactory().create()).setupRestTemplate(); + RestTemplate restTemplate = new Foo(config, new ProxyConfigFactory().create()).createRestTemplate(); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setObjectMapper(this.objectMapper); restTemplate.setMessageConverters(List.of( diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/service/ImportScanService2.java b/src/main/java/io/securecodebox/persistence/defectdojo/service/ImportScanService2.java index 85676d27..092f1a59 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/service/ImportScanService2.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/service/ImportScanService2.java @@ -54,7 +54,7 @@ private HttpHeaders getDefectDojoAuthorizationHeaders() { } protected RestTemplate setupRestTemplate() { - return new Foo(config, new ProxyConfigFactory().create()).setupRestTemplate(); + return new Foo(config, new ProxyConfigFactory().create()).createRestTemplate(); } /** From a238f26e0d12f0933f8a19fd89fb40c2883c184a Mon Sep 17 00:00:00 2001 From: Sven Strittmatter Date: Mon, 4 Sep 2023 16:34:31 +0200 Subject: [PATCH 03/10] #36 Simplify syntax of method Signed-off-by: Sven Strittmatter --- .../persistence/defectdojo/http/Foo.java | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java index 07560c53..7981f285 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java @@ -58,31 +58,26 @@ static String encodeProxyCredentials(@NonNull final ProxyConfig cfg) { } public RestTemplate createRestTemplate() { - RestTemplate restTemplate; - - if (System.getProperty("http.proxyUser") != null && System.getProperty("http.proxyPassword") != null) { + if (proxyConfig.isComplete()) { // Configuring Proxy Authentication explicitly as it isn't done by default for spring rest templates :( - CredentialsProvider credsProvider = new BasicCredentialsProvider(); - credsProvider.setCredentials( - new AuthScope(System.getProperty("http.proxyHost"), Integer.parseInt(System.getProperty("http.proxyPort"))), - new UsernamePasswordCredentials(System.getProperty("http.proxyUser"), System.getProperty("http.proxyPassword")) + final var credentials = new BasicCredentialsProvider(); + credentials.setCredentials( + new AuthScope(proxyConfig.getHost(), proxyConfig.getPort()), + new UsernamePasswordCredentials(proxyConfig.getUser(), proxyConfig.getPassword()) ); - HttpClientBuilder clientBuilder = HttpClientBuilder.create(); - clientBuilder.useSystemProperties(); - clientBuilder.setProxy(new HttpHost(System.getProperty("http.proxyHost"), Integer.parseInt(System.getProperty("http.proxyPort")))); - clientBuilder.setDefaultCredentialsProvider(credsProvider); - clientBuilder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy()); + final var builder = HttpClientBuilder.create(); + builder.useSystemProperties(); + builder.setProxy(new HttpHost(proxyConfig.getHost(), proxyConfig.getPort())); + builder.setDefaultCredentialsProvider(credentials); + builder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy()); - CloseableHttpClient client = clientBuilder.build(); - - HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); - factory.setHttpClient(client); - restTemplate = new RestTemplate(factory); - } else { - restTemplate = new RestTemplate(); + final var factory = new HttpComponentsClientHttpRequestFactory(); + factory.setHttpClient(builder.build()); + return new RestTemplate(factory); } - return restTemplate; + return new RestTemplate(); + } } } From 97d74cb5cdfc2c49f751b1776d9f5c33a2d29057 Mon Sep 17 00:00:00 2001 From: Sven Strittmatter Date: Mon, 4 Sep 2023 16:35:02 +0200 Subject: [PATCH 04/10] #36 Decompose method to make code testable Signed-off-by: Sven Strittmatter --- .../persistence/defectdojo/http/Foo.java | 5 ++- .../persistence/defectdojo/http/FooTest.java | 39 ++++++++++++------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java index 7981f285..abf51d51 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java @@ -62,7 +62,7 @@ public RestTemplate createRestTemplate() { // Configuring Proxy Authentication explicitly as it isn't done by default for spring rest templates :( final var credentials = new BasicCredentialsProvider(); credentials.setCredentials( - new AuthScope(proxyConfig.getHost(), proxyConfig.getPort()), + createAuthScope(), new UsernamePasswordCredentials(proxyConfig.getUser(), proxyConfig.getPassword()) ); @@ -79,5 +79,8 @@ public RestTemplate createRestTemplate() { return new RestTemplate(); } + + AuthScope createAuthScope() { + return new AuthScope(proxyConfig.getHost(), proxyConfig.getPort()); } } diff --git a/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java b/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java index 6e97b9a0..e038f9e2 100644 --- a/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java +++ b/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java @@ -6,6 +6,7 @@ import io.securecodebox.persistence.defectdojo.config.Config; import lombok.NonNull; +import org.apache.http.auth.AuthScope; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; @@ -19,40 +20,38 @@ */ class FooTest { private final Config config = new Config("url", "apikey"); + private final ProxyConfig proxyConfig = ProxyConfig.builder() + .user("user") + .password("pw") + .host("host") + .port(42) + .build(); + private final Foo sut = new Foo(config, proxyConfig); @Test void generateAuthorizationHeaders_withoutProxyAuth() { - final var incompleteProxyConfig = ProxyConfig.NULL; - - final var sut = new Foo(config, incompleteProxyConfig); + final var innerSut = new Foo(config, ProxyConfig.NULL); assertAll( () -> assertThat( - sut.generateAuthorizationHeaders().get(HttpHeaders.AUTHORIZATION), + innerSut.generateAuthorizationHeaders().get(HttpHeaders.AUTHORIZATION), contains("Token apikey")), () -> assertThat( - sut.generateAuthorizationHeaders().get(HttpHeaders.PROXY_AUTHORIZATION), + innerSut.generateAuthorizationHeaders().get(HttpHeaders.PROXY_AUTHORIZATION), not(contains("Basic dXNlcjpwdw=="))) ); } @Test void generateAuthorizationHeaders_withProxyAuth() { - final var completeProxyConfig = ProxyConfig.builder() - .user("user") - .password("pw") - .host("host") - .port(42) - .build(); - - final var sut = new Foo(config, completeProxyConfig); + final var innerSut = new Foo(config, proxyConfig); assertAll( () -> assertThat( - sut.generateAuthorizationHeaders().get(HttpHeaders.AUTHORIZATION), + innerSut.generateAuthorizationHeaders().get(HttpHeaders.AUTHORIZATION), contains("Token apikey")), () -> assertThat( - sut.generateAuthorizationHeaders().get(HttpHeaders.PROXY_AUTHORIZATION), + innerSut.generateAuthorizationHeaders().get(HttpHeaders.PROXY_AUTHORIZATION), contains("Basic dXNlcjpwdw==")) ); } @@ -66,4 +65,14 @@ void encodeProxyCredentials() { assertThat(Foo.encodeProxyCredentials(proxyConfig), is("YsOkcnRyYW06Z29oemU4QWU=")); } + + @Test + void createAuthScope() { + final var result = sut.createAuthScope(); + + assertAll( + () -> assertThat(result.getHost(), is(proxyConfig.getHost())), + () -> assertThat(result.getPort(), is(proxyConfig.getPort())) + ); + } } From b557e841320765f2568c1084f35e1fbebd93c0cf Mon Sep 17 00:00:00 2001 From: Sven Strittmatter Date: Mon, 4 Sep 2023 16:37:56 +0200 Subject: [PATCH 05/10] #36 Decompose method to make code testable Signed-off-by: Sven Strittmatter --- .../persistence/defectdojo/http/Foo.java | 7 ++++++- .../persistence/defectdojo/http/FooTest.java | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java index abf51d51..9a52cb16 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java @@ -8,6 +8,7 @@ import lombok.NonNull; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; +import org.apache.http.auth.Credentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.impl.client.BasicCredentialsProvider; @@ -63,7 +64,7 @@ public RestTemplate createRestTemplate() { final var credentials = new BasicCredentialsProvider(); credentials.setCredentials( createAuthScope(), - new UsernamePasswordCredentials(proxyConfig.getUser(), proxyConfig.getPassword()) + createCredentials() ); final var builder = HttpClientBuilder.create(); @@ -83,4 +84,8 @@ public RestTemplate createRestTemplate() { AuthScope createAuthScope() { return new AuthScope(proxyConfig.getHost(), proxyConfig.getPort()); } + + Credentials createCredentials() { + return new UsernamePasswordCredentials(proxyConfig.getUser(), proxyConfig.getPassword()); + } } diff --git a/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java b/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java index e038f9e2..f4dc35b4 100644 --- a/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java +++ b/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java @@ -7,6 +7,7 @@ import io.securecodebox.persistence.defectdojo.config.Config; import lombok.NonNull; import org.apache.http.auth.AuthScope; +import org.apache.http.auth.Credentials; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; @@ -75,4 +76,14 @@ void createAuthScope() { () -> assertThat(result.getPort(), is(proxyConfig.getPort())) ); } + + @Test + void createCredentials() { + final var result = sut.createCredentials(); + + assertAll( + () -> assertThat(result.getUserPrincipal().getName(), is(proxyConfig.getUser())), + () -> assertThat(result.getPassword(), is(proxyConfig.getPassword())) + ); + } } From 7696009b28165f5ef37704528678f7d72247bcfe Mon Sep 17 00:00:00 2001 From: Sven Strittmatter Date: Mon, 4 Sep 2023 22:28:14 +0200 Subject: [PATCH 06/10] #36 Decompose method to make code testable Signed-off-by: Sven Strittmatter --- .../io/securecodebox/persistence/defectdojo/http/Foo.java | 6 +++++- .../persistence/defectdojo/http/FooTest.java | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java index 9a52cb16..285194cd 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java @@ -69,7 +69,7 @@ public RestTemplate createRestTemplate() { final var builder = HttpClientBuilder.create(); builder.useSystemProperties(); - builder.setProxy(new HttpHost(proxyConfig.getHost(), proxyConfig.getPort())); + builder.setProxy(createHttpHost()); builder.setDefaultCredentialsProvider(credentials); builder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy()); @@ -88,4 +88,8 @@ AuthScope createAuthScope() { Credentials createCredentials() { return new UsernamePasswordCredentials(proxyConfig.getUser(), proxyConfig.getPassword()); } + + HttpHost createHttpHost() { + return new HttpHost(proxyConfig.getHost(), proxyConfig.getPort()); + } } diff --git a/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java b/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java index f4dc35b4..db2a1683 100644 --- a/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java +++ b/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java @@ -84,6 +84,14 @@ void createCredentials() { assertAll( () -> assertThat(result.getUserPrincipal().getName(), is(proxyConfig.getUser())), () -> assertThat(result.getPassword(), is(proxyConfig.getPassword())) + + @Test + void createHttpHost() { + final var result = sut.createHttpHost(); + + assertAll( + () -> assertThat(result.getHostName(), is(proxyConfig.getHost())), + () -> assertThat(result.getPort(), is(proxyConfig.getPort())) ); } } From 386d1a6eb00ee26d33bfd48502c068e2cf403d07 Mon Sep 17 00:00:00 2001 From: Sven Strittmatter Date: Mon, 4 Sep 2023 22:29:10 +0200 Subject: [PATCH 07/10] #36 Reformatting Signed-off-by: Sven Strittmatter --- .../persistence/defectdojo/config/Config.java | 2 +- .../persistence/defectdojo/http/Foo.java | 5 +- .../service/DefaultImportScanService.java | 24 ++++----- .../service/GenericDefectDojoService.java | 4 +- .../service/ImportScanService2.java | 2 +- .../persistence/defectdojo/http/FooTest.java | 51 ++++++++++--------- 6 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/config/Config.java b/src/main/java/io/securecodebox/persistence/defectdojo/config/Config.java index f5546357..ac66a519 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/config/Config.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/config/Config.java @@ -99,7 +99,7 @@ public static Config fromEnv() { maxPageCountForGets = Integer.parseInt(findEnvVar(EnvVars.DEFECTDOJO_MAX_PAGE_COUNT_FOR_GETS)); } catch (final NumberFormatException e) { throw new ConfigException(String.format("Given value for environment variable '%s' is not a valid number! Given was '%s'.", EnvVars.DEFECTDOJO_MAX_PAGE_COUNT_FOR_GETS.literal, findEnvVar(EnvVars.DEFECTDOJO_MAX_PAGE_COUNT_FOR_GETS)), - e); + e); } } else { maxPageCountForGets = DEFAULT_MAX_PAGE_COUNT_FOR_GETS; diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java index 285194cd..f3419cd4 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java @@ -62,10 +62,7 @@ public RestTemplate createRestTemplate() { if (proxyConfig.isComplete()) { // Configuring Proxy Authentication explicitly as it isn't done by default for spring rest templates :( final var credentials = new BasicCredentialsProvider(); - credentials.setCredentials( - createAuthScope(), - createCredentials() - ); + credentials.setCredentials(createAuthScope(), createCredentials()); final var builder = HttpClientBuilder.create(); builder.useSystemProperties(); diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/service/DefaultImportScanService.java b/src/main/java/io/securecodebox/persistence/defectdojo/service/DefaultImportScanService.java index 0b92bec7..bea38469 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/service/DefaultImportScanService.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/service/DefaultImportScanService.java @@ -42,9 +42,9 @@ */ class DefaultImportScanService implements ImportScanService { private static final List> HTTP_MESSAGE_CONVERTERS = List.of( - new FormHttpMessageConverter(), - new ResourceHttpMessageConverter(), - new MappingJackson2HttpMessageConverter()); + new FormHttpMessageConverter(), + new ResourceHttpMessageConverter(), + new MappingJackson2HttpMessageConverter()); @Getter private final String defectDojoUrl; @Getter @@ -130,11 +130,11 @@ public String getFilename() { ImportScanResponse exchangeRequest(String endpoint, HttpEntity payload) { final var restTemplate = this.createRestTemplate(); return restTemplate.exchange( - generateApiUrl(endpoint), - HttpMethod.POST, - payload, - ImportScanResponse.class) - .getBody(); + generateApiUrl(endpoint), + HttpMethod.POST, + payload, + ImportScanResponse.class) + .getBody(); } String generateApiUrl(final String endpoint) { @@ -187,10 +187,10 @@ boolean shouldConfigureProxySettings() { ClientHttpRequestFactory createRequestFactoryWithProxyAuthConfig() { final var credentials = new BasicCredentialsProvider(); credentials.setCredentials( - new AuthScope(proxyConfig.getHost(), proxyConfig.getPort()), - new UsernamePasswordCredentials( - proxyConfig.getUser(), - proxyConfig.getPassword()) + new AuthScope(proxyConfig.getHost(), proxyConfig.getPort()), + new UsernamePasswordCredentials( + proxyConfig.getUser(), + proxyConfig.getPassword()) ); final var clientBuilder = HttpClientBuilder.create(); diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/service/GenericDefectDojoService.java b/src/main/java/io/securecodebox/persistence/defectdojo/service/GenericDefectDojoService.java index 84d384a2..85c0f7c6 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/service/GenericDefectDojoService.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/service/GenericDefectDojoService.java @@ -40,7 +40,7 @@ abstract public class GenericDefectDojoService { protected ObjectMapper objectMapper; protected ObjectMapper searchStringMapper; - + @Getter protected RestTemplate restTemplate; @@ -56,7 +56,7 @@ public GenericDefectDojoService(Config config) { this.searchStringMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); this.searchStringMapper.coercionConfigFor(Engagement.Status.class).setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsNull); this.searchStringMapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT); - + this.restTemplate = this.setupRestTemplate(); } diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/service/ImportScanService2.java b/src/main/java/io/securecodebox/persistence/defectdojo/service/ImportScanService2.java index 092f1a59..b9622f15 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/service/ImportScanService2.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/service/ImportScanService2.java @@ -118,7 +118,7 @@ public ImportScanResponse reimportScan(ScanFile scanFile, long testId, long lead } //overloading with optional parameter - public ImportScanResponse importScan(ScanFile scanFile, long engagementId, long lead, String currentDate, ScanType scanType, long testType, LinkedMultiValueMap additionalValues) { + public ImportScanResponse importScan(ScanFile scanFile, long engagementId, long lead, String currentDate, ScanType scanType, long testType, LinkedMultiValueMap additionalValues) { additionalValues.add("engagement", Long.toString(engagementId)); return this.createFindings(scanFile, "import-scan", lead, currentDate, scanType, testType, additionalValues); diff --git a/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java b/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java index db2a1683..20f44b1c 100644 --- a/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java +++ b/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java @@ -6,6 +6,7 @@ import io.securecodebox.persistence.defectdojo.config.Config; import lombok.NonNull; +import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; import org.junit.jupiter.api.Disabled; @@ -22,11 +23,11 @@ class FooTest { private final Config config = new Config("url", "apikey"); private final ProxyConfig proxyConfig = ProxyConfig.builder() - .user("user") - .password("pw") - .host("host") - .port(42) - .build(); + .user("user") + .password("pw") + .host("host") + .port(42) + .build(); private final Foo sut = new Foo(config, proxyConfig); @Test @@ -34,12 +35,12 @@ void generateAuthorizationHeaders_withoutProxyAuth() { final var innerSut = new Foo(config, ProxyConfig.NULL); assertAll( - () -> assertThat( - innerSut.generateAuthorizationHeaders().get(HttpHeaders.AUTHORIZATION), - contains("Token apikey")), - () -> assertThat( - innerSut.generateAuthorizationHeaders().get(HttpHeaders.PROXY_AUTHORIZATION), - not(contains("Basic dXNlcjpwdw=="))) + () -> assertThat( + innerSut.generateAuthorizationHeaders().get(HttpHeaders.AUTHORIZATION), + contains("Token apikey")), + () -> assertThat( + innerSut.generateAuthorizationHeaders().get(HttpHeaders.PROXY_AUTHORIZATION), + not(contains("Basic dXNlcjpwdw=="))) ); } @@ -48,21 +49,21 @@ void generateAuthorizationHeaders_withProxyAuth() { final var innerSut = new Foo(config, proxyConfig); assertAll( - () -> assertThat( - innerSut.generateAuthorizationHeaders().get(HttpHeaders.AUTHORIZATION), - contains("Token apikey")), - () -> assertThat( - innerSut.generateAuthorizationHeaders().get(HttpHeaders.PROXY_AUTHORIZATION), - contains("Basic dXNlcjpwdw==")) + () -> assertThat( + innerSut.generateAuthorizationHeaders().get(HttpHeaders.AUTHORIZATION), + contains("Token apikey")), + () -> assertThat( + innerSut.generateAuthorizationHeaders().get(HttpHeaders.PROXY_AUTHORIZATION), + contains("Basic dXNlcjpwdw==")) ); } @Test void encodeProxyCredentials() { final var proxyConfig = ProxyConfig.builder() - .user("bärtram") - .password("gohze8Ae") - .build(); + .user("bärtram") + .password("gohze8Ae") + .build(); assertThat(Foo.encodeProxyCredentials(proxyConfig), is("YsOkcnRyYW06Z29oemU4QWU=")); } @@ -72,8 +73,8 @@ void createAuthScope() { final var result = sut.createAuthScope(); assertAll( - () -> assertThat(result.getHost(), is(proxyConfig.getHost())), - () -> assertThat(result.getPort(), is(proxyConfig.getPort())) + () -> assertThat(result.getHost(), is(proxyConfig.getHost())), + () -> assertThat(result.getPort(), is(proxyConfig.getPort())) ); } @@ -82,8 +83,10 @@ void createCredentials() { final var result = sut.createCredentials(); assertAll( - () -> assertThat(result.getUserPrincipal().getName(), is(proxyConfig.getUser())), - () -> assertThat(result.getPassword(), is(proxyConfig.getPassword())) + () -> assertThat(result.getUserPrincipal().getName(), is(proxyConfig.getUser())), + () -> assertThat(result.getPassword(), is(proxyConfig.getPassword())) + ); + } @Test void createHttpHost() { From be1437daca98deaae63b534dc8d45f9ee7cdf43f Mon Sep 17 00:00:00 2001 From: Sven Strittmatter Date: Mon, 4 Sep 2023 22:41:36 +0200 Subject: [PATCH 08/10] #36 Decompose method to make code testable Signed-off-by: Sven Strittmatter --- .../persistence/defectdojo/http/Foo.java | 11 +++++++---- .../persistence/defectdojo/http/FooTest.java | 11 +++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java index f3419cd4..9d873185 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java @@ -61,13 +61,10 @@ static String encodeProxyCredentials(@NonNull final ProxyConfig cfg) { public RestTemplate createRestTemplate() { if (proxyConfig.isComplete()) { // Configuring Proxy Authentication explicitly as it isn't done by default for spring rest templates :( - final var credentials = new BasicCredentialsProvider(); - credentials.setCredentials(createAuthScope(), createCredentials()); - final var builder = HttpClientBuilder.create(); builder.useSystemProperties(); builder.setProxy(createHttpHost()); - builder.setDefaultCredentialsProvider(credentials); + builder.setDefaultCredentialsProvider(createCredentialsProvider()); builder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy()); final var factory = new HttpComponentsClientHttpRequestFactory(); @@ -78,6 +75,12 @@ public RestTemplate createRestTemplate() { return new RestTemplate(); } + CredentialsProvider createCredentialsProvider() { + final var provider = new BasicCredentialsProvider(); + provider.setCredentials(createAuthScope(), createCredentials()); + return provider; + } + AuthScope createAuthScope() { return new AuthScope(proxyConfig.getHost(), proxyConfig.getPort()); } diff --git a/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java b/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java index 20f44b1c..46f48250 100644 --- a/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java +++ b/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java @@ -68,6 +68,17 @@ void encodeProxyCredentials() { assertThat(Foo.encodeProxyCredentials(proxyConfig), is("YsOkcnRyYW06Z29oemU4QWU=")); } + @Test + void createCredentialsProvider() { + final var result = sut.createCredentialsProvider(); + final var credentials = result.getCredentials(sut.createAuthScope()); + + assertAll( + () -> assertThat(credentials.getUserPrincipal().getName(), is(proxyConfig.getUser())), + () -> assertThat(credentials.getPassword(), is(proxyConfig.getPassword())) + ); + } + @Test void createAuthScope() { final var result = sut.createAuthScope(); From 943769b3e9b746d630961ebb8397b8c0700dadbb Mon Sep 17 00:00:00 2001 From: Sven Strittmatter Date: Mon, 4 Sep 2023 22:42:11 +0200 Subject: [PATCH 09/10] #36 Use method chaining for better readability Signed-off-by: Sven Strittmatter --- .../persistence/defectdojo/http/Foo.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java index 9d873185..3430eb42 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java @@ -61,14 +61,15 @@ static String encodeProxyCredentials(@NonNull final ProxyConfig cfg) { public RestTemplate createRestTemplate() { if (proxyConfig.isComplete()) { // Configuring Proxy Authentication explicitly as it isn't done by default for spring rest templates :( - final var builder = HttpClientBuilder.create(); - builder.useSystemProperties(); - builder.setProxy(createHttpHost()); - builder.setDefaultCredentialsProvider(createCredentialsProvider()); - builder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy()); + final var builder = HttpClientBuilder.create() + .useSystemProperties() + .setProxy(createHttpHost()) + .setDefaultCredentialsProvider(createCredentialsProvider()) + .setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy()); final var factory = new HttpComponentsClientHttpRequestFactory(); factory.setHttpClient(builder.build()); + return new RestTemplate(factory); } From 8c053c980e3a3857de8d0b21a2b1301320cfd4f6 Mon Sep 17 00:00:00 2001 From: Sven Strittmatter Date: Tue, 5 Sep 2023 09:57:45 +0200 Subject: [PATCH 10/10] #36 We assume a configured proxy only if username/password are set Signed-off-by: Sven Strittmatter --- .../defectdojo/http/ProxyConfigFactory.java | 43 +++++++++---- .../http/ProxyConfigFactoryTest.java | 60 +++++++++++-------- 2 files changed, 64 insertions(+), 39 deletions(-) diff --git a/src/main/java/io/securecodebox/persistence/defectdojo/http/ProxyConfigFactory.java b/src/main/java/io/securecodebox/persistence/defectdojo/http/ProxyConfigFactory.java index 0358726e..ce2a12d6 100644 --- a/src/main/java/io/securecodebox/persistence/defectdojo/http/ProxyConfigFactory.java +++ b/src/main/java/io/securecodebox/persistence/defectdojo/http/ProxyConfigFactory.java @@ -18,22 +18,39 @@ *

*/ public final class ProxyConfigFactory { + static final ProxyConfig DEFAULT_CONFIG = ProxyConfig.NULL; private final SystemPropertyFinder properties = new SystemPropertyFinder(); + /** + * Creates a configuration based on {@link ProxyConfigNames environment variables} + *

+ * We assume a complete proxy configuration only if {@link ProxyConfigNames#HTTP_PROXY_USER user} and + * {@link ProxyConfigNames#HTTP_PROXY_PASSWORD password} is configured. Unless an + * {@link #DEFAULT_CONFIG} configuration will be returned. + *

+ *

+ * Throws {@link MissingProxyConfigValue}, if not all configuration values are present. + *

+ * + * @return never {@code null} + */ public ProxyConfig create() { - final var builder = ProxyConfig.builder(); - - if (properties.notHasProperty(ProxyConfigNames.HTTP_PROXY_USER)) { - throw new MissingProxyConfigValue(ProxyConfigNames.HTTP_PROXY_USER); + if (shouldCreateFromProperties()) { + return createFromProperties(); } - builder.user(properties.getProperty(ProxyConfigNames.HTTP_PROXY_USER)); + return DEFAULT_CONFIG; + } - if (properties.notHasProperty(ProxyConfigNames.HTTP_PROXY_PASSWORD)) { - throw new MissingProxyConfigValue(ProxyConfigNames.HTTP_PROXY_PASSWORD); - } + private boolean shouldCreateFromProperties() { + return properties.hasProperty(ProxyConfigNames.HTTP_PROXY_USER) && + properties.hasProperty(ProxyConfigNames.HTTP_PROXY_PASSWORD); + } - builder.password(properties.getProperty(ProxyConfigNames.HTTP_PROXY_PASSWORD)); + private ProxyConfig createFromProperties() { + final var builder = ProxyConfig.builder() + .user(properties.getProperty(ProxyConfigNames.HTTP_PROXY_USER)) + .password(properties.getProperty(ProxyConfigNames.HTTP_PROXY_PASSWORD)); if (properties.notHasProperty(ProxyConfigNames.HTTP_PROXY_HOST)) { throw new MissingProxyConfigValue(ProxyConfigNames.HTTP_PROXY_HOST); @@ -49,10 +66,10 @@ public ProxyConfig create() { builder.port(Integer.parseInt(properties.getProperty(ProxyConfigNames.HTTP_PROXY_PORT))); } catch (final NumberFormatException e) { throw new IllegalArgumentException( - String.format("Given port for proxy authentication configuration (property '%s') is not a valid number! Given value wa '%s'.", - ProxyConfigNames.HTTP_PROXY_PORT.getLiterat(), - System.getProperty("http.proxyPort")), - e); + String.format("Given port for proxy authentication configuration (property '%s') is not a valid number! Given value wa '%s'.", + ProxyConfigNames.HTTP_PROXY_PORT.getLiterat(), + System.getProperty("http.proxyPort")), + e); } return builder.build(); diff --git a/src/test/java/io/securecodebox/persistence/defectdojo/http/ProxyConfigFactoryTest.java b/src/test/java/io/securecodebox/persistence/defectdojo/http/ProxyConfigFactoryTest.java index 59d6e228..63e6fb42 100644 --- a/src/test/java/io/securecodebox/persistence/defectdojo/http/ProxyConfigFactoryTest.java +++ b/src/test/java/io/securecodebox/persistence/defectdojo/http/ProxyConfigFactoryTest.java @@ -24,74 +24,82 @@ class ProxyConfigFactoryTest { private final ProxyConfigFactory sut = new ProxyConfigFactory(); @Test - void create_throesExceptionIfUserNotSet() { - System.clearProperty(ProxyConfigNames.HTTP_PROXY_USER.getLiterat()); - System.setProperty(ProxyConfigNames.HTTP_PROXY_PASSWORD.getLiterat(), "password"); - System.setProperty(ProxyConfigNames.HTTP_PROXY_HOST.getLiterat(), "host"); - System.setProperty(ProxyConfigNames.HTTP_PROXY_PORT.getLiterat(), "4242"); + void create_returnsDefaultIfUserAndPasswordNotPresent() { + assertThat(sut.create(), is(ProxyConfigFactory.DEFAULT_CONFIG)); + } - final var thrown = assertThrows( - MissingProxyConfigValue.class, - sut::create); + @Test + void create_returnsDefaultIfUserNotPresent() { + System.setProperty(ProxyConfigNames.HTTP_PROXY_USER.getLiterat(), "user"); - assertThat(thrown.getMessage(), containsString("'http.proxyUser'")); + assertThat(sut.create(), is(ProxyConfigFactory.DEFAULT_CONFIG)); } @Test - void create_throesExceptionIfPasswordNotSet() { + void create_returnsDefaultIfPasswordNotPresent() { + System.setProperty(ProxyConfigNames.HTTP_PROXY_PASSWORD.getLiterat(), "password"); + + assertThat(sut.create(), is(ProxyConfigFactory.DEFAULT_CONFIG)); + } + + @Test + void create_returnsCompleteConfigIfAllPropertiesArePresent() { System.setProperty(ProxyConfigNames.HTTP_PROXY_USER.getLiterat(), "user"); - System.clearProperty(ProxyConfigNames.HTTP_PROXY_PASSWORD.getLiterat()); + System.setProperty(ProxyConfigNames.HTTP_PROXY_PASSWORD.getLiterat(), "password"); System.setProperty(ProxyConfigNames.HTTP_PROXY_HOST.getLiterat(), "host"); System.setProperty(ProxyConfigNames.HTTP_PROXY_PORT.getLiterat(), "4242"); - final var thrown = assertThrows( - MissingProxyConfigValue.class, - sut::create); + final var expected = ProxyConfig.builder() + .user("user") + .password("password") + .host("host") + .port(4242) + .build(); - assertThat(thrown.getMessage(), containsString("'http.proxyPassword'")); + assertThat(sut.create(), is(expected)); } @Test - void create_throesExceptionIfHostNotSet() { + void create_throwsExceptionIfHostNotSet() { System.setProperty(ProxyConfigNames.HTTP_PROXY_USER.getLiterat(), "user"); System.setProperty(ProxyConfigNames.HTTP_PROXY_PASSWORD.getLiterat(), "password"); System.clearProperty(ProxyConfigNames.HTTP_PROXY_HOST.getLiterat()); System.setProperty(ProxyConfigNames.HTTP_PROXY_PORT.getLiterat(), "4242"); final var thrown = assertThrows( - MissingProxyConfigValue.class, - sut::create); + MissingProxyConfigValue.class, + sut::create); assertThat(thrown.getMessage(), containsString("'http.proxyHost'")); } @Test - void create_throesExceptionIfPortNotSet() { + void create_throwsExceptionIfPortNotSet() { System.setProperty(ProxyConfigNames.HTTP_PROXY_USER.getLiterat(), "user"); System.setProperty(ProxyConfigNames.HTTP_PROXY_PASSWORD.getLiterat(), "password"); System.setProperty(ProxyConfigNames.HTTP_PROXY_HOST.getLiterat(), "host"); System.clearProperty(ProxyConfigNames.HTTP_PROXY_PORT.getLiterat()); final var thrown = assertThrows( - MissingProxyConfigValue.class, - sut::create); + MissingProxyConfigValue.class, + sut::create); assertThat(thrown.getMessage(), containsString("'http.proxyPort'")); } @Test - void create_throesExceptionIfPortIsNotInteger() { + void create_throwsExceptionIfPortIsNotInteger() { System.setProperty(ProxyConfigNames.HTTP_PROXY_USER.getLiterat(), "user"); System.setProperty(ProxyConfigNames.HTTP_PROXY_PASSWORD.getLiterat(), "password"); System.setProperty(ProxyConfigNames.HTTP_PROXY_HOST.getLiterat(), "host"); System.setProperty(ProxyConfigNames.HTTP_PROXY_PORT.getLiterat(), "FUBAR"); final var thrown = assertThrows( - IllegalArgumentException.class, - sut::create); + IllegalArgumentException.class, + sut::create); assertThat( - thrown.getMessage(), - is("Given port for proxy authentication configuration (property 'http.proxyPort') is not a valid number! Given value wa 'FUBAR'.")); + thrown.getMessage(), + is("Given port for proxy authentication configuration (property 'http.proxyPort') is not a valid number! Given value wa 'FUBAR'.")); } }