Skip to content
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

Furhtor Refactroing #123

Draft
wants to merge 33 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a1329e7
#121 Introduce Our Own Exception Type Hierarchy
Weltraumschaf Feb 16, 2024
9c3bd78
#121 Remove Checked Exception to Provide a Cleaner API
Weltraumschaf Feb 16, 2024
1a2f61a
#121 Use Latest Version 17 of Java
Weltraumschaf Feb 16, 2024
a662260
#121 Javadoc Tool Can't Lookup Lombok Generated Stuff
Weltraumschaf Feb 16, 2024
f1cc201
#121 Extract Auth Header Facotry from Intermediate Class
Weltraumschaf Feb 16, 2024
8804bf1
#121 Extract Proxy Credential Facotry from Intermediate Class
Weltraumschaf Feb 16, 2024
814d455
#121 Log in Debug Level Which Auth Headers are Set
Weltraumschaf Feb 16, 2024
f5ff0ae
#121 Remove Unused field from Intermediate Class
Weltraumschaf Feb 16, 2024
7c192c0
#121 Give Config a Better Name to Make it More Distinguishable from P…
Weltraumschaf Feb 16, 2024
78f330a
#121 Log proxi configuration
Weltraumschaf Mar 1, 2024
29ba64d
#121 Do not Create Unecessary Objects
Weltraumschaf Mar 14, 2024
4f2ee00
#121 Use Better Variable Name
Weltraumschaf Mar 14, 2024
e5368d6
#121 Extract Method to Generate Base URL
Weltraumschaf Mar 14, 2024
f439576
#121 Mark Dedicated Constructor
Weltraumschaf Mar 14, 2024
e9ad077
#121 Make Vars Final
Weltraumschaf Mar 14, 2024
28c7c4b
#121 Add Bug Marker
Weltraumschaf Mar 15, 2024
eb975b1
#121 Add Missing JavaDoc
Weltraumschaf Mar 15, 2024
3309da3
#121 Use URI Instead of String
Weltraumschaf Mar 15, 2024
a537644
#121 Reformat Lambdas for Readability
Weltraumschaf Mar 15, 2024
1ce7c07
#121 Remove Obsolete Checked Exceptions from Method Signature
Weltraumschaf Mar 15, 2024
08f98cc
#121 Move Overloaded Method Before the Implemented
Weltraumschaf Mar 15, 2024
34abd4c
#121 Add Tests to Verify Presence of Auth Token in Headers
Weltraumschaf Mar 15, 2024
b67f8c5
#121 Hide Client Config Because Only USed in This Class
Weltraumschaf Mar 15, 2024
307747c
#121 Hide Rest Template Because Only USed in This Class
Weltraumschaf Mar 15, 2024
e00225a
#121 Extract Proxy Config As Field to Make it Injectable in Tests
Weltraumschaf Mar 15, 2024
9fb2b5e
#121 Give Method Better Name Since it is Not a Simple Getter
Weltraumschaf Mar 15, 2024
d72ee2f
#121 Add Tests to Verify Presence of Proxy Auth Header
Weltraumschaf Mar 15, 2024
9797207
#121 Remove Uneccessary Indirect Call to REST Template
Weltraumschaf Mar 15, 2024
190dfc7
#121 Reduce Coupling to Jackso by Extracting Mappers into Own Object
Weltraumschaf Mar 15, 2024
e4c7afd
#121 Remove Uneccessary This Qualifier
Weltraumschaf Mar 15, 2024
51c3122
#121 Give Class a More Meaningful Name
Weltraumschaf Mar 15, 2024
2d58c31
#121 Do Not Create Proxy Config Twice
Weltraumschaf Mar 15, 2024
4f67514
#121 Extract Request Entity Creation
Weltraumschaf Mar 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .sdkmanrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=17.0.7-tem
java=17.0.10-tem
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ The client is supposed to be compatible with DefectDojo 1.10 and later, older ve

```java
import com.fasterxml.jackson.core.JsonProcessingException;
import io.securecodebox.persistence.defectdojo.config.ClientConfig;
import io.securecodebox.persistence.defectdojo.config.Config;
import io.securecodebox.persistence.defectdojo.service.ProductTypeService;

Expand All @@ -41,7 +42,7 @@ public class DefectDojoClientTest {
public static void main(String[] args) throws URISyntaxException, JsonProcessingException {

// Configure DefectDojo URl and APIv2 Key
var conf = new Config("https://defectdojo.example.com", "f8....");
var conf = new ClientConfig("https://defectdojo.example.com", "f8....");

var productTypeService = new ProductTypeService(conf);
var productTypes = productTypeService.search();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

package io.securecodebox.persistence.defectdojo.config;

import io.securecodebox.persistence.defectdojo.exception.ConfigException;
import io.securecodebox.persistence.defectdojo.exception.ClientConfigException;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;
Expand All @@ -16,15 +16,19 @@
@Getter
@ToString
@EqualsAndHashCode
public final class Config {
public final class ClientConfig {
/**
* Path prefix for the Defectdojo REST API
*/
public static final String API_PREFIX = "/api/v2/";
/**
* Default for {@link #maxPageCountForGets}
*/
static final int DEFAULT_MAX_PAGE_COUNT_FOR_GETS = 100;
/**
* Null pattern object.
*/
public static final Config NULL = new Config("", "", DEFAULT_MAX_PAGE_COUNT_FOR_GETS);
public static final ClientConfig NULL = new ClientConfig("", "", DEFAULT_MAX_PAGE_COUNT_FOR_GETS);

/**
* URL of the host which serves the DefectDojo API.
Expand Down Expand Up @@ -59,7 +63,7 @@ public final class Config {
* @param url not {@code null}
* @param apiKey not {@code null}
*/
public Config(final @NonNull String url, final @NonNull String apiKey) {
public ClientConfig(final @NonNull String url, final @NonNull String apiKey) {
this(url, apiKey, DEFAULT_MAX_PAGE_COUNT_FOR_GETS);
}

Expand All @@ -70,7 +74,7 @@ public Config(final @NonNull String url, final @NonNull String apiKey) {
* @param apiKey not {@code null}
* @param maxPageCountForGets not less than 1
*/
public Config(final @NonNull String url, final @NonNull String apiKey, final int maxPageCountForGets) {
public ClientConfig(final @NonNull String url, final @NonNull String apiKey, final int maxPageCountForGets) {
super();
this.url = url;
this.apiKey = apiKey;
Expand All @@ -90,7 +94,7 @@ private static int validateIsGreaterZero(final int number, final String name) {
*
* @return never {@code null}
*/
public static Config fromEnv() {
public static ClientConfig fromEnv() {
final var url = findRequiredEnvVar(EnvVars.DEFECTDOJO_URL);
final var apiKey = findRequiredEnvVar(EnvVars.DEFECTDOJO_APIKEY);
final int maxPageCountForGets;
Expand All @@ -99,14 +103,14 @@ public static Config fromEnv() {
try {
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)),
throw new ClientConfigException(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);
}
} else {
maxPageCountForGets = DEFAULT_MAX_PAGE_COUNT_FOR_GETS;
}

return new Config(url, apiKey, maxPageCountForGets);
return new ClientConfig(url, apiKey, maxPageCountForGets);
}

private static boolean hasEnvVar(final @NonNull EnvVars name) {
Expand All @@ -121,7 +125,7 @@ private static String findRequiredEnvVar(final @NonNull EnvVars name) {
final var envVar = System.getenv(name.literal);

if (envVar == null) {
throw new ConfigException(String.format("Missing environment variable '%s'!", name.literal));
throw new ClientConfigException(String.format("Missing environment variable '%s'!", name.literal));
}
return envVar;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2021 iteratec GmbH
// SPDX-FileCopyrightText: 2023 iteratec GmbH
//
// SPDX-License-Identifier: Apache-2.0

package io.securecodebox.persistence.defectdojo.exception;

import io.securecodebox.persistence.defectdojo.config.ClientConfig;

/**
* Indicates a missing/bad {@link ClientConfig config property}
*/
public final class ClientConfigException extends PersistenceException {
public ClientConfigException(final String message) {
super(message);
}

public ClientConfigException(final String message, final Throwable cause) {
super(message, cause);
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@

package io.securecodebox.persistence.defectdojo.exception;

public final class PersistenceException extends RuntimeException {
/**
* Generic exception which is thrown for any unforeseen error at runtime
*/
public class PersistenceException extends RuntimeException {
public PersistenceException(String message) {
super(message);
}
Expand Down
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.exception;

import io.securecodebox.persistence.defectdojo.config.ClientConfig;

/**
* Thrown if we receive more objects than {@link ClientConfig configured}
*/
public final class TooManyResponsesException extends PersistenceException {
public TooManyResponsesException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.securecodebox.persistence.defectdojo.http;

import io.securecodebox.persistence.defectdojo.config.ClientConfig;
import lombok.NonNull;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;

import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
* Utility class to create HTTP authorization headers
*/
@Slf4j
public final class AuthHeaderFactory {
private final ClientConfig clientConfig;
@Setter
@NonNull
private ProxyConfig proxyConfig = ProxyConfig.NULL;

public AuthHeaderFactory(@NonNull ClientConfig clientConfig) {
super();
this.clientConfig = clientConfig;
}

/**
* This method generates appropriate authorization headers
*
* @return never {@code null}
*/
public HttpHeaders generateAuthorizationHeaders() {
final var headers = new HttpHeaders();
log.debug("Add Authorization header.");
headers.set(HttpHeaders.AUTHORIZATION, "Token " + this.clientConfig.getApiKey());

if (proxyConfig.isComplete()) {
log.debug("Add Proxy-Authorization header.");
headers.set(HttpHeaders.PROXY_AUTHORIZATION, "Basic " + encodeProxyCredentials(proxyConfig));
}

return headers;
}

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));
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.securecodebox.persistence.defectdojo.http;

import lombok.NonNull;
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;

/**
* Utility class to create credentials to authenticate against a HTTP proxy
*/
final class ProxyCredentialFactory {
private final ProxyConfig proxyConfig;

ProxyCredentialFactory(@NonNull ProxyConfig proxyConfig) {
super();
this.proxyConfig = proxyConfig;
}

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());
}
}
Loading