From bf9eac46068cd4251bb7ccc49763d6e25e89caca Mon Sep 17 00:00:00 2001 From: Laura Date: Tue, 7 May 2024 15:56:11 +0200 Subject: [PATCH 01/19] Integrating skopeo modul for prepraing docker images #3028 --- .../cli/PrepareWrapperKeyConstants.java | 10 + .../modules/PrepareWrapperModuleGit.java | 4 +- .../modules/PrepareWrapperModuleSkopeo.java | 172 ++++++++++++++++++ .../prepare/modules/SkopeoContext.java | 36 ++++ .../prepare/modules/SkopeoInputValidator.java | 62 +++++++ .../prepare/modules/WrapperSkopeo.java | 156 ++++++++++++++++ .../PrepareWrapperModuleSkopeoTest.java | 25 +++ .../modules/SkopeoInputValidatorTest.java | 72 ++++++++ .../prepare/modules/WrapperSkopeoTest.java | 28 +++ 9 files changed, 563 insertions(+), 2 deletions(-) create mode 100644 sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeo.java create mode 100644 sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoContext.java create mode 100644 sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidator.java create mode 100644 sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeo.java create mode 100644 sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeoTest.java create mode 100644 sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidatorTest.java create mode 100644 sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeoTest.java diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/cli/PrepareWrapperKeyConstants.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/cli/PrepareWrapperKeyConstants.java index ee95b11b1..990c8c4d5 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/cli/PrepareWrapperKeyConstants.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/cli/PrepareWrapperKeyConstants.java @@ -20,8 +20,18 @@ public class PrepareWrapperKeyConstants { */ public static final String KEY_PDS_PREPARE_MODULE_GIT_ENABLED = "pds.prepare.module.git.enabled"; + /** + * Flag to enable the skopeo prepare module + */ + public static final String KEY_PDS_PREPARE_MODULE_SKOPEO_ENABLED = "pds.prepare.module.skopeo.enabled"; + /** * Flag to clean the git folder from git files and clone without history */ public static final String KEY_PDS_PREPARE_AUTO_CLEANUP_GIT_FOLDER = "pds.prepare.auto.cleanup.git.folder"; + + /** + * Filename for skopeo authentication file + */ + public static final String KEY_PDS_PREPARE_AUTHENTICATION_FILE_SKOPEO = "pds.prepare.authentication.file.skopeo"; } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGit.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGit.java index b0220323c..238162e40 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGit.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGit.java @@ -134,8 +134,8 @@ private void clonePrivateRepository(PrepareWrapperContext context, SecHubRemoteC /* @formatter:off */ GitContext gitContext = (GitContext) new GitContext.GitContextBuilder(). setCloneWithoutHistory(pdsPrepareAutoCleanupGitFolder). - setLocation(location) - .setCredentialMap(credentialMap). + setLocation(location). + setCredentialMap(credentialMap). setUploadDirectory(context.getEnvironment().getPdsPrepareUploadFolderDirectory()). build(); /* @formatter:on */ diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeo.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeo.java new file mode 100644 index 000000000..9bfb9bbd7 --- /dev/null +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeo.java @@ -0,0 +1,172 @@ +package com.mercedesbenz.sechub.wrapper.prepare.modules; + +import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_PASSWORD; +import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_USERNAME; +import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperKeyConstants.KEY_PDS_PREPARE_MODULE_SKOPEO_ENABLED; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.List; +import java.util.Optional; + +import javax.crypto.SealedObject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import com.mercedesbenz.sechub.commons.core.security.CryptoAccess; +import com.mercedesbenz.sechub.commons.model.*; +import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperContext; + +@Service +public class PrepareWrapperModuleSkopeo implements PrepareWrapperModule { + + Logger LOG = LoggerFactory.getLogger(PrepareWrapperModuleSkopeo.class); + + private static final String TYPE = "docker"; + + @Value("${" + KEY_PDS_PREPARE_MODULE_SKOPEO_ENABLED + ":true}") + private boolean pdsPrepareModuleSkopeoEnabled; + + @Autowired + SkopeoInputValidator skopeoInputValidator; + + @Autowired + WrapperSkopeo skopeo; + + @Override + public boolean isAbleToPrepare(PrepareWrapperContext context) { + + if (!pdsPrepareModuleSkopeoEnabled) { + LOG.debug("Skopeo module is disabled"); + return false; + } + + for (SecHubRemoteDataConfiguration secHubRemoteDataConfiguration : context.getRemoteDataConfigurationList()) { + String location = secHubRemoteDataConfiguration.getLocation(); + + skopeoInputValidator.validateLocationCharacters(location, null); + + if (isMatchingSkopeoType(secHubRemoteDataConfiguration.getType())) { + LOG.debug("Type is: " + TYPE); + if (!skopeoInputValidator.validateLocation(location)) { + context.getUserMessages().add(new SecHubMessage(SecHubMessageType.WARNING, "Type is " + TYPE + " but location does not match URL pattern")); + LOG.warn("User defined type as " + TYPE + ", but the defined location was not a valid location: {}", location); + return false; + } + return true; + } + + if (skopeoInputValidator.validateLocation(location)) { + LOG.debug("Location is a " + TYPE + " URL"); + return true; + } + + } + return false; + } + + @Override + public void prepare(PrepareWrapperContext context) throws IOException { + LOG.debug("Start remote data preparation for GIT repository"); + + List remoteDataConfigurationList = context.getRemoteDataConfigurationList(); + + for (SecHubRemoteDataConfiguration secHubRemoteDataConfiguration : remoteDataConfigurationList) { + prepareRemoteConfiguration(context, secHubRemoteDataConfiguration); + } + + if (!isDownloadSuccessful(context)) { + throw new IOException("Download of git repository was not successful."); + } + } + + boolean isDownloadSuccessful(PrepareWrapperContext context) { + // check if download folder contains docker archive + Path path = Paths.get(context.getEnvironment().getPdsPrepareUploadFolderDirectory()); + if (Files.isDirectory(path)) { + String gitFile = "image.tar"; + Path gitPath = Paths.get(path + "/" + gitFile); + return Files.exists(gitPath); + } + return false; + } + + private void prepareRemoteConfiguration(PrepareWrapperContext context, SecHubRemoteDataConfiguration secHubRemoteDataConfiguration) throws IOException { + String location = secHubRemoteDataConfiguration.getLocation(); + Optional credentials = secHubRemoteDataConfiguration.getCredentials(); + + if (!credentials.isPresent()) { + downloadPublicImage(context, location); + return; + } + + Optional optUser = credentials.get().getUser(); + if (optUser.isPresent()) { + SecHubRemoteCredentialUserData user = optUser.get(); + downloadPrivateImage(context, user, location); + return; + } + + throw new IllegalStateException("Defined credentials have no credential user data for location: " + location); + } + + private void downloadPrivateImage(PrepareWrapperContext context, SecHubRemoteCredentialUserData user, String location) throws IOException { + assertUserCredentials(user); + + HashMap credentialMap = new HashMap<>(); + addSealedUserCredentials(user, credentialMap); + + /* @formatter:off */ + SkopeoContext skopeoContext = (SkopeoContext) new SkopeoContext.SkopeoContextBuilder(). + setLocation(location). + setCredentialMap(credentialMap). + setUploadDirectory(context.getEnvironment().getPdsPrepareUploadFolderDirectory()). + build(); + /* @formatter:on */ + + skopeo.download(skopeoContext); + + SecHubMessage message = new SecHubMessage(SecHubMessageType.INFO, "Cloned private repository: " + location); + context.getUserMessages().add(message); + } + + private static void addSealedUserCredentials(SecHubRemoteCredentialUserData user, HashMap credentialMap) { + SealedObject sealedUsername = CryptoAccess.CRYPTO_STRING.seal(user.getName()); + SealedObject sealedPassword = CryptoAccess.CRYPTO_STRING.seal(user.getPassword()); + credentialMap.put(PDS_PREPARE_CREDENTIAL_USERNAME, sealedUsername); + credentialMap.put(PDS_PREPARE_CREDENTIAL_PASSWORD, sealedPassword); + } + + private void assertUserCredentials(SecHubRemoteCredentialUserData user) { + skopeoInputValidator.validateUsername(user.getName()); + skopeoInputValidator.validatePassword(user.getPassword()); + } + + private void downloadPublicImage(PrepareWrapperContext context, String location) throws IOException { + /* @formatter:off */ + SkopeoContext skopeoContext = (SkopeoContext) new SkopeoContext.SkopeoContextBuilder(). + setLocation(location). + setUploadDirectory(context.getEnvironment().getPdsPrepareUploadFolderDirectory()). + build(); + /* @formatter:on */ + + skopeo.download(skopeoContext); + + SecHubMessage message = new SecHubMessage(SecHubMessageType.INFO, "Cloned public repository: " + location); + context.getUserMessages().add(message); + } + + private boolean isMatchingSkopeoType(String type) { + if (type == null || type.isBlank()) { + return false; + } + return TYPE.equalsIgnoreCase(type); + } +} diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoContext.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoContext.java new file mode 100644 index 000000000..34b8aefdc --- /dev/null +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoContext.java @@ -0,0 +1,36 @@ +package com.mercedesbenz.sechub.wrapper.prepare.modules; + +public class SkopeoContext extends ToolContext { + + private final String filename; + + private SkopeoContext(SkopeoContextBuilder builder) { + super(builder); + this.filename = builder.filename; + } + + public String getFilename() { + return filename; + } + + public static class SkopeoContextBuilder extends ToolContextBuilder { + + private String filename = "SkopeoDownloadFile.tar"; + + @Override + public SkopeoContext build() { + return new SkopeoContext(this); + } + + public SkopeoContextBuilder filename(String filename) { + if (filename == null || filename.isBlank()) { + return this; + } + if (!filename.endsWith(".tar")) { + throw new IllegalArgumentException("Filename must end with .tar"); + } + this.filename = filename; + return this; + } + } +} diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidator.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidator.java new file mode 100644 index 000000000..87bd00ca6 --- /dev/null +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidator.java @@ -0,0 +1,62 @@ +package com.mercedesbenz.sechub.wrapper.prepare.modules; + +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; + +import org.springframework.stereotype.Component; + +@Component +public class SkopeoInputValidator implements InputValidator { + + private static final String SKOPEO_LOCATION_REGEX = "((docker://|https://)?([a-zA-Z0-9-_.].[a-zA-Z0-9-_.]/)?[a-zA-Z0-9-_.]+(:[a-zA-Z0-9-_.]+)?(/)?)+(@sha256:[a-f0-9]{64})?"; + private static final Pattern SKOPEO_LOCATION_PATTERN = Pattern.compile(SKOPEO_LOCATION_REGEX); + private static final String SKOPEO_USERNAME_REGEX = "^[a-zA-Z0-9-_\\d](?:[a-zA-Z0-9-_\\d]|(?=[a-zA-Z0-9-_\\d])){0,38}$"; + private static final Pattern SKOPEO_USERNAME_PATTERN = Pattern.compile(SKOPEO_USERNAME_REGEX); + private static final String SKOPEO_PASSWORD_REGEX = "^[a-zA-Z0-9-_\\d]{0,72}$"; + private static final Pattern SKOPEO_PASSWORD_PATTERN = Pattern.compile(SKOPEO_PASSWORD_REGEX); + private final List defaultForbiddenCharacters = Arrays.asList(">", "<", "!", "?", "*", "'", "\"", ";", "&", "|", "`", "$", "{", "}"); + + @Override + public boolean validateLocation(String location) { + if (location == null || location.isBlank()) { + throw new IllegalStateException("Defined location must not be null or empty."); + } + return SKOPEO_LOCATION_PATTERN.matcher(location).matches(); + } + + @Override + public void validateUsername(String username) { + if (username == null || username.isBlank()) { + throw new IllegalStateException("Defined username must not be null or empty."); + } + if (!SKOPEO_USERNAME_PATTERN.matcher(username).matches()) { + throw new IllegalStateException("Defined username must match the modules pattern."); + } + } + + @Override + public void validatePassword(String password) { + if (password == null || password.isBlank()) { + throw new IllegalStateException("Defined password must not be null or empty."); + } + if (!SKOPEO_PASSWORD_PATTERN.matcher(password).matches()) { + throw new IllegalStateException("Defined password must match the Skopeo Api token pattern."); + } + } + + @Override + public void validateLocationCharacters(String url, List forbiddenCharacters) { + if (forbiddenCharacters == null) { + forbiddenCharacters = defaultForbiddenCharacters; + } + if (url.contains(" ")) { + throw new IllegalArgumentException("Defined URL must not contain whitespaces."); + } + for (String forbiddenCharacter : forbiddenCharacters) { + if (url.contains(forbiddenCharacter)) { + throw new IllegalArgumentException("Defined URL must not contain forbidden characters: " + forbiddenCharacter); + } + } + } +} diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeo.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeo.java new file mode 100644 index 000000000..1a6c3a694 --- /dev/null +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeo.java @@ -0,0 +1,156 @@ +package com.mercedesbenz.sechub.wrapper.prepare.modules; + +import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.*; +import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperKeyConstants.KEY_PDS_PREPARE_AUTHENTICATION_FILE_SKOPEO; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import com.mercedesbenz.sechub.commons.pds.ProcessAdapter; + +@Component +public class WrapperSkopeo extends WrapperTool { + + @Value("${" + KEY_PDS_PREPARE_AUTHENTICATION_FILE_SKOPEO + ":authentication.json}") + String pdsPrepareAuthenticationFileSkopeo; + + void download(SkopeoContext context) throws IOException { + login(context); + + ProcessBuilder builder = buildProcessDownload(context); + ProcessAdapter process = null; + + try { + process = processAdapterFactory.startProcess(builder); + } catch (IOException e) { + throw new IOException("Error download with Skopeo from: " + context.getLocation(), e); + } + + waitForProcessToFinish(process); + } + + @Override + void cleanUploadDirectory(String uploadDirectory) throws IOException { + ProcessBuilder builder = buildProcessClean(uploadDirectory); + ProcessAdapter process = null; + + try { + process = processAdapterFactory.startProcess(builder); + } catch (IOException e) { + throw new IOException("Error while cleaning authentication file.", e); + } + + waitForProcessToFinish(process); + } + + private void login(SkopeoContext context) throws IOException { + ProcessBuilder builder = buildProcessLogin(context); + exportEnvironmentVariables(builder, context.getCredentialMap()); + ProcessAdapter process = null; + + try { + process = processAdapterFactory.startProcess(builder); + } catch (IOException e) { + throw new IOException("Error while login with Skopeo to: " + context.getLocation(), e); + } + + waitForProcessToFinish(process); + } + + private ProcessBuilder buildProcessLogin(SkopeoContext context) { + // skopeo login "$LOCATION" --username "$USERNAME" --password "$PASSWORD" + // --authfile "$PDS_JOB_WORKSPACE_LOCATION/$SKOPEO_AUTH" + List commands = new ArrayList<>(); + + String location = transformLocationForLogin(context.getLocation()); + File uploadDir = Paths.get(context.getUploadDirectory()).toAbsolutePath().toFile(); + + commands.add("/bin/bash"); + commands.add("-c"); + commands.add("skopeo"); + commands.add("login"); + commands.add(location); + commands.add("--username"); + commands.add("$" + PDS_PREPARE_CREDENTIAL_USERNAME); + commands.add("--password"); + commands.add("$" + PDS_PREPARE_CREDENTIAL_PASSWORD); + commands.add("--authfile"); + commands.add(pdsPrepareAuthenticationFileSkopeo); + + ProcessBuilder builder = new ProcessBuilder(commands); + builder.directory(uploadDir); + builder.inheritIO(); + + return builder; + } + + private ProcessBuilder buildProcessDownload(SkopeoContext context) { + // skopeo copy docker://$LOCATION + // docker-archive:$PDS_JOB_WORKSPACE_LOCATION/$PDS_PREPARE_UPLOAD_FOLDER + List commands = new ArrayList<>(); + + String location = transformLocationForDownload(context.getLocation()); + File uploadDir = Paths.get(context.getUploadDirectory()).toAbsolutePath().toFile(); + + commands.add("/bin/bash"); + commands.add("-c"); + commands.add("skopeo"); + commands.add("copy"); + commands.add(location); + commands.add("docker-archive:" + context.getFilename()); + commands.add("--authfile"); + commands.add(pdsPrepareAuthenticationFileSkopeo); + + ProcessBuilder builder = new ProcessBuilder(commands); + builder.directory(uploadDir); + builder.inheritIO(); + + return builder; + } + + private ProcessBuilder buildProcessClean(String pdsPrepareUploadFolderDirectory) { + List commands = new ArrayList<>(); + + File uploadDir = Paths.get(pdsPrepareUploadFolderDirectory).toAbsolutePath().toFile(); + + commands.add("/bin/bash"); + commands.add("-c"); + commands.add("rm -rf " + pdsPrepareAuthenticationFileSkopeo); + + ProcessBuilder builder = new ProcessBuilder(commands); + builder.directory(uploadDir); + builder.inheritIO(); + return builder; + } + + private String transformLocationForDownload(String location) { + String dockerPrefix = "docker://"; + + if (location.startsWith(dockerPrefix)) { + return location; + } + + if (location.startsWith("https://")) { + location = location.replace("https://", dockerPrefix); + return location; + } + + return dockerPrefix + location; + } + + private String transformLocationForLogin(String location) { + if (location.startsWith("docker://")) { + location = location.replace("docker://", ""); + } + if (location.startsWith("https://")) { + location = location.replace("https://", ""); + } + return location; + } +} diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeoTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeoTest.java new file mode 100644 index 000000000..0e773f777 --- /dev/null +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeoTest.java @@ -0,0 +1,25 @@ +package com.mercedesbenz.sechub.wrapper.prepare.modules; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.mock; + +import org.junit.jupiter.api.BeforeEach; + +class PrepareWrapperModuleSkopeoTest { + + PrepareWrapperModuleSkopeo wrapperToTest; + SkopeoInputValidator skopeoInputValidator; + WrapperSkopeo skopeo; + + @BeforeEach + void beforeEach() { + wrapperToTest = new PrepareWrapperModuleSkopeo(); + skopeoInputValidator = mock(SkopeoInputValidator.class); + skopeo = mock(WrapperSkopeo.class); + + wrapperToTest.skopeoInputValidator = skopeoInputValidator; + wrapperToTest.skopeo = skopeo; + } + + // TODO: 07.05.24 laura add tests +} \ No newline at end of file diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidatorTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidatorTest.java new file mode 100644 index 000000000..e2e7a91b8 --- /dev/null +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidatorTest.java @@ -0,0 +1,72 @@ +package com.mercedesbenz.sechub.wrapper.prepare.modules; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class SkopeoInputValidatorTest { + + SkopeoInputValidator validatorToTest; + + @BeforeEach + void beforeEach() { + validatorToTest = new SkopeoInputValidator(); + } + + @ParameterizedTest + @ValueSource(strings = { "ubuntu:22.04", "ubuntu", "docker://ubuntu:22.04", "docker://ubuntu", "oci:busybox_ocilayout:latest", "https://hub.docker.com", + "docker://docker.io/library/busybox:latest", "ubuntu@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d", + "ghcr.io/owner/repo:tag" }) + void validateLocation_returns_true_for_valid_docker_urls(String location) { + /* execute + test */ + assertTrue(validatorToTest.validateLocation(location)); + } + + @ParameterizedTest + @ValueSource(strings = { "invalid-registry ubuntu:22.04", "docker://registry/ubuntu:invalid tag", "docker://ubuntu:tag$maliciousCode", + "docker://ubuntu:tag|maliciousCode", "my-registry/oci:busybox_ocilayout;latest", }) + void validateLocation_returns_false_for_invalid_docker_urls(String location) { + /* execute + test */ + assertFalse(validatorToTest.validateLocation(location)); + } + + @ParameterizedTest + @ValueSource(strings = { "username", "username123", "username_123", "username-123", "username-123_456", "username1234567890123456789003890123456", + "user_user_user" }) + void validateUsername_returns_true_for_valid_usernames(String username) { + /* execute + test */ + assertDoesNotThrow(() -> validatorToTest.validateUsername(username)); + } + + @ParameterizedTest + @ValueSource(strings = { "user name", "username?", "username!", "username>", "username<", "username'", "username\"", "username;", "username&", "username|", + "username`", "username$", "username{", "username}" }) + void validateUsername_throws_exception_for_invalid_usernames(String username) { + /* execute */ + IllegalStateException exception = assertThrows(IllegalStateException.class, () -> validatorToTest.validateUsername(username)); + + /* test */ + assertEquals("Defined username must match the modules pattern.", exception.getMessage()); + } + + @ParameterizedTest + @ValueSource(strings = { "password", "password123", "password_123", "password-123", "password-123_456", "password1234567890123456789003890123456", + "dXNlckBleGFtcGxlLmNvbTpzZWNyZXQexample", "Z2hjcl9wczpzc2VjcmV0example" }) + void validatePassword_returns_true_for_valid_passwords(String password) { + /* execute + test */ + assertDoesNotThrow(() -> validatorToTest.validatePassword(password)); + } + + @ParameterizedTest + @ValueSource(strings = { "password?", "password!", "password>", "password<", "password'", "password\"", "password;", "password&", "password|", "password`", + "password$", "password{", "password}", "password;echo 'malicious'" }) + void validatePassword_throws_exception_for_invalid_passwords(String password) { + /* execute */ + IllegalStateException exception = assertThrows(IllegalStateException.class, () -> validatorToTest.validatePassword(password)); + + /* test */ + assertEquals("Defined password must match the Skopeo Api token pattern.", exception.getMessage()); + } +} diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeoTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeoTest.java new file mode 100644 index 000000000..da52f68de --- /dev/null +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeoTest.java @@ -0,0 +1,28 @@ +package com.mercedesbenz.sechub.wrapper.prepare.modules; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.io.IOException; + +import org.junit.jupiter.api.BeforeEach; + +import com.mercedesbenz.sechub.commons.pds.PDSProcessAdapterFactory; + +class WrapperSkopeoTest { + + WrapperSkopeo wrapperToTest; + PDSProcessAdapterFactory processAdapterFactory; + + @BeforeEach + void beforeEach() throws IOException { + wrapperToTest = new WrapperSkopeo(); + processAdapterFactory = mock(PDSProcessAdapterFactory.class); + doNothing().when(processAdapterFactory).startProcess(any()); + + wrapperToTest.processAdapterFactory = processAdapterFactory; + } + + // TODO: 07.05.24 laura add tests + +} \ No newline at end of file From a0faba42af9c22576e649a124b310f92a80a706e Mon Sep 17 00:00:00 2001 From: Laura Date: Wed, 8 May 2024 15:42:37 +0200 Subject: [PATCH 02/19] Added tests and tested skopeo moduel #3028 --- .../modules/PrepareWrapperModuleGit.java | 12 +- .../modules/PrepareWrapperModuleSkopeo.java | 51 ++- .../prepare/modules/SkopeoInputValidator.java | 2 +- .../prepare/modules/WrapperSkopeo.java | 45 ++- .../wrapper/prepare/modules/WrapperTool.java | 8 +- ...epareWrapperApplicationSpringBootTest.java | 3 +- .../modules/PrepareWrapperModuleGitTest.java | 1 - .../PrepareWrapperModuleSkopeoTest.java | 307 +++++++++++++++++- .../prepare/modules/WrapperSkopeoTest.java | 74 ++++- .../application-test-fail.properties | 3 +- 10 files changed, 458 insertions(+), 48 deletions(-) diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGit.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGit.java index 238162e40..86d1aadbc 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGit.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGit.java @@ -50,10 +50,11 @@ public boolean isAbleToPrepare(PrepareWrapperContext context) { for (SecHubRemoteDataConfiguration secHubRemoteDataConfiguration : context.getRemoteDataConfigurationList()) { String location = secHubRemoteDataConfiguration.getLocation(); + String type = secHubRemoteDataConfiguration.getType(); gitInputValidator.validateLocationCharacters(location, null); - if (isMatchingGitType(secHubRemoteDataConfiguration.getType())) { + if (isMatchingGitType(type)) { LOG.debug("Type is git"); if (!gitInputValidator.validateLocation(location)) { context.getUserMessages().add(new SecHubMessage(SecHubMessageType.WARNING, "Type is git but location does not match git URL pattern")); @@ -63,6 +64,11 @@ public boolean isAbleToPrepare(PrepareWrapperContext context) { return true; } + if (!isTypeNullOrEmpty(type)) { + // type was explicitly defined but is not matching + return false; + } + if (gitInputValidator.validateLocation(location)) { LOG.debug("Location is a git URL"); return true; @@ -106,6 +112,10 @@ boolean isDownloadSuccessful(PrepareWrapperContext context) { return false; } + private boolean isTypeNullOrEmpty(String type) { + return type == null || type.isBlank(); + } + private void prepareRemoteConfiguration(PrepareWrapperContext context, SecHubRemoteDataConfiguration secHubRemoteDataConfiguration) throws IOException { String location = secHubRemoteDataConfiguration.getLocation(); Optional credentials = secHubRemoteDataConfiguration.getCredentials(); diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeo.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeo.java index 9bfb9bbd7..22e637564 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeo.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeo.java @@ -11,6 +11,7 @@ import java.util.HashMap; import java.util.List; import java.util.Optional; +import java.util.stream.Stream; import javax.crypto.SealedObject; @@ -50,10 +51,11 @@ public boolean isAbleToPrepare(PrepareWrapperContext context) { for (SecHubRemoteDataConfiguration secHubRemoteDataConfiguration : context.getRemoteDataConfigurationList()) { String location = secHubRemoteDataConfiguration.getLocation(); + String type = secHubRemoteDataConfiguration.getType(); skopeoInputValidator.validateLocationCharacters(location, null); - if (isMatchingSkopeoType(secHubRemoteDataConfiguration.getType())) { + if (isMatchingSkopeoType(type)) { LOG.debug("Type is: " + TYPE); if (!skopeoInputValidator.validateLocation(location)) { context.getUserMessages().add(new SecHubMessage(SecHubMessageType.WARNING, "Type is " + TYPE + " but location does not match URL pattern")); @@ -63,18 +65,22 @@ public boolean isAbleToPrepare(PrepareWrapperContext context) { return true; } + if (!isTypeNullOrEmpty(type)) { + // type was explicitly defined but is not matching + return false; + } + if (skopeoInputValidator.validateLocation(location)) { LOG.debug("Location is a " + TYPE + " URL"); return true; } - } return false; } @Override public void prepare(PrepareWrapperContext context) throws IOException { - LOG.debug("Start remote data preparation for GIT repository"); + LOG.debug("Start remote data preparation for Docker repository"); List remoteDataConfigurationList = context.getRemoteDataConfigurationList(); @@ -83,21 +89,43 @@ public void prepare(PrepareWrapperContext context) throws IOException { } if (!isDownloadSuccessful(context)) { - throw new IOException("Download of git repository was not successful."); + throw new IOException("Download of docker image was not successful."); } + cleanup(context); } boolean isDownloadSuccessful(PrepareWrapperContext context) { - // check if download folder contains docker archive + // check if download folder contains a .tar archive Path path = Paths.get(context.getEnvironment().getPdsPrepareUploadFolderDirectory()); if (Files.isDirectory(path)) { - String gitFile = "image.tar"; - Path gitPath = Paths.get(path + "/" + gitFile); - return Files.exists(gitPath); + try (Stream walk = Files.walk(path)) { + List result = walk.filter(p -> !Files.isDirectory(p)) // not a directory + .map(p -> p.toString().toLowerCase()) // convert path to string + .filter(f -> f.endsWith(".tar")) // check end with + .toList(); // collect all matched to a List + return !result.isEmpty(); + } catch (IOException e) { + throw new RuntimeException("Error while checking download of docker image", e); + } } return false; } + boolean isMatchingSkopeoType(String type) { + if (type == null || type.isBlank()) { + return false; + } + return TYPE.equalsIgnoreCase(type); + } + + private boolean isTypeNullOrEmpty(String type) { + return type == null || type.isBlank(); + } + + private void cleanup(PrepareWrapperContext context) throws IOException { + skopeo.cleanUploadDirectory(context.getEnvironment().getPdsPrepareUploadFolderDirectory()); + } + private void prepareRemoteConfiguration(PrepareWrapperContext context, SecHubRemoteDataConfiguration secHubRemoteDataConfiguration) throws IOException { String location = secHubRemoteDataConfiguration.getLocation(); Optional credentials = secHubRemoteDataConfiguration.getCredentials(); @@ -162,11 +190,4 @@ private void downloadPublicImage(PrepareWrapperContext context, String location) SecHubMessage message = new SecHubMessage(SecHubMessageType.INFO, "Cloned public repository: " + location); context.getUserMessages().add(message); } - - private boolean isMatchingSkopeoType(String type) { - if (type == null || type.isBlank()) { - return false; - } - return TYPE.equalsIgnoreCase(type); - } } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidator.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidator.java index 87bd00ca6..e0c8a8711 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidator.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidator.java @@ -13,7 +13,7 @@ public class SkopeoInputValidator implements InputValidator { private static final Pattern SKOPEO_LOCATION_PATTERN = Pattern.compile(SKOPEO_LOCATION_REGEX); private static final String SKOPEO_USERNAME_REGEX = "^[a-zA-Z0-9-_\\d](?:[a-zA-Z0-9-_\\d]|(?=[a-zA-Z0-9-_\\d])){0,38}$"; private static final Pattern SKOPEO_USERNAME_PATTERN = Pattern.compile(SKOPEO_USERNAME_REGEX); - private static final String SKOPEO_PASSWORD_REGEX = "^[a-zA-Z0-9-_\\d]{0,72}$"; + private static final String SKOPEO_PASSWORD_REGEX = "^[a-zA-Z0-9-_\\d]{0,80}$"; private static final Pattern SKOPEO_PASSWORD_PATTERN = Pattern.compile(SKOPEO_PASSWORD_REGEX); private final List defaultForbiddenCharacters = Arrays.asList(">", "<", "!", "?", "*", "'", "\"", ";", "&", "|", "`", "$", "{", "}"); diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeo.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeo.java index 1a6c3a694..0f7c0e991 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeo.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeo.java @@ -21,7 +21,9 @@ public class WrapperSkopeo extends WrapperTool { String pdsPrepareAuthenticationFileSkopeo; void download(SkopeoContext context) throws IOException { - login(context); + if (!context.getCredentialMap().isEmpty()) { + login(context); + } ProcessBuilder builder = buildProcessDownload(context); ProcessAdapter process = null; @@ -29,7 +31,7 @@ void download(SkopeoContext context) throws IOException { try { process = processAdapterFactory.startProcess(builder); } catch (IOException e) { - throw new IOException("Error download with Skopeo from: " + context.getLocation(), e); + throw new IOException("Error while download with Skopeo from: " + context.getLocation(), e); } waitForProcessToFinish(process); @@ -73,15 +75,16 @@ private ProcessBuilder buildProcessLogin(SkopeoContext context) { commands.add("/bin/bash"); commands.add("-c"); - commands.add("skopeo"); - commands.add("login"); - commands.add(location); - commands.add("--username"); - commands.add("$" + PDS_PREPARE_CREDENTIAL_USERNAME); - commands.add("--password"); - commands.add("$" + PDS_PREPARE_CREDENTIAL_PASSWORD); - commands.add("--authfile"); - commands.add(pdsPrepareAuthenticationFileSkopeo); + commands.add("skopeo login " + location + " --username $" + PDS_PREPARE_CREDENTIAL_USERNAME + " --password $" + PDS_PREPARE_CREDENTIAL_PASSWORD + + " --authfile " + pdsPrepareAuthenticationFileSkopeo); + + /* + * commands.add("skopeo"); commands.add("login"); commands.add(location); + * commands.add("--username"); commands.add("$" + + * PDS_PREPARE_CREDENTIAL_USERNAME); commands.add("--password"); + * commands.add("$" + PDS_PREPARE_CREDENTIAL_PASSWORD); + * commands.add("--authfile"); commands.add(pdsPrepareAuthenticationFileSkopeo); + */ ProcessBuilder builder = new ProcessBuilder(commands); builder.directory(uploadDir); @@ -98,14 +101,23 @@ private ProcessBuilder buildProcessDownload(SkopeoContext context) { String location = transformLocationForDownload(context.getLocation()); File uploadDir = Paths.get(context.getUploadDirectory()).toAbsolutePath().toFile(); - commands.add("/bin/bash"); - commands.add("-c"); + /* + * commands.add("/bin/bash"); commands.add("-c"); if + * (!context.getCredentialMap().isEmpty()){ commands.add("skopeo copy " + + * location + " docker-archive:" + context.getFilename()); }else{ + * commands.add("skopeo copy " + location + " docker-archive:" + + * context.getFilename() + " --authfile " + pdsPrepareAuthenticationFileSkopeo); + * } + */ + commands.add("skopeo"); commands.add("copy"); commands.add(location); commands.add("docker-archive:" + context.getFilename()); - commands.add("--authfile"); - commands.add(pdsPrepareAuthenticationFileSkopeo); + if (!context.getCredentialMap().isEmpty()) { + commands.add("--authfile"); + commands.add(pdsPrepareAuthenticationFileSkopeo); + } ProcessBuilder builder = new ProcessBuilder(commands); builder.directory(uploadDir); @@ -115,6 +127,7 @@ private ProcessBuilder buildProcessDownload(SkopeoContext context) { } private ProcessBuilder buildProcessClean(String pdsPrepareUploadFolderDirectory) { + // removes authentication file List commands = new ArrayList<>(); File uploadDir = Paths.get(pdsPrepareUploadFolderDirectory).toAbsolutePath().toFile(); @@ -151,6 +164,6 @@ private String transformLocationForLogin(String location) { if (location.startsWith("https://")) { location = location.replace("https://", ""); } - return location; + return location.split("/")[0]; } } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperTool.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperTool.java index ae03940de..6a132b092 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperTool.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperTool.java @@ -46,15 +46,17 @@ void waitForProcessToFinish(ProcessAdapter process) { try { exitDoneInTime = process.waitFor(seconds, TimeUnit.SECONDS); } catch (InterruptedException e) { - throw new RuntimeException("GIT wrapper could not finish process.", e); + throw new RuntimeException("Wrapper for executed modul " + this.getClass().getSimpleName() + " could not finish process.", e); } if (!exitDoneInTime) { - throw new RuntimeException("GIT wrapper could not finish process. Waited " + pdsPrepareProcessTimeoutSeconds + " seconds."); + throw new RuntimeException("Wrapper for executed modul " + this.getClass().getSimpleName() + " could not finish process. Waited " + + pdsPrepareProcessTimeoutSeconds + " seconds."); } if (process.exitValue() != 0) { - throw new RuntimeException("GIT wrapper process failed with exit code: " + process.exitValue()); + throw new RuntimeException( + "Wrapper for executed modul " + this.getClass().getSimpleName() + " process failed with exit code: " + process.exitValue()); } } diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/PrepareWrapperApplicationSpringBootTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/PrepareWrapperApplicationSpringBootTest.java index 54ca94e64..0febd7dec 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/PrepareWrapperApplicationSpringBootTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/PrepareWrapperApplicationSpringBootTest.java @@ -23,7 +23,8 @@ @SpringBootTest(classes = { PrepareWrapperContextFactory.class, PrepareWrapperPreparationService.class, PrepareWrapperPojoFactory.class, PrepareWrapperEnvironment.class, PrepareWrapperPDSUserMessageSupportPojoFactory.class, PrepareWrapperRemoteConfigurationExtractor.class, - PrepareWrapperModuleGit.class, PrepareWrapperModule.class, WrapperGit.class, GitInputValidator.class, JGitAdapter.class }) + PrepareWrapperModuleGit.class, PrepareWrapperModule.class, WrapperGit.class, GitInputValidator.class, JGitAdapter.class, + PrepareWrapperModuleSkopeo.class, WrapperSkopeo.class, SkopeoInputValidator.class }) @ExtendWith(SpringExtension.class) @TestPropertySource(locations = "classpath:application-test-fail.properties") class PrepareWrapperApplicationSpringBootTest { diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGitTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGitTest.java index 162b90650..fa5fb0b42 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGitTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGitTest.java @@ -147,7 +147,6 @@ void prepare_throws_exception_when_credentials_are_empty() { remoteDataConfiguration.setType("git"); remoteDataConfigurationList.add(remoteDataConfiguration); context.setRemoteDataConfigurationList(remoteDataConfigurationList); - ReflectionTestUtils.setField(moduleToTest, "pdsPrepareModuleGitEnabled", true); /* execute */ IllegalStateException exception = assertThrows(IllegalStateException.class, () -> moduleToTest.prepare(context)); diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeoTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeoTest.java index 0e773f777..f1ae97770 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeoTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeoTest.java @@ -1,25 +1,320 @@ package com.mercedesbenz.sechub.wrapper.prepare.modules; +import static com.mercedesbenz.sechub.commons.model.SecHubScanConfiguration.createFromJSON; import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.mock; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.springframework.test.util.ReflectionTestUtils; + +import com.mercedesbenz.sechub.commons.model.SecHubConfigurationModel; +import com.mercedesbenz.sechub.commons.model.SecHubRemoteCredentialConfiguration; +import com.mercedesbenz.sechub.commons.model.SecHubRemoteCredentialUserData; +import com.mercedesbenz.sechub.commons.model.SecHubRemoteDataConfiguration; +import com.mercedesbenz.sechub.test.TestFileWriter; +import com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironment; +import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperContext; +import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperRemoteConfigurationExtractor; class PrepareWrapperModuleSkopeoTest { - PrepareWrapperModuleSkopeo wrapperToTest; + PrepareWrapperModuleSkopeo moduleToTest; SkopeoInputValidator skopeoInputValidator; WrapperSkopeo skopeo; + TestFileWriter writer; + @BeforeEach void beforeEach() { - wrapperToTest = new PrepareWrapperModuleSkopeo(); - skopeoInputValidator = mock(SkopeoInputValidator.class); + moduleToTest = new PrepareWrapperModuleSkopeo(); + skopeoInputValidator = new SkopeoInputValidator(); + writer = new TestFileWriter(); skopeo = mock(WrapperSkopeo.class); - wrapperToTest.skopeoInputValidator = skopeoInputValidator; - wrapperToTest.skopeo = skopeo; + moduleToTest.skopeoInputValidator = skopeoInputValidator; + moduleToTest.skopeo = skopeo; } // TODO: 07.05.24 laura add tests + + @ParameterizedTest + @ValueSource(strings = { "ubuntu:22.04", "ubuntu", "docker://ubuntu:22.04", "docker://ubuntu", "oci:busybox_ocilayout:latest", "https://hub.docker.com", + "docker://docker.io/library/busybox:latest", "ubuntu@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d", + "ghcr.io/owner/repo:tag" }) + void isAbleToPrepare_returnsFalse_whenSkopeoModuleIsDisabled(String location) { + /* prepare */ + PrepareWrapperContext context = createContextWithRemoteDataConfig(location); + ReflectionTestUtils.setField(moduleToTest, "pdsPrepareModuleSkopeoEnabled", false); + + /* execute */ + boolean result = moduleToTest.isAbleToPrepare(context); + + /* test */ + assertFalse(result); + } + + @Test + void isAbleToPrepare_returnsFalse_whenNoRemoteDataConfigurationIsAvailable() { + /* prepare */ + PrepareWrapperContext context = createContextEmptyConfig(); + ReflectionTestUtils.setField(moduleToTest, "pdsPrepareModuleSkopeoEnabled", true); + + /* execute */ + boolean result = moduleToTest.isAbleToPrepare(context); + + /* test */ + assertFalse(result); + } + + @ParameterizedTest + @ValueSource(strings = { "http://host.xz/path/to/repo.git/", "git://host.xz/path/to/repo.git/", "git@host.com:my-repo/example.git" }) + void isAbleToPrepare_returnsFalse_whenRemoteDataConfigurationIsNotSkopeo(String location) { + /* prepare */ + PrepareWrapperContext context = createContextWithRemoteDataConfig(location); + ReflectionTestUtils.setField(moduleToTest, "pdsPrepareModuleSkopeoEnabled", true); + + /* execute */ + boolean result = moduleToTest.isAbleToPrepare(context); + + /* test */ + assertFalse(result); + } + + @ParameterizedTest + @ValueSource(strings = { "ubuntu:22.04", "ubuntu", "docker://ubuntu:22.04", "docker://ubuntu", "oci:busybox_ocilayout:latest", "https://hub.docker.com", + "docker://docker.io/library/busybox:latest", "ubuntu@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d", + "ghcr.io/owner/repo:tag" }) + void isAbleToPrepare_returnsTrue_whenRemoteDataConfigurationIsSkopeo(String location) { + /* prepare */ + PrepareWrapperContext context = createContextWithRemoteDataConfig(location); + ReflectionTestUtils.setField(moduleToTest, "pdsPrepareModuleSkopeoEnabled", true); + + /* execute */ + boolean result = moduleToTest.isAbleToPrepare(context); + + /* test */ + assertTrue(result); + } + + @Test + void prepare_throws_exception_when_credentials_are_empty() { + /* prepare */ + PrepareWrapperContext context = createContextEmptyConfig(); + List remoteDataConfigurationList = new ArrayList<>(); + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); + remoteDataConfiguration.setCredentials(credentials); + remoteDataConfiguration.setLocation("my-example-location"); + remoteDataConfiguration.setType("docker"); + remoteDataConfigurationList.add(remoteDataConfiguration); + context.setRemoteDataConfigurationList(remoteDataConfigurationList); + + /* execute */ + IllegalStateException exception = assertThrows(IllegalStateException.class, () -> moduleToTest.prepare(context)); + + /* test */ + assertTrue(exception.getMessage().contains("Defined credentials have no credential")); + } + + @Test + void prepare_throws_exception_when_no_username_found() { + /* prepare */ + PrepareWrapperContext context = createContextEmptyConfig(); + List remoteDataConfigurationList = new ArrayList<>(); + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); + SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); + user.setPassword("my-example-password"); + credentials.setUser(user); + remoteDataConfiguration.setCredentials(credentials); + remoteDataConfiguration.setLocation("my-example-location"); + remoteDataConfiguration.setType("docker"); + remoteDataConfigurationList.add(remoteDataConfiguration); + context.setRemoteDataConfigurationList(remoteDataConfigurationList); + + /* execute */ + IllegalStateException exception = assertThrows(IllegalStateException.class, () -> moduleToTest.prepare(context)); + + /* test */ + assertTrue(exception.getMessage().contains("Defined username must not be null or empty.")); + } + + @Test + void prepare_throws_exception_when_no_password_found() { + /* prepare */ + PrepareWrapperContext context = createContextEmptyConfig(); + List remoteDataConfigurationList = new ArrayList<>(); + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); + SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); + user.setName("my-example-name"); + credentials.setUser(user); + remoteDataConfiguration.setCredentials(credentials); + remoteDataConfiguration.setLocation("my-example-location"); + remoteDataConfiguration.setType("git"); + remoteDataConfigurationList.add(remoteDataConfiguration); + context.setRemoteDataConfigurationList(remoteDataConfigurationList); + + /* execute */ + IllegalStateException exception = assertThrows(IllegalStateException.class, () -> moduleToTest.prepare(context)); + + /* test */ + assertTrue(exception.getMessage().contains("Defined password must not be null or empty.")); + } + + @Test + void prepare_successful_when_user_credentials_are_configured_correctly() throws IOException { + /* prepare */ + File tempDir = Files.createTempDirectory("upload-folder").toFile(); + tempDir.deleteOnExit(); + String filename = "testimage.tar"; + writer.save(new File(tempDir, filename), "some text", true); + + PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); + when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn(tempDir.toString()); + PrepareWrapperContext context = new PrepareWrapperContext(createFromJSON("{}"), environment); + + List remoteDataConfigurationList = new ArrayList<>(); + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); + SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); + user.setName("my-example-name"); + user.setPassword("ghp_exampleAPITOKEN8ffne3l6g9f393r8fbcsf"); + credentials.setUser(user); + remoteDataConfiguration.setCredentials(credentials); + remoteDataConfiguration.setLocation("my-example-location"); + remoteDataConfiguration.setType("docker"); + remoteDataConfigurationList.add(remoteDataConfiguration); + context.setRemoteDataConfigurationList(remoteDataConfigurationList); + + /* execute */ + moduleToTest.prepare(context); + + /* test */ + verify(skopeo).download(any(SkopeoContext.class)); + verify(skopeo).cleanUploadDirectory(tempDir.toString()); + } + + @Test + void prepare_successful_when_no_credentials_are_configured() throws IOException { + /* prepare */ + File tempDir = Files.createTempDirectory("upload-folder").toFile(); + tempDir.deleteOnExit(); + String filename = "testimage.tar"; + writer.save(new File(tempDir, filename), "some text", true); + + PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); + when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn(tempDir.toString()); + PrepareWrapperContext context = new PrepareWrapperContext(createFromJSON("{}"), environment); + + List remoteDataConfigurationList = new ArrayList<>(); + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); + user.setName("my-example-name"); + user.setPassword("ghp_exampleAPITOKEN8ffne3l6g9f393r8fbcsf"); + remoteDataConfiguration.setLocation("my-example-location"); + remoteDataConfiguration.setType("docker"); + remoteDataConfigurationList.add(remoteDataConfiguration); + context.setRemoteDataConfigurationList(remoteDataConfigurationList); + + /* execute */ + moduleToTest.prepare(context); + + /* test */ + verify(skopeo).download(any(SkopeoContext.class)); + verify(skopeo).cleanUploadDirectory(tempDir.toString()); + } + + @Test + void isDownloadSuccessful_returns_true_when_tar_file_in_directory() throws IOException { + /* prepare */ + File tempDir = Files.createTempDirectory("upload-folder").toFile(); + tempDir.deleteOnExit(); + String filename = "testimage.tar"; + PrepareWrapperContext context = mock(PrepareWrapperContext.class); + when(context.getEnvironment()).thenReturn(mock(PrepareWrapperEnvironment.class)); + writer.save(new File(tempDir, filename), "some text", true); + when(context.getEnvironment().getPdsPrepareUploadFolderDirectory()).thenReturn(tempDir.toString()); + + /* execute */ + boolean result = moduleToTest.isDownloadSuccessful(context); + + /* test */ + assertTrue(result); + } + + @Test + void isDownloadSuccessful_returns_false_when_no_tar_file_in_directory() throws IOException { + /* prepare */ + File tempDir = Files.createTempDirectory("upload-folder").toFile(); + tempDir.deleteOnExit(); + writer.save(tempDir, "some text", true); + PrepareWrapperContext context = mock(PrepareWrapperContext.class); + when(context.getEnvironment()).thenReturn(mock(PrepareWrapperEnvironment.class)); + when(context.getEnvironment().getPdsPrepareUploadFolderDirectory()).thenReturn(tempDir.toString()); + + /* execute */ + boolean result = moduleToTest.isDownloadSuccessful(context); + + /* test */ + assertFalse(result); + } + + @ParameterizedTest + @ValueSource(strings = { "docker", "DOCKER", "DockEr" }) + void isMatchingSkopeoType_returns_true_when_docker_is_configured(String type) { + /* execute */ + boolean result = moduleToTest.isMatchingSkopeoType(type); + + /* test */ + assertTrue(result); + } + + private PrepareWrapperContext createContextEmptyConfig() { + PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); + when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn("test-upload-folder"); + return new PrepareWrapperContext(createFromJSON("{}"), environment); + } + + private PrepareWrapperContext createContextWithRemoteDataConfig(String location) { + String json = """ + { + "apiVersion": "1.0", + "data": { + "sources": [ + { + "name": "remote_example_name", + "remote": { + "location": "$location", + "type": "docker" + } + } + ] + }, + "codeScan": { + "use": [ + "remote_example_name" + ] + } + } + """.replace("$location", location); + SecHubConfigurationModel model = createFromJSON(json); + PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); + PrepareWrapperRemoteConfigurationExtractor extractor = new PrepareWrapperRemoteConfigurationExtractor(); + List creds = extractor.extract(model); + when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn("test-upload-folder"); + PrepareWrapperContext context = new PrepareWrapperContext(model, environment); + context.setRemoteDataConfigurationList(creds); + return context; + } } \ No newline at end of file diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeoTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeoTest.java index da52f68de..d837079d3 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeoTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeoTest.java @@ -1,28 +1,96 @@ package com.mercedesbenz.sechub.wrapper.prepare.modules; +import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_PASSWORD; +import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_USERNAME; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import javax.crypto.SealedObject; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import com.mercedesbenz.sechub.commons.core.security.CryptoAccess; import com.mercedesbenz.sechub.commons.pds.PDSProcessAdapterFactory; +import com.mercedesbenz.sechub.commons.pds.ProcessAdapter; class WrapperSkopeoTest { WrapperSkopeo wrapperToTest; PDSProcessAdapterFactory processAdapterFactory; + ProcessAdapter processAdapter; + @BeforeEach - void beforeEach() throws IOException { + void beforeEach() throws IOException, InterruptedException { wrapperToTest = new WrapperSkopeo(); processAdapterFactory = mock(PDSProcessAdapterFactory.class); - doNothing().when(processAdapterFactory).startProcess(any()); + processAdapter = mock(ProcessAdapter.class); + when(processAdapterFactory.startProcess(any())).thenReturn(processAdapter); + when(processAdapter.waitFor(any(Long.class), any(TimeUnit.class))).thenReturn(true); wrapperToTest.processAdapterFactory = processAdapterFactory; } - // TODO: 07.05.24 laura add tests + @Test + void when_download_is_executed_download_process_is_executed() throws IOException { + /* prepare */ + SkopeoContext context = (SkopeoContext) new SkopeoContext.SkopeoContextBuilder().setLocation("docker://ubuntu:22.04").setUploadDirectory("folder") + .build(); + + /* execute */ + assertDoesNotThrow(() -> wrapperToTest.download(context)); + + /* test */ + verify(processAdapterFactory, times(1)).startProcess(any()); + } + + @Test + void when_download_is_executed_with_credentials_download_and_login_process_are_executed() throws IOException { + /* prepare */ + Map credentialMap = new HashMap(); + credentialMap.put(PDS_PREPARE_CREDENTIAL_USERNAME, CryptoAccess.CRYPTO_STRING.seal("username")); + credentialMap.put(PDS_PREPARE_CREDENTIAL_PASSWORD, CryptoAccess.CRYPTO_STRING.seal("password")); + SkopeoContext context = (SkopeoContext) new SkopeoContext.SkopeoContextBuilder().setLocation("docker://ubuntu:22.04").setUploadDirectory("folder") + .setCredentialMap(credentialMap).build(); + + /* execute */ + assertDoesNotThrow(() -> wrapperToTest.download(context)); + + /* test */ + verify(processAdapterFactory, times(2)).startProcess(any()); + } + + @Test + void when_process_throws_exception_then_download_throws_exception() throws IOException { + /* prepare */ + String location = "docker://ubuntu:22.04"; + SkopeoContext context = (SkopeoContext) new SkopeoContext.SkopeoContextBuilder().setLocation(location).setUploadDirectory("folder").build(); + when(processAdapterFactory.startProcess(any())).thenThrow(new IOException()); + + /* execute */ + IOException exception = assertThrows(IOException.class, () -> wrapperToTest.download(context)); + + /* test */ + assertEquals("Error while download with Skopeo from: " + location, exception.getMessage()); + + } + + @Test + void when_cleanUploadDirectory_is_executed_clean_process_is_executed() throws IOException { + /* prepare */ + String uploadDirectory = "folder"; + + /* execute */ + assertDoesNotThrow(() -> wrapperToTest.cleanUploadDirectory(uploadDirectory)); + + /* test */ + verify(processAdapterFactory, times(1)).startProcess(any()); + } } \ No newline at end of file diff --git a/sechub-wrapper-prepare/src/test/resources/application-test-fail.properties b/sechub-wrapper-prepare/src/test/resources/application-test-fail.properties index e0df022af..7876fb0f8 100644 --- a/sechub-wrapper-prepare/src/test/resources/application-test-fail.properties +++ b/sechub-wrapper-prepare/src/test/resources/application-test-fail.properties @@ -4,9 +4,10 @@ # --------------- sechub.job.uuid=665dc4e8-d2de-4d2f-a3a3-4c447630b229 -pds.scan.configuration={"projectId":"project1","data": {"binaries": [{"name": "remote_example_name","remote": {"location": "https://not-a-git.repo","type": "not-git"}}]},"codeScan": {"use": ["remote_example_name"]}} +pds.scan.configuration={"projectId":"project1","data": {"binaries": [{"name": "remote_example_name","remote": {"location": "https://not-any.repo/","type": "not-git"}}]},"codeScan": {"use": ["remote_example_name"]}} pds.job.user.messages.folder=./build/pds-prepare/tmp/messages pds.prepare.upload.directory=src/test/resources/test-upload-folder pds.prepare.auto.cleanup.git.folder=true pds.prepare.module.git.enabled=true +pds.prepare.module.skopeo.enabled=true pds.config.product.timeout.minutes=30 From ca593756d14a2841e6ef71e8f4a534739fdce719 Mon Sep 17 00:00:00 2001 From: Laura Date: Mon, 13 May 2024 09:24:36 +0200 Subject: [PATCH 03/19] Added comment for investigation on login failure #3028 --- .../prepare/modules/WrapperSkopeo.java | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeo.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeo.java index 0f7c0e991..4b4a33985 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeo.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeo.java @@ -66,26 +66,18 @@ private void login(SkopeoContext context) throws IOException { } private ProcessBuilder buildProcessLogin(SkopeoContext context) { - // skopeo login "$LOCATION" --username "$USERNAME" --password "$PASSWORD" - // --authfile "$PDS_JOB_WORKSPACE_LOCATION/$SKOPEO_AUTH" List commands = new ArrayList<>(); String location = transformLocationForLogin(context.getLocation()); File uploadDir = Paths.get(context.getUploadDirectory()).toAbsolutePath().toFile(); + // /bin/bash -c is needed to interpret the $USERNAME and $PASSWORD as + // environment variables commands.add("/bin/bash"); commands.add("-c"); commands.add("skopeo login " + location + " --username $" + PDS_PREPARE_CREDENTIAL_USERNAME + " --password $" + PDS_PREPARE_CREDENTIAL_PASSWORD + " --authfile " + pdsPrepareAuthenticationFileSkopeo); - /* - * commands.add("skopeo"); commands.add("login"); commands.add(location); - * commands.add("--username"); commands.add("$" + - * PDS_PREPARE_CREDENTIAL_USERNAME); commands.add("--password"); - * commands.add("$" + PDS_PREPARE_CREDENTIAL_PASSWORD); - * commands.add("--authfile"); commands.add(pdsPrepareAuthenticationFileSkopeo); - */ - ProcessBuilder builder = new ProcessBuilder(commands); builder.directory(uploadDir); builder.inheritIO(); @@ -94,22 +86,11 @@ private ProcessBuilder buildProcessLogin(SkopeoContext context) { } private ProcessBuilder buildProcessDownload(SkopeoContext context) { - // skopeo copy docker://$LOCATION - // docker-archive:$PDS_JOB_WORKSPACE_LOCATION/$PDS_PREPARE_UPLOAD_FOLDER List commands = new ArrayList<>(); String location = transformLocationForDownload(context.getLocation()); File uploadDir = Paths.get(context.getUploadDirectory()).toAbsolutePath().toFile(); - /* - * commands.add("/bin/bash"); commands.add("-c"); if - * (!context.getCredentialMap().isEmpty()){ commands.add("skopeo copy " + - * location + " docker-archive:" + context.getFilename()); }else{ - * commands.add("skopeo copy " + location + " docker-archive:" + - * context.getFilename() + " --authfile " + pdsPrepareAuthenticationFileSkopeo); - * } - */ - commands.add("skopeo"); commands.add("copy"); commands.add(location); From 275ff5401e1273789025b8143245003f81ddc4af Mon Sep 17 00:00:00 2001 From: Jan Winz Date: Fri, 17 May 2024 07:58:13 +0200 Subject: [PATCH 04/19] Enlarge project_id database field #3102 --- .../db/migration/U28__enlarge_project_id.sql | 24 +++++++++++++++++++ .../db/migration/V28__enlarge_project_id.sql | 22 +++++++++++++++++ .../validation/ProjectIdValidationImpl.java | 2 +- .../ProjectIdValidationImplTest.java | 6 ++--- 4 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 sechub-server/src/main/resources/db/migration/U28__enlarge_project_id.sql create mode 100644 sechub-server/src/main/resources/db/migration/V28__enlarge_project_id.sql diff --git a/sechub-server/src/main/resources/db/migration/U28__enlarge_project_id.sql b/sechub-server/src/main/resources/db/migration/U28__enlarge_project_id.sql new file mode 100644 index 000000000..890de902e --- /dev/null +++ b/sechub-server/src/main/resources/db/migration/U28__enlarge_project_id.sql @@ -0,0 +1,24 @@ +-- SPDX-License-Identifier: MIT + +-- we switch project_id size back to old 120 (3x40) +-- If this is not possible because already added bigger data, database shall give us an error, +-- so we know we have to migrate those data manually... +ALTER TABLE adm_project ALTER COLUMN project_id TYPE varchar(120); +ALTER TABLE scan_report ALTER COLUMN project_id TYPE varchar(120); +ALTER TABLE scan_access ALTER COLUMN project_id TYPE varchar(120); +ALTER TABLE schedule_access ALTER COLUMN project_id TYPE varchar(120); +ALTER TABLE schedule_project_whitelist ALTER COLUMN project_id TYPE varchar(120); +ALTER TABLE schedule_sechub_job ALTER COLUMN project_id TYPE varchar(120); +ALTER TABLE scan_project_log ALTER COLUMN project_id TYPE varchar(120); +ALTER TABLE adm_job_information ALTER COLUMN project_id TYPE varchar(120); +ALTER TABLE scan_product_result ALTER COLUMN project_id TYPE varchar(120); +ALTER TABLE scan_project_config ALTER COLUMN project_id TYPE varchar(120); +ALTER TABLE adm_project_metadata ALTER COLUMN project_id TYPE varchar(120); +ALTER TABLE schedule_project_config ALTER COLUMN project_id TYPE varchar(120); +ALTER TABLE statistic_job ALTER COLUMN project_id TYPE varchar(120); +ALTER TABLE statistic_job_run ALTER COLUMN project_id TYPE varchar(120); + +ALTER TABLE adm_project_whitelist_uri ALTER COLUMN project_project_id TYPE varchar(120); + +ALTER TABLE adm_project_to_user ALTER COLUMN projects_project_id TYPE varchar(120); +ALTER TABLE scan_execution_profile_to_project ALTER COLUMN projects_project_id TYPE varchar(120); \ No newline at end of file diff --git a/sechub-server/src/main/resources/db/migration/V28__enlarge_project_id.sql b/sechub-server/src/main/resources/db/migration/V28__enlarge_project_id.sql new file mode 100644 index 000000000..eb2b925d7 --- /dev/null +++ b/sechub-server/src/main/resources/db/migration/V28__enlarge_project_id.sql @@ -0,0 +1,22 @@ +-- SPDX-License-Identifier: MIT + +-- Update project id : we now accept 765 (3 x 255) see ProjectIdValidation +ALTER TABLE adm_project ALTER COLUMN project_id TYPE varchar(765); +ALTER TABLE scan_report ALTER COLUMN project_id TYPE varchar(765); +ALTER TABLE scan_access ALTER COLUMN project_id TYPE varchar(765); +ALTER TABLE schedule_access ALTER COLUMN project_id TYPE varchar(765); +ALTER TABLE schedule_project_whitelist ALTER COLUMN project_id TYPE varchar(765); +ALTER TABLE schedule_sechub_job ALTER COLUMN project_id TYPE varchar(765); +ALTER TABLE scan_project_log ALTER COLUMN project_id TYPE varchar(765); +ALTER TABLE adm_job_information ALTER COLUMN project_id TYPE varchar(765); +ALTER TABLE scan_product_result ALTER COLUMN project_id TYPE varchar(765); +ALTER TABLE scan_project_config ALTER COLUMN project_id TYPE varchar(765); +ALTER TABLE adm_project_metadata ALTER COLUMN project_id TYPE varchar(765); +ALTER TABLE schedule_project_config ALTER COLUMN project_id TYPE varchar(765); +ALTER TABLE statistic_job ALTER COLUMN project_id TYPE varchar(765); +ALTER TABLE statistic_job_run ALTER COLUMN project_id TYPE varchar(765); + +ALTER TABLE adm_project_whitelist_uri ALTER COLUMN project_project_id TYPE varchar(765); + +ALTER TABLE adm_project_to_user ALTER COLUMN projects_project_id TYPE varchar(765); +ALTER TABLE scan_execution_profile_to_project ALTER COLUMN projects_project_id TYPE varchar(765); \ No newline at end of file diff --git a/sechub-shared-kernel/src/main/java/com/mercedesbenz/sechub/sharedkernel/validation/ProjectIdValidationImpl.java b/sechub-shared-kernel/src/main/java/com/mercedesbenz/sechub/sharedkernel/validation/ProjectIdValidationImpl.java index 1171f2a84..49c23cc56 100644 --- a/sechub-shared-kernel/src/main/java/com/mercedesbenz/sechub/sharedkernel/validation/ProjectIdValidationImpl.java +++ b/sechub-shared-kernel/src/main/java/com/mercedesbenz/sechub/sharedkernel/validation/ProjectIdValidationImpl.java @@ -7,7 +7,7 @@ public class ProjectIdValidationImpl extends AbstractSimpleStringValidation implements ProjectIdValidation { public static final int PROJECTID_LENGTH_MIN = 2; - public static final int PROJECTID_LENGTH_MAX = 40; + public static final int PROJECTID_LENGTH_MAX = 255; @Override protected void setup(ValidationConfig config) { diff --git a/sechub-shared-kernel/src/test/java/com/mercedesbenz/sechub/sharedkernel/validation/ProjectIdValidationImplTest.java b/sechub-shared-kernel/src/test/java/com/mercedesbenz/sechub/sharedkernel/validation/ProjectIdValidationImplTest.java index 4b44c0f5c..58ce54ba6 100644 --- a/sechub-shared-kernel/src/test/java/com/mercedesbenz/sechub/sharedkernel/validation/ProjectIdValidationImplTest.java +++ b/sechub-shared-kernel/src/test/java/com/mercedesbenz/sechub/sharedkernel/validation/ProjectIdValidationImplTest.java @@ -12,10 +12,10 @@ public class ProjectIdValidationImplTest { private ProjectIdValidationImpl validationToTest = new ProjectIdValidationImpl(); - private static final String VALID_PROJECT_ID_WITH_40_CHARS = "a2345678901234567890b2345678901234567890"; + private static final String VALID_PROJECT_ID_WITH_255_CHARS = "a0123456789b0123456789c0123456789d0123456789e0123456789f0123456789g0123456789h0123456789i0123456789j0123456789k0123456789l0123456789m0123456789n0123456789o0123456789p0123456789q0123456789r0123456789s0123456789t0123456789u0123456789v0123456789w0123456789yz"; @ParameterizedTest - @ValueSource(strings = { "a2", "i-am-with-hyphens", "i_am_with_underscore", VALID_PROJECT_ID_WITH_40_CHARS }) + @ValueSource(strings = { "a2", "i-am-with-hyphens", "i_am_with_underscore", VALID_PROJECT_ID_WITH_255_CHARS }) void valid_projectIds(String projectId) { /* execute */ ValidationResult validationResult = validationToTest.validate(projectId); @@ -30,7 +30,7 @@ void valid_projectIds(String projectId) { @NullSource @EmptySource @ValueSource(strings = { "a", "i.am.with.dot", "i-am/slashy", "with\\backslash", "percent%", "dollar$", "question?", "colon:", "exclamationmark!", - VALID_PROJECT_ID_WITH_40_CHARS + "x" }) + VALID_PROJECT_ID_WITH_255_CHARS + "x" }) void invalid_projectIds(String projectId) { /* execute */ ValidationResult validationResult = validationToTest.validate(projectId); From fed1767c3de18c6106565e84b7e1c6671ccbf87d Mon Sep 17 00:00:00 2001 From: Laura Date: Thu, 16 May 2024 16:48:58 +0200 Subject: [PATCH 05/19] Added change requests --- .../prepare/modules/PrepareWrapperModule.java | 25 ++++++++++++++- .../wrapper/prepare/modules/WrapperTool.java | 21 +++--------- .../prepare/modules/{ => git}/GitContext.java | 4 ++- .../modules/{ => git}/GitInputValidator.java | 3 +- .../modules/{ => git}/JGitAdapter.java | 2 +- .../{ => git}/PrepareWrapperModuleGit.java | 29 ++++------------- .../prepare/modules/{ => git}/WrapperGit.java | 3 +- .../PrepareWrapperModuleSkopeo.java | 32 +++++-------------- .../modules/{ => skopeo}/SkopeoContext.java | 6 ++-- .../{ => skopeo}/SkopeoInputValidator.java | 3 +- .../modules/{ => skopeo}/WrapperSkopeo.java | 30 +++++++++-------- .../PrepareWrapperPreparationService.java | 1 + ...epareWrapperApplicationSpringBootTest.java | 7 ++++ .../{ => git}/GitInputValidatorTest.java | 4 ++- .../PrepareWrapperModuleGitTest.java | 8 +++-- .../modules/{ => git}/WrapperGitTest.java | 5 ++- .../PrepareWrapperModuleSkopeoTest.java | 13 ++++---- .../SkopeoInputValidatorTest.java | 3 +- .../{ => skopeo}/WrapperSkopeoTest.java | 4 ++- .../PrepareWrapperPreparationServiceTest.java | 2 +- 20 files changed, 106 insertions(+), 99 deletions(-) rename sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/{ => git}/GitContext.java (85%) rename sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/{ => git}/GitInputValidator.java (95%) rename sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/{ => git}/JGitAdapter.java (98%) rename sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/{ => git}/PrepareWrapperModuleGit.java (86%) rename sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/{ => git}/WrapperGit.java (93%) rename sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/{ => skopeo}/PrepareWrapperModuleSkopeo.java (85%) rename sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/{ => skopeo}/SkopeoContext.java (81%) rename sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/{ => skopeo}/SkopeoInputValidator.java (95%) rename sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/{ => skopeo}/WrapperSkopeo.java (82%) rename sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/{ => git}/GitInputValidatorTest.java (95%) rename sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/{ => git}/PrepareWrapperModuleGitTest.java (96%) rename sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/{ => git}/WrapperGitTest.java (93%) rename sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/{ => skopeo}/PrepareWrapperModuleSkopeoTest.java (96%) rename sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/{ => skopeo}/SkopeoInputValidatorTest.java (95%) rename sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/{ => skopeo}/WrapperSkopeoTest.java (94%) diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModule.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModule.java index 3109d9b0a..2fc0e4f2d 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModule.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModule.java @@ -2,16 +2,39 @@ package com.mercedesbenz.sechub.wrapper.prepare.modules; import java.io.IOException; +import java.util.HashMap; +import com.mercedesbenz.sechub.commons.core.security.CryptoAccess; +import com.mercedesbenz.sechub.commons.model.SecHubRemoteCredentialUserData; import org.springframework.stereotype.Service; import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperContext; +import javax.crypto.SealedObject; + +import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_PASSWORD; +import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_USERNAME; + @Service public interface PrepareWrapperModule { - boolean isAbleToPrepare(PrepareWrapperContext context); + public boolean isAbleToPrepare(PrepareWrapperContext context); void prepare(PrepareWrapperContext context) throws IOException; + default boolean isTypeConfigured(String type) { + return type != null && !type.isBlank(); + } + + default void addSealedUserCredentials(SecHubRemoteCredentialUserData user, HashMap credentialMap) { + SealedObject sealedUsername = CryptoAccess.CRYPTO_STRING.seal(user.getName()); + SealedObject sealedPassword = CryptoAccess.CRYPTO_STRING.seal(user.getPassword()); + credentialMap.put(PDS_PREPARE_CREDENTIAL_USERNAME, sealedUsername); + credentialMap.put(PDS_PREPARE_CREDENTIAL_PASSWORD, sealedPassword); + } + + default boolean isMatchingType(String type, String expectedType) { + return expectedType.equalsIgnoreCase(type); + } + } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperTool.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperTool.java index 6a132b092..178274535 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperTool.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperTool.java @@ -21,7 +21,7 @@ import com.mercedesbenz.sechub.commons.pds.ProcessAdapter; @Component -abstract class WrapperTool { +public abstract class WrapperTool { private static final Logger LOG = LoggerFactory.getLogger(WrapperTool.class); private static final int defaultMinutesToWaitForProduct = PDSDefaultParameterValueConstants.DEFAULT_MINUTES_TO_WAIT_FOR_PRODUCT; @@ -33,11 +33,11 @@ abstract class WrapperTool { private int pdsPrepareProcessTimeoutSeconds; @Autowired - PDSProcessAdapterFactory processAdapterFactory; + public PDSProcessAdapterFactory processAdapterFactory; - abstract void cleanUploadDirectory(String uploadDirectory) throws IOException; + protected abstract void cleanUploadDirectory(String uploadDirectory) throws IOException; - void waitForProcessToFinish(ProcessAdapter process) { + protected void waitForProcessToFinish(ProcessAdapter process) { LOG.debug("Wait for wrapper to finish process."); int seconds = calculateTimeoutSeconds(); @@ -60,19 +60,6 @@ void waitForProcessToFinish(ProcessAdapter process) { } } - void exportEnvironmentVariables(ProcessBuilder builder, Map credentialMap) throws IOException { - Map environment = builder.environment(); - if (credentialMap != null && !credentialMap.isEmpty()) { - for (Map.Entry entry : credentialMap.entrySet()) { - try { - environment.put(entry.getKey(), CryptoAccess.CRYPTO_STRING.unseal(entry.getValue())); - } catch (Exception e) { - throw new IOException("Error while unsealing credential: " + entry.getKey(), e); - } - } - } - } - private int calculateTimeoutSeconds() { int pdsProductTimeoutInSeconds = pdsProductTimeoutMinutes * 60; diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/GitContext.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitContext.java similarity index 85% rename from sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/GitContext.java rename to sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitContext.java index b8564988e..643278c0c 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/GitContext.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitContext.java @@ -1,4 +1,6 @@ -package com.mercedesbenz.sechub.wrapper.prepare.modules; +package com.mercedesbenz.sechub.wrapper.prepare.modules.git; + +import com.mercedesbenz.sechub.wrapper.prepare.modules.ToolContext; public class GitContext extends ToolContext { private boolean cloneWithoutHistory; diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/GitInputValidator.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidator.java similarity index 95% rename from sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/GitInputValidator.java rename to sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidator.java index f7d65a3dd..0d9e1f124 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/GitInputValidator.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidator.java @@ -1,9 +1,10 @@ -package com.mercedesbenz.sechub.wrapper.prepare.modules; +package com.mercedesbenz.sechub.wrapper.prepare.modules.git; import java.util.Arrays; import java.util.List; import java.util.regex.Pattern; +import com.mercedesbenz.sechub.wrapper.prepare.modules.InputValidator; import org.springframework.stereotype.Component; @Component diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/JGitAdapter.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/JGitAdapter.java similarity index 98% rename from sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/JGitAdapter.java rename to sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/JGitAdapter.java index 219436a65..9b271438f 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/JGitAdapter.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/JGitAdapter.java @@ -1,4 +1,4 @@ -package com.mercedesbenz.sechub.wrapper.prepare.modules; +package com.mercedesbenz.sechub.wrapper.prepare.modules.git; import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_PASSWORD; import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_USERNAME; diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGit.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGit.java similarity index 86% rename from sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGit.java rename to sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGit.java index 86d1aadbc..1fff14be0 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGit.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGit.java @@ -1,4 +1,4 @@ -package com.mercedesbenz.sechub.wrapper.prepare.modules; +package com.mercedesbenz.sechub.wrapper.prepare.modules.git; import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.*; import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperKeyConstants.KEY_PDS_PREPARE_AUTO_CLEANUP_GIT_FOLDER; @@ -12,6 +12,7 @@ import javax.crypto.SealedObject; +import com.mercedesbenz.sechub.wrapper.prepare.modules.PrepareWrapperModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -54,7 +55,7 @@ public boolean isAbleToPrepare(PrepareWrapperContext context) { gitInputValidator.validateLocationCharacters(location, null); - if (isMatchingGitType(type)) { + if (isMatchingType(type, TYPE)) { LOG.debug("Type is git"); if (!gitInputValidator.validateLocation(location)) { context.getUserMessages().add(new SecHubMessage(SecHubMessageType.WARNING, "Type is git but location does not match git URL pattern")); @@ -64,7 +65,7 @@ public boolean isAbleToPrepare(PrepareWrapperContext context) { return true; } - if (!isTypeNullOrEmpty(type)) { + if (isTypeConfigured(type)) { // type was explicitly defined but is not matching return false; } @@ -94,14 +95,7 @@ public void prepare(PrepareWrapperContext context) throws IOException { cleanup(context); } - boolean isMatchingGitType(String type) { - if (type == null || type.isBlank()) { - return false; - } - return TYPE.equalsIgnoreCase(type); - } - - boolean isDownloadSuccessful(PrepareWrapperContext context) { + public boolean isDownloadSuccessful(PrepareWrapperContext context) { // check if download folder contains git Path path = Paths.get(context.getEnvironment().getPdsPrepareUploadFolderDirectory()); if (Files.isDirectory(path)) { @@ -112,15 +106,11 @@ boolean isDownloadSuccessful(PrepareWrapperContext context) { return false; } - private boolean isTypeNullOrEmpty(String type) { - return type == null || type.isBlank(); - } - private void prepareRemoteConfiguration(PrepareWrapperContext context, SecHubRemoteDataConfiguration secHubRemoteDataConfiguration) throws IOException { String location = secHubRemoteDataConfiguration.getLocation(); Optional credentials = secHubRemoteDataConfiguration.getCredentials(); - if (!credentials.isPresent()) { + if (credentials.isEmpty()) { clonePublicRepository(context, location); return; } @@ -156,13 +146,6 @@ private void clonePrivateRepository(PrepareWrapperContext context, SecHubRemoteC context.getUserMessages().add(message); } - private static void addSealedUserCredentials(SecHubRemoteCredentialUserData user, HashMap credentialMap) { - SealedObject sealedUsername = CryptoAccess.CRYPTO_STRING.seal(user.getName()); - SealedObject sealedPassword = CryptoAccess.CRYPTO_STRING.seal(user.getPassword()); - credentialMap.put(PDS_PREPARE_CREDENTIAL_USERNAME, sealedUsername); - credentialMap.put(PDS_PREPARE_CREDENTIAL_PASSWORD, sealedPassword); - } - private void assertUserCredentials(SecHubRemoteCredentialUserData user) { gitInputValidator.validateUsername(user.getName()); gitInputValidator.validatePassword(user.getPassword()); diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperGit.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGit.java similarity index 93% rename from sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperGit.java rename to sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGit.java index bf0238127..25c58fadb 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperGit.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGit.java @@ -1,4 +1,4 @@ -package com.mercedesbenz.sechub.wrapper.prepare.modules; +package com.mercedesbenz.sechub.wrapper.prepare.modules.git; import java.io.File; import java.io.IOException; @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.List; +import com.mercedesbenz.sechub.wrapper.prepare.modules.WrapperTool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeo.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeo.java similarity index 85% rename from sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeo.java rename to sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeo.java index 22e637564..5c4772eb2 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeo.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeo.java @@ -1,4 +1,4 @@ -package com.mercedesbenz.sechub.wrapper.prepare.modules; +package com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo; import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_PASSWORD; import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_USERNAME; @@ -15,6 +15,7 @@ import javax.crypto.SealedObject; +import com.mercedesbenz.sechub.wrapper.prepare.modules.PrepareWrapperModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -55,17 +56,17 @@ public boolean isAbleToPrepare(PrepareWrapperContext context) { skopeoInputValidator.validateLocationCharacters(location, null); - if (isMatchingSkopeoType(type)) { + if (isMatchingType(type, TYPE)) { LOG.debug("Type is: " + TYPE); if (!skopeoInputValidator.validateLocation(location)) { context.getUserMessages().add(new SecHubMessage(SecHubMessageType.WARNING, "Type is " + TYPE + " but location does not match URL pattern")); - LOG.warn("User defined type as " + TYPE + ", but the defined location was not a valid location: {}", location); + LOG.warn("User defined type as {}, but the defined location was not a valid location: {}", TYPE, location); return false; } return true; } - if (!isTypeNullOrEmpty(type)) { + if (isTypeConfigured(type)) { // type was explicitly defined but is not matching return false; } @@ -85,6 +86,7 @@ public void prepare(PrepareWrapperContext context) throws IOException { List remoteDataConfigurationList = context.getRemoteDataConfigurationList(); for (SecHubRemoteDataConfiguration secHubRemoteDataConfiguration : remoteDataConfigurationList) { + // TODO: 16.05.24 laura isabletoprepare prepareRemoteConfiguration(context, secHubRemoteDataConfiguration); } @@ -94,7 +96,7 @@ public void prepare(PrepareWrapperContext context) throws IOException { cleanup(context); } - boolean isDownloadSuccessful(PrepareWrapperContext context) { + public boolean isDownloadSuccessful(PrepareWrapperContext context) { // check if download folder contains a .tar archive Path path = Paths.get(context.getEnvironment().getPdsPrepareUploadFolderDirectory()); if (Files.isDirectory(path)) { @@ -111,17 +113,6 @@ boolean isDownloadSuccessful(PrepareWrapperContext context) { return false; } - boolean isMatchingSkopeoType(String type) { - if (type == null || type.isBlank()) { - return false; - } - return TYPE.equalsIgnoreCase(type); - } - - private boolean isTypeNullOrEmpty(String type) { - return type == null || type.isBlank(); - } - private void cleanup(PrepareWrapperContext context) throws IOException { skopeo.cleanUploadDirectory(context.getEnvironment().getPdsPrepareUploadFolderDirectory()); } @@ -130,7 +121,7 @@ private void prepareRemoteConfiguration(PrepareWrapperContext context, SecHubRem String location = secHubRemoteDataConfiguration.getLocation(); Optional credentials = secHubRemoteDataConfiguration.getCredentials(); - if (!credentials.isPresent()) { + if (credentials.isEmpty()) { downloadPublicImage(context, location); return; } @@ -165,13 +156,6 @@ private void downloadPrivateImage(PrepareWrapperContext context, SecHubRemoteCre context.getUserMessages().add(message); } - private static void addSealedUserCredentials(SecHubRemoteCredentialUserData user, HashMap credentialMap) { - SealedObject sealedUsername = CryptoAccess.CRYPTO_STRING.seal(user.getName()); - SealedObject sealedPassword = CryptoAccess.CRYPTO_STRING.seal(user.getPassword()); - credentialMap.put(PDS_PREPARE_CREDENTIAL_USERNAME, sealedUsername); - credentialMap.put(PDS_PREPARE_CREDENTIAL_PASSWORD, sealedPassword); - } - private void assertUserCredentials(SecHubRemoteCredentialUserData user) { skopeoInputValidator.validateUsername(user.getName()); skopeoInputValidator.validatePassword(user.getPassword()); diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoContext.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoContext.java similarity index 81% rename from sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoContext.java rename to sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoContext.java index 34b8aefdc..4a392ef92 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoContext.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoContext.java @@ -1,4 +1,6 @@ -package com.mercedesbenz.sechub.wrapper.prepare.modules; +package com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo; + +import com.mercedesbenz.sechub.wrapper.prepare.modules.ToolContext; public class SkopeoContext extends ToolContext { @@ -22,7 +24,7 @@ public SkopeoContext build() { return new SkopeoContext(this); } - public SkopeoContextBuilder filename(String filename) { + public SkopeoContextBuilder setFilename(String filename) { if (filename == null || filename.isBlank()) { return this; } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidator.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidator.java similarity index 95% rename from sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidator.java rename to sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidator.java index e0c8a8711..9efac0cc0 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidator.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidator.java @@ -1,9 +1,10 @@ -package com.mercedesbenz.sechub.wrapper.prepare.modules; +package com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo; import java.util.Arrays; import java.util.List; import java.util.regex.Pattern; +import com.mercedesbenz.sechub.wrapper.prepare.modules.InputValidator; import org.springframework.stereotype.Component; @Component diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeo.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeo.java similarity index 82% rename from sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeo.java rename to sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeo.java index 4b4a33985..68dec54d1 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeo.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeo.java @@ -1,4 +1,4 @@ -package com.mercedesbenz.sechub.wrapper.prepare.modules; +package com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo; import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.*; import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperKeyConstants.KEY_PDS_PREPARE_AUTHENTICATION_FILE_SKOPEO; @@ -9,6 +9,8 @@ import java.util.ArrayList; import java.util.List; +import com.mercedesbenz.sechub.commons.core.security.CryptoAccess; +import com.mercedesbenz.sechub.wrapper.prepare.modules.WrapperTool; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -20,7 +22,7 @@ public class WrapperSkopeo extends WrapperTool { @Value("${" + KEY_PDS_PREPARE_AUTHENTICATION_FILE_SKOPEO + ":authentication.json}") String pdsPrepareAuthenticationFileSkopeo; - void download(SkopeoContext context) throws IOException { + public void download(SkopeoContext context) throws IOException { if (!context.getCredentialMap().isEmpty()) { login(context); } @@ -38,7 +40,7 @@ void download(SkopeoContext context) throws IOException { } @Override - void cleanUploadDirectory(String uploadDirectory) throws IOException { + public void cleanUploadDirectory(String uploadDirectory) throws IOException { ProcessBuilder builder = buildProcessClean(uploadDirectory); ProcessAdapter process = null; @@ -53,7 +55,6 @@ void cleanUploadDirectory(String uploadDirectory) throws IOException { private void login(SkopeoContext context) throws IOException { ProcessBuilder builder = buildProcessLogin(context); - exportEnvironmentVariables(builder, context.getCredentialMap()); ProcessAdapter process = null; try { @@ -71,12 +72,15 @@ private ProcessBuilder buildProcessLogin(SkopeoContext context) { String location = transformLocationForLogin(context.getLocation()); File uploadDir = Paths.get(context.getUploadDirectory()).toAbsolutePath().toFile(); - // /bin/bash -c is needed to interpret the $USERNAME and $PASSWORD as - // environment variables - commands.add("/bin/bash"); - commands.add("-c"); - commands.add("skopeo login " + location + " --username $" + PDS_PREPARE_CREDENTIAL_USERNAME + " --password $" + PDS_PREPARE_CREDENTIAL_PASSWORD - + " --authfile " + pdsPrepareAuthenticationFileSkopeo); + commands.add("skopeo"); + commands.add("login"); + commands.add(location); + commands.add("--username"); + commands.add(CryptoAccess.CRYPTO_STRING.unseal(context.getCredentialMap().get(PDS_PREPARE_CREDENTIAL_USERNAME))); + commands.add("--password"); + commands.add(CryptoAccess.CRYPTO_STRING.unseal(context.getCredentialMap().get(PDS_PREPARE_CREDENTIAL_PASSWORD))); + commands.add("--authfile"); + commands.add(pdsPrepareAuthenticationFileSkopeo); ProcessBuilder builder = new ProcessBuilder(commands); builder.directory(uploadDir); @@ -113,9 +117,9 @@ private ProcessBuilder buildProcessClean(String pdsPrepareUploadFolderDirectory) File uploadDir = Paths.get(pdsPrepareUploadFolderDirectory).toAbsolutePath().toFile(); - commands.add("/bin/bash"); - commands.add("-c"); - commands.add("rm -rf " + pdsPrepareAuthenticationFileSkopeo); + commands.add("rm"); + commands.add("-rf"); + commands.add(pdsPrepareAuthenticationFileSkopeo); ProcessBuilder builder = new ProcessBuilder(commands); builder.directory(uploadDir); diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java index 7095f46f0..e9d8fd33d 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java @@ -45,6 +45,7 @@ public AdapterExecutionResult startPreparation() throws IOException { return createAdapterExecutionResult(PrepareStatus.OK, SecHubMessageType.WARNING, "No Remote Configuration found."); } + // TODO: 16.05.24 laura for each schleife hier und in modulen raus? nur eins möglich? for (PrepareWrapperModule module : modules) { if (!module.isAbleToPrepare(context)) { continue; diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/PrepareWrapperApplicationSpringBootTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/PrepareWrapperApplicationSpringBootTest.java index 0febd7dec..3898504ae 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/PrepareWrapperApplicationSpringBootTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/PrepareWrapperApplicationSpringBootTest.java @@ -5,6 +5,13 @@ import java.io.IOException; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.GitInputValidator; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.JGitAdapter; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.PrepareWrapperModuleGit; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.WrapperGit; +import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.PrepareWrapperModuleSkopeo; +import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.SkopeoInputValidator; +import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.WrapperSkopeo; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/GitInputValidatorTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidatorTest.java similarity index 95% rename from sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/GitInputValidatorTest.java rename to sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidatorTest.java index 3267a81ea..b0b5942a7 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/GitInputValidatorTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidatorTest.java @@ -1,7 +1,9 @@ -package com.mercedesbenz.sechub.wrapper.prepare.modules; +package com.mercedesbenz.sechub.wrapper.prepare.modules.git; import static org.junit.jupiter.api.Assertions.*; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.GitInputValidator; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.PrepareWrapperModuleGit; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGitTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java similarity index 96% rename from sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGitTest.java rename to sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java index fa5fb0b42..4ed166a27 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleGitTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java @@ -1,4 +1,4 @@ -package com.mercedesbenz.sechub.wrapper.prepare.modules; +package com.mercedesbenz.sechub.wrapper.prepare.modules.git; import static com.mercedesbenz.sechub.commons.model.SecHubScanConfiguration.createFromJSON; import static org.junit.jupiter.api.Assertions.*; @@ -10,6 +10,10 @@ import java.util.ArrayList; import java.util.List; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.GitContext; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.GitInputValidator; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.PrepareWrapperModuleGit; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.WrapperGit; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -300,7 +304,7 @@ void isDownloadSuccessful_returns_false_when_no_git_file_in_directory() throws I @ValueSource(strings = { "git", "GIT", "gIT" }) void isMatchingGitType_returns_true_when_git_is_configured(String type) { /* execute */ - boolean result = moduleToTest.isMatchingGitType(type); + boolean result = moduleToTest.isMatchingType(type, "git"); /* test */ assertTrue(result); diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperGitTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGitTest.java similarity index 93% rename from sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperGitTest.java rename to sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGitTest.java index a9d41fd89..8f7121faf 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperGitTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGitTest.java @@ -1,4 +1,4 @@ -package com.mercedesbenz.sechub.wrapper.prepare.modules; +package com.mercedesbenz.sechub.wrapper.prepare.modules.git; import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_PASSWORD; import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_USERNAME; @@ -13,6 +13,9 @@ import javax.crypto.SealedObject; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.GitContext; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.JGitAdapter; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.WrapperGit; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeoTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java similarity index 96% rename from sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeoTest.java rename to sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java index f1ae97770..6e00b176d 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModuleSkopeoTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java @@ -1,4 +1,4 @@ -package com.mercedesbenz.sechub.wrapper.prepare.modules; +package com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo; import static com.mercedesbenz.sechub.commons.model.SecHubScanConfiguration.createFromJSON; import static org.junit.jupiter.api.Assertions.*; @@ -11,6 +11,10 @@ import java.util.ArrayList; import java.util.List; +import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.PrepareWrapperModuleSkopeo; +import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.SkopeoContext; +import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.SkopeoInputValidator; +import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.WrapperSkopeo; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -45,8 +49,6 @@ void beforeEach() { moduleToTest.skopeo = skopeo; } - // TODO: 07.05.24 laura add tests - @ParameterizedTest @ValueSource(strings = { "ubuntu:22.04", "ubuntu", "docker://ubuntu:22.04", "docker://ubuntu", "oci:busybox_ocilayout:latest", "https://hub.docker.com", "docker://docker.io/library/busybox:latest", "ubuntu@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d", @@ -219,9 +221,6 @@ void prepare_successful_when_no_credentials_are_configured() throws IOException List remoteDataConfigurationList = new ArrayList<>(); SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); - SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); - user.setName("my-example-name"); - user.setPassword("ghp_exampleAPITOKEN8ffne3l6g9f393r8fbcsf"); remoteDataConfiguration.setLocation("my-example-location"); remoteDataConfiguration.setType("docker"); remoteDataConfigurationList.add(remoteDataConfiguration); @@ -274,7 +273,7 @@ void isDownloadSuccessful_returns_false_when_no_tar_file_in_directory() throws I @ValueSource(strings = { "docker", "DOCKER", "DockEr" }) void isMatchingSkopeoType_returns_true_when_docker_is_configured(String type) { /* execute */ - boolean result = moduleToTest.isMatchingSkopeoType(type); + boolean result = moduleToTest.isMatchingType(type, "docker"); /* test */ assertTrue(result); diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidatorTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java similarity index 95% rename from sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidatorTest.java rename to sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java index e2e7a91b8..9ba603c5c 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/SkopeoInputValidatorTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java @@ -1,7 +1,8 @@ -package com.mercedesbenz.sechub.wrapper.prepare.modules; +package com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo; import static org.junit.jupiter.api.Assertions.*; +import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.SkopeoInputValidator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeoTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeoTest.java similarity index 94% rename from sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeoTest.java rename to sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeoTest.java index d837079d3..14b29087f 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperSkopeoTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeoTest.java @@ -1,4 +1,4 @@ -package com.mercedesbenz.sechub.wrapper.prepare.modules; +package com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo; import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_PASSWORD; import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_USERNAME; @@ -12,6 +12,8 @@ import javax.crypto.SealedObject; +import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.SkopeoContext; +import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.WrapperSkopeo; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationServiceTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationServiceTest.java index 474cfe0ba..d443bf8fb 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationServiceTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationServiceTest.java @@ -14,7 +14,7 @@ import com.mercedesbenz.sechub.adapter.AdapterExecutionResult; import com.mercedesbenz.sechub.commons.model.SecHubRemoteDataConfiguration; import com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironment; -import com.mercedesbenz.sechub.wrapper.prepare.modules.PrepareWrapperModuleGit; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.PrepareWrapperModuleGit; class PrepareWrapperPreparationServiceTest { From 9456f8aebb8da1bb3bd67ee20cff159162ab2135 Mon Sep 17 00:00:00 2001 From: Laura Date: Fri, 17 May 2024 15:41:50 +0200 Subject: [PATCH 06/19] Added validation for remote data source #3133 --- ...cHubConfigurationModelValidationError.java | 10 ++- .../SecHubConfigurationModelValidator.java | 67 ++++++++++++-- .../model/SecHubDataConfigurationObject.java | 4 + ...SecHubConfigurationModelValidatorTest.java | 90 +++++++++++++++++++ ...data_config_invalid_credentials_empty.json | 21 +++++ ..._data_config_invalid_missing_location.json | 18 ++++ ...mote_data_config_invalid_multi_config.json | 38 ++++++++ ...alid_user_credential_missing_password.json | 24 +++++ ...alid_user_credential_missing_username.json | 24 +++++ 9 files changed, 287 insertions(+), 9 deletions(-) create mode 100644 sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_credentials_empty.json create mode 100644 sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_missing_location.json create mode 100644 sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_multi_config.json create mode 100644 sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_user_credential_missing_password.json create mode 100644 sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_user_credential_missing_username.json diff --git a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidationError.java b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidationError.java index 60db4e7a8..2a3725aff 100644 --- a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidationError.java +++ b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidationError.java @@ -66,7 +66,15 @@ public enum SecHubConfigurationModelValidationError { METADATA_LABEL_KEY_CONTAINS_ILLEGAL_CHARACTERS("Meta data label key contains illegal characters."), - ; + REMOTE_DATA_MULTI_CONFIGURATION_NOT_ALLOWED("Remote data configuration is not allowed for multiple data configurations."), + + REMOTE_DATA_CONFIGURATION_LOCATION_NOT_DEFINED("Remote data configuration location is not defined."), + + REMOTE_DATA_CONFIGURATION_USER_NOT_DEFINED("Remote data configuration credentials: no user is defined."), + + REMOTE_DATA_CONFIGURATION_USER_NAME_NOT_DEFINED("Remote data configuration credentials: user name is not defined."), + + REMOTE_DATA_CONFIGURATION_USER_PASSWORD_NOT_DEFINED("Remote data configuration credentials: user password is not defined."),; private String defaultMessage; diff --git a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java index b75ffb880..703bc4d23 100644 --- a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java +++ b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java @@ -217,7 +217,7 @@ private void handleScanConfigurations(InternalValidationContext context) { private void handleLicenseScanConfiguration(InternalValidationContext context) { Optional licenseScanOpt = context.model.getLicenseScan(); - if (!licenseScanOpt.isPresent()) { + if (licenseScanOpt.isEmpty()) { return; } SecHubDataConfigurationUsageByName licenseScan = licenseScanOpt.get(); @@ -232,7 +232,7 @@ private void handleLicenseScanConfiguration(InternalValidationContext context) { private void handleSecretScanConfiguration(InternalValidationContext context) { Optional secretScanOpt = context.model.getSecretScan(); - if (!secretScanOpt.isPresent()) { + if (secretScanOpt.isEmpty()) { return; } SecHubDataConfigurationUsageByName secretScan = secretScanOpt.get(); @@ -246,7 +246,7 @@ private void handleSecretScanConfiguration(InternalValidationContext context) { private void handleCodeScanConfiguration(InternalValidationContext context) { Optional codeScanOpt = context.model.getCodeScan(); - if (!codeScanOpt.isPresent()) { + if (codeScanOpt.isEmpty()) { return; } SecHubDataConfigurationUsageByName codeScan = codeScanOpt.get(); @@ -266,7 +266,7 @@ private void handleUsages(InternalValidationContext context, SecHubDataConfigura private void handleWebScanConfiguration(InternalValidationContext context) { Optional webScanOpt = context.model.getWebScan(); - if (!webScanOpt.isPresent()) { + if (webScanOpt.isEmpty()) { return; } @@ -308,7 +308,7 @@ private void handleIncludesAndExcludes(InternalValidationContext context, SecHub private void handleApi(InternalValidationContext context, SecHubWebScanConfiguration webScan) { Optional apiOpt = webScan.getApi(); - if (!apiOpt.isPresent()) { + if (apiOpt.isEmpty()) { return; } @@ -318,7 +318,7 @@ private void handleApi(InternalValidationContext context, SecHubWebScanConfigura private void handleHTTPHeaders(InternalValidationContext context, SecHubWebScanConfiguration webScan) { Optional> optHttpHeaders = webScan.getHeaders(); - if (!optHttpHeaders.isPresent()) { + if (optHttpHeaders.isEmpty()) { return; } String targetUrl = webScan.getUrl().toString(); @@ -495,7 +495,7 @@ private String createUrlWithoutWildCards(String url) { private void handleInfraScanConfiguration(InternalValidationContext context) { Optional infraScanOpt = context.model.getInfraScan(); - if (!infraScanOpt.isPresent()) { + if (infraScanOpt.isEmpty()) { return; } SecHubInfrastructureScanConfiguration infraScan = infraScanOpt.get(); @@ -507,7 +507,7 @@ private void handleInfraScanConfiguration(InternalValidationContext context) { private void handleDataConfiguration(InternalValidationContext context) { Optional dataOpt = context.model.getData(); - if (!dataOpt.isPresent()) { + if (dataOpt.isEmpty()) { return; } @@ -516,6 +516,8 @@ private void handleDataConfiguration(InternalValidationContext context) { validateNameUniqueAndNotNull(context, data.getSources()); validateNameUniqueAndNotNull(context, data.getBinaries()); + validateRemoteDataSection(context, data.getSources()); + validateRemoteDataSection(context, data.getBinaries()); } private void validateNameUniqueAndNotNull(InternalValidationContext context, Collection configurationObjects) { @@ -552,6 +554,55 @@ private void validateNameUniqueAndNotNull(InternalValidationContext context, Col } + private void validateRemoteDataSection(InternalValidationContext context, Collection configurationObjects) { + + SecHubConfigurationModelValidationResult result = context.result; + + for (SecHubDataConfigurationObject configurationObject : configurationObjects) { + Optional optRemoteData = configurationObject.getRemote(); + + if (optRemoteData.isEmpty()) { + // no remote data is configured + return; + } + + String uniqueName = configurationObject.getUniqueName(); + + if (configurationObjects.size() > 1) { + // remote data is configured with multiple configurations + result.addError(REMOTE_DATA_MULTI_CONFIGURATION_NOT_ALLOWED); + } + + SecHubRemoteDataConfiguration remoteData = optRemoteData.get(); + if (remoteData.getLocation() == null || remoteData.getLocation().isEmpty()) { + result.addError(REMOTE_DATA_CONFIGURATION_LOCATION_NOT_DEFINED, "Remote data location is not defined for " + uniqueName); + } + + if (remoteData.getCredentials().isEmpty()) { + // credentials don't need to be defined for public accessible remote data + return; + } + + SecHubRemoteCredentialConfiguration remoteCredential = remoteData.getCredentials().get(); + if (remoteCredential.getUser().isEmpty()) { + result.addError(REMOTE_DATA_CONFIGURATION_USER_NOT_DEFINED, "Remote data configuration credentials: no user is defined for " + uniqueName); + + } else { + SecHubRemoteCredentialUserData user = remoteCredential.getUser().get(); + if (user.getName() == null || user.getName().isEmpty()) { + result.addError(REMOTE_DATA_CONFIGURATION_USER_NAME_NOT_DEFINED, + "Remote data configuration credentials: user name is not defined for " + uniqueName); + } + + if (user.getPassword() == null || user.getPassword().isEmpty()) { + result.addError(REMOTE_DATA_CONFIGURATION_USER_PASSWORD_NOT_DEFINED, + "Remote data configuration credentials: user password is not defined for " + uniqueName); + } + } + + } + } + private boolean hasAtLeastOneScanConfiguration(InternalValidationContext context) { boolean atLeastOne = false; SecHubConfigurationModel model = context.model; diff --git a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubDataConfigurationObject.java b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubDataConfigurationObject.java index c374930e1..6e99d3f04 100644 --- a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubDataConfigurationObject.java +++ b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubDataConfigurationObject.java @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT package com.mercedesbenz.sechub.commons.model; +import java.util.Optional; + import com.fasterxml.jackson.annotation.JsonProperty; public interface SecHubDataConfigurationObject { @@ -18,4 +20,6 @@ public interface SecHubDataConfigurationObject { @JsonProperty("name") public String getUniqueName(); + public Optional getRemote(); + } diff --git a/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java b/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java index 67392e139..2840e2a27 100644 --- a/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java +++ b/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java @@ -1615,6 +1615,96 @@ void when_sechub_config_has_exactly_maximum_size_allowed_error_SECHUB_CONFIGURAT assertHasNotError(result, SECHUB_CONFIGURATION_TOO_LARGE); } + @ParameterizedTest + @ValueSource(strings = { "src/test/resources/sechub_remote_data_config_binary_code_scan_example.json", + "src/test/resources/sechub_remote_data_config_source_code_scan_example.json" }) + void when_remote_sechub_configuration_is_valid_no_errors_are_reported(String file) { + String json = TestFileReader.loadTextFile(file); + SecHubScanConfiguration sechubConfiguration = SecHubScanConfiguration.createFromJSON(json); + modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); + + /* execute */ + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + + /* test */ + assertHasNoErrors(result); + } + + @Test + void when_multiple_remote_configurations_are_configured_error_REMOTE_DATA_MULTI_CONFIGURATION_NOT_ALLOWED() { + /* prepare */ + String json = TestFileReader.loadTextFile("src/test/resources/sechub_remote_data_config_invalid_multi_config.json"); + SecHubScanConfiguration sechubConfiguration = SecHubScanConfiguration.createFromJSON(json); + modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); + + /* execute */ + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + + /* test */ + assertTrue(result.hasErrors()); + assertHasError(result, REMOTE_DATA_MULTI_CONFIGURATION_NOT_ALLOWED); + } + + @Test + void when_remote_configuration_location_is_not_defined_error_REMOTE_DATA_CONFIGURATION_LOCATION_NOT_DEFINED() { + /* prepare */ + String json = TestFileReader.loadTextFile("src/test/resources/sechub_remote_data_config_invalid_missing_location.json"); + SecHubScanConfiguration sechubConfiguration = SecHubScanConfiguration.createFromJSON(json); + modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); + + /* execute */ + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + + /* test */ + assertTrue(result.hasErrors()); + assertHasError(result, REMOTE_DATA_CONFIGURATION_LOCATION_NOT_DEFINED); + } + + @Test + void when_remote_configuration_has_empty_credentials_error_REMOTE_DATA_CONFIGURATION_USER_NOT_DEFINED() { + /* prepare */ + String json = TestFileReader.loadTextFile("src/test/resources/sechub_remote_data_config_invalid_credentials_empty.json"); + SecHubScanConfiguration sechubConfiguration = SecHubScanConfiguration.createFromJSON(json); + modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); + + /* execute */ + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + + /* test */ + assertTrue(result.hasErrors()); + assertHasError(result, REMOTE_DATA_CONFIGURATION_USER_NOT_DEFINED); + } + + @Test + void when_remote_configuration_credential_user_has_no_username_error_REMOTE_DATA_CONFIGURATION_USER_NAME_NOT_DEFINED() { + /* prepare */ + String json = TestFileReader.loadTextFile("src/test/resources/sechub_remote_data_config_invalid_user_credential_missing_username.json"); + SecHubScanConfiguration sechubConfiguration = SecHubScanConfiguration.createFromJSON(json); + modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); + + /* execute */ + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + + /* test */ + assertTrue(result.hasErrors()); + assertHasError(result, REMOTE_DATA_CONFIGURATION_USER_NAME_NOT_DEFINED); + } + + @Test + void when_remote_configuration_credential_user_has_no_password_error_REMOTE_DATA_CONFIGURATION_USER_PASSWORD_NOT_DEFINED() { + /* prepare */ + String json = TestFileReader.loadTextFile("src/test/resources/sechub_remote_data_config_invalid_user_credential_missing_password.json"); + SecHubScanConfiguration sechubConfiguration = SecHubScanConfiguration.createFromJSON(json); + modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); + + /* execute */ + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + + /* test */ + assertTrue(result.hasErrors()); + assertHasError(result, REMOTE_DATA_CONFIGURATION_USER_PASSWORD_NOT_DEFINED); + } + private SecHubConfigurationModel createSecHubConfigModelWithExactly8193Characters() { // 128*64 = 8192, so we take 127 because of the overhead of the JSON model: // {"apiVersion":""} = 17 characters so we need to add 48 characters afterwards diff --git a/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_credentials_empty.json b/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_credentials_empty.json new file mode 100644 index 000000000..8251ca090 --- /dev/null +++ b/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_credentials_empty.json @@ -0,0 +1,21 @@ +{ + "apiVersion": "1.0", + "data": { + "sources": [ + { + "name": "remote_example_name", + "remote": { + "location": "remote_example_location", + "type": "git", + "credentials": { + } + } + } + ] + }, + "codeScan": { + "use": [ + "remote_example_name" + ] + } +} \ No newline at end of file diff --git a/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_missing_location.json b/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_missing_location.json new file mode 100644 index 000000000..865f74e8b --- /dev/null +++ b/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_missing_location.json @@ -0,0 +1,18 @@ +{ + "apiVersion": "1.0", + "data": { + "binaries": [ + { + "name": "remote_example_name", + "remote": { + "type": "docker" + } + } + ] + }, + "codeScan": { + "use": [ + "remote_example_name" + ] + } +} \ No newline at end of file diff --git a/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_multi_config.json b/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_multi_config.json new file mode 100644 index 000000000..9ccee2e65 --- /dev/null +++ b/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_multi_config.json @@ -0,0 +1,38 @@ +{ + "apiVersion": "1.0", + "data": { + "sources": [ + { + "name": "remote_example_name", + "remote": { + "location": "remote_example_location", + "type": "git", + "credentials": { + "user": { + "name": "my-example-user", + "password": "my-example-password" + } + } + } + }, + { + "name": "remote_example_name_two", + "remote": { + "location": "remote_example_location", + "type": "some-other-type", + "credentials": { + "user": { + "name": "my-example-user", + "password": "my-example-password" + } + } + } + } + ] + }, + "codeScan": { + "use": [ + "remote_example_name" + ] + } +} \ No newline at end of file diff --git a/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_user_credential_missing_password.json b/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_user_credential_missing_password.json new file mode 100644 index 000000000..ea548a2fc --- /dev/null +++ b/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_user_credential_missing_password.json @@ -0,0 +1,24 @@ +{ + "apiVersion": "1.0", + "data": { + "binaries": [ + { + "name": "remote_example_name", + "remote": { + "location": "remote_example_location", + "type": "docker", + "credentials": { + "user": { + "name": "my-example-name" + } + } + } + } + ] + }, + "codeScan": { + "use": [ + "remote_example_name" + ] + } +} \ No newline at end of file diff --git a/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_user_credential_missing_username.json b/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_user_credential_missing_username.json new file mode 100644 index 000000000..fdc2610e9 --- /dev/null +++ b/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_user_credential_missing_username.json @@ -0,0 +1,24 @@ +{ + "apiVersion": "1.0", + "data": { + "binaries": [ + { + "name": "remote_example_name", + "remote": { + "location": "remote_example_location", + "type": "docker", + "credentials": { + "user": { + "password": "my-example-password" + } + } + } + } + ] + }, + "codeScan": { + "use": [ + "remote_example_name" + ] + } +} \ No newline at end of file From 105ed5086eb547607ace32419edeeb2869ab3c44 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 06:18:29 +0000 Subject: [PATCH 07/19] --- updated-dependencies: - dependency-name: requests dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .../src/main/resources/zap-ruleset-helper/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sechub-wrapper-owasp-zap/src/main/resources/zap-ruleset-helper/requirements.txt b/sechub-wrapper-owasp-zap/src/main/resources/zap-ruleset-helper/requirements.txt index 049e44a34..e69108647 100644 --- a/sechub-wrapper-owasp-zap/src/main/resources/zap-ruleset-helper/requirements.txt +++ b/sechub-wrapper-owasp-zap/src/main/resources/zap-ruleset-helper/requirements.txt @@ -1,3 +1,3 @@ bs4==0.0.1 beautifulsoup4==4.11.1 -requests==2.31.0 \ No newline at end of file +requests==2.32.0 \ No newline at end of file From 6c486bf77488a4e33918ef47fa3d0dcd9539023f Mon Sep 17 00:00:00 2001 From: Laura Date: Tue, 21 May 2024 10:58:50 +0200 Subject: [PATCH 08/19] Added change requests --- .../modules/AbstractInputValidator.java | 121 +++++++++++ .../prepare/modules/InputValidator.java | 12 +- .../modules/InputValidatorExitcode.java | 22 ++ ...PrepareWrapperInputValidatorException.java | 20 ++ .../prepare/modules/PrepareWrapperModule.java | 27 +-- .../wrapper/prepare/modules/WrapperTool.java | 4 - .../modules/git/GitInputValidator.java | 58 +----- .../modules/git/PrepareWrapperModuleGit.java | 53 +---- .../prepare/modules/git/WrapperGit.java | 2 +- .../skopeo/PrepareWrapperModuleSkopeo.java | 55 +---- .../modules/skopeo/SkopeoInputValidator.java | 55 +---- .../prepare/modules/skopeo/WrapperSkopeo.java | 4 +- .../PrepareWrapperPreparationService.java | 11 +- ...epareWrapperApplicationSpringBootTest.java | 14 +- .../modules/git/GitInputValidatorTest.java | 54 ++--- .../git/PrepareWrapperModuleGitTest.java | 163 +-------------- .../prepare/modules/git/WrapperGitTest.java | 3 - .../PrepareWrapperModuleSkopeoTest.java | 186 +---------------- .../skopeo/SkopeoInputValidatorTest.java | 197 +++++++++++++++++- .../modules/skopeo/WrapperSkopeoTest.java | 2 - .../PrepareWrapperPreparationServiceTest.java | 3 +- 21 files changed, 449 insertions(+), 617 deletions(-) create mode 100644 sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/AbstractInputValidator.java create mode 100644 sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/InputValidatorExitcode.java create mode 100644 sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperInputValidatorException.java diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/AbstractInputValidator.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/AbstractInputValidator.java new file mode 100644 index 000000000..4388116f2 --- /dev/null +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/AbstractInputValidator.java @@ -0,0 +1,121 @@ +package com.mercedesbenz.sechub.wrapper.prepare.modules; + +import static com.mercedesbenz.sechub.wrapper.prepare.modules.InputValidatorExitcode.*; + +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.mercedesbenz.sechub.commons.model.*; +import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperContext; + +public class AbstractInputValidator implements InputValidator { + + private static final Logger LOG = LoggerFactory.getLogger(AbstractInputValidator.class); + private final String TYPE; + private final Pattern LOCATION_PATTERN; + private final Pattern USERNAME_PATTERN; + private final Pattern PASSWORD_PATTERN; + private final List forbiddenCharacters = Arrays.asList(">", "<", "!", "?", "*", "'", "\"", ";", "&", "|", "`", "$", "{", "}"); + + public AbstractInputValidator(String type, Pattern locationPattern, Pattern usernamePattern, Pattern passwordPattern) { + this.TYPE = type; + this.LOCATION_PATTERN = locationPattern; + this.USERNAME_PATTERN = usernamePattern; + this.PASSWORD_PATTERN = passwordPattern; + } + + public void validate(PrepareWrapperContext context) throws PrepareWrapperInputValidatorException { + validateModule(context); + validateCredentials(context); + } + + private void validateModule(PrepareWrapperContext context) throws PrepareWrapperInputValidatorException { + for (SecHubRemoteDataConfiguration secHubRemoteDataConfiguration : context.getRemoteDataConfigurationList()) { + String location = secHubRemoteDataConfiguration.getLocation(); + String type = secHubRemoteDataConfiguration.getType(); + + if (isTypeNullOrEmpty(type)) { + LOG.debug("Not type defined. Location is: {}", location); + validateLocation(location); + return; + } else if (isMatchingType(type)) { + LOG.debug("Type is matching type {}. Location is: {}", TYPE, location); + validateLocation(location); + return; + } + throw new PrepareWrapperInputValidatorException("Defined type " + type + " was not modules type " + TYPE + ".", TYPE_NOT_MATCHING_PATTERN); + } + } + + private void validateCredentials(PrepareWrapperContext context) throws PrepareWrapperInputValidatorException { + for (SecHubRemoteDataConfiguration secHubRemoteDataConfiguration : context.getRemoteDataConfigurationList()) { + if (secHubRemoteDataConfiguration.getCredentials().isEmpty()) { + return; + } else { + SecHubRemoteCredentialConfiguration remoteCredentialConfiguration = secHubRemoteDataConfiguration.getCredentials().get(); + if (remoteCredentialConfiguration.getUser().isPresent()) { + SecHubRemoteCredentialUserData user = remoteCredentialConfiguration.getUser().get(); + validateUsername(user.getName()); + validatePassword(user.getPassword()); + return; + } + // credentials object was empty + throw new IllegalStateException("Defined credentials must not be null."); + } + } + } + + public void validateUsername(String username) throws PrepareWrapperInputValidatorException { + if (username == null || username.isBlank()) { + throw new IllegalStateException("Defined username must not be null or empty."); + } + + if (!USERNAME_PATTERN.matcher(username).matches()) { + throw new PrepareWrapperInputValidatorException("Defined username must match the " + TYPE + " pattern.", CREDENTIALS_USERNAME_NOT_MATCHING_PATTERN); + } + } + + public void validatePassword(String password) throws PrepareWrapperInputValidatorException { + if (password == null || password.isBlank()) { + throw new IllegalStateException("Defined password must not be null or empty."); + } + + if (!PASSWORD_PATTERN.matcher(password).matches()) { + throw new PrepareWrapperInputValidatorException("Defined password must match the " + TYPE + " Api token pattern.", + CREDENTIALS_PASSWORD_NOT_MATCHING_PATTERN); + } + } + + public void validateLocation(String location) throws PrepareWrapperInputValidatorException { + if (location == null || location.isBlank()) { + throw new IllegalStateException("Defined location must not be null or empty."); + } + validateLocationCharacters(location); + if (!LOCATION_PATTERN.matcher(location).matches()) { + throw new PrepareWrapperInputValidatorException("Defined location must match the " + TYPE + " pattern.", LOCATION_NOT_MATCHING_PATTERN); + } + } + + private boolean isTypeNullOrEmpty(String type) { + return type == null || type.isEmpty(); + } + + private boolean isMatchingType(String type) { + return TYPE.equalsIgnoreCase(type); + } + + private void validateLocationCharacters(String url) { + if (url.contains(" ")) { + throw new IllegalArgumentException("Defined URL must not contain whitespaces."); + } + for (String forbiddenCharacter : forbiddenCharacters) { + if (url.contains(forbiddenCharacter)) { + throw new IllegalArgumentException("Defined URL must not contain forbidden characters: " + forbiddenCharacter); + } + } + } +} diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/InputValidator.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/InputValidator.java index d8e28d1b7..5e4037f45 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/InputValidator.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/InputValidator.java @@ -1,15 +1,7 @@ package com.mercedesbenz.sechub.wrapper.prepare.modules; -import java.util.List; +import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperContext; public interface InputValidator { - - boolean validateLocation(String location); - - void validateUsername(String username); - - void validatePassword(String password); - - void validateLocationCharacters(String url, List forbiddenCharacters); - + void validate(PrepareWrapperContext context) throws PrepareWrapperInputValidatorException; } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/InputValidatorExitcode.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/InputValidatorExitcode.java new file mode 100644 index 000000000..f8d76c2b0 --- /dev/null +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/InputValidatorExitcode.java @@ -0,0 +1,22 @@ +package com.mercedesbenz.sechub.wrapper.prepare.modules; + +public enum InputValidatorExitcode { + + LOCATION_NOT_MATCHING_PATTERN(1), + + CREDENTIALS_USERNAME_NOT_MATCHING_PATTERN(2), + + CREDENTIALS_PASSWORD_NOT_MATCHING_PATTERN(3), + + TYPE_NOT_MATCHING_PATTERN(4); + + private int exitCode; + + private InputValidatorExitcode(int exitCode) { + this.exitCode = exitCode; + } + + public int getExitCode() { + return exitCode; + } +} diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperInputValidatorException.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperInputValidatorException.java new file mode 100644 index 000000000..76525f391 --- /dev/null +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperInputValidatorException.java @@ -0,0 +1,20 @@ +package com.mercedesbenz.sechub.wrapper.prepare.modules; + +public class PrepareWrapperInputValidatorException extends Exception { + private static final long serialVersionUID = 1L; + + private InputValidatorExitcode exitCode; + + public PrepareWrapperInputValidatorException(String message, InputValidatorExitcode exitCode) { + this(message, null, exitCode); + } + + public PrepareWrapperInputValidatorException(String message, Exception e, InputValidatorExitcode exitCode) { + super(message, e); + this.exitCode = exitCode; + } + + public InputValidatorExitcode getExitCode() { + return exitCode; + } +} diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModule.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModule.java index 2fc0e4f2d..46d24a7fa 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModule.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/PrepareWrapperModule.java @@ -1,30 +1,24 @@ // SPDX-License-Identifier: MIT package com.mercedesbenz.sechub.wrapper.prepare.modules; +import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_PASSWORD; +import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_USERNAME; + import java.io.IOException; import java.util.HashMap; -import com.mercedesbenz.sechub.commons.core.security.CryptoAccess; -import com.mercedesbenz.sechub.commons.model.SecHubRemoteCredentialUserData; +import javax.crypto.SealedObject; + import org.springframework.stereotype.Service; +import com.mercedesbenz.sechub.commons.core.security.CryptoAccess; +import com.mercedesbenz.sechub.commons.model.SecHubRemoteCredentialUserData; import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperContext; -import javax.crypto.SealedObject; - -import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_PASSWORD; -import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_USERNAME; - @Service public interface PrepareWrapperModule { - public boolean isAbleToPrepare(PrepareWrapperContext context); - - void prepare(PrepareWrapperContext context) throws IOException; - - default boolean isTypeConfigured(String type) { - return type != null && !type.isBlank(); - } + boolean prepare(PrepareWrapperContext context) throws IOException; default void addSealedUserCredentials(SecHubRemoteCredentialUserData user, HashMap credentialMap) { SealedObject sealedUsername = CryptoAccess.CRYPTO_STRING.seal(user.getName()); @@ -32,9 +26,4 @@ default void addSealedUserCredentials(SecHubRemoteCredentialUserData user, HashM credentialMap.put(PDS_PREPARE_CREDENTIAL_USERNAME, sealedUsername); credentialMap.put(PDS_PREPARE_CREDENTIAL_PASSWORD, sealedPassword); } - - default boolean isMatchingType(String type, String expectedType) { - return expectedType.equalsIgnoreCase(type); - } - } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperTool.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperTool.java index 178274535..89cb5212b 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperTool.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperTool.java @@ -4,18 +4,14 @@ import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperKeyConstants.KEY_PDS_PREPARE_PROCESS_TIMEOUT_SECONDS; import java.io.IOException; -import java.util.Map; import java.util.concurrent.TimeUnit; -import javax.crypto.SealedObject; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import com.mercedesbenz.sechub.commons.core.security.CryptoAccess; import com.mercedesbenz.sechub.commons.pds.PDSDefaultParameterValueConstants; import com.mercedesbenz.sechub.commons.pds.PDSProcessAdapterFactory; import com.mercedesbenz.sechub.commons.pds.ProcessAdapter; diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidator.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidator.java index 0d9e1f124..2ed907f16 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidator.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidator.java @@ -1,63 +1,21 @@ package com.mercedesbenz.sechub.wrapper.prepare.modules.git; -import java.util.Arrays; -import java.util.List; import java.util.regex.Pattern; -import com.mercedesbenz.sechub.wrapper.prepare.modules.InputValidator; import org.springframework.stereotype.Component; +import com.mercedesbenz.sechub.commons.model.*; +import com.mercedesbenz.sechub.wrapper.prepare.modules.AbstractInputValidator; + @Component -public class GitInputValidator implements InputValidator { - private static final String GIT_LOCATION_REGEX = "((git|ssh|http(s)?)|(git@[\\w\\.]+))(:(//)?)([\\w\\.@\\:/\\-~]+)(\\.git)(/)?$"; - private static final Pattern GIT_LOCATION_PATTERN = Pattern.compile(GIT_LOCATION_REGEX); +public class GitInputValidator extends AbstractInputValidator { + private static final String TYPE = "git"; + private static final String GIT_LOCATION_REGEX = "((git|ssh|http(s)?)|(git@[\\w\\.]+))(:(//)?)([\\w\\.@\\:/\\-~]+)(\\.git)(/)?$"; private static final String GIT_USERNAME_REGEX = "^[a-zA-Z0-9-_\\d](?:[a-zA-Z0-9-_\\d]|(?=[a-zA-Z0-9-_\\d])){0,38}$"; - private static final Pattern GIT_USERNAME_PATTERN = Pattern.compile(GIT_USERNAME_REGEX); - private static final String GIT_PASSWORD_REGEX = "^(gh[ps]_[a-zA-Z0-9]{36}|github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59})$"; - private static final Pattern GIT_PASSWORD_PATTERN = Pattern.compile(GIT_PASSWORD_REGEX); - - private final List defaultForbiddenCharacters = Arrays.asList(">", "<", "!", "?", "*", "'", "\"", ";", "&", "|", "`", "$", "{", "}"); - - public void validateLocationCharacters(String url, List forbiddenCharacters) { - if (forbiddenCharacters == null) { - forbiddenCharacters = defaultForbiddenCharacters; - } - if (url.contains(" ")) { - throw new IllegalArgumentException("Defined URL must not contain whitespaces."); - } - for (String forbiddenCharacter : forbiddenCharacters) { - if (url.contains(forbiddenCharacter)) { - throw new IllegalArgumentException("Defined URL must not contain forbidden characters: " + forbiddenCharacter); - } - } - } - - public void validateUsername(String username) { - if (username == null || username.isBlank()) { - throw new IllegalStateException("Defined username must not be null or empty."); - } - - if (!GIT_USERNAME_PATTERN.matcher(username).matches()) { - throw new IllegalStateException("Defined username must match the modules pattern."); - } - } - - public void validatePassword(String password) { - if (password == null || password.isBlank()) { - throw new IllegalStateException("Defined password must not be null or empty."); - } - - if (!GIT_PASSWORD_PATTERN.matcher(password).matches()) { - throw new IllegalStateException("Defined password must match the Git Api token pattern."); - } - } - public boolean validateLocation(String location) { - if (location == null || location.isBlank()) { - throw new IllegalStateException("Defined location must not be null or empty."); - } - return GIT_LOCATION_PATTERN.matcher(location).matches(); + public GitInputValidator() { + super(TYPE, Pattern.compile(GIT_LOCATION_REGEX), Pattern.compile(GIT_USERNAME_REGEX), Pattern.compile(GIT_PASSWORD_REGEX)); } } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGit.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGit.java index 1fff14be0..9c51b105c 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGit.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGit.java @@ -12,15 +12,15 @@ import javax.crypto.SealedObject; -import com.mercedesbenz.sechub.wrapper.prepare.modules.PrepareWrapperModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; -import com.mercedesbenz.sechub.commons.core.security.CryptoAccess; import com.mercedesbenz.sechub.commons.model.*; +import com.mercedesbenz.sechub.wrapper.prepare.modules.PrepareWrapperInputValidatorException; +import com.mercedesbenz.sechub.wrapper.prepare.modules.PrepareWrapperModule; import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperContext; @Service @@ -28,8 +28,6 @@ public class PrepareWrapperModuleGit implements PrepareWrapperModule { Logger LOG = LoggerFactory.getLogger(PrepareWrapperModuleGit.class); - private static final String TYPE = "git"; - @Value("${" + KEY_PDS_PREPARE_AUTO_CLEANUP_GIT_FOLDER + ":true}") private boolean pdsPrepareAutoCleanupGitFolder; @@ -42,46 +40,21 @@ public class PrepareWrapperModuleGit implements PrepareWrapperModule { @Autowired GitInputValidator gitInputValidator; - public boolean isAbleToPrepare(PrepareWrapperContext context) { + public boolean prepare(PrepareWrapperContext context) throws IOException { if (!pdsPrepareModuleGitEnabled) { LOG.debug("Git module is disabled"); return false; } - for (SecHubRemoteDataConfiguration secHubRemoteDataConfiguration : context.getRemoteDataConfigurationList()) { - String location = secHubRemoteDataConfiguration.getLocation(); - String type = secHubRemoteDataConfiguration.getType(); - - gitInputValidator.validateLocationCharacters(location, null); - - if (isMatchingType(type, TYPE)) { - LOG.debug("Type is git"); - if (!gitInputValidator.validateLocation(location)) { - context.getUserMessages().add(new SecHubMessage(SecHubMessageType.WARNING, "Type is git but location does not match git URL pattern")); - LOG.warn("User defined type as 'git', but the defined location was not a valid git location: {}", location); - return false; - } - return true; - } - - if (isTypeConfigured(type)) { - // type was explicitly defined but is not matching - return false; - } - - if (gitInputValidator.validateLocation(location)) { - LOG.debug("Location is a git URL"); - return true; - } - + try { + gitInputValidator.validate(context); + } catch (PrepareWrapperInputValidatorException e) { + LOG.warn("Module {} could not resolve remote configuration.", getClass().getSimpleName(), e); + return false; } - return false; - } - - public void prepare(PrepareWrapperContext context) throws IOException { - LOG.debug("Start remote data preparation for GIT repository"); + LOG.debug("Module {} resolved remote configuration and will prepare.", getClass().getSimpleName()); List remoteDataConfigurationList = context.getRemoteDataConfigurationList(); @@ -93,6 +66,7 @@ public void prepare(PrepareWrapperContext context) throws IOException { throw new IOException("Download of git repository was not successful."); } cleanup(context); + return true; } public boolean isDownloadSuccessful(PrepareWrapperContext context) { @@ -126,8 +100,6 @@ private void prepareRemoteConfiguration(PrepareWrapperContext context, SecHubRem } private void clonePrivateRepository(PrepareWrapperContext context, SecHubRemoteCredentialUserData user, String location) throws IOException { - assertUserCredentials(user); - HashMap credentialMap = new HashMap<>(); addSealedUserCredentials(user, credentialMap); @@ -146,11 +118,6 @@ private void clonePrivateRepository(PrepareWrapperContext context, SecHubRemoteC context.getUserMessages().add(message); } - private void assertUserCredentials(SecHubRemoteCredentialUserData user) { - gitInputValidator.validateUsername(user.getName()); - gitInputValidator.validatePassword(user.getPassword()); - } - private void clonePublicRepository(PrepareWrapperContext context, String location) { /* @formatter:off */ GitContext contextGit = (GitContext) new GitContext.GitContextBuilder(). diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGit.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGit.java index 25c58fadb..05f248700 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGit.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGit.java @@ -6,13 +6,13 @@ import java.util.ArrayList; import java.util.List; -import com.mercedesbenz.sechub.wrapper.prepare.modules.WrapperTool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.mercedesbenz.sechub.commons.pds.ProcessAdapter; +import com.mercedesbenz.sechub.wrapper.prepare.modules.WrapperTool; @Component public class WrapperGit extends WrapperTool { diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeo.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeo.java index 5c4772eb2..66c7ddc3d 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeo.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeo.java @@ -1,7 +1,5 @@ package com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo; -import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_PASSWORD; -import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironmentVariables.PDS_PREPARE_CREDENTIAL_USERNAME; import static com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperKeyConstants.KEY_PDS_PREPARE_MODULE_SKOPEO_ENABLED; import java.io.IOException; @@ -15,15 +13,15 @@ import javax.crypto.SealedObject; -import com.mercedesbenz.sechub.wrapper.prepare.modules.PrepareWrapperModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; -import com.mercedesbenz.sechub.commons.core.security.CryptoAccess; import com.mercedesbenz.sechub.commons.model.*; +import com.mercedesbenz.sechub.wrapper.prepare.modules.PrepareWrapperInputValidatorException; +import com.mercedesbenz.sechub.wrapper.prepare.modules.PrepareWrapperModule; import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperContext; @Service @@ -31,8 +29,6 @@ public class PrepareWrapperModuleSkopeo implements PrepareWrapperModule { Logger LOG = LoggerFactory.getLogger(PrepareWrapperModuleSkopeo.class); - private static final String TYPE = "docker"; - @Value("${" + KEY_PDS_PREPARE_MODULE_SKOPEO_ENABLED + ":true}") private boolean pdsPrepareModuleSkopeoEnabled; @@ -43,50 +39,24 @@ public class PrepareWrapperModuleSkopeo implements PrepareWrapperModule { WrapperSkopeo skopeo; @Override - public boolean isAbleToPrepare(PrepareWrapperContext context) { + public boolean prepare(PrepareWrapperContext context) throws IOException { + LOG.debug("Start remote data preparation for Docker repository"); if (!pdsPrepareModuleSkopeoEnabled) { LOG.debug("Skopeo module is disabled"); return false; } - for (SecHubRemoteDataConfiguration secHubRemoteDataConfiguration : context.getRemoteDataConfigurationList()) { - String location = secHubRemoteDataConfiguration.getLocation(); - String type = secHubRemoteDataConfiguration.getType(); - - skopeoInputValidator.validateLocationCharacters(location, null); - - if (isMatchingType(type, TYPE)) { - LOG.debug("Type is: " + TYPE); - if (!skopeoInputValidator.validateLocation(location)) { - context.getUserMessages().add(new SecHubMessage(SecHubMessageType.WARNING, "Type is " + TYPE + " but location does not match URL pattern")); - LOG.warn("User defined type as {}, but the defined location was not a valid location: {}", TYPE, location); - return false; - } - return true; - } - - if (isTypeConfigured(type)) { - // type was explicitly defined but is not matching - return false; - } - - if (skopeoInputValidator.validateLocation(location)) { - LOG.debug("Location is a " + TYPE + " URL"); - return true; - } + try { + skopeoInputValidator.validate(context); + } catch (PrepareWrapperInputValidatorException e) { + LOG.warn("Module {} could not resolve remote configuration.", getClass().getSimpleName(), e); + return false; } - return false; - } - - @Override - public void prepare(PrepareWrapperContext context) throws IOException { - LOG.debug("Start remote data preparation for Docker repository"); List remoteDataConfigurationList = context.getRemoteDataConfigurationList(); for (SecHubRemoteDataConfiguration secHubRemoteDataConfiguration : remoteDataConfigurationList) { - // TODO: 16.05.24 laura isabletoprepare prepareRemoteConfiguration(context, secHubRemoteDataConfiguration); } @@ -94,6 +64,7 @@ public void prepare(PrepareWrapperContext context) throws IOException { throw new IOException("Download of docker image was not successful."); } cleanup(context); + return true; } public boolean isDownloadSuccessful(PrepareWrapperContext context) { @@ -137,7 +108,6 @@ private void prepareRemoteConfiguration(PrepareWrapperContext context, SecHubRem } private void downloadPrivateImage(PrepareWrapperContext context, SecHubRemoteCredentialUserData user, String location) throws IOException { - assertUserCredentials(user); HashMap credentialMap = new HashMap<>(); addSealedUserCredentials(user, credentialMap); @@ -156,11 +126,6 @@ private void downloadPrivateImage(PrepareWrapperContext context, SecHubRemoteCre context.getUserMessages().add(message); } - private void assertUserCredentials(SecHubRemoteCredentialUserData user) { - skopeoInputValidator.validateUsername(user.getName()); - skopeoInputValidator.validatePassword(user.getPassword()); - } - private void downloadPublicImage(PrepareWrapperContext context, String location) throws IOException { /* @formatter:off */ SkopeoContext skopeoContext = (SkopeoContext) new SkopeoContext.SkopeoContextBuilder(). diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidator.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidator.java index 9efac0cc0..ba51fb3da 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidator.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidator.java @@ -1,63 +1,22 @@ package com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo; -import java.util.Arrays; -import java.util.List; import java.util.regex.Pattern; -import com.mercedesbenz.sechub.wrapper.prepare.modules.InputValidator; import org.springframework.stereotype.Component; +import com.mercedesbenz.sechub.commons.model.*; +import com.mercedesbenz.sechub.wrapper.prepare.modules.AbstractInputValidator; + @Component -public class SkopeoInputValidator implements InputValidator { +public class SkopeoInputValidator extends AbstractInputValidator { + public static final String TYPE = "docker"; private static final String SKOPEO_LOCATION_REGEX = "((docker://|https://)?([a-zA-Z0-9-_.].[a-zA-Z0-9-_.]/)?[a-zA-Z0-9-_.]+(:[a-zA-Z0-9-_.]+)?(/)?)+(@sha256:[a-f0-9]{64})?"; - private static final Pattern SKOPEO_LOCATION_PATTERN = Pattern.compile(SKOPEO_LOCATION_REGEX); private static final String SKOPEO_USERNAME_REGEX = "^[a-zA-Z0-9-_\\d](?:[a-zA-Z0-9-_\\d]|(?=[a-zA-Z0-9-_\\d])){0,38}$"; - private static final Pattern SKOPEO_USERNAME_PATTERN = Pattern.compile(SKOPEO_USERNAME_REGEX); private static final String SKOPEO_PASSWORD_REGEX = "^[a-zA-Z0-9-_\\d]{0,80}$"; - private static final Pattern SKOPEO_PASSWORD_PATTERN = Pattern.compile(SKOPEO_PASSWORD_REGEX); - private final List defaultForbiddenCharacters = Arrays.asList(">", "<", "!", "?", "*", "'", "\"", ";", "&", "|", "`", "$", "{", "}"); - - @Override - public boolean validateLocation(String location) { - if (location == null || location.isBlank()) { - throw new IllegalStateException("Defined location must not be null or empty."); - } - return SKOPEO_LOCATION_PATTERN.matcher(location).matches(); - } - @Override - public void validateUsername(String username) { - if (username == null || username.isBlank()) { - throw new IllegalStateException("Defined username must not be null or empty."); - } - if (!SKOPEO_USERNAME_PATTERN.matcher(username).matches()) { - throw new IllegalStateException("Defined username must match the modules pattern."); - } + public SkopeoInputValidator() { + super(TYPE, Pattern.compile(SKOPEO_LOCATION_REGEX), Pattern.compile(SKOPEO_USERNAME_REGEX), Pattern.compile(SKOPEO_PASSWORD_REGEX)); } - @Override - public void validatePassword(String password) { - if (password == null || password.isBlank()) { - throw new IllegalStateException("Defined password must not be null or empty."); - } - if (!SKOPEO_PASSWORD_PATTERN.matcher(password).matches()) { - throw new IllegalStateException("Defined password must match the Skopeo Api token pattern."); - } - } - - @Override - public void validateLocationCharacters(String url, List forbiddenCharacters) { - if (forbiddenCharacters == null) { - forbiddenCharacters = defaultForbiddenCharacters; - } - if (url.contains(" ")) { - throw new IllegalArgumentException("Defined URL must not contain whitespaces."); - } - for (String forbiddenCharacter : forbiddenCharacters) { - if (url.contains(forbiddenCharacter)) { - throw new IllegalArgumentException("Defined URL must not contain forbidden characters: " + forbiddenCharacter); - } - } - } } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeo.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeo.java index 68dec54d1..72936f20e 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeo.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeo.java @@ -9,12 +9,12 @@ import java.util.ArrayList; import java.util.List; -import com.mercedesbenz.sechub.commons.core.security.CryptoAccess; -import com.mercedesbenz.sechub.wrapper.prepare.modules.WrapperTool; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import com.mercedesbenz.sechub.commons.core.security.CryptoAccess; import com.mercedesbenz.sechub.commons.pds.ProcessAdapter; +import com.mercedesbenz.sechub.wrapper.prepare.modules.WrapperTool; @Component public class WrapperSkopeo extends WrapperTool { diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java index e9d8fd33d..714130a89 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java @@ -45,14 +45,13 @@ public AdapterExecutionResult startPreparation() throws IOException { return createAdapterExecutionResult(PrepareStatus.OK, SecHubMessageType.WARNING, "No Remote Configuration found."); } - // TODO: 16.05.24 laura for each schleife hier und in modulen raus? nur eins möglich? for (PrepareWrapperModule module : modules) { - if (!module.isAbleToPrepare(context)) { - continue; - } - atLeastOneModuleExecuted = true; + + // atLeastOneModuleExecuted = true; context.getUserMessages().add(new SecHubMessage(SecHubMessageType.INFO, "Execute prepare module: " + module.getClass().getSimpleName())); - module.prepare(context); + if (module.prepare(context)) { + atLeastOneModuleExecuted = true; + } } if (!atLeastOneModuleExecuted) { diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/PrepareWrapperApplicationSpringBootTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/PrepareWrapperApplicationSpringBootTest.java index 3898504ae..52cb47d2e 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/PrepareWrapperApplicationSpringBootTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/PrepareWrapperApplicationSpringBootTest.java @@ -5,13 +5,6 @@ import java.io.IOException; -import com.mercedesbenz.sechub.wrapper.prepare.modules.git.GitInputValidator; -import com.mercedesbenz.sechub.wrapper.prepare.modules.git.JGitAdapter; -import com.mercedesbenz.sechub.wrapper.prepare.modules.git.PrepareWrapperModuleGit; -import com.mercedesbenz.sechub.wrapper.prepare.modules.git.WrapperGit; -import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.PrepareWrapperModuleSkopeo; -import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.SkopeoInputValidator; -import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.WrapperSkopeo; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -24,6 +17,13 @@ import com.mercedesbenz.sechub.wrapper.prepare.factory.PrepareWrapperPDSUserMessageSupportPojoFactory; import com.mercedesbenz.sechub.wrapper.prepare.factory.PrepareWrapperPojoFactory; import com.mercedesbenz.sechub.wrapper.prepare.modules.*; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.GitInputValidator; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.JGitAdapter; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.PrepareWrapperModuleGit; +import com.mercedesbenz.sechub.wrapper.prepare.modules.git.WrapperGit; +import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.PrepareWrapperModuleSkopeo; +import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.SkopeoInputValidator; +import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.WrapperSkopeo; import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperContextFactory; import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperPreparationService; import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperRemoteConfigurationExtractor; diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidatorTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidatorTest.java index b0b5942a7..08371ac41 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidatorTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidatorTest.java @@ -1,13 +1,14 @@ package com.mercedesbenz.sechub.wrapper.prepare.modules.git; +import static com.mercedesbenz.sechub.wrapper.prepare.modules.InputValidatorExitcode.LOCATION_NOT_MATCHING_PATTERN; import static org.junit.jupiter.api.Assertions.*; -import com.mercedesbenz.sechub.wrapper.prepare.modules.git.GitInputValidator; -import com.mercedesbenz.sechub.wrapper.prepare.modules.git.PrepareWrapperModuleGit; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import com.mercedesbenz.sechub.wrapper.prepare.modules.PrepareWrapperInputValidatorException; + class GitInputValidatorTest { GitInputValidator gitInputValidatorToTest; @@ -22,63 +23,61 @@ void beforeEach() { @ParameterizedTest @ValueSource(strings = { "https://example.com;echoMalicious", "https://example.com.git>text.txt", "https://example.com/some-git-repo.git&&cd.." }) - void validateURL_throws_exception_when_url_does_contain_forbidden_characters(String repositoryUrl) { + void validateLocation_throws_exception_when_url_does_contain_forbidden_characters(String repositoryUrl) { /* execute */ - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, - () -> gitInputValidatorToTest.validateLocationCharacters(repositoryUrl, null)); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> gitInputValidatorToTest.validateLocation(repositoryUrl)); /* test */ assertTrue(exception.getMessage().contains("Defined URL must not contain forbidden characters: ")); } @ParameterizedTest - @ValueSource(strings = { "https://y-git-host/my-git-user/my-git-repo.git", "https://example.org/some-git-repo.git", "git@gitrepo:my-repo" }) - void validateURL_does_not_throw_exception_when_url_is_valid(String repositoryUrl) { + @ValueSource(strings = { "https://y-git-host/my-git-user/my-git-repo.git", "https://example.org/some-git-repo.git", "git@gitrepo:my-repo.git" }) + void validateLocation_does_not_throw_exception_when_url_is_valid(String repositoryUrl) { /* execute + test */ - assertDoesNotThrow(() -> gitInputValidatorToTest.validateLocationCharacters(repositoryUrl, null)); + assertDoesNotThrow(() -> gitInputValidatorToTest.validateLocation(repositoryUrl)); } @ParameterizedTest @ValueSource(strings = { "https://my-repo.com.git", "http://my-repo.com.git", "git://host.xz/~user/path/to/repo.git", "git@github.com:my/repo.git", "https://host.xz/path/to/repo.git/", "http://host.xz/path/to/repo.git/", "git://host.xz/path/to/repo.git/", "git@host.com:my-repo/example.git" }) - void escapeLocation_returns_true_when_git_pattern_is_configured(String location) { - /* execute */ - boolean result = gitInputValidatorToTest.validateLocation(location); - - /* test */ - assertTrue(result); + void validateLocation_does_not_throw_exception_when_git_pattern_is_configured(String location) { + /* execute + test */ + assertDoesNotThrow(() -> gitInputValidatorToTest.validateLocation(location)); } @ParameterizedTest - @ValueSource(strings = { "https://my-repo.com.notAgit_repo", "http://my-repo.com.git;./bin/bash", - "git://host.xz/~user/path/to/repo.git some eval execution", "git@github.com:my/repo.git\nexecuteMalicious" }) - void escapeLocation__returns_false_when_invalid_git_pattern_is_configured(String location) { + @ValueSource(strings = { "https://my-repo.com.notAgit_repo", "http://my-repo.com.git./bin/bash", "git://host.xz/~user/path/to/repo.gitsomeevalexecution", + "git@github.com:my/repo.git\nexecuteMalicious" }) + void validateLocation_throws_exception_when_invalid_git_location_is_configured(String location) { /* execute */ - boolean result = gitInputValidatorToTest.validateLocation(location); + PrepareWrapperInputValidatorException e = assertThrows(PrepareWrapperInputValidatorException.class, + () -> gitInputValidatorToTest.validateLocation(location)); /* test */ - assertFalse(result); + assertEquals(LOCATION_NOT_MATCHING_PATTERN, e.getExitCode()); } @ParameterizedTest @ValueSource(strings = { "user", "user-name", "user_name", "user-name-123", "user-name-123-456", "user-name_23" }) - void escapeUsername_does_not_throw_exception_when_username_is_valid(String username) { + void validateUsername_does_not_throw_exception_when_username_is_valid(String username) { /* execute + test */ assertDoesNotThrow(() -> gitInputValidatorToTest.validateUsername(username)); } @ParameterizedTest @ValueSource(strings = { "user name", "user name 123", "./bin/bash" }) - void escapeUsername_throws_exception_when_username_is_invalid(String username) { + void validateUsername_throws_exception_when_username_is_invalid(String username) { /* execute + test */ - IllegalStateException exception = assertThrows(IllegalStateException.class, () -> gitInputValidatorToTest.validateUsername(username)); - assertEquals("Defined username must match the modules pattern.", exception.getMessage()); + PrepareWrapperInputValidatorException exception = assertThrows(PrepareWrapperInputValidatorException.class, + () -> gitInputValidatorToTest.validateUsername(username)); + assertEquals("Defined username must match the git pattern.", exception.getMessage()); } @ParameterizedTest @ValueSource(strings = { "ghp_123456789012345678901234567890123456", "ghs_123456789012345678901234567890123456", "github_pat_1234567890123456789012_1234567890123456789012345678901234567890123456789012example" }) - void escapePassword_does_not_throw_exception_when_password_is_valid(String password) { + void validatePassword_does_not_throw_exception_when_password_is_valid(String password) { /* execute + test */ assertDoesNotThrow(() -> gitInputValidatorToTest.validatePassword(password)); } @@ -86,10 +85,11 @@ void escapePassword_does_not_throw_exception_when_password_is_valid(String passw @ParameterizedTest @ValueSource(strings = { "./bin/bash", "ghp_1234567890123456789012345678901234567", "ghs_1234567890123456789012345678901234567", "github_pat_123456789012345678901234567890123456_;echo 'malicious'" }) - void escapePassword_throws_exception_when_password_is_invalid(String password) { + void validatePassword_throws_exception_when_password_is_invalid(String password) { /* execute + test */ - IllegalStateException exception = assertThrows(IllegalStateException.class, () -> gitInputValidatorToTest.validatePassword(password)); - assertEquals("Defined password must match the Git Api token pattern.", exception.getMessage()); + PrepareWrapperInputValidatorException exception = assertThrows(PrepareWrapperInputValidatorException.class, + () -> gitInputValidatorToTest.validatePassword(password)); + assertEquals("Defined password must match the git Api token pattern.", exception.getMessage()); } } \ No newline at end of file diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java index 4ed166a27..8d20432a4 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java @@ -10,17 +10,10 @@ import java.util.ArrayList; import java.util.List; -import com.mercedesbenz.sechub.wrapper.prepare.modules.git.GitContext; -import com.mercedesbenz.sechub.wrapper.prepare.modules.git.GitInputValidator; -import com.mercedesbenz.sechub.wrapper.prepare.modules.git.PrepareWrapperModuleGit; -import com.mercedesbenz.sechub.wrapper.prepare.modules.git.WrapperGit; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; import org.springframework.test.util.ReflectionTestUtils; -import com.mercedesbenz.sechub.commons.model.SecHubConfigurationModel; import com.mercedesbenz.sechub.commons.model.SecHubRemoteCredentialConfiguration; import com.mercedesbenz.sechub.commons.model.SecHubRemoteCredentialUserData; import com.mercedesbenz.sechub.commons.model.SecHubRemoteDataConfiguration; @@ -42,156 +35,21 @@ class PrepareWrapperModuleGitTest { void beforeEach() { moduleToTest = new PrepareWrapperModuleGit(); writer = new TestFileWriter(); - gitInputValidator = new GitInputValidator(); + gitInputValidator = mock(GitInputValidator.class); git = mock(WrapperGit.class); + ReflectionTestUtils.setField(moduleToTest, "pdsPrepareModuleGitEnabled", true); moduleToTest.git = git; moduleToTest.gitInputValidator = gitInputValidator; } - @ParameterizedTest - @ValueSource(strings = { "https://host.xz/path/to/notARepo/", "http://my.eval.com", "example.org" }) - void isAbleToPrepare_returns_false_when_no_git_remote_data_was_configured(String location) { - /* prepare */ - String json = """ - { - "apiVersion": "1.0", - "data": { - "sources": [ - { - "name": "remote_example_name", - "remote": { - "location": "$location" - } - } - ] - }, - "codeScan": { - "use": [ - "remote_example_name" - ] - } - } - """.replace("$location", location); - SecHubConfigurationModel model = createFromJSON(json); - PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); - PrepareWrapperContext context = new PrepareWrapperContext(model, environment); - - /* execute */ - boolean ableToPrepare = moduleToTest.isAbleToPrepare(context); - - /* test */ - assertFalse(ableToPrepare); - } - - @ParameterizedTest - @ValueSource(strings = { "https://host.xz/path/to/notARepo/", "http://my.eval.com", "example.org", " " }) - void isAbleToPrepare_returns_false_when_git_remote_data_type_was_configured_but_is_not_git_location(String location) { - /* prepare */ - PrepareWrapperContext context = createContext(); - List remoteDataConfigurationList = new ArrayList<>(); - SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); - remoteDataConfiguration.setLocation(location); - remoteDataConfiguration.setType("git"); - remoteDataConfigurationList.add(remoteDataConfiguration); - - context.setRemoteDataConfigurationList(remoteDataConfigurationList); - - /* execute */ - boolean ableToPrepare = moduleToTest.isAbleToPrepare(context); - - /* test */ - assertFalse(ableToPrepare); - } - - @Test - void isAbleToPrepare_returns_false_when_configuration_is_empty() { - /* prepare */ - PrepareWrapperContext context = createContext(); - List remoteDataConfigurationList = new ArrayList<>(); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); - - /* execute */ - boolean ableToPrepare = moduleToTest.isAbleToPrepare(context); - - /* test */ - assertFalse(ableToPrepare); - } - - @ParameterizedTest - @ValueSource(strings = { "https://host.xz/path/to/repo.git/", "http://host.xz/path/to/repo.git/", "git://host.xz/path/to/repo.git/", - "git@host.com:my-repo/example.git" }) - void isAbleToPrepare_returns_true_when_git_remote_location_was_configured(String location) { - /* prepare */ - PrepareWrapperContext context = createContext(); - List remoteDataConfigurationList = new ArrayList<>(); - SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); - remoteDataConfiguration.setLocation(location); - remoteDataConfiguration.setType(""); - remoteDataConfigurationList.add(remoteDataConfiguration); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); - ReflectionTestUtils.setField(moduleToTest, "pdsPrepareModuleGitEnabled", true); - - /* execute */ - boolean ableToPrepare = moduleToTest.isAbleToPrepare(context); - - /* test */ - assertTrue(ableToPrepare); - } - - @Test - void prepare_throws_exception_when_credentials_are_empty() { - /* prepare */ - PrepareWrapperContext context = createContext(); - List remoteDataConfigurationList = new ArrayList<>(); - SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); - SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); - remoteDataConfiguration.setCredentials(credentials); - remoteDataConfiguration.setLocation("my-example-location"); - remoteDataConfiguration.setType("git"); - remoteDataConfigurationList.add(remoteDataConfiguration); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); - - /* execute */ - IllegalStateException exception = assertThrows(IllegalStateException.class, () -> moduleToTest.prepare(context)); - - /* test */ - assertTrue(exception.getMessage().contains("Defined credentials have no credential")); - } - - @Test - void prepare_throws_exception_when_no_username_found() { - /* prepare */ - PrepareWrapperContext context = createContext(); - List remoteDataConfigurationList = new ArrayList<>(); - SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); - SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); - SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); - user.setPassword("my-example-password"); - credentials.setUser(user); - remoteDataConfiguration.setCredentials(credentials); - remoteDataConfiguration.setLocation("my-example-location"); - remoteDataConfiguration.setType("git"); - remoteDataConfigurationList.add(remoteDataConfiguration); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); - - /* execute */ - IllegalStateException exception = assertThrows(IllegalStateException.class, () -> moduleToTest.prepare(context)); - - /* test */ - assertTrue(exception.getMessage().contains("Defined username must not be null or empty.")); - } - @Test - void prepare_throws_exception_when_no_password_found() { + void prepare_throws_exception_when_credentials_are_empty() throws IOException { /* prepare */ PrepareWrapperContext context = createContext(); List remoteDataConfigurationList = new ArrayList<>(); SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); - SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); - user.setName("my-example-name"); - credentials.setUser(user); remoteDataConfiguration.setCredentials(credentials); remoteDataConfiguration.setLocation("my-example-location"); remoteDataConfiguration.setType("git"); @@ -202,7 +60,7 @@ void prepare_throws_exception_when_no_password_found() { IllegalStateException exception = assertThrows(IllegalStateException.class, () -> moduleToTest.prepare(context)); /* test */ - assertTrue(exception.getMessage().contains("Defined password must not be null or empty.")); + assertEquals("Defined credentials have no credential user data for location: my-example-location", exception.getMessage()); } @Test @@ -233,9 +91,10 @@ void prepare_successful_when_user_credentials_are_configured_correctly() throws ReflectionTestUtils.setField(moduleToTest, "pdsPrepareModuleGitEnabled", true); /* execute */ - moduleToTest.prepare(context); + boolean result = moduleToTest.prepare(context); /* test */ + assertTrue(result); verify(git).downloadRemoteData(any(GitContext.class)); } @@ -300,16 +159,6 @@ void isDownloadSuccessful_returns_false_when_no_git_file_in_directory() throws I assertFalse(result); } - @ParameterizedTest - @ValueSource(strings = { "git", "GIT", "gIT" }) - void isMatchingGitType_returns_true_when_git_is_configured(String type) { - /* execute */ - boolean result = moduleToTest.isMatchingType(type, "git"); - - /* test */ - assertTrue(result); - } - private PrepareWrapperContext createContext() { PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn("test-upload-folder"); diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGitTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGitTest.java index 8f7121faf..004fd2de7 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGitTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGitTest.java @@ -13,9 +13,6 @@ import javax.crypto.SealedObject; -import com.mercedesbenz.sechub.wrapper.prepare.modules.git.GitContext; -import com.mercedesbenz.sechub.wrapper.prepare.modules.git.JGitAdapter; -import com.mercedesbenz.sechub.wrapper.prepare.modules.git.WrapperGit; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java index 6e00b176d..f62454aa5 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java @@ -11,167 +11,35 @@ import java.util.ArrayList; import java.util.List; -import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.PrepareWrapperModuleSkopeo; -import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.SkopeoContext; -import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.SkopeoInputValidator; -import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.WrapperSkopeo; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; import org.springframework.test.util.ReflectionTestUtils; -import com.mercedesbenz.sechub.commons.model.SecHubConfigurationModel; import com.mercedesbenz.sechub.commons.model.SecHubRemoteCredentialConfiguration; import com.mercedesbenz.sechub.commons.model.SecHubRemoteCredentialUserData; import com.mercedesbenz.sechub.commons.model.SecHubRemoteDataConfiguration; import com.mercedesbenz.sechub.test.TestFileWriter; import com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironment; import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperContext; -import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperRemoteConfigurationExtractor; class PrepareWrapperModuleSkopeoTest { PrepareWrapperModuleSkopeo moduleToTest; SkopeoInputValidator skopeoInputValidator; WrapperSkopeo skopeo; - TestFileWriter writer; @BeforeEach void beforeEach() { moduleToTest = new PrepareWrapperModuleSkopeo(); - skopeoInputValidator = new SkopeoInputValidator(); + skopeoInputValidator = mock(SkopeoInputValidator.class); writer = new TestFileWriter(); skopeo = mock(WrapperSkopeo.class); - moduleToTest.skopeoInputValidator = skopeoInputValidator; - moduleToTest.skopeo = skopeo; - } - - @ParameterizedTest - @ValueSource(strings = { "ubuntu:22.04", "ubuntu", "docker://ubuntu:22.04", "docker://ubuntu", "oci:busybox_ocilayout:latest", "https://hub.docker.com", - "docker://docker.io/library/busybox:latest", "ubuntu@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d", - "ghcr.io/owner/repo:tag" }) - void isAbleToPrepare_returnsFalse_whenSkopeoModuleIsDisabled(String location) { - /* prepare */ - PrepareWrapperContext context = createContextWithRemoteDataConfig(location); - ReflectionTestUtils.setField(moduleToTest, "pdsPrepareModuleSkopeoEnabled", false); - - /* execute */ - boolean result = moduleToTest.isAbleToPrepare(context); - - /* test */ - assertFalse(result); - } - - @Test - void isAbleToPrepare_returnsFalse_whenNoRemoteDataConfigurationIsAvailable() { - /* prepare */ - PrepareWrapperContext context = createContextEmptyConfig(); - ReflectionTestUtils.setField(moduleToTest, "pdsPrepareModuleSkopeoEnabled", true); - - /* execute */ - boolean result = moduleToTest.isAbleToPrepare(context); - - /* test */ - assertFalse(result); - } - - @ParameterizedTest - @ValueSource(strings = { "http://host.xz/path/to/repo.git/", "git://host.xz/path/to/repo.git/", "git@host.com:my-repo/example.git" }) - void isAbleToPrepare_returnsFalse_whenRemoteDataConfigurationIsNotSkopeo(String location) { - /* prepare */ - PrepareWrapperContext context = createContextWithRemoteDataConfig(location); - ReflectionTestUtils.setField(moduleToTest, "pdsPrepareModuleSkopeoEnabled", true); - - /* execute */ - boolean result = moduleToTest.isAbleToPrepare(context); - - /* test */ - assertFalse(result); - } - - @ParameterizedTest - @ValueSource(strings = { "ubuntu:22.04", "ubuntu", "docker://ubuntu:22.04", "docker://ubuntu", "oci:busybox_ocilayout:latest", "https://hub.docker.com", - "docker://docker.io/library/busybox:latest", "ubuntu@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d", - "ghcr.io/owner/repo:tag" }) - void isAbleToPrepare_returnsTrue_whenRemoteDataConfigurationIsSkopeo(String location) { - /* prepare */ - PrepareWrapperContext context = createContextWithRemoteDataConfig(location); ReflectionTestUtils.setField(moduleToTest, "pdsPrepareModuleSkopeoEnabled", true); - /* execute */ - boolean result = moduleToTest.isAbleToPrepare(context); - - /* test */ - assertTrue(result); - } - - @Test - void prepare_throws_exception_when_credentials_are_empty() { - /* prepare */ - PrepareWrapperContext context = createContextEmptyConfig(); - List remoteDataConfigurationList = new ArrayList<>(); - SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); - SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); - remoteDataConfiguration.setCredentials(credentials); - remoteDataConfiguration.setLocation("my-example-location"); - remoteDataConfiguration.setType("docker"); - remoteDataConfigurationList.add(remoteDataConfiguration); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); - - /* execute */ - IllegalStateException exception = assertThrows(IllegalStateException.class, () -> moduleToTest.prepare(context)); - - /* test */ - assertTrue(exception.getMessage().contains("Defined credentials have no credential")); - } - - @Test - void prepare_throws_exception_when_no_username_found() { - /* prepare */ - PrepareWrapperContext context = createContextEmptyConfig(); - List remoteDataConfigurationList = new ArrayList<>(); - SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); - SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); - SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); - user.setPassword("my-example-password"); - credentials.setUser(user); - remoteDataConfiguration.setCredentials(credentials); - remoteDataConfiguration.setLocation("my-example-location"); - remoteDataConfiguration.setType("docker"); - remoteDataConfigurationList.add(remoteDataConfiguration); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); - - /* execute */ - IllegalStateException exception = assertThrows(IllegalStateException.class, () -> moduleToTest.prepare(context)); - - /* test */ - assertTrue(exception.getMessage().contains("Defined username must not be null or empty.")); - } - - @Test - void prepare_throws_exception_when_no_password_found() { - /* prepare */ - PrepareWrapperContext context = createContextEmptyConfig(); - List remoteDataConfigurationList = new ArrayList<>(); - SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); - SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); - SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); - user.setName("my-example-name"); - credentials.setUser(user); - remoteDataConfiguration.setCredentials(credentials); - remoteDataConfiguration.setLocation("my-example-location"); - remoteDataConfiguration.setType("git"); - remoteDataConfigurationList.add(remoteDataConfiguration); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); - - /* execute */ - IllegalStateException exception = assertThrows(IllegalStateException.class, () -> moduleToTest.prepare(context)); - - /* test */ - assertTrue(exception.getMessage().contains("Defined password must not be null or empty.")); + moduleToTest.skopeoInputValidator = skopeoInputValidator; + moduleToTest.skopeo = skopeo; } @Test @@ -268,52 +136,4 @@ void isDownloadSuccessful_returns_false_when_no_tar_file_in_directory() throws I /* test */ assertFalse(result); } - - @ParameterizedTest - @ValueSource(strings = { "docker", "DOCKER", "DockEr" }) - void isMatchingSkopeoType_returns_true_when_docker_is_configured(String type) { - /* execute */ - boolean result = moduleToTest.isMatchingType(type, "docker"); - - /* test */ - assertTrue(result); - } - - private PrepareWrapperContext createContextEmptyConfig() { - PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); - when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn("test-upload-folder"); - return new PrepareWrapperContext(createFromJSON("{}"), environment); - } - - private PrepareWrapperContext createContextWithRemoteDataConfig(String location) { - String json = """ - { - "apiVersion": "1.0", - "data": { - "sources": [ - { - "name": "remote_example_name", - "remote": { - "location": "$location", - "type": "docker" - } - } - ] - }, - "codeScan": { - "use": [ - "remote_example_name" - ] - } - } - """.replace("$location", location); - SecHubConfigurationModel model = createFromJSON(json); - PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); - PrepareWrapperRemoteConfigurationExtractor extractor = new PrepareWrapperRemoteConfigurationExtractor(); - List creds = extractor.extract(model); - when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn("test-upload-folder"); - PrepareWrapperContext context = new PrepareWrapperContext(model, environment); - context.setRemoteDataConfigurationList(creds); - return context; - } } \ No newline at end of file diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java index 9ba603c5c..aff6de9a7 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java @@ -1,18 +1,39 @@ package com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo; +import static com.mercedesbenz.sechub.commons.model.SecHubScanConfiguration.createFromJSON; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; -import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.SkopeoInputValidator; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import com.mercedesbenz.sechub.commons.model.SecHubConfigurationModel; +import com.mercedesbenz.sechub.commons.model.SecHubRemoteCredentialConfiguration; +import com.mercedesbenz.sechub.commons.model.SecHubRemoteCredentialUserData; +import com.mercedesbenz.sechub.commons.model.SecHubRemoteDataConfiguration; +import com.mercedesbenz.sechub.test.TestFileWriter; +import com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironment; +import com.mercedesbenz.sechub.wrapper.prepare.modules.PrepareWrapperInputValidatorException; +import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperContext; +import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperRemoteConfigurationExtractor; + class SkopeoInputValidatorTest { SkopeoInputValidator validatorToTest; + TestFileWriter writer; + @BeforeEach void beforeEach() { + writer = new TestFileWriter(); validatorToTest = new SkopeoInputValidator(); } @@ -22,15 +43,15 @@ void beforeEach() { "ghcr.io/owner/repo:tag" }) void validateLocation_returns_true_for_valid_docker_urls(String location) { /* execute + test */ - assertTrue(validatorToTest.validateLocation(location)); + assertDoesNotThrow(() -> validatorToTest.validateLocation(location)); } @ParameterizedTest @ValueSource(strings = { "invalid-registry ubuntu:22.04", "docker://registry/ubuntu:invalid tag", "docker://ubuntu:tag$maliciousCode", "docker://ubuntu:tag|maliciousCode", "my-registry/oci:busybox_ocilayout;latest", }) - void validateLocation_returns_false_for_invalid_docker_urls(String location) { + void validateLocation_throws_IllegalArgumentException_for_invalid_docker_urls(String location) { /* execute + test */ - assertFalse(validatorToTest.validateLocation(location)); + assertThrows(IllegalArgumentException.class, () -> validatorToTest.validateLocation(location)); } @ParameterizedTest @@ -46,10 +67,11 @@ void validateUsername_returns_true_for_valid_usernames(String username) { "username`", "username$", "username{", "username}" }) void validateUsername_throws_exception_for_invalid_usernames(String username) { /* execute */ - IllegalStateException exception = assertThrows(IllegalStateException.class, () -> validatorToTest.validateUsername(username)); + PrepareWrapperInputValidatorException exception = assertThrows(PrepareWrapperInputValidatorException.class, + () -> validatorToTest.validateUsername(username)); /* test */ - assertEquals("Defined username must match the modules pattern.", exception.getMessage()); + assertEquals("Defined username must match the docker pattern.", exception.getMessage()); } @ParameterizedTest @@ -65,9 +87,168 @@ void validatePassword_returns_true_for_valid_passwords(String password) { "password$", "password{", "password}", "password;echo 'malicious'" }) void validatePassword_throws_exception_for_invalid_passwords(String password) { /* execute */ - IllegalStateException exception = assertThrows(IllegalStateException.class, () -> validatorToTest.validatePassword(password)); + PrepareWrapperInputValidatorException exception = assertThrows(PrepareWrapperInputValidatorException.class, + () -> validatorToTest.validatePassword(password)); + + /* test */ + assertEquals("Defined password must match the docker Api token pattern.", exception.getMessage()); + } + + @Test + void validate_throws_exception_when_credentials_are_empty() { + /* prepare */ + PrepareWrapperContext context = createContextEmptyConfig(); + List remoteDataConfigurationList = new ArrayList<>(); + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); + remoteDataConfiguration.setCredentials(credentials); + remoteDataConfiguration.setLocation("my-example-location"); + remoteDataConfiguration.setType("docker"); + remoteDataConfigurationList.add(remoteDataConfiguration); + context.setRemoteDataConfigurationList(remoteDataConfigurationList); + + /* execute */ + IllegalStateException exception = assertThrows(IllegalStateException.class, () -> validatorToTest.validate(context)); + + /* test */ + assertEquals("Defined credentials must not be null.", exception.getMessage()); + } + + @Test + void prepare_throws_exception_when_no_username_found() { + /* prepare */ + PrepareWrapperContext context = createContextEmptyConfig(); + List remoteDataConfigurationList = new ArrayList<>(); + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); + SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); + user.setPassword("my-example-password"); + credentials.setUser(user); + remoteDataConfiguration.setCredentials(credentials); + remoteDataConfiguration.setLocation("my-example-location"); + remoteDataConfiguration.setType("docker"); + remoteDataConfigurationList.add(remoteDataConfiguration); + context.setRemoteDataConfigurationList(remoteDataConfigurationList); + + /* execute */ + IllegalStateException exception = assertThrows(IllegalStateException.class, () -> validatorToTest.validate(context)); /* test */ - assertEquals("Defined password must match the Skopeo Api token pattern.", exception.getMessage()); + assertTrue(exception.getMessage().contains("Defined username must not be null or empty.")); + } + + @Test + void prepare_throws_exception_when_no_password_found() { + /* prepare */ + PrepareWrapperContext context = createContextEmptyConfig(); + List remoteDataConfigurationList = new ArrayList<>(); + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); + SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); + user.setName("my-example-name"); + credentials.setUser(user); + remoteDataConfiguration.setCredentials(credentials); + remoteDataConfiguration.setLocation("my-example-location"); + remoteDataConfiguration.setType("docker"); + remoteDataConfigurationList.add(remoteDataConfiguration); + context.setRemoteDataConfigurationList(remoteDataConfigurationList); + + /* execute */ + IllegalStateException exception = assertThrows(IllegalStateException.class, () -> validatorToTest.validate(context)); + + /* test */ + assertEquals("Defined password must not be null or empty.", exception.getMessage()); + + } + + @Test + void prepare_successful_when_user_credentials_are_configured_correctly() throws IOException { + /* prepare */ + File tempDir = Files.createTempDirectory("upload-folder").toFile(); + tempDir.deleteOnExit(); + String filename = "testimage.tar"; + writer.save(new File(tempDir, filename), "some text", true); + + PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); + when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn(tempDir.toString()); + PrepareWrapperContext context = new PrepareWrapperContext(createFromJSON("{}"), environment); + + List remoteDataConfigurationList = new ArrayList<>(); + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); + SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); + user.setName("my-example-name"); + user.setPassword("ghp_exampleAPITOKEN8ffne3l6g9f393r8fbcsf"); + credentials.setUser(user); + remoteDataConfiguration.setCredentials(credentials); + remoteDataConfiguration.setLocation("my-example-location"); + remoteDataConfiguration.setType("docker"); + remoteDataConfigurationList.add(remoteDataConfiguration); + context.setRemoteDataConfigurationList(remoteDataConfigurationList); + + /* execute + test */ + assertDoesNotThrow(() -> validatorToTest.validate(context)); + } + + @Test + void prepare_successful_when_no_credentials_are_configured() throws IOException { + /* prepare */ + File tempDir = Files.createTempDirectory("upload-folder").toFile(); + tempDir.deleteOnExit(); + String filename = "testimage.tar"; + writer.save(new File(tempDir, filename), "some text", true); + + PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); + when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn(tempDir.toString()); + PrepareWrapperContext context = new PrepareWrapperContext(createFromJSON("{}"), environment); + + List remoteDataConfigurationList = new ArrayList<>(); + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + remoteDataConfiguration.setLocation("my-example-location"); + remoteDataConfiguration.setType("docker"); + remoteDataConfigurationList.add(remoteDataConfiguration); + context.setRemoteDataConfigurationList(remoteDataConfigurationList); + + /* execute + test */ + assertDoesNotThrow(() -> validatorToTest.validate(context)); + + } + + private PrepareWrapperContext createContextEmptyConfig() { + PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); + when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn("test-upload-folder"); + return new PrepareWrapperContext(createFromJSON("{}"), environment); + } + + private PrepareWrapperContext createContextWithRemoteDataConfig(String location) { + String json = """ + { + "apiVersion": "1.0", + "data": { + "sources": [ + { + "name": "remote_example_name", + "remote": { + "location": "$location", + "type": "docker" + } + } + ] + }, + "codeScan": { + "use": [ + "remote_example_name" + ] + } + } + """.replace("$location", location); + SecHubConfigurationModel model = createFromJSON(json); + PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); + PrepareWrapperRemoteConfigurationExtractor extractor = new PrepareWrapperRemoteConfigurationExtractor(); + List creds = extractor.extract(model); + when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn("test-upload-folder"); + PrepareWrapperContext context = new PrepareWrapperContext(model, environment); + context.setRemoteDataConfigurationList(creds); + return context; } } diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeoTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeoTest.java index 14b29087f..dcae2c7a4 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeoTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeoTest.java @@ -12,8 +12,6 @@ import javax.crypto.SealedObject; -import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.SkopeoContext; -import com.mercedesbenz.sechub.wrapper.prepare.modules.skopeo.WrapperSkopeo; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationServiceTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationServiceTest.java index d443bf8fb..6f430373a 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationServiceTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationServiceTest.java @@ -73,6 +73,7 @@ void when_remote_data_was_configured_but_no_module_executed_return_preparation_f void when_remote_data_was_configured_and_git_module_added_return_preparation_success_without_message() throws IOException { /* prepare */ PrepareWrapperModuleGit gitModule = mock(PrepareWrapperModuleGit.class); + when(gitModule.prepare(context)).thenReturn(true); serviceToTest.modules.add(gitModule); List remoteDataConfigurationList = new ArrayList<>(); @@ -82,8 +83,6 @@ void when_remote_data_was_configured_and_git_module_added_return_preparation_suc remoteDataConfigurationList.add(remoteDataConfiguration); when(context.getRemoteDataConfigurationList()).thenReturn(remoteDataConfigurationList); - when(gitModule.isAbleToPrepare(context)).thenReturn(true); - /* execute */ AdapterExecutionResult result = serviceToTest.startPreparation(); From 7474185f934a3040ede72ea59345dba5e22268ff Mon Sep 17 00:00:00 2001 From: Laura Date: Tue, 21 May 2024 12:10:04 +0200 Subject: [PATCH 09/19] Allow only one Remote Configuration --- .../modules/AbstractInputValidator.java | 50 ++++++++--------- .../modules/git/PrepareWrapperModuleGit.java | 6 +- .../skopeo/PrepareWrapperModuleSkopeo.java | 7 +-- .../prepare/PrepareWrapperContext.java | 14 ++--- .../prepare/PrepareWrapperContextFactory.java | 2 +- .../PrepareWrapperPreparationService.java | 4 +- ...reWrapperRemoteConfigurationExtractor.java | 10 +++- .../git/PrepareWrapperModuleGitTest.java | 14 +---- .../PrepareWrapperModuleSkopeoTest.java | 11 +--- .../skopeo/SkopeoInputValidatorTest.java | 56 ++----------------- .../PrepareWrapperPreparationServiceTest.java | 9 +-- ...apperRemoteConfigurationExtractorTest.java | 25 +++------ 12 files changed, 65 insertions(+), 143 deletions(-) diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/AbstractInputValidator.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/AbstractInputValidator.java index 4388116f2..f494ea58f 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/AbstractInputValidator.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/AbstractInputValidator.java @@ -34,38 +34,36 @@ public void validate(PrepareWrapperContext context) throws PrepareWrapperInputVa } private void validateModule(PrepareWrapperContext context) throws PrepareWrapperInputValidatorException { - for (SecHubRemoteDataConfiguration secHubRemoteDataConfiguration : context.getRemoteDataConfigurationList()) { - String location = secHubRemoteDataConfiguration.getLocation(); - String type = secHubRemoteDataConfiguration.getType(); - - if (isTypeNullOrEmpty(type)) { - LOG.debug("Not type defined. Location is: {}", location); - validateLocation(location); - return; - } else if (isMatchingType(type)) { - LOG.debug("Type is matching type {}. Location is: {}", TYPE, location); - validateLocation(location); - return; - } - throw new PrepareWrapperInputValidatorException("Defined type " + type + " was not modules type " + TYPE + ".", TYPE_NOT_MATCHING_PATTERN); + SecHubRemoteDataConfiguration secHubRemoteDataConfiguration = context.getRemoteDataConfiguration(); + String location = secHubRemoteDataConfiguration.getLocation(); + String type = secHubRemoteDataConfiguration.getType(); + + if (isTypeNullOrEmpty(type)) { + LOG.debug("Not type defined. Location is: {}", location); + validateLocation(location); + return; + } else if (isMatchingType(type)) { + LOG.debug("Type is matching type {}. Location is: {}", TYPE, location); + validateLocation(location); + return; } + throw new PrepareWrapperInputValidatorException("Defined type " + type + " was not modules type " + TYPE + ".", TYPE_NOT_MATCHING_PATTERN); } private void validateCredentials(PrepareWrapperContext context) throws PrepareWrapperInputValidatorException { - for (SecHubRemoteDataConfiguration secHubRemoteDataConfiguration : context.getRemoteDataConfigurationList()) { - if (secHubRemoteDataConfiguration.getCredentials().isEmpty()) { + SecHubRemoteDataConfiguration secHubRemoteDataConfiguration = context.getRemoteDataConfiguration(); + if (secHubRemoteDataConfiguration.getCredentials().isEmpty()) { + return; + } else { + SecHubRemoteCredentialConfiguration remoteCredentialConfiguration = secHubRemoteDataConfiguration.getCredentials().get(); + if (remoteCredentialConfiguration.getUser().isPresent()) { + SecHubRemoteCredentialUserData user = remoteCredentialConfiguration.getUser().get(); + validateUsername(user.getName()); + validatePassword(user.getPassword()); return; - } else { - SecHubRemoteCredentialConfiguration remoteCredentialConfiguration = secHubRemoteDataConfiguration.getCredentials().get(); - if (remoteCredentialConfiguration.getUser().isPresent()) { - SecHubRemoteCredentialUserData user = remoteCredentialConfiguration.getUser().get(); - validateUsername(user.getName()); - validatePassword(user.getPassword()); - return; - } - // credentials object was empty - throw new IllegalStateException("Defined credentials must not be null."); } + // credentials object was empty + throw new IllegalStateException("Defined credentials must not be null."); } } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGit.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGit.java index 9c51b105c..5b41b38d6 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGit.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGit.java @@ -56,11 +56,9 @@ public boolean prepare(PrepareWrapperContext context) throws IOException { LOG.debug("Module {} resolved remote configuration and will prepare.", getClass().getSimpleName()); - List remoteDataConfigurationList = context.getRemoteDataConfigurationList(); + SecHubRemoteDataConfiguration secHubRemoteDataConfiguration = context.getRemoteDataConfiguration(); - for (SecHubRemoteDataConfiguration secHubRemoteDataConfiguration : remoteDataConfigurationList) { - prepareRemoteConfiguration(context, secHubRemoteDataConfiguration); - } + prepareRemoteConfiguration(context, secHubRemoteDataConfiguration); if (!isDownloadSuccessful(context)) { throw new IOException("Download of git repository was not successful."); diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeo.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeo.java index 66c7ddc3d..a48982d00 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeo.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeo.java @@ -54,11 +54,8 @@ public boolean prepare(PrepareWrapperContext context) throws IOException { return false; } - List remoteDataConfigurationList = context.getRemoteDataConfigurationList(); - - for (SecHubRemoteDataConfiguration secHubRemoteDataConfiguration : remoteDataConfigurationList) { - prepareRemoteConfiguration(context, secHubRemoteDataConfiguration); - } + SecHubRemoteDataConfiguration secHubRemoteDataConfiguration = context.getRemoteDataConfiguration(); + prepareRemoteConfiguration(context, secHubRemoteDataConfiguration); if (!isDownloadSuccessful(context)) { throw new IOException("Download of docker image was not successful."); diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperContext.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperContext.java index fa72948a2..c325d3c11 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperContext.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperContext.java @@ -13,20 +13,16 @@ public class PrepareWrapperContext { private SecHubConfigurationModel secHubConfiguration; private PrepareWrapperEnvironment environment; - private List remoteDataConfigurationList = new ArrayList<>(); private List userMessages = new ArrayList<>(); + private SecHubRemoteDataConfiguration remoteDataConfiguration; public PrepareWrapperContext(SecHubConfigurationModel secHubConfiguration, PrepareWrapperEnvironment environment) { this.secHubConfiguration = secHubConfiguration; this.environment = environment; } - public void setRemoteDataConfigurationList(List remoteDataConfigurationList) { - this.remoteDataConfigurationList = remoteDataConfigurationList; - } - - public List getRemoteDataConfigurationList() { - return remoteDataConfigurationList; + public void setRemoteDataConfiguration(SecHubRemoteDataConfiguration remoteDataConfiguration) { + this.remoteDataConfiguration = remoteDataConfiguration; } public SecHubConfigurationModel getSecHubConfiguration() { @@ -40,4 +36,8 @@ public PrepareWrapperEnvironment getEnvironment() { public List getUserMessages() { return userMessages; } + + public SecHubRemoteDataConfiguration getRemoteDataConfiguration() { + return remoteDataConfiguration; + } } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperContextFactory.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperContextFactory.java index b266b4fb1..afd2a72e7 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperContextFactory.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperContextFactory.java @@ -37,6 +37,6 @@ private SecHubConfigurationModel createSecHubConfigModel(String json) { } private void addRemoteDataConfiguration(PrepareWrapperContext context) { - context.setRemoteDataConfigurationList(extractor.extract(context.getSecHubConfiguration())); + context.setRemoteDataConfiguration(extractor.extract(context.getSecHubConfiguration())); } } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java index 714130a89..153707aa1 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java @@ -38,9 +38,9 @@ public AdapterExecutionResult startPreparation() throws IOException { LOG.debug("Start preparation"); PrepareWrapperContext context = factory.create(environment); - List remoteDataConfigurationList = context.getRemoteDataConfigurationList(); + SecHubRemoteDataConfiguration remoteDataConfiguration = context.getRemoteDataConfiguration(); - if (remoteDataConfigurationList.isEmpty()) { + if (remoteDataConfiguration == null) { LOG.warn("No Remote configuration was found"); return createAdapterExecutionResult(PrepareStatus.OK, SecHubMessageType.WARNING, "No Remote Configuration found."); } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperRemoteConfigurationExtractor.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperRemoteConfigurationExtractor.java index 99a33b044..f2cdbba5e 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperRemoteConfigurationExtractor.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperRemoteConfigurationExtractor.java @@ -13,7 +13,7 @@ @Component public class PrepareWrapperRemoteConfigurationExtractor { - public List extract(SecHubConfigurationModel model) { + public SecHubRemoteDataConfiguration extract(SecHubConfigurationModel model) { List remoteDataConfigurationList = new ArrayList<>(); if (model == null) { throw new IllegalStateException("Context was not initialized correctly. SecHub configuration was null"); @@ -33,7 +33,13 @@ public List extract(SecHubConfigurationModel mode remoteOpt.ifPresent(remoteDataConfigurationList::add); } } - return remoteDataConfigurationList; + if (remoteDataConfigurationList.isEmpty()) { + return null; + } else if (remoteDataConfigurationList.size() > 1) { + throw new IllegalStateException("Only one remote data configuration is allowed."); + } else { + return remoteDataConfigurationList.get(0); + } } } diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java index 8d20432a4..bda73d5ef 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java @@ -7,8 +7,6 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -47,14 +45,12 @@ void beforeEach() { void prepare_throws_exception_when_credentials_are_empty() throws IOException { /* prepare */ PrepareWrapperContext context = createContext(); - List remoteDataConfigurationList = new ArrayList<>(); SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); remoteDataConfiguration.setCredentials(credentials); remoteDataConfiguration.setLocation("my-example-location"); remoteDataConfiguration.setType("git"); - remoteDataConfigurationList.add(remoteDataConfiguration); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); + context.setRemoteDataConfiguration(remoteDataConfiguration); /* execute */ IllegalStateException exception = assertThrows(IllegalStateException.class, () -> moduleToTest.prepare(context)); @@ -75,7 +71,6 @@ void prepare_successful_when_user_credentials_are_configured_correctly() throws when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn(tempDir.toString()); PrepareWrapperContext context = new PrepareWrapperContext(createFromJSON("{}"), environment); - List remoteDataConfigurationList = new ArrayList<>(); SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); @@ -85,8 +80,7 @@ void prepare_successful_when_user_credentials_are_configured_correctly() throws remoteDataConfiguration.setCredentials(credentials); remoteDataConfiguration.setLocation("my-example-location"); remoteDataConfiguration.setType("git"); - remoteDataConfigurationList.add(remoteDataConfiguration); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); + context.setRemoteDataConfiguration(remoteDataConfiguration); ReflectionTestUtils.setField(moduleToTest, "pdsPrepareModuleGitEnabled", true); @@ -110,12 +104,10 @@ void prepare_successful_when_no_credentials_are_configured() throws IOException when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn(tempDir.toString()); PrepareWrapperContext context = new PrepareWrapperContext(createFromJSON("{}"), environment); - List remoteDataConfigurationList = new ArrayList<>(); SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); remoteDataConfiguration.setLocation("my-example-location"); remoteDataConfiguration.setType("git"); - remoteDataConfigurationList.add(remoteDataConfiguration); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); + context.setRemoteDataConfiguration(remoteDataConfiguration); /* execute */ moduleToTest.prepare(context); diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java index f62454aa5..5d1de3973 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java @@ -8,8 +8,6 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -54,7 +52,6 @@ void prepare_successful_when_user_credentials_are_configured_correctly() throws when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn(tempDir.toString()); PrepareWrapperContext context = new PrepareWrapperContext(createFromJSON("{}"), environment); - List remoteDataConfigurationList = new ArrayList<>(); SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); @@ -64,8 +61,7 @@ void prepare_successful_when_user_credentials_are_configured_correctly() throws remoteDataConfiguration.setCredentials(credentials); remoteDataConfiguration.setLocation("my-example-location"); remoteDataConfiguration.setType("docker"); - remoteDataConfigurationList.add(remoteDataConfiguration); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); + context.setRemoteDataConfiguration(remoteDataConfiguration); /* execute */ moduleToTest.prepare(context); @@ -87,13 +83,10 @@ void prepare_successful_when_no_credentials_are_configured() throws IOException when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn(tempDir.toString()); PrepareWrapperContext context = new PrepareWrapperContext(createFromJSON("{}"), environment); - List remoteDataConfigurationList = new ArrayList<>(); SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); remoteDataConfiguration.setLocation("my-example-location"); remoteDataConfiguration.setType("docker"); - remoteDataConfigurationList.add(remoteDataConfiguration); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); - + context.setRemoteDataConfiguration(remoteDataConfiguration); /* execute */ moduleToTest.prepare(context); diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java index aff6de9a7..f5485f4aa 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java @@ -7,15 +7,12 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import com.mercedesbenz.sechub.commons.model.SecHubConfigurationModel; import com.mercedesbenz.sechub.commons.model.SecHubRemoteCredentialConfiguration; import com.mercedesbenz.sechub.commons.model.SecHubRemoteCredentialUserData; import com.mercedesbenz.sechub.commons.model.SecHubRemoteDataConfiguration; @@ -23,7 +20,6 @@ import com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironment; import com.mercedesbenz.sechub.wrapper.prepare.modules.PrepareWrapperInputValidatorException; import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperContext; -import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperRemoteConfigurationExtractor; class SkopeoInputValidatorTest { @@ -98,14 +94,12 @@ void validatePassword_throws_exception_for_invalid_passwords(String password) { void validate_throws_exception_when_credentials_are_empty() { /* prepare */ PrepareWrapperContext context = createContextEmptyConfig(); - List remoteDataConfigurationList = new ArrayList<>(); SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); remoteDataConfiguration.setCredentials(credentials); remoteDataConfiguration.setLocation("my-example-location"); remoteDataConfiguration.setType("docker"); - remoteDataConfigurationList.add(remoteDataConfiguration); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); + context.setRemoteDataConfiguration(remoteDataConfiguration); /* execute */ IllegalStateException exception = assertThrows(IllegalStateException.class, () -> validatorToTest.validate(context)); @@ -118,7 +112,6 @@ void validate_throws_exception_when_credentials_are_empty() { void prepare_throws_exception_when_no_username_found() { /* prepare */ PrepareWrapperContext context = createContextEmptyConfig(); - List remoteDataConfigurationList = new ArrayList<>(); SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); @@ -127,8 +120,7 @@ void prepare_throws_exception_when_no_username_found() { remoteDataConfiguration.setCredentials(credentials); remoteDataConfiguration.setLocation("my-example-location"); remoteDataConfiguration.setType("docker"); - remoteDataConfigurationList.add(remoteDataConfiguration); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); + context.setRemoteDataConfiguration(remoteDataConfiguration); /* execute */ IllegalStateException exception = assertThrows(IllegalStateException.class, () -> validatorToTest.validate(context)); @@ -141,7 +133,6 @@ void prepare_throws_exception_when_no_username_found() { void prepare_throws_exception_when_no_password_found() { /* prepare */ PrepareWrapperContext context = createContextEmptyConfig(); - List remoteDataConfigurationList = new ArrayList<>(); SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); @@ -150,8 +141,7 @@ void prepare_throws_exception_when_no_password_found() { remoteDataConfiguration.setCredentials(credentials); remoteDataConfiguration.setLocation("my-example-location"); remoteDataConfiguration.setType("docker"); - remoteDataConfigurationList.add(remoteDataConfiguration); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); + context.setRemoteDataConfiguration(remoteDataConfiguration); /* execute */ IllegalStateException exception = assertThrows(IllegalStateException.class, () -> validatorToTest.validate(context)); @@ -173,7 +163,6 @@ void prepare_successful_when_user_credentials_are_configured_correctly() throws when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn(tempDir.toString()); PrepareWrapperContext context = new PrepareWrapperContext(createFromJSON("{}"), environment); - List remoteDataConfigurationList = new ArrayList<>(); SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); @@ -183,8 +172,7 @@ void prepare_successful_when_user_credentials_are_configured_correctly() throws remoteDataConfiguration.setCredentials(credentials); remoteDataConfiguration.setLocation("my-example-location"); remoteDataConfiguration.setType("docker"); - remoteDataConfigurationList.add(remoteDataConfiguration); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); + context.setRemoteDataConfiguration(remoteDataConfiguration); /* execute + test */ assertDoesNotThrow(() -> validatorToTest.validate(context)); @@ -202,12 +190,10 @@ void prepare_successful_when_no_credentials_are_configured() throws IOException when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn(tempDir.toString()); PrepareWrapperContext context = new PrepareWrapperContext(createFromJSON("{}"), environment); - List remoteDataConfigurationList = new ArrayList<>(); SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); remoteDataConfiguration.setLocation("my-example-location"); remoteDataConfiguration.setType("docker"); - remoteDataConfigurationList.add(remoteDataConfiguration); - context.setRemoteDataConfigurationList(remoteDataConfigurationList); + context.setRemoteDataConfiguration(remoteDataConfiguration); /* execute + test */ assertDoesNotThrow(() -> validatorToTest.validate(context)); @@ -219,36 +205,4 @@ private PrepareWrapperContext createContextEmptyConfig() { when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn("test-upload-folder"); return new PrepareWrapperContext(createFromJSON("{}"), environment); } - - private PrepareWrapperContext createContextWithRemoteDataConfig(String location) { - String json = """ - { - "apiVersion": "1.0", - "data": { - "sources": [ - { - "name": "remote_example_name", - "remote": { - "location": "$location", - "type": "docker" - } - } - ] - }, - "codeScan": { - "use": [ - "remote_example_name" - ] - } - } - """.replace("$location", location); - SecHubConfigurationModel model = createFromJSON(json); - PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); - PrepareWrapperRemoteConfigurationExtractor extractor = new PrepareWrapperRemoteConfigurationExtractor(); - List creds = extractor.extract(model); - when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn("test-upload-folder"); - PrepareWrapperContext context = new PrepareWrapperContext(model, environment); - context.setRemoteDataConfigurationList(creds); - return context; - } } diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationServiceTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationServiceTest.java index 6f430373a..4b225b550 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationServiceTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationServiceTest.java @@ -6,7 +6,6 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -53,12 +52,10 @@ void when_no_remote_data_was_configured_return_preparation_success_with_warn_mes @Test void when_remote_data_was_configured_but_no_module_executed_return_preparation_failed_with_message() throws IOException { /* prepare */ - List remoteDataConfigurationList = new ArrayList<>(); SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); remoteDataConfiguration.setLocation("my-example_location"); remoteDataConfiguration.setType("git"); - remoteDataConfigurationList.add(remoteDataConfiguration); - when(context.getRemoteDataConfigurationList()).thenReturn(remoteDataConfigurationList); + when(context.getRemoteDataConfiguration()).thenReturn(remoteDataConfiguration); /* execute */ AdapterExecutionResult result = serviceToTest.startPreparation(); @@ -76,12 +73,10 @@ void when_remote_data_was_configured_and_git_module_added_return_preparation_suc when(gitModule.prepare(context)).thenReturn(true); serviceToTest.modules.add(gitModule); - List remoteDataConfigurationList = new ArrayList<>(); SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); remoteDataConfiguration.setLocation("my-example_location"); remoteDataConfiguration.setType("git"); - remoteDataConfigurationList.add(remoteDataConfiguration); - when(context.getRemoteDataConfigurationList()).thenReturn(remoteDataConfigurationList); + when(context.getRemoteDataConfiguration()).thenReturn(remoteDataConfiguration); /* execute */ AdapterExecutionResult result = serviceToTest.startPreparation(); diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperRemoteConfigurationExtractorTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperRemoteConfigurationExtractorTest.java index 7671702cf..0337d3338 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperRemoteConfigurationExtractorTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperRemoteConfigurationExtractorTest.java @@ -3,8 +3,6 @@ import static com.mercedesbenz.sechub.commons.model.SecHubScanConfiguration.createFromJSON; import static org.junit.jupiter.api.Assertions.*; -import java.util.List; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -46,12 +44,11 @@ void extractor_returns_list_with_one_element_when_one_remote_section_is_configur SecHubConfigurationModel model = createFromJSON(json); /* execute */ - List result = extractorToTest.extract(model); + SecHubRemoteDataConfiguration result = extractorToTest.extract(model); /* test */ - assertEquals(1, result.size()); - assertEquals("remote_example_location", result.get(0).getLocation()); - assertEquals("git", result.get(0).getType()); + assertEquals("remote_example_location", result.getLocation()); + assertEquals("git", result.getType()); } @Test @@ -60,10 +57,10 @@ void extractor_returns_empty_list_when_sechub_model_is_empty() { SecHubConfigurationModel model = new SecHubConfigurationModel(); /* execute */ - List result = extractorToTest.extract(model); + SecHubRemoteDataConfiguration result = extractorToTest.extract(model); /* test */ - assertTrue(result.isEmpty()); + assertNull(result); } @Test @@ -114,18 +111,10 @@ void extractor_returns_list_with_three_elements_when_three_remote_sections_are_c SecHubConfigurationModel model = createFromJSON(json); /* execute */ - List result = extractorToTest.extract(model); + IllegalStateException exception = assertThrows(IllegalStateException.class, () -> extractorToTest.extract(model)); /* test */ - assertEquals(3, result.size()); - assertEquals("remote_example_location", result.get(0).getLocation()); - assertEquals("git", result.get(0).getType()); - - assertEquals("remote_example_location2", result.get(1).getLocation()); - assertEquals("docker", result.get(1).getType()); - - assertEquals("remote_example_location3", result.get(2).getLocation()); - assertEquals("", result.get(2).getType()); + assertTrue(exception.getMessage().contains("Only one remote data configuration is allowed.")); } } \ No newline at end of file From e4eeb3723d27a26b4eb5d1e5f54db01ccc2e72ad Mon Sep 17 00:00:00 2001 From: Laura Date: Tue, 21 May 2024 13:06:34 +0200 Subject: [PATCH 10/19] Refactored unit tests #3028 --- .../PrepareWrapperPreparationService.java | 1 - .../modules/git/GitInputValidatorTest.java | 134 +++++++++++++++++- .../git/PrepareWrapperModuleGitTest.java | 28 ++-- .../skopeo/SkopeoInputValidatorTest.java | 8 +- 4 files changed, 154 insertions(+), 17 deletions(-) diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java index 153707aa1..7fd2541da 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java @@ -47,7 +47,6 @@ public AdapterExecutionResult startPreparation() throws IOException { for (PrepareWrapperModule module : modules) { - // atLeastOneModuleExecuted = true; context.getUserMessages().add(new SecHubMessage(SecHubMessageType.INFO, "Execute prepare module: " + module.getClass().getSimpleName())); if (module.prepare(context)) { atLeastOneModuleExecuted = true; diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidatorTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidatorTest.java index 08371ac41..334861fc2 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidatorTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidatorTest.java @@ -1,24 +1,38 @@ package com.mercedesbenz.sechub.wrapper.prepare.modules.git; +import static com.mercedesbenz.sechub.commons.model.SecHubScanConfiguration.createFromJSON; import static com.mercedesbenz.sechub.wrapper.prepare.modules.InputValidatorExitcode.LOCATION_NOT_MATCHING_PATTERN; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import com.mercedesbenz.sechub.commons.model.SecHubRemoteCredentialConfiguration; +import com.mercedesbenz.sechub.commons.model.SecHubRemoteCredentialUserData; +import com.mercedesbenz.sechub.commons.model.SecHubRemoteDataConfiguration; +import com.mercedesbenz.sechub.test.TestFileWriter; +import com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironment; import com.mercedesbenz.sechub.wrapper.prepare.modules.PrepareWrapperInputValidatorException; +import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperContext; class GitInputValidatorTest { GitInputValidator gitInputValidatorToTest; - PrepareWrapperModuleGit gitModule; + TestFileWriter writer; @BeforeEach void beforeEach() { + writer = new TestFileWriter(); gitInputValidatorToTest = new GitInputValidator(); - gitModule = new PrepareWrapperModuleGit(); } @ParameterizedTest @@ -92,4 +106,120 @@ void validatePassword_throws_exception_when_password_is_invalid(String password) assertEquals("Defined password must match the git Api token pattern.", exception.getMessage()); } + @Test + void validate_throws_exception_when_credentials_are_empty() { + /* prepare */ + PrepareWrapperContext context = createContextEmptyConfig(); + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); + remoteDataConfiguration.setCredentials(credentials); + remoteDataConfiguration.setLocation("https://example.com/my-repo.git"); + remoteDataConfiguration.setType("git"); + context.setRemoteDataConfiguration(remoteDataConfiguration); + + /* execute */ + IllegalStateException exception = assertThrows(IllegalStateException.class, () -> gitInputValidatorToTest.validate(context)); + + /* test */ + assertEquals("Defined credentials must not be null.", exception.getMessage()); + } + + @Test + void validate_throws_exception_when_no_username_found() { + /* prepare */ + PrepareWrapperContext context = createContextEmptyConfig(); + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); + SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); + user.setPassword("password"); + credentials.setUser(user); + remoteDataConfiguration.setCredentials(credentials); + remoteDataConfiguration.setLocation("https://example.com/my-repo.git"); + remoteDataConfiguration.setType("git"); + context.setRemoteDataConfiguration(remoteDataConfiguration); + + /* execute */ + IllegalStateException exception = assertThrows(IllegalStateException.class, () -> gitInputValidatorToTest.validate(context)); + + /* test */ + assertTrue(exception.getMessage().contains("Defined username must not be null or empty.")); + } + + @Test + void validate_throws_exception_when_no_password_found() { + /* prepare */ + PrepareWrapperContext context = createContextEmptyConfig(); + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); + SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); + user.setName("my-example-name"); + credentials.setUser(user); + remoteDataConfiguration.setCredentials(credentials); + remoteDataConfiguration.setLocation("https://example.com/my-repo.git"); + remoteDataConfiguration.setType("git"); + context.setRemoteDataConfiguration(remoteDataConfiguration); + + /* execute */ + IllegalStateException exception = assertThrows(IllegalStateException.class, () -> gitInputValidatorToTest.validate(context)); + + /* test */ + assertEquals("Defined password must not be null or empty.", exception.getMessage()); + + } + + @Test + void validate_successful_when_user_credentials_are_configured_correctly() throws IOException { + /* prepare */ + File tempDir = Files.createTempDirectory("upload-folder").toFile(); + tempDir.deleteOnExit(); + String filename = "test"; + writer.save(new File(tempDir, filename), "some text", true); + + PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); + when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn(tempDir.toString()); + PrepareWrapperContext context = new PrepareWrapperContext(createFromJSON("{}"), environment); + + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); + SecHubRemoteCredentialUserData user = new SecHubRemoteCredentialUserData(); + user.setName("my-example-name"); + user.setPassword("ghp_exampleAPITOKEN8ffne3l6g9f393r8fbcsf"); + credentials.setUser(user); + remoteDataConfiguration.setCredentials(credentials); + remoteDataConfiguration.setLocation("https://example.com/my-repo.git"); + remoteDataConfiguration.setType("git"); + context.setRemoteDataConfiguration(remoteDataConfiguration); + + /* execute + test */ + assertDoesNotThrow(() -> gitInputValidatorToTest.validate(context)); + } + + @Test + void validate_successful_when_no_credentials_are_configured() throws IOException { + /* prepare */ + File tempDir = Files.createTempDirectory("upload-folder").toFile(); + tempDir.deleteOnExit(); + String filename = "test"; + writer.save(new File(tempDir, filename), "some text", true); + + PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); + when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn(tempDir.toString()); + PrepareWrapperContext context = new PrepareWrapperContext(createFromJSON("{}"), environment); + + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + remoteDataConfiguration.setLocation("https://example.com/my-repo.git"); + remoteDataConfiguration.setType("git"); + context.setRemoteDataConfiguration(remoteDataConfiguration); + + /* execute + test */ + assertDoesNotThrow(() -> gitInputValidatorToTest.validate(context)); + + } + + private PrepareWrapperContext createContextEmptyConfig() { + PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); + when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn("test-upload-folder"); + return new PrepareWrapperContext(createFromJSON("{}"), environment); + } + } \ No newline at end of file diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java index bda73d5ef..4105476f9 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java @@ -17,6 +17,8 @@ import com.mercedesbenz.sechub.commons.model.SecHubRemoteDataConfiguration; import com.mercedesbenz.sechub.test.TestFileWriter; import com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironment; +import com.mercedesbenz.sechub.wrapper.prepare.modules.InputValidatorExitcode; +import com.mercedesbenz.sechub.wrapper.prepare.modules.PrepareWrapperInputValidatorException; import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperContext; class PrepareWrapperModuleGitTest { @@ -42,25 +44,31 @@ void beforeEach() { } @Test - void prepare_throws_exception_when_credentials_are_empty() throws IOException { + void when_inputvalidator_throws_InputValidatorException_prepare_return_false() throws IOException, PrepareWrapperInputValidatorException { /* prepare */ PrepareWrapperContext context = createContext(); - SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); - SecHubRemoteCredentialConfiguration credentials = new SecHubRemoteCredentialConfiguration(); - remoteDataConfiguration.setCredentials(credentials); - remoteDataConfiguration.setLocation("my-example-location"); - remoteDataConfiguration.setType("git"); - context.setRemoteDataConfiguration(remoteDataConfiguration); + doThrow(new PrepareWrapperInputValidatorException("test", InputValidatorExitcode.LOCATION_NOT_MATCHING_PATTERN)).when(gitInputValidator) + .validate(context); /* execute */ - IllegalStateException exception = assertThrows(IllegalStateException.class, () -> moduleToTest.prepare(context)); + boolean result = moduleToTest.prepare(context); /* test */ - assertEquals("Defined credentials have no credential user data for location: my-example-location", exception.getMessage()); + assertFalse(result); + } + + @Test + void when_inputvalidator_throws_exception_prepare_throws_exception() throws PrepareWrapperInputValidatorException { + /* prepare */ + PrepareWrapperContext context = createContext(); + doThrow(new IllegalStateException("test")).when(gitInputValidator).validate(context); + + /* execute + test */ + assertThrows(IllegalStateException.class, () -> moduleToTest.prepare(context)); } @Test - void prepare_successful_when_user_credentials_are_configured_correctly() throws IOException { + void prepare_successful_with_user_credentials_configured() throws IOException { /* prepare */ File tempDir = Files.createTempDirectory("upload-folder").toFile(); tempDir.deleteOnExit(); diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java index f5485f4aa..69e0639ed 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java @@ -109,7 +109,7 @@ void validate_throws_exception_when_credentials_are_empty() { } @Test - void prepare_throws_exception_when_no_username_found() { + void validate_throws_exception_when_no_username_found() { /* prepare */ PrepareWrapperContext context = createContextEmptyConfig(); SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); @@ -130,7 +130,7 @@ void prepare_throws_exception_when_no_username_found() { } @Test - void prepare_throws_exception_when_no_password_found() { + void validate_throws_exception_when_no_password_found() { /* prepare */ PrepareWrapperContext context = createContextEmptyConfig(); SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); @@ -152,7 +152,7 @@ void prepare_throws_exception_when_no_password_found() { } @Test - void prepare_successful_when_user_credentials_are_configured_correctly() throws IOException { + void validate_successful_when_user_credentials_are_configured_correctly() throws IOException { /* prepare */ File tempDir = Files.createTempDirectory("upload-folder").toFile(); tempDir.deleteOnExit(); @@ -179,7 +179,7 @@ void prepare_successful_when_user_credentials_are_configured_correctly() throws } @Test - void prepare_successful_when_no_credentials_are_configured() throws IOException { + void validate_successful_when_no_credentials_are_configured() throws IOException { /* prepare */ File tempDir = Files.createTempDirectory("upload-folder").toFile(); tempDir.deleteOnExit(); From d3fd439983afdb63486f7b2c4e192eee7543097f Mon Sep 17 00:00:00 2001 From: Laura Date: Tue, 21 May 2024 13:33:45 +0200 Subject: [PATCH 11/19] Added secodn test for filesystem and remote data #3133 --- .../SecHubConfigurationModelValidator.java | 3 +- .../model/SecHubDataConfigurationObject.java | 4 +-- ...SecHubConfigurationModelValidatorTest.java | 15 +++++++++ ...config_invalid_config_with_filesystem.json | 31 +++++++++++++++++++ 4 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_config_with_filesystem.json diff --git a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java index 703bc4d23..ea52eb0d9 100644 --- a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java +++ b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java @@ -569,7 +569,8 @@ private void validateRemoteDataSection(InternalValidationContext context, Collec String uniqueName = configurationObject.getUniqueName(); if (configurationObjects.size() > 1) { - // remote data is configured with multiple configurations + // remote data is configured with multiple configurations (filesystem or second + // remote) result.addError(REMOTE_DATA_MULTI_CONFIGURATION_NOT_ALLOWED); } diff --git a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubDataConfigurationObject.java b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubDataConfigurationObject.java index 6e99d3f04..73394aa26 100644 --- a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubDataConfigurationObject.java +++ b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubDataConfigurationObject.java @@ -18,8 +18,8 @@ public interface SecHubDataConfigurationObject { * null */ @JsonProperty("name") - public String getUniqueName(); + String getUniqueName(); - public Optional getRemote(); + Optional getRemote(); } diff --git a/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java b/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java index 2840e2a27..8dd5d037f 100644 --- a/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java +++ b/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java @@ -1705,6 +1705,21 @@ void when_remote_configuration_credential_user_has_no_password_error_REMOTE_DATA assertHasError(result, REMOTE_DATA_CONFIGURATION_USER_PASSWORD_NOT_DEFINED); } + @Test + void when_remote_configuration_is_mixed_with_filesystem_REMOTE_DATA_MIXED_CONFIGURATION_NOT_ALLOWED() { + /* prepare */ + String json = TestFileReader.loadTextFile("src/test/resources/sechub_remote_data_config_invalid_config_with_filesystem.json"); + SecHubScanConfiguration sechubConfiguration = SecHubScanConfiguration.createFromJSON(json); + modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); + + /* execute */ + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + + /* test */ + assertTrue(result.hasErrors()); + assertHasError(result, REMOTE_DATA_MULTI_CONFIGURATION_NOT_ALLOWED); + } + private SecHubConfigurationModel createSecHubConfigModelWithExactly8193Characters() { // 128*64 = 8192, so we take 127 because of the overhead of the JSON model: // {"apiVersion":""} = 17 characters so we need to add 48 characters afterwards diff --git a/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_config_with_filesystem.json b/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_config_with_filesystem.json new file mode 100644 index 000000000..e9de4830d --- /dev/null +++ b/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_config_with_filesystem.json @@ -0,0 +1,31 @@ +{ + "apiVersion": "1.0", + "data": { + "sources": [ + { + "name": "remote_example_name", + "remote": { + "location": "remote_example_location", + "type": "git", + "credentials": { + "user": { + "name": "my-example-user", + "password": "my-example-password" + } + } + } + }, + { + "name": "filesystem_example", + "fileSystem" : { + "folders" : [ "myProject/build" ] + } + } + ] + }, + "codeScan": { + "use": [ + "remote_example_name" + ] + } +} \ No newline at end of file From 702299ae938781bad0b5c49f6fde804ec01f8781 Mon Sep 17 00:00:00 2001 From: Laura Date: Wed, 22 May 2024 08:49:19 +0200 Subject: [PATCH 12/19] Added change requests #3133 --- ...cHubConfigurationModelValidationError.java | 2 +- .../SecHubConfigurationModelValidator.java | 63 ++++--- ...SecHubConfigurationModelValidatorTest.java | 162 +++++++++--------- .../SecHubConfigurationValidator.java | 2 +- .../SecHubConfigurationValidatorTest.java | 2 +- 5 files changed, 121 insertions(+), 110 deletions(-) diff --git a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidationError.java b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidationError.java index 2a3725aff..28e9d163c 100644 --- a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidationError.java +++ b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidationError.java @@ -74,7 +74,7 @@ public enum SecHubConfigurationModelValidationError { REMOTE_DATA_CONFIGURATION_USER_NAME_NOT_DEFINED("Remote data configuration credentials: user name is not defined."), - REMOTE_DATA_CONFIGURATION_USER_PASSWORD_NOT_DEFINED("Remote data configuration credentials: user password is not defined."),; + REMOTE_DATA_CONFIGURATION_USER_PASSWORD_NOT_DEFINED("Remote data configuration credentials: user password is not defined."); private String defaultMessage; diff --git a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java index ea52eb0d9..84c97e9d6 100644 --- a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java +++ b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java @@ -72,12 +72,12 @@ public SecHubConfigurationModelValidator() { * @param model * @return validation result */ - public SecHubConfigurationModelValidationResult validate(SecHubConfigurationModel model) { + public SecHubConfigurationModelValidationResult validateRemoteData(SecHubConfigurationModel model) { SecHubConfigurationModelValidationResult result = new SecHubConfigurationModelValidationResult(); InternalValidationContext context = new InternalValidationContext(); context.result = result; context.model = model; - validate(context); + validateRemoteData(context); return result; } @@ -128,7 +128,7 @@ private void handleMetaDataLabels(Map labels, SecHubConfiguratio } } - private void validate(InternalValidationContext context) { + private void validateRemoteData(InternalValidationContext context) { if (context.model == null) { context.result.addError(MODEL_NULL); return; @@ -566,41 +566,52 @@ private void validateRemoteDataSection(InternalValidationContext context, Collec return; } - String uniqueName = configurationObject.getUniqueName(); - if (configurationObjects.size() > 1) { // remote data is configured with multiple configurations (filesystem or second // remote) result.addError(REMOTE_DATA_MULTI_CONFIGURATION_NOT_ALLOWED); } - SecHubRemoteDataConfiguration remoteData = optRemoteData.get(); - if (remoteData.getLocation() == null || remoteData.getLocation().isEmpty()) { - result.addError(REMOTE_DATA_CONFIGURATION_LOCATION_NOT_DEFINED, "Remote data location is not defined for " + uniqueName); - } + validateRemoteData(configurationObject, result, optRemoteData); - if (remoteData.getCredentials().isEmpty()) { - // credentials don't need to be defined for public accessible remote data - return; - } + } + } - SecHubRemoteCredentialConfiguration remoteCredential = remoteData.getCredentials().get(); - if (remoteCredential.getUser().isEmpty()) { - result.addError(REMOTE_DATA_CONFIGURATION_USER_NOT_DEFINED, "Remote data configuration credentials: no user is defined for " + uniqueName); + private void validateRemoteData(SecHubDataConfigurationObject configurationObject, SecHubConfigurationModelValidationResult result, Optional optRemoteData) { + String uniqueName = configurationObject.getUniqueName(); + SecHubRemoteDataConfiguration remoteData = optRemoteData.get(); - } else { - SecHubRemoteCredentialUserData user = remoteCredential.getUser().get(); - if (user.getName() == null || user.getName().isEmpty()) { - result.addError(REMOTE_DATA_CONFIGURATION_USER_NAME_NOT_DEFINED, - "Remote data configuration credentials: user name is not defined for " + uniqueName); - } + if (remoteData.getLocation() == null || remoteData.getLocation().isEmpty()) { + result.addError(REMOTE_DATA_CONFIGURATION_LOCATION_NOT_DEFINED, "Remote data location is not defined for " + uniqueName); + } - if (user.getPassword() == null || user.getPassword().isEmpty()) { - result.addError(REMOTE_DATA_CONFIGURATION_USER_PASSWORD_NOT_DEFINED, - "Remote data configuration credentials: user password is not defined for " + uniqueName); - } + if (remoteData.getCredentials().isEmpty()) { + // credentials don't need to be defined for public accessible remote data + return; + } + + validateRemoteDataCredentials(result, remoteData, uniqueName); + } + + private void validateRemoteDataCredentials(SecHubConfigurationModelValidationResult result, SecHubRemoteDataConfiguration remoteData, String uniqueName) { + SecHubRemoteCredentialConfiguration remoteCredential = remoteData.getCredentials().get(); + if (remoteCredential.getUser().isEmpty()) { + result.addError(REMOTE_DATA_CONFIGURATION_USER_NOT_DEFINED, "Remote data configuration credentials: no user is defined for " + uniqueName); + + } else { + SecHubRemoteCredentialUserData user = remoteCredential.getUser().get(); + + String name = user.getName(); + if (name == null || name.isBlank()) { + result.addError(REMOTE_DATA_CONFIGURATION_USER_NAME_NOT_DEFINED, + "Remote data configuration credentials: user name is not defined for " + uniqueName); } + String password = user.getPassword(); + if (password == null || password.isBlank()) { + result.addError(REMOTE_DATA_CONFIGURATION_USER_PASSWORD_NOT_DEFINED, + "Remote data configuration credentials: user password is not defined for " + uniqueName); + } } } diff --git a/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java b/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java index 8dd5d037f..5a2ca6af4 100644 --- a/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java +++ b/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java @@ -56,7 +56,7 @@ void when_no_scan_type_is_set_validation_fails_with_CONTAINS_NO_SCAN_CONFIGURATI model.setApiVersion("1.0"); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, CONTAINS_NO_SCAN_CONFIGURATION); @@ -69,7 +69,7 @@ void when_scan_type_codescan_validation_fails_NOT_with_CONTAINS_NO_SCAN_CONFIGUR model.setCodeScan(new SecHubCodeScanConfiguration()); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNotError(result, CONTAINS_NO_SCAN_CONFIGURATION); @@ -82,7 +82,7 @@ void when_scan_type_licensescan_validation_fails_NOT_with_CONTAINS_NO_SCAN_CONFI model.setLicenseScan(new SecHubLicenseScanConfiguration()); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNotError(result, CONTAINS_NO_SCAN_CONFIGURATION); @@ -95,7 +95,7 @@ void when_scan_type_webscan_validation_fails_NOT_with_CONTAINS_NO_SCAN_CONFIGURA model.setWebScan(new SecHubWebScanConfiguration()); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNotError(result, CONTAINS_NO_SCAN_CONFIGURATION); @@ -108,7 +108,7 @@ void when_scan_type_secretscan_validation_fails_NOT_with_CONTAINS_NO_SCAN_CONFIG model.setSecretScan(new SecHubSecretScanConfiguration()); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNotError(result, CONTAINS_NO_SCAN_CONFIGURATION); @@ -121,7 +121,7 @@ void when_scan_type_infrascan_validation_fails_NOT_with_CONTAINS_NO_SCAN_CONFIGU model.setInfraScan(new SecHubInfrastructureScanConfiguration()); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNotError(result, CONTAINS_NO_SCAN_CONFIGURATION); @@ -136,7 +136,7 @@ void when_modelcollector_collects_no_scan_types_the_validation_fails_with_nonuni assertNull(ModuleGroup.resolveModuleGroupOrNull(modelSupportCollectedScanTypes)); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.NO_MODULE_GROUP_DETECTED); @@ -155,7 +155,7 @@ void when_modelcollector_collects_two_scan_types_which_are_not_in_same_group_the assertNull(ModuleGroup.resolveModuleGroupOrNull(modelSupportCollectedScanTypes)); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.MULTIPLE_MODULE_GROUPS_DETECTED); @@ -173,7 +173,7 @@ void when_modelcollector_collects_two_scan_types_which_are_in_same_group_the_val assertNotNull(ModuleGroup.resolveModuleGroupOrNull(modelSupportCollectedScanTypes)); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNoErrors(result); @@ -205,7 +205,7 @@ void a_configuration_which_has_code_scan_and_license_scan_will_NOT_fail_because_ model.getLicenseScan().get().getNamesOfUsedDataConfigurationObjects().add("config-object-name"); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNoErrors(result); @@ -223,7 +223,7 @@ void empty_webscanconfig_results_in_error() throws Exception { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_HAS_NO_URL_DEFINED); @@ -242,7 +242,7 @@ void license_scan__empty_config_results_in_error() throws Exception { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.NO_DATA_CONFIG_SPECIFIED_FOR_SCAN); @@ -271,7 +271,7 @@ void license_scan__config_with_data() throws Exception { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNoErrors(result); @@ -291,7 +291,7 @@ void webscanconfig_with_https_uri_set_has_no_error() throws Exception { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertFalse(result.hasErrors()); @@ -311,7 +311,7 @@ void webscanconfig_with_ftp_uri_set_has_error() throws Exception { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_URL_HAS_UNSUPPORTED_SCHEMA); @@ -330,7 +330,7 @@ void empty_infrascanconfig_results_in_error() throws Exception { modelSupportCollectedScanTypes.add(ScanType.INFRA_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.INFRA_SCAN_HAS_NO_URIS_OR_IPS_DEFINED); @@ -351,7 +351,7 @@ void infrascanconfig_with_one_uri_results_in_no_error() throws Exception { modelSupportCollectedScanTypes.add(ScanType.INFRA_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNoErrors(result); @@ -371,7 +371,7 @@ void infrascanconfig_with_one_ip_results_in_no_error() throws Exception { modelSupportCollectedScanTypes.add(ScanType.INFRA_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertFalse(result.hasErrors()); @@ -381,7 +381,7 @@ void infrascanconfig_with_one_ip_results_in_no_error() throws Exception { @Test void null_model_results_in_one_error() { /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(null); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(null); modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found @@ -399,7 +399,7 @@ void api_version_set_but_no_scan_configuration_results_in_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.CONTAINS_NO_SCAN_CONFIGURATION); @@ -415,7 +415,7 @@ void api_version_null_in_model_results_in_one_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.API_VERSION_NULL); @@ -431,7 +431,7 @@ void api_version_unsupported_results_in_one_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.API_VERSION_NOT_SUPPORTED); @@ -455,7 +455,7 @@ void model_having_a_data_configuration_with_valid_name_has_no_error(String name) modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute + test */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNoErrors(result); @@ -476,7 +476,7 @@ void model_having_a_data_configuration_with_invalid_name_has_error(String name) modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute + test */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertTrue(result.hasErrors()); @@ -498,7 +498,7 @@ void model_having_a_code_scan_configuration_which_references_a_wellknown_data_ob modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute + test */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNoErrors(result); @@ -513,7 +513,7 @@ void model_having_a_code_scan_configuration_which_references_an_unknown_data_obj modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute + test */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, "config-object-not-existing1", SecHubConfigurationModelValidationError.REFERENCED_DATA_CONFIG_OBJECT_NAME_NOT_EXISTING); @@ -536,7 +536,7 @@ void model_having_a_web_scan_configuration_with_open_api_which_references_an_unk modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); // simulate correct module group found /* execute + test */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, "unknown-configuration", SecHubConfigurationModelValidationError.REFERENCED_DATA_CONFIG_OBJECT_NAME_NOT_EXISTING); @@ -566,7 +566,7 @@ void model_having_a_web_scan_configuration_with_open_api_which_references_a_well modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); // simulate correct module group found /* execute + test */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertFalse(result.hasErrors()); @@ -592,7 +592,7 @@ void model_having_two_elements_in_source_data_section_with_same_name_results_in_ modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute + test */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.DATA_CONFIG_OBJECT_NAME_IS_NOT_UNIQUE); @@ -614,7 +614,7 @@ void model_having_one_elements_with_name_with_length101_has_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.DATA_CONFIG_OBJECT_NAME_LENGTH_TOO_LONG); @@ -636,7 +636,7 @@ void model_having_one_elements_with_name_with_length0_has_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.DATA_CONFIG_OBJECT_NAME_LENGTH_TOO_SHORT); @@ -658,7 +658,7 @@ void model_having_one_elements_with_name_null_has_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.DATA_CONFIG_OBJECT_NAME_IS_NULL); @@ -679,7 +679,7 @@ void model_having_one_element_with_name_not_set_has_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.DATA_CONFIG_OBJECT_NAME_IS_NULL); @@ -707,7 +707,7 @@ void model_having_two_elements_in_binary_data_section_with_same_name_has_error() modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ @@ -735,7 +735,7 @@ void model_having_two_elements_in_binary_and_source_data_section_with_same_name_ modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertEquals(1, result.getErrors().size()); @@ -766,7 +766,7 @@ void model_having_two_elements_in_binary_and_source_data_section_with_different_ modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNoErrors(result); @@ -784,7 +784,7 @@ void secret_scan__empty_config_results_in_error() throws Exception { modelSupportCollectedScanTypes.add(ScanType.SECRET_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.NO_DATA_CONFIG_SPECIFIED_FOR_SCAN); @@ -813,7 +813,7 @@ void secret_scan__config_with_data() throws Exception { modelSupportCollectedScanTypes.add(ScanType.SECRET_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertFalse(result.hasErrors()); @@ -842,7 +842,7 @@ void model_with_given_amount_of__valid_metadata_labels_has_no_error(int amount) modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertFalse(result.hasErrors()); @@ -872,7 +872,7 @@ void model_with_given_amount_of__valid_metadata_labels_has_error(int amount) { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertTrue(result.hasErrors()); @@ -900,7 +900,7 @@ void model_with_metadata_label_key_length31_has_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.METADATA_LABEL_KEY_TOO_LONG); @@ -927,7 +927,7 @@ void model_with_metadata_label_key_length30_has_no_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNoErrors(result); @@ -954,7 +954,7 @@ void model_with_metadata_label_value_length_has_error(int length) { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.METADATA_LABEL_VALUE_TOO_LONG); @@ -982,7 +982,7 @@ void model_with_metadata_label_key_not_allowed_character_inside_has_error_code_s modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.METADATA_LABEL_KEY_CONTAINS_ILLEGAL_CHARACTERS); @@ -1010,7 +1010,7 @@ void model_with_metadata_label_key_not_allowed_character_inside_has_error_licens modelSupportCollectedScanTypes.add(ScanType.LICENSE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.METADATA_LABEL_KEY_CONTAINS_ILLEGAL_CHARACTERS); @@ -1039,7 +1039,7 @@ void model_with_metadata_label_key_allowed_character_inside_has_no_error_codeSca modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNoErrors(result); @@ -1067,7 +1067,7 @@ void model_with_metadata_label_key_allowed_character_inside_has_no_error_webScan modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNoErrors(result); @@ -1094,7 +1094,7 @@ void model_with_metadata_label_value_length_has_no_error(int length) { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNoErrors(result); @@ -1114,7 +1114,7 @@ void model_has_valid_urls_for_headers_specified_has_no_error(String onlyForUrl) modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNoErrors(result); @@ -1143,7 +1143,7 @@ void model_has_valid_only_for_urls_and_multiple_headers_for_headers_specified_ha modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNoErrors(result); @@ -1170,7 +1170,7 @@ void model_has_valid_only_for_urls_and_one_header_for_headers_specified_has_no_e modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNoErrors(result); @@ -1189,7 +1189,7 @@ void model_has_valid_urls_for_headers_specified_but_different_target_url_has_err modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_HTTP_HEADER_ONLY_FOR_URL_DOES_NOT_CONTAIN_TARGET_URL); @@ -1208,7 +1208,7 @@ void model_has_invalid_url_for_headers_specified_has_error(String onlyForUrl) { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_HTTP_HEADER_ONLY_FOR_URL_IS_NOT_A_VALID_URL); @@ -1234,7 +1234,7 @@ void model_has_multiple_only_for_urls_with_at_least_one_invalid_for_headers_spec modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_HTTP_HEADER_ONLY_FOR_URL_IS_NOT_A_VALID_URL); @@ -1262,7 +1262,7 @@ void model_has_multiple_only_for_urls_in_multiple_headers_with_at_least_one_inva modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_HTTP_HEADER_ONLY_FOR_URL_IS_NOT_A_VALID_URL); @@ -1286,7 +1286,7 @@ void model_has_no_header_names_specified_has_error(String missingHeaderName) { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_NO_HEADER_NAME_DEFINED); @@ -1310,7 +1310,7 @@ void model_has_no_header_values_specified_has_error(String missingHeaderValue) { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_NO_HEADER_VALUE_DEFINED); @@ -1336,7 +1336,7 @@ void model_has_header_value_only_from_file_ref_specified_has_no_error(String exp modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNoErrors(result); @@ -1360,7 +1360,7 @@ void model_has_multiple_header_values_from_file_ref_and_direct_value_specified_h modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_MULTIPLE_HEADER_VALUES_DEFINED); @@ -1376,7 +1376,7 @@ void explicit_definitions_for_the_same_header_for_certain_urls_but_list_of_urls_ modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertHasNoErrors(result); @@ -1394,7 +1394,7 @@ void explicit_definitions_for_the_same_header_for_certain_urls_but_list_of_urls_ modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertHasNoErrors(result); @@ -1410,7 +1410,7 @@ void default_for_a_header_with_explicit_definitions_for_the_same_header_for_cert modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertHasNoErrors(result); @@ -1427,7 +1427,7 @@ void duplicated_default_for_the_same_header_has_error(String testFilePath) { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_NON_UNIQUE_HEADER_CONFIGURATION); @@ -1444,7 +1444,7 @@ void explicit_definitions_for_the_same_header_for_certain_urls_but_list_of_urls_ modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_NON_UNIQUE_HEADER_CONFIGURATION); @@ -1465,7 +1465,7 @@ void valid_include_and_exclude_has_no_errors(String includeExcludeEntry) { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertHasNoErrors(result); @@ -1483,7 +1483,7 @@ void double_slashes_include_exclude_has_errors(String includeExcludeEntry) { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_EXCLUDE_INVALID); assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_INCLUDE_INVALID); @@ -1501,7 +1501,7 @@ void spaces_in_include_exclude_has_errors(String includeExcludeEntry) { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_EXCLUDE_INVALID); assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_INCLUDE_INVALID); @@ -1517,7 +1517,7 @@ void too_many_excludes_results_in_error() { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_EXCLUDE_INVALID); @@ -1534,7 +1534,7 @@ void too_many_includes_results_in_error() { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_INCLUDE_INVALID); @@ -1551,7 +1551,7 @@ void exclude_too_long_results_in_error() { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_EXCLUDE_INVALID); @@ -1568,7 +1568,7 @@ void include_too_long_results_in_error() { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_INCLUDE_INVALID); @@ -1583,7 +1583,7 @@ void can_read_sechub_web_scan_config_with_wildcards() { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertHasNoErrors(result); @@ -1595,7 +1595,7 @@ void when_sechub_config_too_large_validation_fails_with_SECHUB_CONFIGURATION_TOO SecHubConfigurationModel model = createSecHubConfigModelWithExactly8193Characters(); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasError(result, SECHUB_CONFIGURATION_TOO_LARGE); @@ -1609,7 +1609,7 @@ void when_sechub_config_has_exactly_maximum_size_allowed_error_SECHUB_CONFIGURAT model.setApiVersion(model.getApiVersion().substring(1)); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); /* test */ assertHasNotError(result, SECHUB_CONFIGURATION_TOO_LARGE); @@ -1624,7 +1624,7 @@ void when_remote_sechub_configuration_is_valid_no_errors_are_reported(String fil modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertHasNoErrors(result); @@ -1638,7 +1638,7 @@ void when_multiple_remote_configurations_are_configured_error_REMOTE_DATA_MULTI_ modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertTrue(result.hasErrors()); @@ -1653,7 +1653,7 @@ void when_remote_configuration_location_is_not_defined_error_REMOTE_DATA_CONFIGU modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertTrue(result.hasErrors()); @@ -1668,7 +1668,7 @@ void when_remote_configuration_has_empty_credentials_error_REMOTE_DATA_CONFIGURA modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertTrue(result.hasErrors()); @@ -1683,7 +1683,7 @@ void when_remote_configuration_credential_user_has_no_username_error_REMOTE_DATA modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertTrue(result.hasErrors()); @@ -1698,7 +1698,7 @@ void when_remote_configuration_credential_user_has_no_password_error_REMOTE_DATA modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertTrue(result.hasErrors()); @@ -1713,7 +1713,7 @@ void when_remote_configuration_is_mixed_with_filesystem_REMOTE_DATA_MIXED_CONFIG modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); /* test */ assertTrue(result.hasErrors()); diff --git a/sechub-shared-kernel/src/main/java/com/mercedesbenz/sechub/sharedkernel/configuration/SecHubConfigurationValidator.java b/sechub-shared-kernel/src/main/java/com/mercedesbenz/sechub/sharedkernel/configuration/SecHubConfigurationValidator.java index ecc4b99e2..001b76bb4 100644 --- a/sechub-shared-kernel/src/main/java/com/mercedesbenz/sechub/sharedkernel/configuration/SecHubConfigurationValidator.java +++ b/sechub-shared-kernel/src/main/java/com/mercedesbenz/sechub/sharedkernel/configuration/SecHubConfigurationValidator.java @@ -41,7 +41,7 @@ public void validate(Object target, Errors errors) { LOG.debug("Start validation for: {}", target); SecHubConfiguration configuration = (SecHubConfiguration) target; - SecHubConfigurationModelValidationResult modelValidationResult = modelValidator.validate(configuration); + SecHubConfigurationModelValidationResult modelValidationResult = modelValidator.validateRemoteData(configuration); handleExplicitErrorCodes(errors, modelValidationResult); addGenericErrorsWhenNecessary(errors, modelValidationResult); diff --git a/sechub-shared-kernel/src/test/java/com/mercedesbenz/sechub/sharedkernel/configuration/SecHubConfigurationValidatorTest.java b/sechub-shared-kernel/src/test/java/com/mercedesbenz/sechub/sharedkernel/configuration/SecHubConfigurationValidatorTest.java index 24226a432..7f96ff312 100644 --- a/sechub-shared-kernel/src/test/java/com/mercedesbenz/sechub/sharedkernel/configuration/SecHubConfigurationValidatorTest.java +++ b/sechub-shared-kernel/src/test/java/com/mercedesbenz/sechub/sharedkernel/configuration/SecHubConfigurationValidatorTest.java @@ -46,7 +46,7 @@ public void before() throws Exception { configurationModelValidationResult = mock(SecHubConfigurationModelValidationResult.class); modelValidator = mock(SecHubConfigurationModelValidator.class); - when(modelValidator.validate(any())).thenReturn(configurationModelValidationResult); + when(modelValidator.validateRemoteData(any())).thenReturn(configurationModelValidationResult); validatorToTest.modelValidator = modelValidator; From 195bf0c3cdd4d24487e5652b31426cabc0387ac2 Mon Sep 17 00:00:00 2001 From: Laura Date: Wed, 22 May 2024 10:45:30 +0200 Subject: [PATCH 13/19] Added change requests #3028 --- .../modules/AbstractInputValidator.java | 36 +++++++++++++------ .../wrapper/prepare/modules/WrapperTool.java | 5 --- .../modules/git/GitInputValidator.java | 5 ++- .../modules/git/PrepareWrapperModuleGit.java | 16 ++++----- .../prepare/modules/git/WrapperGit.java | 4 +++ .../skopeo/PrepareWrapperModuleSkopeo.java | 20 +++++------ .../modules/skopeo/SkopeoInputValidator.java | 5 ++- .../prepare/modules/skopeo/WrapperSkopeo.java | 5 +++ .../PrepareWrapperPreparationService.java | 14 +++----- ...reWrapperRemoteConfigurationExtractor.java | 8 +++++ .../modules/git/GitInputValidatorTest.java | 6 ++-- .../git/PrepareWrapperModuleGitTest.java | 21 +++++++++++ .../PrepareWrapperModuleSkopeoTest.java | 22 ++++++++++++ .../skopeo/SkopeoInputValidatorTest.java | 4 +-- 14 files changed, 120 insertions(+), 51 deletions(-) diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/AbstractInputValidator.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/AbstractInputValidator.java index f494ea58f..d09a85c0f 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/AbstractInputValidator.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/AbstractInputValidator.java @@ -3,6 +3,7 @@ import static com.mercedesbenz.sechub.wrapper.prepare.modules.InputValidatorExitcode.*; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.regex.Pattern; @@ -19,9 +20,17 @@ public class AbstractInputValidator implements InputValidator { private final Pattern LOCATION_PATTERN; private final Pattern USERNAME_PATTERN; private final Pattern PASSWORD_PATTERN; - private final List forbiddenCharacters = Arrays.asList(">", "<", "!", "?", "*", "'", "\"", ";", "&", "|", "`", "$", "{", "}"); + private final List forbiddenCharacters = Collections + .unmodifiableList(Arrays.asList(">", "<", "!", "?", "*", "'", "\"", ";", "&", "|", "`", "$", "{", "}")); public AbstractInputValidator(String type, Pattern locationPattern, Pattern usernamePattern, Pattern passwordPattern) { + assertPatternNotNull(locationPattern); + assertPatternNotNull(usernamePattern); + assertPatternNotNull(passwordPattern); + if (isTypeNullOrEmpty(type)) { + throw new IllegalArgumentException("Type must not be null or empty."); + } + this.TYPE = type; this.LOCATION_PATTERN = locationPattern; this.USERNAME_PATTERN = usernamePattern; @@ -39,7 +48,7 @@ private void validateModule(PrepareWrapperContext context) throws PrepareWrapper String type = secHubRemoteDataConfiguration.getType(); if (isTypeNullOrEmpty(type)) { - LOG.debug("Not type defined. Location is: {}", location); + LOG.debug("No type defined. Location is: {}", location); validateLocation(location); return; } else if (isMatchingType(type)) { @@ -52,9 +61,8 @@ private void validateModule(PrepareWrapperContext context) throws PrepareWrapper private void validateCredentials(PrepareWrapperContext context) throws PrepareWrapperInputValidatorException { SecHubRemoteDataConfiguration secHubRemoteDataConfiguration = context.getRemoteDataConfiguration(); - if (secHubRemoteDataConfiguration.getCredentials().isEmpty()) { - return; - } else { + + if (secHubRemoteDataConfiguration.getCredentials().isPresent()) { SecHubRemoteCredentialConfiguration remoteCredentialConfiguration = secHubRemoteDataConfiguration.getCredentials().get(); if (remoteCredentialConfiguration.getUser().isPresent()) { SecHubRemoteCredentialUserData user = remoteCredentialConfiguration.getUser().get(); @@ -63,13 +71,13 @@ private void validateCredentials(PrepareWrapperContext context) throws PrepareWr return; } // credentials object was empty - throw new IllegalStateException("Defined credentials must not be null."); + throw new IllegalStateException("Defined credentials must contain credential user and can not be empty."); } } public void validateUsername(String username) throws PrepareWrapperInputValidatorException { if (username == null || username.isBlank()) { - throw new IllegalStateException("Defined username must not be null or empty."); + throw new IllegalStateException("Defined username must not be null or empty. Username is required for login."); } if (!USERNAME_PATTERN.matcher(username).matches()) { @@ -79,7 +87,7 @@ public void validateUsername(String username) throws PrepareWrapperInputValidato public void validatePassword(String password) throws PrepareWrapperInputValidatorException { if (password == null || password.isBlank()) { - throw new IllegalStateException("Defined password must not be null or empty."); + throw new IllegalStateException("Defined password must not be null or empty. Password is required for login."); } if (!PASSWORD_PATTERN.matcher(password).matches()) { @@ -90,7 +98,7 @@ public void validatePassword(String password) throws PrepareWrapperInputValidato public void validateLocation(String location) throws PrepareWrapperInputValidatorException { if (location == null || location.isBlank()) { - throw new IllegalStateException("Defined location must not be null or empty."); + throw new IllegalStateException("Defined location must not be null or empty. Location is required for download remote data."); } validateLocationCharacters(location); if (!LOCATION_PATTERN.matcher(location).matches()) { @@ -108,12 +116,18 @@ private boolean isMatchingType(String type) { private void validateLocationCharacters(String url) { if (url.contains(" ")) { - throw new IllegalArgumentException("Defined URL must not contain whitespaces."); + throw new IllegalArgumentException("Defined location URL must not contain whitespaces."); } for (String forbiddenCharacter : forbiddenCharacters) { if (url.contains(forbiddenCharacter)) { - throw new IllegalArgumentException("Defined URL must not contain forbidden characters: " + forbiddenCharacter); + throw new IllegalArgumentException("Defined location URL must not contain forbidden characters: " + forbiddenCharacter); } } } + + private void assertPatternNotNull(Pattern pattern) { + if (pattern == null) { + throw new IllegalArgumentException("Pattern must not be null."); + } + } } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperTool.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperTool.java index 89cb5212b..217ddc00d 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperTool.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/WrapperTool.java @@ -8,12 +8,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.mercedesbenz.sechub.commons.pds.PDSDefaultParameterValueConstants; -import com.mercedesbenz.sechub.commons.pds.PDSProcessAdapterFactory; import com.mercedesbenz.sechub.commons.pds.ProcessAdapter; @Component @@ -28,9 +26,6 @@ public abstract class WrapperTool { @Value("${" + KEY_PDS_PREPARE_PROCESS_TIMEOUT_SECONDS + ":-1}") private int pdsPrepareProcessTimeoutSeconds; - @Autowired - public PDSProcessAdapterFactory processAdapterFactory; - protected abstract void cleanUploadDirectory(String uploadDirectory) throws IOException; protected void waitForProcessToFinish(ProcessAdapter process) { diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidator.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidator.java index 2ed907f16..08ad23daf 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidator.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidator.java @@ -12,10 +12,13 @@ public class GitInputValidator extends AbstractInputValidator { private static final String TYPE = "git"; private static final String GIT_LOCATION_REGEX = "((git|ssh|http(s)?)|(git@[\\w\\.]+))(:(//)?)([\\w\\.@\\:/\\-~]+)(\\.git)(/)?$"; + private static final Pattern GIT_LOCATION_PATTERN = Pattern.compile(GIT_LOCATION_REGEX); private static final String GIT_USERNAME_REGEX = "^[a-zA-Z0-9-_\\d](?:[a-zA-Z0-9-_\\d]|(?=[a-zA-Z0-9-_\\d])){0,38}$"; + private static final Pattern GIT_USERNAME_PATTERN = Pattern.compile(GIT_USERNAME_REGEX); private static final String GIT_PASSWORD_REGEX = "^(gh[ps]_[a-zA-Z0-9]{36}|github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59})$"; + private static final Pattern GIT_PASSWORD_PATTERN = Pattern.compile(GIT_PASSWORD_REGEX); public GitInputValidator() { - super(TYPE, Pattern.compile(GIT_LOCATION_REGEX), Pattern.compile(GIT_USERNAME_REGEX), Pattern.compile(GIT_PASSWORD_REGEX)); + super(TYPE, GIT_LOCATION_PATTERN, GIT_USERNAME_PATTERN, GIT_PASSWORD_PATTERN); } } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGit.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGit.java index 5b41b38d6..4ac7ca0cb 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGit.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGit.java @@ -26,7 +26,7 @@ @Service public class PrepareWrapperModuleGit implements PrepareWrapperModule { - Logger LOG = LoggerFactory.getLogger(PrepareWrapperModuleGit.class); + private static final Logger LOG = LoggerFactory.getLogger(PrepareWrapperModuleGit.class); @Value("${" + KEY_PDS_PREPARE_AUTO_CLEANUP_GIT_FOLDER + ":true}") private boolean pdsPrepareAutoCleanupGitFolder; @@ -61,13 +61,14 @@ public boolean prepare(PrepareWrapperContext context) throws IOException { prepareRemoteConfiguration(context, secHubRemoteDataConfiguration); if (!isDownloadSuccessful(context)) { + LOG.error("Download of git repository was not successful."); throw new IOException("Download of git repository was not successful."); } cleanup(context); return true; } - public boolean isDownloadSuccessful(PrepareWrapperContext context) { + protected boolean isDownloadSuccessful(PrepareWrapperContext context) { // check if download folder contains git Path path = Paths.get(context.getEnvironment().getPdsPrepareUploadFolderDirectory()); if (Files.isDirectory(path)) { @@ -88,13 +89,12 @@ private void prepareRemoteConfiguration(PrepareWrapperContext context, SecHubRem } Optional optUser = credentials.get().getUser(); - if (optUser.isPresent()) { - SecHubRemoteCredentialUserData user = optUser.get(); - clonePrivateRepository(context, user, location); - return; + if (optUser.isEmpty()) { + throw new IllegalStateException("Defined credentials have no credential user data for location: " + location); } - throw new IllegalStateException("Defined credentials have no credential user data for location: " + location); + SecHubRemoteCredentialUserData user = optUser.get(); + clonePrivateRepository(context, user, location); } private void clonePrivateRepository(PrepareWrapperContext context, SecHubRemoteCredentialUserData user, String location) throws IOException { @@ -112,7 +112,7 @@ private void clonePrivateRepository(PrepareWrapperContext context, SecHubRemoteC git.downloadRemoteData(gitContext); - SecHubMessage message = new SecHubMessage(SecHubMessageType.INFO, "Cloned private repository: " + location); + SecHubMessage message = new SecHubMessage(SecHubMessageType.INFO, "Cloned private image: " + location); context.getUserMessages().add(message); } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGit.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGit.java index 05f248700..c06a6f4e6 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGit.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGit.java @@ -11,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import com.mercedesbenz.sechub.commons.pds.PDSProcessAdapterFactory; import com.mercedesbenz.sechub.commons.pds.ProcessAdapter; import com.mercedesbenz.sechub.wrapper.prepare.modules.WrapperTool; @@ -22,6 +23,9 @@ public class WrapperGit extends WrapperTool { @Autowired JGitAdapter jGitAdapter; + @Autowired + PDSProcessAdapterFactory processAdapterFactory; + public void downloadRemoteData(GitContext gitContext) { LOG.debug("Start cloning with JGit."); jGitAdapter.clone(gitContext); diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeo.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeo.java index a48982d00..abbfce049 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeo.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeo.java @@ -27,7 +27,7 @@ @Service public class PrepareWrapperModuleSkopeo implements PrepareWrapperModule { - Logger LOG = LoggerFactory.getLogger(PrepareWrapperModuleSkopeo.class); + private static final Logger LOG = LoggerFactory.getLogger(PrepareWrapperModuleSkopeo.class); @Value("${" + KEY_PDS_PREPARE_MODULE_SKOPEO_ENABLED + ":true}") private boolean pdsPrepareModuleSkopeoEnabled; @@ -58,13 +58,14 @@ public boolean prepare(PrepareWrapperContext context) throws IOException { prepareRemoteConfiguration(context, secHubRemoteDataConfiguration); if (!isDownloadSuccessful(context)) { + LOG.error("Download of git repository was not successful."); throw new IOException("Download of docker image was not successful."); } cleanup(context); return true; } - public boolean isDownloadSuccessful(PrepareWrapperContext context) { + protected boolean isDownloadSuccessful(PrepareWrapperContext context) { // check if download folder contains a .tar archive Path path = Paths.get(context.getEnvironment().getPdsPrepareUploadFolderDirectory()); if (Files.isDirectory(path)) { @@ -75,7 +76,7 @@ public boolean isDownloadSuccessful(PrepareWrapperContext context) { .toList(); // collect all matched to a List return !result.isEmpty(); } catch (IOException e) { - throw new RuntimeException("Error while checking download of docker image", e); + return false; } } return false; @@ -95,13 +96,12 @@ private void prepareRemoteConfiguration(PrepareWrapperContext context, SecHubRem } Optional optUser = credentials.get().getUser(); - if (optUser.isPresent()) { - SecHubRemoteCredentialUserData user = optUser.get(); - downloadPrivateImage(context, user, location); - return; + if (optUser.isEmpty()) { + throw new IllegalStateException("Defined credentials have no credential user data for location: " + location); } - throw new IllegalStateException("Defined credentials have no credential user data for location: " + location); + SecHubRemoteCredentialUserData user = optUser.get(); + downloadPrivateImage(context, user, location); } private void downloadPrivateImage(PrepareWrapperContext context, SecHubRemoteCredentialUserData user, String location) throws IOException { @@ -119,7 +119,7 @@ private void downloadPrivateImage(PrepareWrapperContext context, SecHubRemoteCre skopeo.download(skopeoContext); - SecHubMessage message = new SecHubMessage(SecHubMessageType.INFO, "Cloned private repository: " + location); + SecHubMessage message = new SecHubMessage(SecHubMessageType.INFO, "Download private image: " + location); context.getUserMessages().add(message); } @@ -133,7 +133,7 @@ private void downloadPublicImage(PrepareWrapperContext context, String location) skopeo.download(skopeoContext); - SecHubMessage message = new SecHubMessage(SecHubMessageType.INFO, "Cloned public repository: " + location); + SecHubMessage message = new SecHubMessage(SecHubMessageType.INFO, "Download public image: " + location); context.getUserMessages().add(message); } } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidator.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidator.java index ba51fb3da..6ba219ab2 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidator.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidator.java @@ -12,11 +12,14 @@ public class SkopeoInputValidator extends AbstractInputValidator { public static final String TYPE = "docker"; private static final String SKOPEO_LOCATION_REGEX = "((docker://|https://)?([a-zA-Z0-9-_.].[a-zA-Z0-9-_.]/)?[a-zA-Z0-9-_.]+(:[a-zA-Z0-9-_.]+)?(/)?)+(@sha256:[a-f0-9]{64})?"; + private static final Pattern SKOPEO_LOCATION_PATTERN = Pattern.compile(SKOPEO_LOCATION_REGEX); private static final String SKOPEO_USERNAME_REGEX = "^[a-zA-Z0-9-_\\d](?:[a-zA-Z0-9-_\\d]|(?=[a-zA-Z0-9-_\\d])){0,38}$"; + private static final Pattern SKOPEO_USERNAME_PATTERN = Pattern.compile(SKOPEO_USERNAME_REGEX); private static final String SKOPEO_PASSWORD_REGEX = "^[a-zA-Z0-9-_\\d]{0,80}$"; + private static final Pattern SKOPEO_PASSWORD_PATTERN = Pattern.compile(SKOPEO_PASSWORD_REGEX); public SkopeoInputValidator() { - super(TYPE, Pattern.compile(SKOPEO_LOCATION_REGEX), Pattern.compile(SKOPEO_USERNAME_REGEX), Pattern.compile(SKOPEO_PASSWORD_REGEX)); + super(TYPE, SKOPEO_LOCATION_PATTERN, SKOPEO_USERNAME_PATTERN, SKOPEO_PASSWORD_PATTERN); } } diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeo.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeo.java index 72936f20e..c1524a19d 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeo.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeo.java @@ -9,10 +9,12 @@ import java.util.ArrayList; import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.mercedesbenz.sechub.commons.core.security.CryptoAccess; +import com.mercedesbenz.sechub.commons.pds.PDSProcessAdapterFactory; import com.mercedesbenz.sechub.commons.pds.ProcessAdapter; import com.mercedesbenz.sechub.wrapper.prepare.modules.WrapperTool; @@ -22,6 +24,9 @@ public class WrapperSkopeo extends WrapperTool { @Value("${" + KEY_PDS_PREPARE_AUTHENTICATION_FILE_SKOPEO + ":authentication.json}") String pdsPrepareAuthenticationFileSkopeo; + @Autowired + PDSProcessAdapterFactory processAdapterFactory; + public void download(SkopeoContext context) throws IOException { if (!context.getCredentialMap().isEmpty()) { login(context); diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java index 7fd2541da..bd5f684ed 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperPreparationService.java @@ -34,8 +34,6 @@ public class PrepareWrapperPreparationService { public AdapterExecutionResult startPreparation() throws IOException { - boolean atLeastOneModuleExecuted = false; - LOG.debug("Start preparation"); PrepareWrapperContext context = factory.create(environment); SecHubRemoteDataConfiguration remoteDataConfiguration = context.getRemoteDataConfiguration(); @@ -47,18 +45,14 @@ public AdapterExecutionResult startPreparation() throws IOException { for (PrepareWrapperModule module : modules) { - context.getUserMessages().add(new SecHubMessage(SecHubMessageType.INFO, "Execute prepare module: " + module.getClass().getSimpleName())); if (module.prepare(context)) { - atLeastOneModuleExecuted = true; + context.getUserMessages().add(new SecHubMessage(SecHubMessageType.INFO, "Executed prepare module: " + module.getClass().getSimpleName())); + PrepareResult result = new PrepareResult(PrepareStatus.OK); + return new AdapterExecutionResult(result.toString(), context.getUserMessages()); } } - if (!atLeastOneModuleExecuted) { - return createAdapterExecutionResult(PrepareStatus.FAILED, SecHubMessageType.ERROR, "No module was able to prepare the defined remote data."); - } - - PrepareResult result = new PrepareResult(PrepareStatus.OK); - return new AdapterExecutionResult(result.toString(), context.getUserMessages()); + return createAdapterExecutionResult(PrepareStatus.FAILED, SecHubMessageType.ERROR, "No module was able to prepare the defined remote data."); } private AdapterExecutionResult createAdapterExecutionResult(PrepareStatus status, SecHubMessageType type, String message) { diff --git a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperRemoteConfigurationExtractor.java b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperRemoteConfigurationExtractor.java index f2cdbba5e..d09427065 100644 --- a/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperRemoteConfigurationExtractor.java +++ b/sechub-wrapper-prepare/src/main/java/com/mercedesbenz/sechub/wrapper/prepare/prepare/PrepareWrapperRemoteConfigurationExtractor.java @@ -13,6 +13,14 @@ @Component public class PrepareWrapperRemoteConfigurationExtractor { + /** + * Extracts the remote data configuration from the SecHub configuration model. + * The method returns nul, if no remote configuration could be found. If more + * than one remote configuration is found, an exception is thrown. + * + * @param model sechub configuration model + * @return remote data configuration + */ public SecHubRemoteDataConfiguration extract(SecHubConfigurationModel model) { List remoteDataConfigurationList = new ArrayList<>(); if (model == null) { diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidatorTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidatorTest.java index 334861fc2..55609e897 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidatorTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/GitInputValidatorTest.java @@ -42,7 +42,7 @@ void validateLocation_throws_exception_when_url_does_contain_forbidden_character IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> gitInputValidatorToTest.validateLocation(repositoryUrl)); /* test */ - assertTrue(exception.getMessage().contains("Defined URL must not contain forbidden characters: ")); + assertTrue(exception.getMessage().contains("Defined location URL must not contain forbidden characters: ")); } @ParameterizedTest @@ -121,7 +121,7 @@ void validate_throws_exception_when_credentials_are_empty() { IllegalStateException exception = assertThrows(IllegalStateException.class, () -> gitInputValidatorToTest.validate(context)); /* test */ - assertEquals("Defined credentials must not be null.", exception.getMessage()); + assertEquals("Defined credentials must contain credential user and can not be empty.", exception.getMessage()); } @Test @@ -163,7 +163,7 @@ void validate_throws_exception_when_no_password_found() { IllegalStateException exception = assertThrows(IllegalStateException.class, () -> gitInputValidatorToTest.validate(context)); /* test */ - assertEquals("Defined password must not be null or empty.", exception.getMessage()); + assertEquals("Defined password must not be null or empty. Password is required for login.", exception.getMessage()); } diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java index 4105476f9..559b663c3 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java @@ -124,6 +124,27 @@ void prepare_successful_when_no_credentials_are_configured() throws IOException verify(git).downloadRemoteData(any(GitContext.class)); } + @Test + void prepare_returns_false_when_modul_is_disabled() throws IOException { + /* prepare */ + PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); + when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn("temp"); + PrepareWrapperContext context = new PrepareWrapperContext(createFromJSON("{}"), environment); + + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + remoteDataConfiguration.setLocation("my-example-location"); + remoteDataConfiguration.setType("docker"); + context.setRemoteDataConfiguration(remoteDataConfiguration); + + ReflectionTestUtils.setField(moduleToTest, "pdsPrepareModuleGitEnabled", false); + + /* execute */ + boolean result = moduleToTest.prepare(context); + + /* test */ + assertFalse(result); + } + @Test void isDownloadSuccessful_returns_true_when_git_file_in_directory() throws IOException { /* prepare */ diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java index 5d1de3973..444cf7121 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java @@ -95,6 +95,28 @@ void prepare_successful_when_no_credentials_are_configured() throws IOException verify(skopeo).cleanUploadDirectory(tempDir.toString()); } + @Test + void prepare_returns_false_when_modul_is_disabled() throws IOException { + /* prepare */ + + PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); + when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn("temp"); + PrepareWrapperContext context = new PrepareWrapperContext(createFromJSON("{}"), environment); + + SecHubRemoteDataConfiguration remoteDataConfiguration = new SecHubRemoteDataConfiguration(); + remoteDataConfiguration.setLocation("my-example-location"); + remoteDataConfiguration.setType("docker"); + context.setRemoteDataConfiguration(remoteDataConfiguration); + + ReflectionTestUtils.setField(moduleToTest, "pdsPrepareModuleSkopeoEnabled", false); + + /* execute */ + boolean result = moduleToTest.prepare(context); + + /* test */ + assertFalse(result); + } + @Test void isDownloadSuccessful_returns_true_when_tar_file_in_directory() throws IOException { /* prepare */ diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java index 69e0639ed..dc2e33c0c 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/SkopeoInputValidatorTest.java @@ -105,7 +105,7 @@ void validate_throws_exception_when_credentials_are_empty() { IllegalStateException exception = assertThrows(IllegalStateException.class, () -> validatorToTest.validate(context)); /* test */ - assertEquals("Defined credentials must not be null.", exception.getMessage()); + assertEquals("Defined credentials must contain credential user and can not be empty.", exception.getMessage()); } @Test @@ -147,7 +147,7 @@ void validate_throws_exception_when_no_password_found() { IllegalStateException exception = assertThrows(IllegalStateException.class, () -> validatorToTest.validate(context)); /* test */ - assertEquals("Defined password must not be null or empty.", exception.getMessage()); + assertEquals("Defined password must not be null or empty. Password is required for login.", exception.getMessage()); } From f008140970233667693086b2930810faf60d4fff Mon Sep 17 00:00:00 2001 From: Laura Date: Wed, 22 May 2024 15:11:04 +0200 Subject: [PATCH 14/19] split validation in several methods #3133 --- ...cHubConfigurationModelValidationError.java | 4 +- .../SecHubConfigurationModelValidator.java | 76 ++++++++++++++----- ...SecHubConfigurationModelValidatorTest.java | 24 +++++- ...config_invalid_config_with_filesystem.json | 6 ++ ...ta_config_invalid_source_and_binaries.json | 34 +++++++++ 5 files changed, 118 insertions(+), 26 deletions(-) create mode 100644 sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_source_and_binaries.json diff --git a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidationError.java b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidationError.java index 28e9d163c..b8916e052 100644 --- a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidationError.java +++ b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidationError.java @@ -66,7 +66,9 @@ public enum SecHubConfigurationModelValidationError { METADATA_LABEL_KEY_CONTAINS_ILLEGAL_CHARACTERS("Meta data label key contains illegal characters."), - REMOTE_DATA_MULTI_CONFIGURATION_NOT_ALLOWED("Remote data configuration is not allowed for multiple data configurations."), + REMOTE_DATA_CONFIGURATION_ONLY_FOR_ONE_SOURCE_OR_BINARY("Remote data configuration is only allowed for ONE source or for ONE binary."), + + REMOTE_DATA_MIXED_WITH_FILESYSTEM_NOT_ALLOWED("Remote data configuration is not allowed to be mixed with filesystem."), REMOTE_DATA_CONFIGURATION_LOCATION_NOT_DEFINED("Remote data configuration location is not defined."), diff --git a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java index 84c97e9d6..17cea3452 100644 --- a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java +++ b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java @@ -516,8 +516,11 @@ private void handleDataConfiguration(InternalValidationContext context) { validateNameUniqueAndNotNull(context, data.getSources()); validateNameUniqueAndNotNull(context, data.getBinaries()); - validateRemoteDataSection(context, data.getSources()); - validateRemoteDataSection(context, data.getBinaries()); + List sourcesAndBinaries = new ArrayList(); + sourcesAndBinaries.addAll(data.getSources()); + sourcesAndBinaries.addAll(data.getBinaries()); + + validateRemoteDataConfiguration(context, sourcesAndBinaries); } private void validateNameUniqueAndNotNull(InternalValidationContext context, Collection configurationObjects) { @@ -554,46 +557,77 @@ private void validateNameUniqueAndNotNull(InternalValidationContext context, Col } - private void validateRemoteDataSection(InternalValidationContext context, Collection configurationObjects) { + private void validateRemoteDataConfiguration(InternalValidationContext context, Collection sourcesAndBinaries) { SecHubConfigurationModelValidationResult result = context.result; - for (SecHubDataConfigurationObject configurationObject : configurationObjects) { - Optional optRemoteData = configurationObject.getRemote(); + validateOnlyOneRemoteSourceOrBinary(sourcesAndBinaries, result); + validateRemoteAndFileSystemAreNotMixed(sourcesAndBinaries, result); + validateRemoteData(sourcesAndBinaries, result); + } + + private void validateOnlyOneRemoteSourceOrBinary(Collection sourcesAndBinaries, + SecHubConfigurationModelValidationResult result) { + for (SecHubDataConfigurationObject sourceOrBinary : sourcesAndBinaries) { + Optional optRemoteData = sourceOrBinary.getRemote(); if (optRemoteData.isEmpty()) { // no remote data is configured - return; + continue; } - if (configurationObjects.size() > 1) { - // remote data is configured with multiple configurations (filesystem or second - // remote) - result.addError(REMOTE_DATA_MULTI_CONFIGURATION_NOT_ALLOWED); + // When using a remote data section it is only possible to define ONE binary or + // ONE source definition. + // Means also: It is only possible to define ONE remote data section. + boolean onlyOneBinaryOrOneSource = sourcesAndBinaries.size() == 1; + if (!onlyOneBinaryOrOneSource) { + result.addError(REMOTE_DATA_CONFIGURATION_ONLY_FOR_ONE_SOURCE_OR_BINARY); + break; } + } + } - validateRemoteData(configurationObject, result, optRemoteData); + private void validateRemoteAndFileSystemAreNotMixed(Collection sourcesAndBinaries, + SecHubConfigurationModelValidationResult result) { + boolean containsFileSystem = false; + boolean containsRemote = false; + for (SecHubDataConfigurationObject sourceOrBinary : sourcesAndBinaries) { + containsRemote = containsRemote || sourceOrBinary.getRemote().isPresent(); + if (sourceOrBinary instanceof SecHubFileSystemContainer) { + containsFileSystem = containsFileSystem || ((SecHubFileSystemContainer) sourceOrBinary).getFileSystem().isPresent(); + } + } + if (containsFileSystem && containsRemote) { + result.addError(REMOTE_DATA_MIXED_WITH_FILESYSTEM_NOT_ALLOWED); } } - private void validateRemoteData(SecHubDataConfigurationObject configurationObject, SecHubConfigurationModelValidationResult result, Optional optRemoteData) { - String uniqueName = configurationObject.getUniqueName(); - SecHubRemoteDataConfiguration remoteData = optRemoteData.get(); + private void validateRemoteData(Collection sourcesAndBinaries, SecHubConfigurationModelValidationResult result) { + for (SecHubDataConfigurationObject sourceOrBinary : sourcesAndBinaries) { + Optional optRemoteData = sourceOrBinary.getRemote(); + + if (optRemoteData.isEmpty()) { + // no remote data is configured + continue; + } + + String uniqueName = sourceOrBinary.getUniqueName(); + SecHubRemoteDataConfiguration remoteData = optRemoteData.get(); + + if (remoteData.getLocation() == null || remoteData.getLocation().isBlank()) { + result.addError(REMOTE_DATA_CONFIGURATION_LOCATION_NOT_DEFINED, "Remote data location is not defined for " + uniqueName); + } - if (remoteData.getLocation() == null || remoteData.getLocation().isEmpty()) { - result.addError(REMOTE_DATA_CONFIGURATION_LOCATION_NOT_DEFINED, "Remote data location is not defined for " + uniqueName); + validateRemoteDataCredentials(result, remoteData, uniqueName); } + } + private void validateRemoteDataCredentials(SecHubConfigurationModelValidationResult result, SecHubRemoteDataConfiguration remoteData, String uniqueName) { if (remoteData.getCredentials().isEmpty()) { // credentials don't need to be defined for public accessible remote data return; } - - validateRemoteDataCredentials(result, remoteData, uniqueName); - } - - private void validateRemoteDataCredentials(SecHubConfigurationModelValidationResult result, SecHubRemoteDataConfiguration remoteData, String uniqueName) { SecHubRemoteCredentialConfiguration remoteCredential = remoteData.getCredentials().get(); if (remoteCredential.getUser().isEmpty()) { result.addError(REMOTE_DATA_CONFIGURATION_USER_NOT_DEFINED, "Remote data configuration credentials: no user is defined for " + uniqueName); diff --git a/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java b/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java index 5a2ca6af4..216018118 100644 --- a/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java +++ b/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java @@ -1631,7 +1631,7 @@ void when_remote_sechub_configuration_is_valid_no_errors_are_reported(String fil } @Test - void when_multiple_remote_configurations_are_configured_error_REMOTE_DATA_MULTI_CONFIGURATION_NOT_ALLOWED() { + void when_multiple_remote_configurations_are_configured_error_REMOTE_DATA_CONFIGURATION_ONLY_FOR_ONE_SOURCE_OR_BINARY() { /* prepare */ String json = TestFileReader.loadTextFile("src/test/resources/sechub_remote_data_config_invalid_multi_config.json"); SecHubScanConfiguration sechubConfiguration = SecHubScanConfiguration.createFromJSON(json); @@ -1642,7 +1642,7 @@ void when_multiple_remote_configurations_are_configured_error_REMOTE_DATA_MULTI_ /* test */ assertTrue(result.hasErrors()); - assertHasError(result, REMOTE_DATA_MULTI_CONFIGURATION_NOT_ALLOWED); + assertHasError(result, REMOTE_DATA_CONFIGURATION_ONLY_FOR_ONE_SOURCE_OR_BINARY); } @Test @@ -1706,7 +1706,7 @@ void when_remote_configuration_credential_user_has_no_password_error_REMOTE_DATA } @Test - void when_remote_configuration_is_mixed_with_filesystem_REMOTE_DATA_MIXED_CONFIGURATION_NOT_ALLOWED() { + void when_remote_configuration_is_mixed_with_filesystem_REMOTE_REMOTE_DATA_MIXED_WITH_FILESYSTEM_NOT_ALLOWED() { /* prepare */ String json = TestFileReader.loadTextFile("src/test/resources/sechub_remote_data_config_invalid_config_with_filesystem.json"); SecHubScanConfiguration sechubConfiguration = SecHubScanConfiguration.createFromJSON(json); @@ -1717,7 +1717,23 @@ void when_remote_configuration_is_mixed_with_filesystem_REMOTE_DATA_MIXED_CONFIG /* test */ assertTrue(result.hasErrors()); - assertHasError(result, REMOTE_DATA_MULTI_CONFIGURATION_NOT_ALLOWED); + assertHasError(result, REMOTE_DATA_MIXED_WITH_FILESYSTEM_NOT_ALLOWED); + } + + @Test + void when_remote_data_is_configured_for_binaries_and_sources_error() { + /* prepare */ + String json = TestFileReader.loadTextFile("src/test/resources/sechub_remote_data_config_invalid_source_and_binaries.json"); + SecHubScanConfiguration sechubConfiguration = SecHubScanConfiguration.createFromJSON(json); + modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); + + /* execute */ + SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + + /* test */ + assertTrue(result.hasErrors()); + assertHasError(result, REMOTE_DATA_CONFIGURATION_ONLY_FOR_ONE_SOURCE_OR_BINARY); + } private SecHubConfigurationModel createSecHubConfigModelWithExactly8193Characters() { diff --git a/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_config_with_filesystem.json b/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_config_with_filesystem.json index e9de4830d..b25589847 100644 --- a/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_config_with_filesystem.json +++ b/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_config_with_filesystem.json @@ -2,6 +2,12 @@ "apiVersion": "1.0", "data": { "sources": [ + { + "name": "filesystem_example_1", + "fileSystem" : { + "folders" : [ "myProject/src" ] + } + }, { "name": "remote_example_name", "remote": { diff --git a/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_source_and_binaries.json b/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_source_and_binaries.json new file mode 100644 index 000000000..67d0d2381 --- /dev/null +++ b/sechub-commons-model/src/test/resources/sechub_remote_data_config_invalid_source_and_binaries.json @@ -0,0 +1,34 @@ +{ + "apiVersion": "1.0", + "data": { + "sources": [ + { + "name": "remote_example_name", + "remote": { + "location": "remote_example_location", + "type": "git", + "credentials": { + "user": { + "name": "my-example-user", + "password": "my-example-password" + } + } + } + } + ], + "binaries": [ + { + "name": "binary_example_name", + "remote": { + "location": "remote_example_location", + "type": "docker" + } + } + ] + }, + "codeScan": { + "use": [ + "remote_example_name", "binary_example_name" + ] + } +} \ No newline at end of file From e29b4c682c4829cc913892143c1c1e5b59540d10 Mon Sep 17 00:00:00 2001 From: Laura Date: Wed, 22 May 2024 15:45:04 +0200 Subject: [PATCH 15/19] Renamed validate method #3133 --- .../SecHubConfigurationModelValidator.java | 10 +- ...SecHubConfigurationModelValidatorTest.java | 164 +++++++++--------- .../SecHubConfigurationValidator.java | 2 +- .../SecHubConfigurationValidatorTest.java | 2 +- 4 files changed, 89 insertions(+), 89 deletions(-) diff --git a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java index 17cea3452..4a2570d1e 100644 --- a/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java +++ b/sechub-commons-model/src/main/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidator.java @@ -72,12 +72,12 @@ public SecHubConfigurationModelValidator() { * @param model * @return validation result */ - public SecHubConfigurationModelValidationResult validateRemoteData(SecHubConfigurationModel model) { + public SecHubConfigurationModelValidationResult validate(SecHubConfigurationModel model) { SecHubConfigurationModelValidationResult result = new SecHubConfigurationModelValidationResult(); InternalValidationContext context = new InternalValidationContext(); context.result = result; context.model = model; - validateRemoteData(context); + validate(context); return result; } @@ -128,7 +128,7 @@ private void handleMetaDataLabels(Map labels, SecHubConfiguratio } } - private void validateRemoteData(InternalValidationContext context) { + private void validate(InternalValidationContext context) { if (context.model == null) { context.result.addError(MODEL_NULL); return; @@ -563,7 +563,7 @@ private void validateRemoteDataConfiguration(InternalValidationContext context, validateOnlyOneRemoteSourceOrBinary(sourcesAndBinaries, result); validateRemoteAndFileSystemAreNotMixed(sourcesAndBinaries, result); - validateRemoteData(sourcesAndBinaries, result); + validate(sourcesAndBinaries, result); } private void validateOnlyOneRemoteSourceOrBinary(Collection sourcesAndBinaries, @@ -603,7 +603,7 @@ private void validateRemoteAndFileSystemAreNotMixed(Collection sourcesAndBinaries, SecHubConfigurationModelValidationResult result) { + private void validate(Collection sourcesAndBinaries, SecHubConfigurationModelValidationResult result) { for (SecHubDataConfigurationObject sourceOrBinary : sourcesAndBinaries) { Optional optRemoteData = sourceOrBinary.getRemote(); diff --git a/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java b/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java index 216018118..5d832bd13 100644 --- a/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java +++ b/sechub-commons-model/src/test/java/com/mercedesbenz/sechub/commons/model/SecHubConfigurationModelValidatorTest.java @@ -56,7 +56,7 @@ void when_no_scan_type_is_set_validation_fails_with_CONTAINS_NO_SCAN_CONFIGURATI model.setApiVersion("1.0"); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, CONTAINS_NO_SCAN_CONFIGURATION); @@ -69,7 +69,7 @@ void when_scan_type_codescan_validation_fails_NOT_with_CONTAINS_NO_SCAN_CONFIGUR model.setCodeScan(new SecHubCodeScanConfiguration()); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNotError(result, CONTAINS_NO_SCAN_CONFIGURATION); @@ -82,7 +82,7 @@ void when_scan_type_licensescan_validation_fails_NOT_with_CONTAINS_NO_SCAN_CONFI model.setLicenseScan(new SecHubLicenseScanConfiguration()); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNotError(result, CONTAINS_NO_SCAN_CONFIGURATION); @@ -95,7 +95,7 @@ void when_scan_type_webscan_validation_fails_NOT_with_CONTAINS_NO_SCAN_CONFIGURA model.setWebScan(new SecHubWebScanConfiguration()); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNotError(result, CONTAINS_NO_SCAN_CONFIGURATION); @@ -108,7 +108,7 @@ void when_scan_type_secretscan_validation_fails_NOT_with_CONTAINS_NO_SCAN_CONFIG model.setSecretScan(new SecHubSecretScanConfiguration()); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNotError(result, CONTAINS_NO_SCAN_CONFIGURATION); @@ -121,7 +121,7 @@ void when_scan_type_infrascan_validation_fails_NOT_with_CONTAINS_NO_SCAN_CONFIGU model.setInfraScan(new SecHubInfrastructureScanConfiguration()); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNotError(result, CONTAINS_NO_SCAN_CONFIGURATION); @@ -136,7 +136,7 @@ void when_modelcollector_collects_no_scan_types_the_validation_fails_with_nonuni assertNull(ModuleGroup.resolveModuleGroupOrNull(modelSupportCollectedScanTypes)); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.NO_MODULE_GROUP_DETECTED); @@ -155,7 +155,7 @@ void when_modelcollector_collects_two_scan_types_which_are_not_in_same_group_the assertNull(ModuleGroup.resolveModuleGroupOrNull(modelSupportCollectedScanTypes)); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.MULTIPLE_MODULE_GROUPS_DETECTED); @@ -173,7 +173,7 @@ void when_modelcollector_collects_two_scan_types_which_are_in_same_group_the_val assertNotNull(ModuleGroup.resolveModuleGroupOrNull(modelSupportCollectedScanTypes)); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNoErrors(result); @@ -205,7 +205,7 @@ void a_configuration_which_has_code_scan_and_license_scan_will_NOT_fail_because_ model.getLicenseScan().get().getNamesOfUsedDataConfigurationObjects().add("config-object-name"); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNoErrors(result); @@ -223,7 +223,7 @@ void empty_webscanconfig_results_in_error() throws Exception { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_HAS_NO_URL_DEFINED); @@ -242,7 +242,7 @@ void license_scan__empty_config_results_in_error() throws Exception { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.NO_DATA_CONFIG_SPECIFIED_FOR_SCAN); @@ -271,7 +271,7 @@ void license_scan__config_with_data() throws Exception { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNoErrors(result); @@ -291,7 +291,7 @@ void webscanconfig_with_https_uri_set_has_no_error() throws Exception { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertFalse(result.hasErrors()); @@ -311,7 +311,7 @@ void webscanconfig_with_ftp_uri_set_has_error() throws Exception { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_URL_HAS_UNSUPPORTED_SCHEMA); @@ -330,7 +330,7 @@ void empty_infrascanconfig_results_in_error() throws Exception { modelSupportCollectedScanTypes.add(ScanType.INFRA_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.INFRA_SCAN_HAS_NO_URIS_OR_IPS_DEFINED); @@ -351,7 +351,7 @@ void infrascanconfig_with_one_uri_results_in_no_error() throws Exception { modelSupportCollectedScanTypes.add(ScanType.INFRA_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNoErrors(result); @@ -371,7 +371,7 @@ void infrascanconfig_with_one_ip_results_in_no_error() throws Exception { modelSupportCollectedScanTypes.add(ScanType.INFRA_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertFalse(result.hasErrors()); @@ -381,7 +381,7 @@ void infrascanconfig_with_one_ip_results_in_no_error() throws Exception { @Test void null_model_results_in_one_error() { /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(null); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(null); modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found @@ -399,7 +399,7 @@ void api_version_set_but_no_scan_configuration_results_in_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.CONTAINS_NO_SCAN_CONFIGURATION); @@ -415,7 +415,7 @@ void api_version_null_in_model_results_in_one_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.API_VERSION_NULL); @@ -431,7 +431,7 @@ void api_version_unsupported_results_in_one_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.API_VERSION_NOT_SUPPORTED); @@ -455,7 +455,7 @@ void model_having_a_data_configuration_with_valid_name_has_no_error(String name) modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute + test */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNoErrors(result); @@ -476,7 +476,7 @@ void model_having_a_data_configuration_with_invalid_name_has_error(String name) modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute + test */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertTrue(result.hasErrors()); @@ -498,7 +498,7 @@ void model_having_a_code_scan_configuration_which_references_a_wellknown_data_ob modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute + test */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNoErrors(result); @@ -513,7 +513,7 @@ void model_having_a_code_scan_configuration_which_references_an_unknown_data_obj modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute + test */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, "config-object-not-existing1", SecHubConfigurationModelValidationError.REFERENCED_DATA_CONFIG_OBJECT_NAME_NOT_EXISTING); @@ -536,7 +536,7 @@ void model_having_a_web_scan_configuration_with_open_api_which_references_an_unk modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); // simulate correct module group found /* execute + test */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, "unknown-configuration", SecHubConfigurationModelValidationError.REFERENCED_DATA_CONFIG_OBJECT_NAME_NOT_EXISTING); @@ -566,7 +566,7 @@ void model_having_a_web_scan_configuration_with_open_api_which_references_a_well modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); // simulate correct module group found /* execute + test */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertFalse(result.hasErrors()); @@ -592,7 +592,7 @@ void model_having_two_elements_in_source_data_section_with_same_name_results_in_ modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute + test */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.DATA_CONFIG_OBJECT_NAME_IS_NOT_UNIQUE); @@ -614,7 +614,7 @@ void model_having_one_elements_with_name_with_length101_has_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.DATA_CONFIG_OBJECT_NAME_LENGTH_TOO_LONG); @@ -636,7 +636,7 @@ void model_having_one_elements_with_name_with_length0_has_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.DATA_CONFIG_OBJECT_NAME_LENGTH_TOO_SHORT); @@ -658,7 +658,7 @@ void model_having_one_elements_with_name_null_has_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.DATA_CONFIG_OBJECT_NAME_IS_NULL); @@ -679,7 +679,7 @@ void model_having_one_element_with_name_not_set_has_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.DATA_CONFIG_OBJECT_NAME_IS_NULL); @@ -707,7 +707,7 @@ void model_having_two_elements_in_binary_data_section_with_same_name_has_error() modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ @@ -735,7 +735,7 @@ void model_having_two_elements_in_binary_and_source_data_section_with_same_name_ modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertEquals(1, result.getErrors().size()); @@ -766,7 +766,7 @@ void model_having_two_elements_in_binary_and_source_data_section_with_different_ modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNoErrors(result); @@ -784,7 +784,7 @@ void secret_scan__empty_config_results_in_error() throws Exception { modelSupportCollectedScanTypes.add(ScanType.SECRET_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.NO_DATA_CONFIG_SPECIFIED_FOR_SCAN); @@ -813,7 +813,7 @@ void secret_scan__config_with_data() throws Exception { modelSupportCollectedScanTypes.add(ScanType.SECRET_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertFalse(result.hasErrors()); @@ -842,7 +842,7 @@ void model_with_given_amount_of__valid_metadata_labels_has_no_error(int amount) modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertFalse(result.hasErrors()); @@ -872,7 +872,7 @@ void model_with_given_amount_of__valid_metadata_labels_has_error(int amount) { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertTrue(result.hasErrors()); @@ -900,7 +900,7 @@ void model_with_metadata_label_key_length31_has_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.METADATA_LABEL_KEY_TOO_LONG); @@ -927,7 +927,7 @@ void model_with_metadata_label_key_length30_has_no_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNoErrors(result); @@ -954,7 +954,7 @@ void model_with_metadata_label_value_length_has_error(int length) { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.METADATA_LABEL_VALUE_TOO_LONG); @@ -982,7 +982,7 @@ void model_with_metadata_label_key_not_allowed_character_inside_has_error_code_s modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.METADATA_LABEL_KEY_CONTAINS_ILLEGAL_CHARACTERS); @@ -1010,7 +1010,7 @@ void model_with_metadata_label_key_not_allowed_character_inside_has_error_licens modelSupportCollectedScanTypes.add(ScanType.LICENSE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.METADATA_LABEL_KEY_CONTAINS_ILLEGAL_CHARACTERS); @@ -1039,7 +1039,7 @@ void model_with_metadata_label_key_allowed_character_inside_has_no_error_codeSca modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNoErrors(result); @@ -1067,7 +1067,7 @@ void model_with_metadata_label_key_allowed_character_inside_has_no_error_webScan modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNoErrors(result); @@ -1094,7 +1094,7 @@ void model_with_metadata_label_value_length_has_no_error(int length) { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); // simulate correct module group found /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNoErrors(result); @@ -1114,7 +1114,7 @@ void model_has_valid_urls_for_headers_specified_has_no_error(String onlyForUrl) modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNoErrors(result); @@ -1143,7 +1143,7 @@ void model_has_valid_only_for_urls_and_multiple_headers_for_headers_specified_ha modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNoErrors(result); @@ -1170,7 +1170,7 @@ void model_has_valid_only_for_urls_and_one_header_for_headers_specified_has_no_e modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNoErrors(result); @@ -1189,7 +1189,7 @@ void model_has_valid_urls_for_headers_specified_but_different_target_url_has_err modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_HTTP_HEADER_ONLY_FOR_URL_DOES_NOT_CONTAIN_TARGET_URL); @@ -1208,7 +1208,7 @@ void model_has_invalid_url_for_headers_specified_has_error(String onlyForUrl) { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_HTTP_HEADER_ONLY_FOR_URL_IS_NOT_A_VALID_URL); @@ -1234,7 +1234,7 @@ void model_has_multiple_only_for_urls_with_at_least_one_invalid_for_headers_spec modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_HTTP_HEADER_ONLY_FOR_URL_IS_NOT_A_VALID_URL); @@ -1262,7 +1262,7 @@ void model_has_multiple_only_for_urls_in_multiple_headers_with_at_least_one_inva modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_HTTP_HEADER_ONLY_FOR_URL_IS_NOT_A_VALID_URL); @@ -1286,7 +1286,7 @@ void model_has_no_header_names_specified_has_error(String missingHeaderName) { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_NO_HEADER_NAME_DEFINED); @@ -1310,7 +1310,7 @@ void model_has_no_header_values_specified_has_error(String missingHeaderValue) { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_NO_HEADER_VALUE_DEFINED); @@ -1336,7 +1336,7 @@ void model_has_header_value_only_from_file_ref_specified_has_no_error(String exp modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNoErrors(result); @@ -1360,7 +1360,7 @@ void model_has_multiple_header_values_from_file_ref_and_direct_value_specified_h modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_MULTIPLE_HEADER_VALUES_DEFINED); @@ -1376,7 +1376,7 @@ void explicit_definitions_for_the_same_header_for_certain_urls_but_list_of_urls_ modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertHasNoErrors(result); @@ -1394,7 +1394,7 @@ void explicit_definitions_for_the_same_header_for_certain_urls_but_list_of_urls_ modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertHasNoErrors(result); @@ -1410,7 +1410,7 @@ void default_for_a_header_with_explicit_definitions_for_the_same_header_for_cert modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertHasNoErrors(result); @@ -1427,7 +1427,7 @@ void duplicated_default_for_the_same_header_has_error(String testFilePath) { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_NON_UNIQUE_HEADER_CONFIGURATION); @@ -1444,7 +1444,7 @@ void explicit_definitions_for_the_same_header_for_certain_urls_but_list_of_urls_ modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_NON_UNIQUE_HEADER_CONFIGURATION); @@ -1465,7 +1465,7 @@ void valid_include_and_exclude_has_no_errors(String includeExcludeEntry) { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertHasNoErrors(result); @@ -1483,7 +1483,7 @@ void double_slashes_include_exclude_has_errors(String includeExcludeEntry) { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_EXCLUDE_INVALID); assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_INCLUDE_INVALID); @@ -1501,7 +1501,7 @@ void spaces_in_include_exclude_has_errors(String includeExcludeEntry) { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_EXCLUDE_INVALID); assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_INCLUDE_INVALID); @@ -1517,7 +1517,7 @@ void too_many_excludes_results_in_error() { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_EXCLUDE_INVALID); @@ -1534,7 +1534,7 @@ void too_many_includes_results_in_error() { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_INCLUDE_INVALID); @@ -1551,7 +1551,7 @@ void exclude_too_long_results_in_error() { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_EXCLUDE_INVALID); @@ -1568,7 +1568,7 @@ void include_too_long_results_in_error() { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertHasError(result, SecHubConfigurationModelValidationError.WEB_SCAN_INCLUDE_INVALID); @@ -1583,7 +1583,7 @@ void can_read_sechub_web_scan_config_with_wildcards() { modelSupportCollectedScanTypes.add(ScanType.WEB_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertHasNoErrors(result); @@ -1595,7 +1595,7 @@ void when_sechub_config_too_large_validation_fails_with_SECHUB_CONFIGURATION_TOO SecHubConfigurationModel model = createSecHubConfigModelWithExactly8193Characters(); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasError(result, SECHUB_CONFIGURATION_TOO_LARGE); @@ -1609,7 +1609,7 @@ void when_sechub_config_has_exactly_maximum_size_allowed_error_SECHUB_CONFIGURAT model.setApiVersion(model.getApiVersion().substring(1)); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(model); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(model); /* test */ assertHasNotError(result, SECHUB_CONFIGURATION_TOO_LARGE); @@ -1624,7 +1624,7 @@ void when_remote_sechub_configuration_is_valid_no_errors_are_reported(String fil modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertHasNoErrors(result); @@ -1638,7 +1638,7 @@ void when_multiple_remote_configurations_are_configured_error_REMOTE_DATA_CONFIG modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertTrue(result.hasErrors()); @@ -1653,7 +1653,7 @@ void when_remote_configuration_location_is_not_defined_error_REMOTE_DATA_CONFIGU modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertTrue(result.hasErrors()); @@ -1668,7 +1668,7 @@ void when_remote_configuration_has_empty_credentials_error_REMOTE_DATA_CONFIGURA modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertTrue(result.hasErrors()); @@ -1683,7 +1683,7 @@ void when_remote_configuration_credential_user_has_no_username_error_REMOTE_DATA modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertTrue(result.hasErrors()); @@ -1698,7 +1698,7 @@ void when_remote_configuration_credential_user_has_no_password_error_REMOTE_DATA modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertTrue(result.hasErrors()); @@ -1713,7 +1713,7 @@ void when_remote_configuration_is_mixed_with_filesystem_REMOTE_REMOTE_DATA_MIXED modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertTrue(result.hasErrors()); @@ -1728,7 +1728,7 @@ void when_remote_data_is_configured_for_binaries_and_sources_error() { modelSupportCollectedScanTypes.add(ScanType.CODE_SCAN); /* execute */ - SecHubConfigurationModelValidationResult result = validatorToTest.validateRemoteData(sechubConfiguration); + SecHubConfigurationModelValidationResult result = validatorToTest.validate(sechubConfiguration); /* test */ assertTrue(result.hasErrors()); diff --git a/sechub-shared-kernel/src/main/java/com/mercedesbenz/sechub/sharedkernel/configuration/SecHubConfigurationValidator.java b/sechub-shared-kernel/src/main/java/com/mercedesbenz/sechub/sharedkernel/configuration/SecHubConfigurationValidator.java index 001b76bb4..ecc4b99e2 100644 --- a/sechub-shared-kernel/src/main/java/com/mercedesbenz/sechub/sharedkernel/configuration/SecHubConfigurationValidator.java +++ b/sechub-shared-kernel/src/main/java/com/mercedesbenz/sechub/sharedkernel/configuration/SecHubConfigurationValidator.java @@ -41,7 +41,7 @@ public void validate(Object target, Errors errors) { LOG.debug("Start validation for: {}", target); SecHubConfiguration configuration = (SecHubConfiguration) target; - SecHubConfigurationModelValidationResult modelValidationResult = modelValidator.validateRemoteData(configuration); + SecHubConfigurationModelValidationResult modelValidationResult = modelValidator.validate(configuration); handleExplicitErrorCodes(errors, modelValidationResult); addGenericErrorsWhenNecessary(errors, modelValidationResult); diff --git a/sechub-shared-kernel/src/test/java/com/mercedesbenz/sechub/sharedkernel/configuration/SecHubConfigurationValidatorTest.java b/sechub-shared-kernel/src/test/java/com/mercedesbenz/sechub/sharedkernel/configuration/SecHubConfigurationValidatorTest.java index 7f96ff312..24226a432 100644 --- a/sechub-shared-kernel/src/test/java/com/mercedesbenz/sechub/sharedkernel/configuration/SecHubConfigurationValidatorTest.java +++ b/sechub-shared-kernel/src/test/java/com/mercedesbenz/sechub/sharedkernel/configuration/SecHubConfigurationValidatorTest.java @@ -46,7 +46,7 @@ public void before() throws Exception { configurationModelValidationResult = mock(SecHubConfigurationModelValidationResult.class); modelValidator = mock(SecHubConfigurationModelValidator.class); - when(modelValidator.validateRemoteData(any())).thenReturn(configurationModelValidationResult); + when(modelValidator.validate(any())).thenReturn(configurationModelValidationResult); validatorToTest.modelValidator = modelValidator; From 4c6127c41da662f082e051f84a71613bf87fa5e5 Mon Sep 17 00:00:00 2001 From: Sven Dolderer Date: Wed, 22 May 2024 16:56:33 +0200 Subject: [PATCH 16/19] improved anonymous calls #3137 --- sechub-developertools/scripts/sechub-api.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sechub-developertools/scripts/sechub-api.sh b/sechub-developertools/scripts/sechub-api.sh index c37992356..88948b74f 100755 --- a/sechub-developertools/scripts/sechub-api.sh +++ b/sechub-developertools/scripts/sechub-api.sh @@ -804,7 +804,7 @@ function sechub_user_list_open_signups { function sechub_user_reset_apitoken { - curl_with_sechub_auth -i -X POST -H 'Content-Type: application/json' "$SECHUB_SERVER/api/anonymous/refresh/apitoken/$1" | $CURL_FILTER + curl $CURL_PARAMS -i -X POST -H 'Content-Type: application/json' "$SECHUB_SERVER/api/anonymous/refresh/apitoken/$1" | $CURL_FILTER } @@ -819,7 +819,7 @@ EOF } function sechub_user_signup { - curl_with_sechub_auth -i -X POST -H 'Content-Type: application/json' \ + curl $CURL_PARAMS -i -X POST -H 'Content-Type: application/json' \ -d "$(generate_sechub_user_signup_data $1 $2)" \ "$SECHUB_SERVER/api/anonymous/signup" | $CURL_FILTER } From 4a7dea50e4d95d5cf88fc2f2e4dc62914e2749b7 Mon Sep 17 00:00:00 2001 From: Laura Date: Wed, 22 May 2024 17:39:10 +0200 Subject: [PATCH 17/19] Added test class for abstract validator #3028 --- .../modules/AbstractInputValidatorTest.java | 110 ++++++++++++++++++ .../git/PrepareWrapperModuleGitTest.java | 2 +- .../prepare/modules/git/WrapperGitTest.java | 2 +- .../PrepareWrapperModuleSkopeoTest.java | 33 ++++++ .../modules/skopeo/WrapperSkopeoTest.java | 1 - 5 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/AbstractInputValidatorTest.java diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/AbstractInputValidatorTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/AbstractInputValidatorTest.java new file mode 100644 index 000000000..1c825a966 --- /dev/null +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/AbstractInputValidatorTest.java @@ -0,0 +1,110 @@ +package com.mercedesbenz.sechub.wrapper.prepare.modules; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.regex.Pattern; + +import org.junit.jupiter.api.Test; + +class AbstractInputValidatorTest { + + TestInputValidator validatorToTest; + + @Test + void constructor_throws_exception_when_type_is_null() { + /* prepare */ + Pattern locationPattern = Pattern.compile(".*"); + Pattern usernamePattern = Pattern.compile(".*"); + Pattern passwordPattern = Pattern.compile(".*"); + + /* execute */ + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + validatorToTest = new TestInputValidator(null, locationPattern, usernamePattern, passwordPattern); + }); + + /* test */ + assertEquals("Type must not be null or empty.", exception.getMessage()); + } + + @Test + void constructor_throws_exception_when_type_is_empty() { + /* prepare */ + Pattern locationPattern = Pattern.compile(".*"); + Pattern usernamePattern = Pattern.compile(".*"); + Pattern passwordPattern = Pattern.compile(".*"); + + /* execute */ + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + validatorToTest = new TestInputValidator("", locationPattern, usernamePattern, passwordPattern); + }); + + /* test */ + assertEquals("Type must not be null or empty.", exception.getMessage()); + } + + @Test + void constructor_throws_exception_when_locationPattern_is_null() { + /* prepare */ + Pattern usernamePattern = Pattern.compile(".*"); + Pattern passwordPattern = Pattern.compile(".*"); + + /* execute */ + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + validatorToTest = new TestInputValidator("type", null, usernamePattern, passwordPattern); + }); + + /* test */ + assertEquals("Pattern must not be null.", exception.getMessage()); + } + + @Test + void constructor_throws_exception_when_usernamePattern_is_null() { + /* prepare */ + Pattern locationPattern = Pattern.compile(".*"); + Pattern passwordPattern = Pattern.compile(".*"); + + /* execute */ + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + validatorToTest = new TestInputValidator("type", locationPattern, null, passwordPattern); + }); + + /* test */ + assertEquals("Pattern must not be null.", exception.getMessage()); + } + + @Test + void constructor_throws_exception_when_passwordPattern_is_null() { + /* prepare */ + Pattern locationPattern = Pattern.compile(".*"); + Pattern usernamePattern = Pattern.compile(".*"); + + /* execute */ + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + validatorToTest = new TestInputValidator("type", locationPattern, usernamePattern, null); + }); + + /* test */ + assertEquals("Pattern must not be null.", exception.getMessage()); + } + + @Test + void constructor_creates_instance_when_all_parameters_are_valid() { + /* prepare */ + Pattern locationPattern = Pattern.compile(".*"); + Pattern usernamePattern = Pattern.compile(".*"); + Pattern passwordPattern = Pattern.compile(".*"); + + /* execute */ + validatorToTest = new TestInputValidator("type", locationPattern, usernamePattern, passwordPattern); + + /* test */ + assertNotNull(validatorToTest); + } + + private class TestInputValidator extends AbstractInputValidator { + public TestInputValidator(String type, Pattern locationPattern, Pattern usernamePattern, Pattern passwordPattern) { + super(type, locationPattern, usernamePattern, passwordPattern); + } + } + +} \ No newline at end of file diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java index 559b663c3..56a81466e 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/PrepareWrapperModuleGitTest.java @@ -44,7 +44,7 @@ void beforeEach() { } @Test - void when_inputvalidator_throws_InputValidatorException_prepare_return_false() throws IOException, PrepareWrapperInputValidatorException { + void when_inputValidator_throws_InputValidatorException_prepare_return_false() throws IOException, PrepareWrapperInputValidatorException { /* prepare */ PrepareWrapperContext context = createContext(); doThrow(new PrepareWrapperInputValidatorException("test", InputValidatorExitcode.LOCATION_NOT_MATCHING_PATTERN)).when(gitInputValidator) diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGitTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGitTest.java index 004fd2de7..5843d7ab5 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGitTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/git/WrapperGitTest.java @@ -48,7 +48,7 @@ void beforeEach() throws IOException, InterruptedException { @ParameterizedTest @ValueSource(strings = { "https://host.xz/path/to/repo/.git", "http://myrepo/here/.git", "example.org.git" }) - void when_cloneRepository_is_executed_the_processAdapterFactory_starts_JGit_clone(String location) throws IOException { + void when_cloneRepository_is_executed_the_processAdapterFactory_starts_JGit_clone(String location) { /* prepare */ Map credentialMap = new HashMap<>(); credentialMap.put(PDS_PREPARE_CREDENTIAL_USERNAME, CryptoAccess.CRYPTO_STRING.seal("user")); diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java index 444cf7121..55758b575 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/PrepareWrapperModuleSkopeoTest.java @@ -18,6 +18,8 @@ import com.mercedesbenz.sechub.commons.model.SecHubRemoteDataConfiguration; import com.mercedesbenz.sechub.test.TestFileWriter; import com.mercedesbenz.sechub.wrapper.prepare.cli.PrepareWrapperEnvironment; +import com.mercedesbenz.sechub.wrapper.prepare.modules.InputValidatorExitcode; +import com.mercedesbenz.sechub.wrapper.prepare.modules.PrepareWrapperInputValidatorException; import com.mercedesbenz.sechub.wrapper.prepare.prepare.PrepareWrapperContext; class PrepareWrapperModuleSkopeoTest { @@ -40,6 +42,30 @@ void beforeEach() { moduleToTest.skopeo = skopeo; } + @Test + void when_inputValidator_throws_InputValidatorException_prepare_return_false() throws IOException, PrepareWrapperInputValidatorException { + /* prepare */ + PrepareWrapperContext context = createContext(); + doThrow(new PrepareWrapperInputValidatorException("test", InputValidatorExitcode.LOCATION_NOT_MATCHING_PATTERN)).when(skopeoInputValidator) + .validate(context); + + /* execute */ + boolean result = moduleToTest.prepare(context); + + /* test */ + assertFalse(result); + } + + @Test + void when_inputvalidator_throws_exception_prepare_throws_exception() throws PrepareWrapperInputValidatorException { + /* prepare */ + PrepareWrapperContext context = createContext(); + doThrow(new IllegalStateException("test")).when(skopeoInputValidator).validate(context); + + /* execute + test */ + assertThrows(IllegalStateException.class, () -> moduleToTest.prepare(context)); + } + @Test void prepare_successful_when_user_credentials_are_configured_correctly() throws IOException { /* prepare */ @@ -151,4 +177,11 @@ void isDownloadSuccessful_returns_false_when_no_tar_file_in_directory() throws I /* test */ assertFalse(result); } + + private PrepareWrapperContext createContext() { + PrepareWrapperEnvironment environment = mock(PrepareWrapperEnvironment.class); + when(environment.getPdsPrepareUploadFolderDirectory()).thenReturn("test-upload-folder"); + return new PrepareWrapperContext(createFromJSON("{}"), environment); + } + } \ No newline at end of file diff --git a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeoTest.java b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeoTest.java index dcae2c7a4..c1d518a75 100644 --- a/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeoTest.java +++ b/sechub-wrapper-prepare/src/test/java/com/mercedesbenz/sechub/wrapper/prepare/modules/skopeo/WrapperSkopeoTest.java @@ -23,7 +23,6 @@ class WrapperSkopeoTest { WrapperSkopeo wrapperToTest; PDSProcessAdapterFactory processAdapterFactory; - ProcessAdapter processAdapter; @BeforeEach From 99d40270f4b41c0aecb1f850ff99cca2132c8959 Mon Sep 17 00:00:00 2001 From: Jan Winz Date: Thu, 23 May 2024 07:59:04 +0200 Subject: [PATCH 18/19] PR review changes and added integration tests - change to varchar(255) since times 3 is not necessary - add integrationtest to check for HTTP error if project id is to long - add integrationtest which check if sechub client can handle max size project id --- .../sechub/integrationtest/api/AsUser.java | 14 +++- .../sechub/integrationtest/api/TestAPI.java | 5 ++ .../integrationtest/api/TestProject.java | 18 +++++ .../CheckProjectIdLengthScenario1IntTest.java | 69 +++++++++++++++++++ .../db/migration/V28__enlarge_project_id.sql | 36 +++++----- 5 files changed, 123 insertions(+), 19 deletions(-) create mode 100644 sechub-integrationtest/src/test/java/com/mercedesbenz/sechub/integrationtest/scenario1/CheckProjectIdLengthScenario1IntTest.java diff --git a/sechub-integrationtest/src/main/java/com/mercedesbenz/sechub/integrationtest/api/AsUser.java b/sechub-integrationtest/src/main/java/com/mercedesbenz/sechub/integrationtest/api/AsUser.java index 5c9cdc63e..7bff973b3 100644 --- a/sechub-integrationtest/src/main/java/com/mercedesbenz/sechub/integrationtest/api/AsUser.java +++ b/sechub-integrationtest/src/main/java/com/mercedesbenz/sechub/integrationtest/api/AsUser.java @@ -190,7 +190,19 @@ private IntegrationTestContext getContext() { /** * User trigger create of project * - * @param project + * @param project project instance + * @param owner owner of the project + * @throws RestClientException + */ + public AsUser createProject(TestProject project, TestUser owner) { + return createProject(project, owner.getUserId()); + } + + /** + * User trigger create of project + * + * @param project project instance + * @param ownerUserId owner of the project * @throws RestClientException */ public AsUser createProject(TestProject project, String ownerUserId) { diff --git a/sechub-integrationtest/src/main/java/com/mercedesbenz/sechub/integrationtest/api/TestAPI.java b/sechub-integrationtest/src/main/java/com/mercedesbenz/sechub/integrationtest/api/TestAPI.java index 490c1b590..b3e25cb20 100644 --- a/sechub-integrationtest/src/main/java/com/mercedesbenz/sechub/integrationtest/api/TestAPI.java +++ b/sechub-integrationtest/src/main/java/com/mercedesbenz/sechub/integrationtest/api/TestAPI.java @@ -45,6 +45,7 @@ import com.mercedesbenz.sechub.integrationtest.internal.DefaultTestExecutionProfile; import com.mercedesbenz.sechub.integrationtest.internal.IntegrationTestContext; import com.mercedesbenz.sechub.integrationtest.internal.IntegrationTestDefaultProfiles; +import com.mercedesbenz.sechub.integrationtest.internal.SecHubClientExecutor.ExecutionResult; import com.mercedesbenz.sechub.integrationtest.internal.TestAutoCleanupData; import com.mercedesbenz.sechub.integrationtest.internal.TestAutoCleanupData.TestCleanupTimeUnit; import com.mercedesbenz.sechub.integrationtest.internal.TestJSONHelper; @@ -124,6 +125,10 @@ public static AssertReportUnordered assertReportUnordered(String json) { return AssertReportUnordered.assertReportUnordered(json); } + public static AssertExecutionResult assertExecutionResult(ExecutionResult result) { + return AssertExecutionResult.assertResult(result); + } + /** * Asserts given report json - for checks you will always need to explicit use * indexes and the report must have an explicit ordering - otherwise you have diff --git a/sechub-integrationtest/src/main/java/com/mercedesbenz/sechub/integrationtest/api/TestProject.java b/sechub-integrationtest/src/main/java/com/mercedesbenz/sechub/integrationtest/api/TestProject.java index a910d7b9e..a9bb4cf54 100644 --- a/sechub-integrationtest/src/main/java/com/mercedesbenz/sechub/integrationtest/api/TestProject.java +++ b/sechub-integrationtest/src/main/java/com/mercedesbenz/sechub/integrationtest/api/TestProject.java @@ -20,6 +20,14 @@ public class TestProject { all.add(this); } + /** + * Creates a test project without a whitelist. Description is automatically + * generated and contains the project id as well + * + * @param projectIdPart name of the project if {@link #prepare(TestScenario)} is + * not called, otherwise it will be the part after the + * scenario prefix + */ public TestProject(String projectIdPart) { this(projectIdPart, false); } @@ -31,6 +39,16 @@ public TestProject(String projectIdPart, boolean withWhiteList) { this.withWhiteList = withWhiteList; } + public void setDescription(String description) { + this.description = description; + } + + /** + * Prepare the test project for the given scenario. Calculates the prefix for + * the project id from the scenario name. + * + * @param scenario + */ public void prepare(TestScenario scenario) { this.prefix = scenario.getName().toLowerCase(); whiteListUrls.clear(); diff --git a/sechub-integrationtest/src/test/java/com/mercedesbenz/sechub/integrationtest/scenario1/CheckProjectIdLengthScenario1IntTest.java b/sechub-integrationtest/src/test/java/com/mercedesbenz/sechub/integrationtest/scenario1/CheckProjectIdLengthScenario1IntTest.java new file mode 100644 index 000000000..61cd2d482 --- /dev/null +++ b/sechub-integrationtest/src/test/java/com/mercedesbenz/sechub/integrationtest/scenario1/CheckProjectIdLengthScenario1IntTest.java @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: MIT +package com.mercedesbenz.sechub.integrationtest.scenario1; + +import static com.mercedesbenz.sechub.integrationtest.api.TestAPI.*; +import static com.mercedesbenz.sechub.integrationtest.internal.IntegrationTestDefaultProfiles.PROFILE_1; +import static com.mercedesbenz.sechub.integrationtest.scenario1.Scenario1.*; +import static org.junit.Assert.*; + +import org.junit.Rule; +import org.junit.Test; +import org.springframework.http.HttpStatus; + +import com.mercedesbenz.sechub.integrationtest.api.IntegrationTestSetup; +import com.mercedesbenz.sechub.integrationtest.api.TestProject; +import com.mercedesbenz.sechub.integrationtest.api.TestUser; +import com.mercedesbenz.sechub.integrationtest.internal.SecHubClientExecutor.ExecutionResult; +import com.mercedesbenz.sechub.sharedkernel.validation.ProjectIdValidationImpl; + +public class CheckProjectIdLengthScenario1IntTest { + + private static final int PROJECT_ID_MAX_LENGTH = ProjectIdValidationImpl.PROJECTID_LENGTH_MAX; + + private static final int PROJECT_ID_MAX_LENGTH_PLUS_ONE = ProjectIdValidationImpl.PROJECTID_LENGTH_MAX + 1; + + @Rule + public IntegrationTestSetup setup = IntegrationTestSetup.forScenario(Scenario1.class); + + @Test + public void can_create_project_with_project_id_having_maximum_length_and_execute_scan_using_sechub_cli() { + /* prepare */ + TestUser user = OWNER_1; + TestProject project = createTestProjectWithProjectIdLength(PROJECT_ID_MAX_LENGTH); + + /* execute + test 1 */ + as(SUPER_ADMIN).createProject(project, user).assignUserToProject(user, project); + as(SUPER_ADMIN).addProjectsToProfile(PROFILE_1.id, project); + + /* test2 */ + // check client is able to handle the long project id as well + ExecutionResult result = as(user).withSecHubClient().startAndWaitForCodeScan(project); + assertExecutionResult(result).isGreen(); // result is as expected... + } + + @Test + public void cannot_create_project_with_project_id_having_more_than_maximum_length() { + /* prepare */ + TestUser user = OWNER_1; + TestProject project = createTestProjectWithProjectIdLength(PROJECT_ID_MAX_LENGTH_PLUS_ONE); + + /* execute + test */ + expectHttpFailure(() -> { + as(SUPER_ADMIN).createProject(project, user); + }, HttpStatus.BAD_REQUEST); + + } + + private TestProject createTestProjectWithProjectIdLength(int projectIdLength) { + String prefix = System.currentTimeMillis() + "_"; + String postfix = "x".repeat(projectIdLength - prefix.length()); + String projectIdPart = prefix + postfix; + + assertEquals(projectIdLength, projectIdPart.length()); + + TestProject project = new TestProject(projectIdPart); + project.setDescription("a small description"); // we want to keep the description small... + return project; + } + +} diff --git a/sechub-server/src/main/resources/db/migration/V28__enlarge_project_id.sql b/sechub-server/src/main/resources/db/migration/V28__enlarge_project_id.sql index eb2b925d7..5c3289a40 100644 --- a/sechub-server/src/main/resources/db/migration/V28__enlarge_project_id.sql +++ b/sechub-server/src/main/resources/db/migration/V28__enlarge_project_id.sql @@ -1,22 +1,22 @@ -- SPDX-License-Identifier: MIT --- Update project id : we now accept 765 (3 x 255) see ProjectIdValidation -ALTER TABLE adm_project ALTER COLUMN project_id TYPE varchar(765); -ALTER TABLE scan_report ALTER COLUMN project_id TYPE varchar(765); -ALTER TABLE scan_access ALTER COLUMN project_id TYPE varchar(765); -ALTER TABLE schedule_access ALTER COLUMN project_id TYPE varchar(765); -ALTER TABLE schedule_project_whitelist ALTER COLUMN project_id TYPE varchar(765); -ALTER TABLE schedule_sechub_job ALTER COLUMN project_id TYPE varchar(765); -ALTER TABLE scan_project_log ALTER COLUMN project_id TYPE varchar(765); -ALTER TABLE adm_job_information ALTER COLUMN project_id TYPE varchar(765); -ALTER TABLE scan_product_result ALTER COLUMN project_id TYPE varchar(765); -ALTER TABLE scan_project_config ALTER COLUMN project_id TYPE varchar(765); -ALTER TABLE adm_project_metadata ALTER COLUMN project_id TYPE varchar(765); -ALTER TABLE schedule_project_config ALTER COLUMN project_id TYPE varchar(765); -ALTER TABLE statistic_job ALTER COLUMN project_id TYPE varchar(765); -ALTER TABLE statistic_job_run ALTER COLUMN project_id TYPE varchar(765); +-- Update project id : we now accept 255 characters see ProjectIdValidation +ALTER TABLE adm_project ALTER COLUMN project_id TYPE varchar(255); +ALTER TABLE scan_report ALTER COLUMN project_id TYPE varchar(255); +ALTER TABLE scan_access ALTER COLUMN project_id TYPE varchar(255); +ALTER TABLE schedule_access ALTER COLUMN project_id TYPE varchar(255); +ALTER TABLE schedule_project_whitelist ALTER COLUMN project_id TYPE varchar(255); +ALTER TABLE schedule_sechub_job ALTER COLUMN project_id TYPE varchar(255); +ALTER TABLE scan_project_log ALTER COLUMN project_id TYPE varchar(255); +ALTER TABLE adm_job_information ALTER COLUMN project_id TYPE varchar(255); +ALTER TABLE scan_product_result ALTER COLUMN project_id TYPE varchar(255); +ALTER TABLE scan_project_config ALTER COLUMN project_id TYPE varchar(255); +ALTER TABLE adm_project_metadata ALTER COLUMN project_id TYPE varchar(255); +ALTER TABLE schedule_project_config ALTER COLUMN project_id TYPE varchar(255); +ALTER TABLE statistic_job ALTER COLUMN project_id TYPE varchar(255); +ALTER TABLE statistic_job_run ALTER COLUMN project_id TYPE varchar(255); -ALTER TABLE adm_project_whitelist_uri ALTER COLUMN project_project_id TYPE varchar(765); +ALTER TABLE adm_project_whitelist_uri ALTER COLUMN project_project_id TYPE varchar(255); -ALTER TABLE adm_project_to_user ALTER COLUMN projects_project_id TYPE varchar(765); -ALTER TABLE scan_execution_profile_to_project ALTER COLUMN projects_project_id TYPE varchar(765); \ No newline at end of file +ALTER TABLE adm_project_to_user ALTER COLUMN projects_project_id TYPE varchar(255); +ALTER TABLE scan_execution_profile_to_project ALTER COLUMN projects_project_id TYPE varchar(255); \ No newline at end of file From 0d918f2dae6d5166fa7b2bd4af34745dc089c1e7 Mon Sep 17 00:00:00 2001 From: Jan Winz Date: Thu, 23 May 2024 12:27:08 +0200 Subject: [PATCH 19/19] Change max project length size to 150 #3102 - reason for this change is the maximum filename length on OS - The project id will be part of the report filename --- .../db/migration/V28__enlarge_project_id.sql | 36 +++++++++---------- .../validation/ProjectIdValidationImpl.java | 2 +- .../ProjectIdValidationImplTest.java | 6 ++-- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/sechub-server/src/main/resources/db/migration/V28__enlarge_project_id.sql b/sechub-server/src/main/resources/db/migration/V28__enlarge_project_id.sql index 5c3289a40..765ab4490 100644 --- a/sechub-server/src/main/resources/db/migration/V28__enlarge_project_id.sql +++ b/sechub-server/src/main/resources/db/migration/V28__enlarge_project_id.sql @@ -1,22 +1,22 @@ -- SPDX-License-Identifier: MIT --- Update project id : we now accept 255 characters see ProjectIdValidation -ALTER TABLE adm_project ALTER COLUMN project_id TYPE varchar(255); -ALTER TABLE scan_report ALTER COLUMN project_id TYPE varchar(255); -ALTER TABLE scan_access ALTER COLUMN project_id TYPE varchar(255); -ALTER TABLE schedule_access ALTER COLUMN project_id TYPE varchar(255); -ALTER TABLE schedule_project_whitelist ALTER COLUMN project_id TYPE varchar(255); -ALTER TABLE schedule_sechub_job ALTER COLUMN project_id TYPE varchar(255); -ALTER TABLE scan_project_log ALTER COLUMN project_id TYPE varchar(255); -ALTER TABLE adm_job_information ALTER COLUMN project_id TYPE varchar(255); -ALTER TABLE scan_product_result ALTER COLUMN project_id TYPE varchar(255); -ALTER TABLE scan_project_config ALTER COLUMN project_id TYPE varchar(255); -ALTER TABLE adm_project_metadata ALTER COLUMN project_id TYPE varchar(255); -ALTER TABLE schedule_project_config ALTER COLUMN project_id TYPE varchar(255); -ALTER TABLE statistic_job ALTER COLUMN project_id TYPE varchar(255); -ALTER TABLE statistic_job_run ALTER COLUMN project_id TYPE varchar(255); +-- Update project id : we now accept 150 characters see ProjectIdValidation +ALTER TABLE adm_project ALTER COLUMN project_id TYPE varchar(150); +ALTER TABLE scan_report ALTER COLUMN project_id TYPE varchar(150); +ALTER TABLE scan_access ALTER COLUMN project_id TYPE varchar(150); +ALTER TABLE schedule_access ALTER COLUMN project_id TYPE varchar(150); +ALTER TABLE schedule_project_whitelist ALTER COLUMN project_id TYPE varchar(150); +ALTER TABLE schedule_sechub_job ALTER COLUMN project_id TYPE varchar(150); +ALTER TABLE scan_project_log ALTER COLUMN project_id TYPE varchar(150); +ALTER TABLE adm_job_information ALTER COLUMN project_id TYPE varchar(150); +ALTER TABLE scan_product_result ALTER COLUMN project_id TYPE varchar(150); +ALTER TABLE scan_project_config ALTER COLUMN project_id TYPE varchar(150); +ALTER TABLE adm_project_metadata ALTER COLUMN project_id TYPE varchar(150); +ALTER TABLE schedule_project_config ALTER COLUMN project_id TYPE varchar(150); +ALTER TABLE statistic_job ALTER COLUMN project_id TYPE varchar(150); +ALTER TABLE statistic_job_run ALTER COLUMN project_id TYPE varchar(150); -ALTER TABLE adm_project_whitelist_uri ALTER COLUMN project_project_id TYPE varchar(255); +ALTER TABLE adm_project_whitelist_uri ALTER COLUMN project_project_id TYPE varchar(150); -ALTER TABLE adm_project_to_user ALTER COLUMN projects_project_id TYPE varchar(255); -ALTER TABLE scan_execution_profile_to_project ALTER COLUMN projects_project_id TYPE varchar(255); \ No newline at end of file +ALTER TABLE adm_project_to_user ALTER COLUMN projects_project_id TYPE varchar(150); +ALTER TABLE scan_execution_profile_to_project ALTER COLUMN projects_project_id TYPE varchar(150); \ No newline at end of file diff --git a/sechub-shared-kernel/src/main/java/com/mercedesbenz/sechub/sharedkernel/validation/ProjectIdValidationImpl.java b/sechub-shared-kernel/src/main/java/com/mercedesbenz/sechub/sharedkernel/validation/ProjectIdValidationImpl.java index 49c23cc56..620125904 100644 --- a/sechub-shared-kernel/src/main/java/com/mercedesbenz/sechub/sharedkernel/validation/ProjectIdValidationImpl.java +++ b/sechub-shared-kernel/src/main/java/com/mercedesbenz/sechub/sharedkernel/validation/ProjectIdValidationImpl.java @@ -7,7 +7,7 @@ public class ProjectIdValidationImpl extends AbstractSimpleStringValidation implements ProjectIdValidation { public static final int PROJECTID_LENGTH_MIN = 2; - public static final int PROJECTID_LENGTH_MAX = 255; + public static final int PROJECTID_LENGTH_MAX = 150; @Override protected void setup(ValidationConfig config) { diff --git a/sechub-shared-kernel/src/test/java/com/mercedesbenz/sechub/sharedkernel/validation/ProjectIdValidationImplTest.java b/sechub-shared-kernel/src/test/java/com/mercedesbenz/sechub/sharedkernel/validation/ProjectIdValidationImplTest.java index 58ce54ba6..baa713940 100644 --- a/sechub-shared-kernel/src/test/java/com/mercedesbenz/sechub/sharedkernel/validation/ProjectIdValidationImplTest.java +++ b/sechub-shared-kernel/src/test/java/com/mercedesbenz/sechub/sharedkernel/validation/ProjectIdValidationImplTest.java @@ -12,10 +12,10 @@ public class ProjectIdValidationImplTest { private ProjectIdValidationImpl validationToTest = new ProjectIdValidationImpl(); - private static final String VALID_PROJECT_ID_WITH_255_CHARS = "a0123456789b0123456789c0123456789d0123456789e0123456789f0123456789g0123456789h0123456789i0123456789j0123456789k0123456789l0123456789m0123456789n0123456789o0123456789p0123456789q0123456789r0123456789s0123456789t0123456789u0123456789v0123456789w0123456789yz"; + private static final String VALID_PROJECT_ID_WITH_150_CHARS = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"; @ParameterizedTest - @ValueSource(strings = { "a2", "i-am-with-hyphens", "i_am_with_underscore", VALID_PROJECT_ID_WITH_255_CHARS }) + @ValueSource(strings = { "a2", "i-am-with-hyphens", "i_am_with_underscore", VALID_PROJECT_ID_WITH_150_CHARS }) void valid_projectIds(String projectId) { /* execute */ ValidationResult validationResult = validationToTest.validate(projectId); @@ -30,7 +30,7 @@ void valid_projectIds(String projectId) { @NullSource @EmptySource @ValueSource(strings = { "a", "i.am.with.dot", "i-am/slashy", "with\\backslash", "percent%", "dollar$", "question?", "colon:", "exclamationmark!", - VALID_PROJECT_ID_WITH_255_CHARS + "x" }) + VALID_PROJECT_ID_WITH_150_CHARS + "x" }) void invalid_projectIds(String projectId) { /* execute */ ValidationResult validationResult = validationToTest.validate(projectId);