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..ac66a519 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 * @@ -89,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 f185ee99..3430eb42 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; @@ -26,53 +27,70 @@ */ 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; } - public RestTemplate setupRestTemplate() { - RestTemplate restTemplate; + 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)); + } - if (System.getProperty("http.proxyUser") != null && System.getProperty("http.proxyPassword") != null) { + public RestTemplate createRestTemplate() { + 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")) - ); - 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()); - - CloseableHttpClient client = clientBuilder.build(); - - HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); - factory.setHttpClient(client); - restTemplate = new RestTemplate(factory); - } else { - restTemplate = new RestTemplate(); + 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); } - return restTemplate; + 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()); + } + + Credentials createCredentials() { + return new UsernamePasswordCredentials(proxyConfig.getUser(), proxyConfig.getPassword()); + } + + HttpHost createHttpHost() { + return new HttpHost(proxyConfig.getHost(), proxyConfig.getPort()); } } 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/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 084c0b64..85c0f7c6 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; @@ -39,7 +40,7 @@ abstract public class GenericDefectDojoService { protected ObjectMapper objectMapper; protected ObjectMapper searchStringMapper; - + @Getter protected RestTemplate restTemplate; @@ -55,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(); } @@ -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()).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 36c660be..b9622f15 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()).createRestTemplate(); } /** @@ -117,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 new file mode 100644 index 00000000..46f48250 --- /dev/null +++ b/src/test/java/io/securecodebox/persistence/defectdojo/http/FooTest.java @@ -0,0 +1,111 @@ +// 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.apache.http.HttpHost; +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; + +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"); + 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 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=="))) + ); + } + + @Test + 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==")) + ); + } + + @Test + void encodeProxyCredentials() { + final var proxyConfig = ProxyConfig.builder() + .user("bärtram") + .password("gohze8Ae") + .build(); + + 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(); + + assertAll( + () -> assertThat(result.getHost(), is(proxyConfig.getHost())), + () -> 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())) + ); + } + + @Test + void createHttpHost() { + final var result = sut.createHttpHost(); + + assertAll( + () -> assertThat(result.getHostName(), is(proxyConfig.getHost())), + () -> assertThat(result.getPort(), is(proxyConfig.getPort())) + ); + } +} 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'.")); } }