-
Notifications
You must be signed in to change notification settings - Fork 12
Reduce Code Duplication #92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Weltraumschaf
merged 18 commits into
secureCodeBox:main
from
Weltraumschaf:36_refactoring
Sep 4, 2023
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
3a251f5
#36 Add issue id to fixme tags
Weltraumschaf 83caaa8
#36 Make the default name a constant
Weltraumschaf 5fe20e9
#36 Remove obsolete comment
Weltraumschaf 68e93a9
Revert "#36 Extract network side effect into interface so we can mock…
Weltraumschaf fe5d649
#36 Add class to hold proxy configuration
Weltraumschaf 79108cb
#36 Fix robert's lastname
Weltraumschaf 185028f
#36 Add facotry to create proxy config from system properties
Weltraumschaf 35d1856
#36 Marke methods deprecated which will be removed after code refacto…
Weltraumschaf d87455e
#36 Use new proxy config in import scan service
Weltraumschaf 4fa891d
#36 Extract config name enum in own file forbetter readability
Weltraumschaf c7bc277
#36 Extract exception for missingproxy config in own file forbetter r…
Weltraumschaf 482662b
#36 Start to extract duplicated code
Weltraumschaf dc255d6
#36 Add a old version because did to many refactorings so that's hard…
Weltraumschaf bd237d2
#36 Make the code identical to duplicated one
Weltraumschaf d3ea3e6
#36 Extract duplicated code to create rest template
Weltraumschaf 8d4cd06
#36 Add missing SPDX headers
Weltraumschaf 40c0ba3
#36 Fix license header to meet SPDX spec
Weltraumschaf a87c80e
#36 Add missing SPDX headers
Weltraumschaf File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 78 additions & 0 deletions
78
src/main/java/io/securecodebox/persistence/defectdojo/http/Foo.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// 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.UsernamePasswordCredentials; | ||
import org.apache.http.client.CredentialsProvider; | ||
import org.apache.http.impl.client.BasicCredentialsProvider; | ||
import org.apache.http.impl.client.CloseableHttpClient; | ||
import org.apache.http.impl.client.HttpClientBuilder; | ||
import org.apache.http.impl.client.ProxyAuthenticationStrategy; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; | ||
import org.springframework.web.client.RestTemplate; | ||
|
||
import java.nio.charset.StandardCharsets; | ||
import java.util.Base64; | ||
|
||
/** | ||
* Placeholder to move duplicated code, will be named better later | ||
*/ | ||
public final class Foo { | ||
private final Config config; | ||
|
||
public Foo(@NonNull final Config config) { | ||
super(); | ||
this.config = config; | ||
} | ||
|
||
public HttpHeaders getDefectDojoAuthorizationHeaders() { | ||
HttpHeaders headers = new HttpHeaders(); | ||
headers.set("Authorization", "Token " + this.config.getApiKey()); | ||
|
||
String username = System.getProperty("http.proxyUser", ""); | ||
String password = System.getProperty("http.proxyPassword", ""); | ||
|
||
if (!username.isEmpty() || !password.isEmpty()) { | ||
System.out.println("Setting Proxy Auth Header..."); | ||
headers.set(HttpHeaders.PROXY_AUTHORIZATION, "Basic " + Base64.getEncoder().encodeToString((username + ':' + password).getBytes(StandardCharsets.UTF_8))); | ||
} | ||
|
||
return headers; | ||
} | ||
|
||
public RestTemplate setupRestTemplate() { | ||
RestTemplate restTemplate; | ||
|
||
if (System.getProperty("http.proxyUser") != null && System.getProperty("http.proxyPassword") != null) { | ||
// 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(); | ||
} | ||
|
||
return restTemplate; | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/main/java/io/securecodebox/persistence/defectdojo/http/MissingProxyConfigValue.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// SPDX-FileCopyrightText: the secureCodeBox authors | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package io.securecodebox.persistence.defectdojo.http; | ||
Weltraumschaf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
import lombok.NonNull; | ||
|
||
/** | ||
* This exception indicates a missing proxy config value | ||
*/ | ||
public final class MissingProxyConfigValue extends RuntimeException { | ||
MissingProxyConfigValue(@NonNull final ProxyConfigNames name) { | ||
super(String.format("Expected system property '%s' not set!", name.getLiterat())); | ||
} | ||
} |
88 changes: 88 additions & 0 deletions
88
src/main/java/io/securecodebox/persistence/defectdojo/http/ProxyConfig.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// SPDX-FileCopyrightText: the secureCodeBox authors | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package io.securecodebox.persistence.defectdojo.http; | ||
Weltraumschaf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
import lombok.Builder; | ||
import lombok.Value; | ||
|
||
/** | ||
* Holds HTTP proxy configuration | ||
* <p> | ||
* This class is immutable by design and therefor thread safe. As defaults it does not use |{@code null} to prevent null | ||
* pointer exceptions. It utilizes sane defaults (empty string or 0) to indicate a not set value. Also it introduces a | ||
* null-object to indicate a not-existing configuration. | ||
* </p> | ||
*/ | ||
@Value | ||
@Builder | ||
public class ProxyConfig { | ||
/** | ||
* Null pattern object. | ||
*/ | ||
public static final ProxyConfig NULL = ProxyConfig.builder().build(); | ||
private static final String DEFAULT_STRING = ""; | ||
private static final int DEFAULT_INT = 0; | ||
|
||
/** | ||
* Username to authenticate on a proxy. | ||
* <p> | ||
* Defaults to empty string. | ||
* </p> | ||
*/ | ||
@Builder.Default | ||
String user = DEFAULT_STRING; | ||
|
||
/** | ||
* Password to authenticate on a proxy. | ||
* <p> | ||
* Defaults to empty string. | ||
* </p> | ||
*/ | ||
@Builder.Default | ||
String password = DEFAULT_STRING; | ||
|
||
/** | ||
* Host name of the proxy. | ||
* <p> | ||
* Defaults to empty string. | ||
* </p> | ||
*/ | ||
@Builder.Default | ||
String host = DEFAULT_STRING; | ||
|
||
/** | ||
* Port of the proxy. | ||
* <p> | ||
* Defaults to 0 (zero). | ||
* </p> | ||
*/ | ||
@Builder.Default | ||
int port = DEFAULT_INT; | ||
|
||
/** | ||
* configuration is considered complete if all values are not default values | ||
* | ||
* @return {@code true} if all values are set else {@code false} | ||
*/ | ||
public boolean isComplete() { | ||
if (getUser().equals(DEFAULT_STRING)) { | ||
return false; | ||
} | ||
|
||
if (getPassword().equals(DEFAULT_STRING)) { | ||
return false; | ||
} | ||
|
||
if (getHost().equals(DEFAULT_STRING)) { | ||
return false; | ||
} | ||
|
||
if (getPort() == DEFAULT_INT) { | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
} |
75 changes: 75 additions & 0 deletions
75
src/main/java/io/securecodebox/persistence/defectdojo/http/ProxyConfigFactory.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// SPDX-FileCopyrightText: the secureCodeBox authors | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package io.securecodebox.persistence.defectdojo.http; | ||
Weltraumschaf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
import lombok.NonNull; | ||
|
||
/** | ||
* This class is responsible to create a proxy configuration | ||
* <p> | ||
* This implementation collects the configuration values from Java system properties. It also treats the | ||
* cases of non-present values ot values of incorrect type. | ||
* </p> | ||
* <p> | ||
* This class does not validate for semantic errors of the values, e.g. malformed hostnames or invalid | ||
* port numbers. | ||
* </p> | ||
*/ | ||
public final class ProxyConfigFactory { | ||
private final SystemPropertyFinder properties = new SystemPropertyFinder(); | ||
|
||
public ProxyConfig create() { | ||
final var builder = ProxyConfig.builder(); | ||
|
||
if (properties.notHasProperty(ProxyConfigNames.HTTP_PROXY_USER)) { | ||
throw new MissingProxyConfigValue(ProxyConfigNames.HTTP_PROXY_USER); | ||
} | ||
|
||
builder.user(properties.getProperty(ProxyConfigNames.HTTP_PROXY_USER)); | ||
|
||
if (properties.notHasProperty(ProxyConfigNames.HTTP_PROXY_PASSWORD)) { | ||
throw new MissingProxyConfigValue(ProxyConfigNames.HTTP_PROXY_PASSWORD); | ||
} | ||
|
||
builder.password(properties.getProperty(ProxyConfigNames.HTTP_PROXY_PASSWORD)); | ||
|
||
if (properties.notHasProperty(ProxyConfigNames.HTTP_PROXY_HOST)) { | ||
throw new MissingProxyConfigValue(ProxyConfigNames.HTTP_PROXY_HOST); | ||
} | ||
|
||
builder.host(properties.getProperty(ProxyConfigNames.HTTP_PROXY_HOST)); | ||
|
||
if (properties.notHasProperty(ProxyConfigNames.HTTP_PROXY_PORT)) { | ||
throw new MissingProxyConfigValue(ProxyConfigNames.HTTP_PROXY_PORT); | ||
} | ||
|
||
try { | ||
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); | ||
} | ||
|
||
return builder.build(); | ||
} | ||
|
||
private static class SystemPropertyFinder { | ||
private boolean hasProperty(@NonNull final ProxyConfigNames name) { | ||
return System.getProperty(name.getLiterat()) != null; | ||
} | ||
|
||
private boolean notHasProperty(@NonNull final ProxyConfigNames name) { | ||
return !hasProperty(name); | ||
} | ||
|
||
private String getProperty(@NonNull final ProxyConfigNames name) { | ||
return System.getProperty(name.getLiterat()); | ||
} | ||
} | ||
|
||
} |
43 changes: 43 additions & 0 deletions
43
src/main/java/io/securecodebox/persistence/defectdojo/http/ProxyConfigNames.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// SPDX-FileCopyrightText: the secureCodeBox authors | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package io.securecodebox.persistence.defectdojo.http; | ||
Weltraumschaf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
import lombok.Getter; | ||
|
||
/** | ||
* These properties can be configured by passing them to the running Java process w/ flag {@literal -D} | ||
* <p> | ||
* Example: {@literal java -Dhttp.proxyHost=... -D... -jar ...} | ||
* </p> | ||
* <p> | ||
* <strong>Important</strong>: All four parameters are mandatory. You must set them all | ||
* or none of them! | ||
* </p> | ||
*/ | ||
@Getter | ||
public enum ProxyConfigNames { | ||
/** | ||
* System property name for the proxy username | ||
*/ | ||
HTTP_PROXY_USER("http.proxyUser"), | ||
/** | ||
* System property name for the proxy user's password | ||
*/ | ||
HTTP_PROXY_PASSWORD("http.proxyPassword"), | ||
/** | ||
* System property name for the proxy's hostname | ||
*/ | ||
HTTP_PROXY_HOST("http.proxyHost"), | ||
/** | ||
* System property for the proxy's port number | ||
*/ | ||
HTTP_PROXY_PORT("http.proxyPort"); | ||
|
||
private final String literat; | ||
|
||
ProxyConfigNames(String literat) { | ||
this.literat = literat; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.