From 488f99e82e03d437b6e25669c2c24b8d595791d4 Mon Sep 17 00:00:00 2001 From: Yashh Jaggi <32009709+yashhjaggi1998@users.noreply.github.com> Date: Wed, 8 Jun 2022 17:10:42 +0530 Subject: [PATCH] Integration boa&config as code (#102) * we are implementing Override and Origin via Config as Code we are implementing Override and Origin via Config as Code We have added one flag in cx.config file which will decide whether we need to override the parameter mention in cx.config file If the project is new irrespective of flag it will override the parameter in cx.config file * bugid: BOA changes merge CR_by: n/a * Upgraded springshell version * Updated Common client version * upgraded version * Fixed vulnerable dependencies Co-authored-by: Sumit Nigade Co-authored-by: ilandn --- config/cx_console.properties | 2 +- pom.xml | 298 ++++++++-------- .../com/cx/plugin/cli/CxConsoleLauncher.java | 44 +-- .../plugin/cli/configascode/SastConfig.java | 13 + .../plugin/cli/constants/ArgDescriptions.java | 4 + .../com/cx/plugin/cli/constants/Command.java | 6 +- .../cx/plugin/cli/constants/Parameters.java | 4 + .../cli/errorsconstants/ErrorMessages.java | 7 + .../cx/plugin/cli/errorsconstants/Errors.java | 8 + .../cx/plugin/cli/utils/CxConfigHelper.java | 328 +++++++++++------- .../plugin/cli/utils/ErrorParsingHelper.java | 36 +- 11 files changed, 449 insertions(+), 301 deletions(-) diff --git a/config/cx_console.properties b/config/cx_console.properties index ca818ca..024f455 100644 --- a/config/cx_console.properties +++ b/config/cx_console.properties @@ -19,7 +19,7 @@ scan.osa.exclude.files= #List of files which will be extracted in order to get files for OSA analysis (wildcards are supported) #Supported archive files are: "jar", "war", "ear", "sca", "gem", "whl", "egg", "tar", "tar.gz", "tgz", "zip", "rar" -scan.osa.extractable.include.files=*.zip, *.war, *.ear, *.tgz +scan.osa.extractable.include.files=**/*.jar,**/*.war,**/*.ear,**/*.sca,**/*.gem,**/*.whl,**/*.egg,**/*.tar,**/*.tar.gz,**/*.tgz,**/*.zip,**/*.rar #Value of the unzip depth for extracting files for OSA analysis scan.osa.extractable.depth=4 diff --git a/pom.xml b/pom.xml index 1cb3288..90771bf 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.cx.plugin CxConsolePlugin - 1.1.12 + 1.1.13 jar @@ -132,110 +132,120 @@ com.checkmarx cx-client-common - 2022.1.10 + 2022.2.12 - - - org.freemarker - freemarker - - - com.github.junrar - junrar - - - org.mozilla - rhino - - - io.vertx - vertx-web - - - ch.qos.logback - logback-classic - - - io.netty - netty-codec-http - - - io.netty - netty-codec - - - com.fasterxml.jackson.core - jackson-databind - - - org.springframework - spring-core - - - + + + org.freemarker + freemarker + + + com.github.junrar + junrar + + + org.mozilla + rhino + + + io.vertx + vertx-web + + + ch.qos.logback + logback-classic + + + io.netty + netty-codec-http + + + io.netty + netty-codec + + + com.fasterxml.jackson.core + jackson-databind + + + org.springframework + spring-core + + + net.lingala.zip4j + zip4j + + + - - com.github.junrar - junrar - 7.4.1 - - - org.slf4j - slf4j-api - - - - - org.freemarker - freemarker - 2.3.31 - - - io.netty - netty-codec-http - 4.1.75.Final - - - com.fasterxml.jackson.core - jackson-databind - 2.13.2.1 - - - org.springframework - spring-core - 5.3.18 - - org.mozilla - rhino - 1.7.12 + com.github.junrar + junrar + 7.4.1 + + + org.slf4j + slf4j-api + + - io.vertx - vertx-web - 4.0.2 - - - io.netty - netty-codec-http - - - io.netty - netty-codec - - - io.netty - netty-codec-http2 - - + org.freemarker + freemarker + 2.3.31 - + io.netty - netty-codec - 4.1.75.Final + netty-codec-http + 4.1.77.Final + + + com.fasterxml.jackson.core + jackson-databind + 2.13.2.1 + + + org.springframework + spring-core + 5.3.20 + + + org.mozilla + rhino + 1.7.12 - + + io.vertx + vertx-web + 4.0.2 + + + io.netty + netty-codec-http + + + io.netty + netty-codec + + + io.netty + netty-codec-http2 + + + + + io.netty + netty-codec + 4.1.77.Final + + + net.lingala.zip4j + zip4j + 2.10.0 + + + commons-cli commons-cli @@ -258,27 +268,31 @@ cx-config-provider 1.0.13 - - commons-io - commons-io - - - com.fasterxml.jackson.core - jackson-databind - - - org.apache.logging.log4j - log4j-core - - - org.apache.logging.log4j - log4j-api - - - org.apache.logging.log4j - log4j-slf4j-impl - - + + commons-io + commons-io + + + com.fasterxml.jackson.core + jackson-databind + + + org.slf4j + slf4j-api + + + org.apache.logging.log4j + log4j-core + + + org.apache.logging.log4j + log4j-api + + + org.apache.logging.log4j + log4j-slf4j-impl + + commons-io @@ -289,36 +303,36 @@ org.apache.httpcomponents httpclient 4.5.13 - - - commons-codec - commons-codec - - + + + commons-codec + commons-codec + + - + commons-codec commons-codec 1.15 - - - org.apache.logging.log4j - log4j-slf4j-impl - 2.17.1 - - - - org.apache.logging.log4j - log4j-core - 2.17.1 - - - - org.apache.logging.log4j - log4j-api - 2.17.1 - + + + org.apache.logging.log4j + log4j-slf4j-impl + 2.17.1 + + + + org.apache.logging.log4j + log4j-core + 2.17.1 + + + + org.apache.logging.log4j + log4j-api + 2.17.1 + diff --git a/src/main/java/com/cx/plugin/cli/CxConsoleLauncher.java b/src/main/java/com/cx/plugin/cli/CxConsoleLauncher.java index f1a7ed3..344d4d6 100644 --- a/src/main/java/com/cx/plugin/cli/CxConsoleLauncher.java +++ b/src/main/java/com/cx/plugin/cli/CxConsoleLauncher.java @@ -13,14 +13,7 @@ import com.cx.restclient.dto.ScannerType; import com.cx.restclient.dto.scansummary.ScanSummary; import com.cx.restclient.exception.CxClientException; - - -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.*; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; @@ -37,15 +30,14 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.cx.plugin.cli.constants.Parameters.*; -import static com.cx.plugin.cli.errorsconstants.ErrorMessages.INVALID_COMMAND_COUNT; -import static com.cx.plugin.cli.errorsconstants.ErrorMessages.INVALID_COMMAND_ERROR; +import static com.cx.plugin.cli.errorsconstants.ErrorMessages.*; +import static com.cx.plugin.cli.utils.CxConfigHelper.EMPTY_JSON; /** * Created by idanA on 11/4/2018. @@ -92,6 +84,7 @@ public static void main(String[] args) { log.error(String.format("%n%n[CxConsole] Error parsing command: %n%s%n%n", e)); exitCode = ErrorParsingHelper.parseError(e.getMessage()); } catch (CxClientException | IOException | InterruptedException e) { + log.error("CLI process terminated, error: " + e.getMessage()); exitCode = ErrorParsingHelper.parseError(e.getMessage()); } @@ -212,12 +205,19 @@ private static int execute(Command command, CommandLine commandLine) return exitCode; } - private static void validateScanParameters(CxScanConfig cxScanConfig) throws CLIParsingException { + private static void validateScanParameters(CxScanConfig cxScanConfig) throws CLIParsingException, CxClientException { if (cxScanConfig == null) return; - if (cxScanConfig.isAstScaEnabled() && checkContainsSpecialChars(cxScanConfig.getProjectName(), SCA_PROJECT_NAME_INVALID_CHARS)) + if (cxScanConfig.isOsaEnabled() && + cxScanConfig.getOsaDependenciesJson() != null && + cxScanConfig.getOsaDependenciesJson().equals(EMPTY_JSON)) { + throw new CxClientException(OSA_NO_DEPENDENCIES_ERROR_MSG); + } + + if (cxScanConfig.isAstScaEnabled() && checkContainsSpecialChars(cxScanConfig.getProjectName(), SCA_PROJECT_NAME_INVALID_CHARS)) { throw new CLIParsingException("[CxConsole] SCA project name cannot contain special characters."); + } } private static boolean checkContainsSpecialChars(String valueToCheck, String regex) { @@ -284,20 +284,20 @@ private static int countCommands(CommandLine commandLine) { private static String[] convertParamToLowerCase(String[] args) { return Arrays .stream(args) - .map(arg -> arg.startsWith("-") && isCliCmdOption(arg)? arg.toLowerCase() : arg) + .map(arg -> arg.startsWith("-") && isCliCmdOption(arg) ? arg.toLowerCase() : arg) .toArray(String[]::new); } private static boolean isCliCmdOption(String argName) { - - Option argfound = Command.getOptions().getOption(argName.toLowerCase()); - if(argfound != null && !StringUtils.isEmpty(argfound.getOpt().toString())) - return true; - else - return false; + + Option argfound = Command.getOptions().getOption(argName.toLowerCase()); + if (argfound != null && !StringUtils.isEmpty(argfound.getOpt().toString())) + return true; + else + return false; } - - + + private static void initFileLogging(String logLocation, String logLevel) { System.setProperty("cliLogPath", logLocation); System.setProperty("logLevel", logLevel); diff --git a/src/main/java/com/cx/plugin/cli/configascode/SastConfig.java b/src/main/java/com/cx/plugin/cli/configascode/SastConfig.java index e3a11b7..6f2fab6 100644 --- a/src/main/java/com/cx/plugin/cli/configascode/SastConfig.java +++ b/src/main/java/com/cx/plugin/cli/configascode/SastConfig.java @@ -21,6 +21,8 @@ public class SastConfig { private int medium; @Optional private int high; + @Optional + private boolean isOverrideProjectSetting; public SastConfig() { @@ -97,4 +99,15 @@ public boolean isPrivateScan() { public void setPrivateScan(boolean privateScan) { this.privateScan = privateScan; } + + public boolean isOverrideProjectSetting() { + return isOverrideProjectSetting; + } + + public void setOverrideProjectSetting(boolean isOverrideProjectSetting) { + this.isOverrideProjectSetting = isOverrideProjectSetting; + } + + + } diff --git a/src/main/java/com/cx/plugin/cli/constants/ArgDescriptions.java b/src/main/java/com/cx/plugin/cli/constants/ArgDescriptions.java index ca51815..3f57519 100644 --- a/src/main/java/com/cx/plugin/cli/constants/ArgDescriptions.java +++ b/src/main/java/com/cx/plugin/cli/constants/ArgDescriptions.java @@ -72,6 +72,10 @@ private ArgDescriptions() { static final String OSA_ENABLED = "Enable open source analysis (CxOSA). -osaLocationPath should be specified or the -LocationType parameter needs to be defined as 'folder' or 'shared' (if -osaLocationPath doesn't exist, use -locationPath). Optional."; static final String SCA_ENABLED = String.format("Enable software composition analysis (SCA). SCA is the successor of CxOSA. Normally either -%1$s or -%2$s should be specified. If both are specified, -%2$s will be used. -osaLocationPath should be specified or the -LocationType parameter needs to be defined as 'folder' or 'shared' (if -osaLocationPath doesn't exist, use -locationPath). Optional.", Parameters.OSA_ENABLED, Parameters.SCA_ENABLED); static final String OSA_JSON_REPORT = "Generate CxOSA JSON report. Optional, not supported in AsyncScan mode"; + static final String OSA_FAIL_ON_ERROR = "Fails the execution in case of any error during the dependencies resolution process."; + static final String OSA_FSA_CONF = "Comma separated list of FSA args, Example: 'npm.runPreStep,nuget.resolveDependencies' will override default values."; + static final String OSA_ERR_LOG_DIR = "OSA error logs root path, if not provided will be stored at runtime directory."; + static final String OSA_SCAN_JSON = "OSA dependencies json to scan."; static final String SCA_JSON_REPORT = "Generates three CxSCA JSON reports. Saves the reports in the specified folder path, Optional. Not supported in AsyncScaScan/AsyncScan mode"; static final String INSTALL_PACKAGE_MANAGER = "Retrieve all supported package dependencies before performing OSA scan (see Remarks section). Optional."; static final String DOCKER_IMAGE_PATTERN = "The docker images to be selected for scan"; diff --git a/src/main/java/com/cx/plugin/cli/constants/Command.java b/src/main/java/com/cx/plugin/cli/constants/Command.java index cf91f1f..b4cf428 100644 --- a/src/main/java/com/cx/plugin/cli/constants/Command.java +++ b/src/main/java/com/cx/plugin/cli/constants/Command.java @@ -113,6 +113,10 @@ public static Options getOptions() { options.addOption(OSA_JSON_REPORT, true, ArgDescriptions.OSA_JSON_REPORT); options.addOption(SCA_JSON_REPORT, true, ArgDescriptions.SCA_JSON_REPORT); options.addOption(INSTALL_PACKAGE_MANAGER, false, ArgDescriptions.INSTALL_PACKAGE_MANAGER); + options.addOption(OSA_FAIL_ON_ERROR, false, ArgDescriptions.OSA_FAIL_ON_ERROR); + options.addOption(Option.builder(OSA_FSA_CONF).hasArg(true).hasArgs().argName("fsa configuration").desc(ArgDescriptions.OSA_FSA_CONF).valueSeparator(',').build()); + options.addOption(Option.builder(OSA_ERR_LOG_DIR).hasArg(true).hasArgs().argName("osa error log dir").desc(ArgDescriptions.OSA_ERR_LOG_DIR).build()); + options.addOption(Option.builder(OSA_SCAN_JSON).hasArg(true).hasArgs().argName("osa scan json").desc(ArgDescriptions.OSA_SCAN_JSON).build()); options.addOption(PDF_REPORT, true, ArgDescriptions.PDF_REPORT); options.addOption(XML_REPORT, true, ArgDescriptions.XML_REPORT); @@ -164,7 +168,7 @@ public static Options getOptions() { options.addOption(SAST_SERVER_URL, true, ArgDescriptions.SAST_SERVER_URL); options.addOption(SAST_USER, true, ArgDescriptions.SAST_USER); options.addOption(SAST_PASSWORD, true, ArgDescriptions.SAST_PASSWORD); - + options.addOption(SCA_CONFIG_FILE, true, ArgDescriptions.SCA_CONFIG_FILE); options.addOption(SCA_INCLUDE_SOURCE_FLAG, false, ArgDescriptions.SCA_INCLUDE_SOURCE_FLAG); options.addOption(SCA_TIMEOUT, true, ArgDescriptions.SCA_TIME_OUT); diff --git a/src/main/java/com/cx/plugin/cli/constants/Parameters.java b/src/main/java/com/cx/plugin/cli/constants/Parameters.java index 5d49d76..b9f07ed 100644 --- a/src/main/java/com/cx/plugin/cli/constants/Parameters.java +++ b/src/main/java/com/cx/plugin/cli/constants/Parameters.java @@ -44,6 +44,10 @@ private Parameters() { public static final String OSA_ARCHIVE_TO_EXTRACT = "osaarchivetoextract"; public static final String OSA_SCAN_DEPTH = "osascandepth"; public static final String OSA_ENABLED = "enableosa"; + public static final String OSA_FAIL_ON_ERROR = "osafailonerror"; + public static final String OSA_FSA_CONF = "osafsaconf"; + public static final String OSA_ERR_LOG_DIR = "osaerrorlogdir"; + public static final String OSA_SCAN_JSON = "osascanjson"; public static final String SCA_ENABLED = "enablesca"; public static final String OSA_JSON_REPORT = "osajson"; public static final String SCA_JSON_REPORT = "scajsondirpath"; diff --git a/src/main/java/com/cx/plugin/cli/errorsconstants/ErrorMessages.java b/src/main/java/com/cx/plugin/cli/errorsconstants/ErrorMessages.java index 005d8ef..1358a96 100644 --- a/src/main/java/com/cx/plugin/cli/errorsconstants/ErrorMessages.java +++ b/src/main/java/com/cx/plugin/cli/errorsconstants/ErrorMessages.java @@ -12,6 +12,8 @@ private ErrorMessages() { public static final String GENERAL_ERROR_MSG = "Failed to start scan (missing or invalid parameters)"; public static final String SDLC_ERROR_MSG = "This feature is available only on SDLC edition"; public static final String NO_OSA_LICENSE_ERROR_MSG = "Open Source Analysis License is not enabled for this project.Please contact your CxSAST Administrator"; + public static final String OSA_RESOLVE_ERROR_MSG = "Failed to resolve dependencies for OSA scan:"; + public static final String OSA_NO_DEPENDENCIES_ERROR_MSG = "No dependencies found for OSA scan"; public static final String LOGIN_FAILED_MSG = "Login Failed"; public static final String UNSUCCESSFUL_LOGIN_ERROR_MSG = "Unsuccessful login"; public static final String UNSUCCESSFUL_REST_LOGIN = "Fail to login with credentials: Fail to authenticate: status code: HTTP/1.1 403 Forbidden."; @@ -37,4 +39,9 @@ private ErrorMessages() { public static final String INVALID_COMMAND_ERROR = "command [%s] is invalid, valid command must start with one of %s"; public static final String INVALID_COMMAND_COUNT = "Invalid command count, One command must be provided Only. One of these commands must be provided only %s. "; + public static final String OSA_MAVEN_RESOLVE_ERROR_MSG = "Failed to resolve Maven dependencies for OSA scan"; + public static final String OSA_GRADLE_RESOLVE_ERROR_MSG = "Failed to resolve Gradle dependencies for OSA scan"; + public static final String OSA_NPM_RESOLVE_ERROR_MSG = "Failed to resolve NPM dependencies for OSA scan"; + public static final String OSA_NUGET_RESOLVE_ERROR_MSG = "Failed to resolve Nuget/DotNet dependencies for OSA scan"; + } diff --git a/src/main/java/com/cx/plugin/cli/errorsconstants/Errors.java b/src/main/java/com/cx/plugin/cli/errorsconstants/Errors.java index 8025059..d9a8868 100644 --- a/src/main/java/com/cx/plugin/cli/errorsconstants/Errors.java +++ b/src/main/java/com/cx/plugin/cli/errorsconstants/Errors.java @@ -7,12 +7,15 @@ * Created by idanA on 11/5/2018. */ public enum Errors { + SCAN_SUCCEEDED(0, NO_ERROR_MSG), GENERAL_ERROR(1, GENERAL_ERROR_MSG), SDLC_ERROR(2, SDLC_ERROR_MSG), NO_OSA_LICENSE_ERROR(3, NO_OSA_LICENSE_ERROR_MSG), LOGIN_FAILED_ERROR(4, LOGIN_FAILED_MSG), NO_PROJECT_PRIOR_TO_OSA_SCAN_ERROR(5, NO_PROJECT_PRIOR_TO_OSA_SCAN_ERROR_MSG), + OSA_RESOLVE_ERROR(6, OSA_RESOLVE_ERROR_MSG), + OSA_NO_DEPENDENCIES_ERROR(7, OSA_NO_DEPENDENCIES_ERROR_MSG), SAST_HIGH_THRESHOLD_ERROR(10, SAST_HIGH_THRESHOLD_ERROR_MSG), SAST_MEDIUM_THRESHOLD_ERROR(11, SAST_MEDIUM_THRESHOLD_ERROR_MSG), @@ -24,6 +27,11 @@ public enum Errors { POLICY_VIOLATION_ERROR(18, POLICY_VIOLATED_ERROR_MSG), GENERIC_THRESHOLD_FAILURE_ERROR(19, GENERIC_THRESHOLD_FAILURE_ERROR_MSG), + OSA_MAVEN_RESOLVE_ERROR(30, OSA_MAVEN_RESOLVE_ERROR_MSG), + OSA_GRADLE_RESOLVE_ERROR(31, OSA_GRADLE_RESOLVE_ERROR_MSG), + OSA_NPM_RESOLVE_ERROR(32, OSA_NPM_RESOLVE_ERROR_MSG), + OSA_NUGET_RESOLVE_ERROR(33, OSA_NUGET_RESOLVE_ERROR_MSG), + CANCELED_BY_USER_ERROR(130, CANCELED_BY_USER_ERROR_MSG); private final int exitCode; diff --git a/src/main/java/com/cx/plugin/cli/utils/CxConfigHelper.java b/src/main/java/com/cx/plugin/cli/utils/CxConfigHelper.java index 48b5439..2a63625 100644 --- a/src/main/java/com/cx/plugin/cli/utils/CxConfigHelper.java +++ b/src/main/java/com/cx/plugin/cli/utils/CxConfigHelper.java @@ -16,7 +16,6 @@ import com.cx.plugin.cli.constants.Parameters; import com.cx.plugin.cli.exceptions.BadOptionCombinationException; import com.cx.plugin.cli.exceptions.CLIParsingException; -import com.cx.plugin.cli.utils.PropertiesManager; import com.cx.restclient.ast.dto.sca.AstScaConfig; import com.cx.restclient.configuration.CxScanConfig; import com.cx.restclient.dto.ProxyConfig; @@ -24,31 +23,30 @@ import com.cx.restclient.dto.ScannerType; import com.cx.restclient.dto.SourceLocationType; import com.cx.restclient.sca.utils.CxSCAFileSystemUtils; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Strings; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.SystemUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.eclipse.jgit.transport.URIish; +import org.whitesource.agent.api.model.AgentProjectInfo; import javax.annotation.Nullable; import javax.naming.ConfigurationException; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.List; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; +import java.util.*; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -62,6 +60,8 @@ */ public final class CxConfigHelper { + public static final String EMPTY_JSON = "EMPTY_JSON"; + private static final String CONFIG_AS_CODE_FILE_NAME = "cx.config"; public static final String CONFIG_FILE_S_NOT_FOUND_OR_COULDN_T_BE_LOADED = "Config file %s not found or couldn't " + "be loaded,please check if file exist's and if file content is valid"; @@ -129,8 +129,8 @@ public CxScanConfig resolveConfiguration(Command command, CommandLine cmd) throw } scanConfig.setEngineConfigurationName(cmd.getOptionValue(CONFIGURATION)); - if(cmd.hasOption(CUSTOM_FIELDS)) { - scanConfig.setCustomFields(apiFormat(cmd.getOptionValue(CUSTOM_FIELDS))); + if (cmd.hasOption(CUSTOM_FIELDS)) { + scanConfig.setCustomFields(apiFormat(cmd.getOptionValue(CUSTOM_FIELDS))); } scanConfig.setUseSSOLogin(cmd.hasOption(IS_SSO)); scanConfig.setDisableCertificateValidation(cmd.hasOption(TRUSTED_CERTIFICATES)); @@ -141,9 +141,9 @@ public CxScanConfig resolveConfiguration(Command command, CommandLine cmd) throw if ((command.equals(Command.SCA_SCAN)) || (command.equals(Command.ASYNC_SCA_SCAN))) { scanConfig.setProjectName(extractProjectName(cmd.getOptionValue(FULL_PROJECT_PATH), true)); scanConfig.setTeamPath(extractTeamPath(cmd.getOptionValue(FULL_PROJECT_PATH), true)); - if (cmd.hasOption(SCA_TIMEOUT)) { - scanConfig.setSCAScanTimeoutInMinutes(Integer.valueOf(cmd.getOptionValue(SCA_TIMEOUT))); - } + if (cmd.hasOption(SCA_TIMEOUT)) { + scanConfig.setSCAScanTimeoutInMinutes(Integer.valueOf(cmd.getOptionValue(SCA_TIMEOUT))); + } } else { scanConfig.setProjectName(extractProjectName(cmd.getOptionValue(FULL_PROJECT_PATH), false)); scanConfig.setTeamPath(extractTeamPath(cmd.getOptionValue(FULL_PROJECT_PATH), false)); @@ -180,16 +180,16 @@ public CxScanConfig resolveConfiguration(Command command, CommandLine cmd) throw return scanConfig; } - + private String apiFormat(String customFields) { - if(StringUtils.isNotEmpty(customFields)) { - customFields = customFields.replaceAll(":", "\":\""); - customFields = customFields.replaceAll(",", "\",\""); - customFields = "{\"".concat(customFields).concat("\"}"); - } - return customFields; - } - + if (StringUtils.isNotEmpty(customFields)) { + customFields = customFields.replaceAll(":", "\":\""); + customFields = customFields.replaceAll(",", "\",\""); + customFields = "{\"".concat(customFields).concat("\"}"); + } + return customFields; + } + private void checkForConfigAsCode(CxScanConfig scanConfig) throws CLIParsingException, IOException, ConfigurationException { if (StringUtils.isNotEmpty(scanConfig.getRemoteSrcUrl()) && RemoteSourceTypes.GIT == scanConfig.getRemoteType()) { resolveConfigAsCodeFromRemote(scanConfig); @@ -203,9 +203,9 @@ private void checkForConfigAsCode(CxScanConfig scanConfig) throws CLIParsingExce private void resolveConfigAsCodeLocal(CxScanConfig scanConfig) throws CLIParsingException, IOException, ConfigurationException { log.info("loading config file from local working directory .."); - ConfigAsCode configAsCodeFromFile = getConfigAsCodeFromFile( - scanConfig.getSourceDir() + File.separator + ".checkmarx" + File.separator + CONFIG_AS_CODE_FILE_NAME); - overrideConfigAsCode(configAsCodeFromFile, scanConfig); + ConfigAsCode configAsCodeFromFile = getConfigAsCodeFromFile( + scanConfig.getSourceDir() + File.separator + ".checkmarx" + File.separator + CONFIG_AS_CODE_FILE_NAME); + overrideConfigAsCode(configAsCodeFromFile, scanConfig); } @@ -249,7 +249,7 @@ private ConfigAsCode getConfigAsCode(ConfigReader reader) throws ConfigurationEx configProvider.init(CX_ORIGIN, reader); if (!configProvider.hasAnyConfiguration(CX_ORIGIN)) - throw new ConfigurationException(String.format(CONFIG_FILE_S_NOT_FOUND_OR_COULDN_T_BE_LOADED, ".checkmarx/"+CONFIG_AS_CODE_FILE_NAME)); + throw new ConfigurationException(String.format(CONFIG_FILE_S_NOT_FOUND_OR_COULDN_T_BE_LOADED, ".checkmarx/" + CONFIG_AS_CODE_FILE_NAME)); ConfigAsCode configAsCodeFromFile = new ConfigAsCode(); @@ -330,7 +330,8 @@ private void mapScaConfiguration(Optional sca, CxScanConfig scanConfi scanConfig.setOsaLowThreshold(pValue); overridesResults.put("Sca Low", String.valueOf(pValue)); }); - + + //build include/exclude file pattern if (!fileExclude.get().isEmpty() || !fileInclude.get().isEmpty()) setDependencyScanFilterPattern(scanConfig, fileInclude.get(), fileExclude.get()); @@ -414,10 +415,16 @@ private void mapSastConfiguration(Optional sast, CxScanConfig scanCo scanConfig.setSastFilterPattern(pValue); overridesResults.put("Include/Exclude pattern", pValue); }); + + + sast.map(SastConfig::isOverrideProjectSetting) + .ifPresent(pValue -> { + scanConfig.setIsOverrideProjectSetting(pValue); + overridesResults.put("Is Overridable", String.valueOf(pValue)); + }); } private void mapProjectConfiguration(Optional project, CxScanConfig scanConfig, Map overridesResults) throws CLIParsingException { - String projectName = project.map(ProjectConfig::getFullPath).orElse(null); if ((command.equals(Command.SCA_SCAN)) || (command.equals(Command.ASYNC_SCA_SCAN))) { @@ -428,7 +435,6 @@ private void mapProjectConfiguration(Optional project, CxScanConf scanConfig.setTeamPath(extractTeamPath(projectName, false)); } - if (projectName != null) overridesResults.put("Project Name", projectName); @@ -442,15 +448,11 @@ private void mapProjectConfiguration(Optional project, CxScanConf } private ConfigAsCode getConfigAsCodeFromFile(String filePath) throws ConfigurationException, IOException { - com.checkmarx.configprovider.readers.FileReader reader = new FileReader(ResourceType.YAML, filePath); return getConfigAsCode(reader); - - } - private URIish prepareRemoteUrl(String remoteSrcUrl, int remoteSrcPort) throws URISyntaxException { URIish urIish = new URIish(remoteSrcUrl); if (remoteSrcPort > 0) { @@ -466,6 +468,7 @@ private void configureDependencyScan(CxScanConfig scanConfig) throws CLIParsingE } if (scanConfig.isOsaEnabled()) { + setOSAEnv(); setOsaSpecificConfig(scanConfig); } else if (scanConfig.isAstScaEnabled()) { setScaSpecificConfig(scanConfig); @@ -474,6 +477,32 @@ private void configureDependencyScan(CxScanConfig scanConfig) throws CLIParsingE setSharedDependencyScanConfig(scanConfig); } + private void setOSAEnv() { + System.setProperty("FSA_ENRICH_ERR_LOGS", "true"); + + String[] fsaConfArr = commandLine.getOptionValues(OSA_FSA_CONF); + if (fsaConfArr != null && !Arrays.asList(fsaConfArr).isEmpty()) { + StringBuilder sb = new StringBuilder(); + String prefix = ""; + for (String arg : fsaConfArr) { + arg = arg.trim(); + if (StringUtils.isNotEmpty(arg)) { + sb.append(prefix + arg); + prefix = ";"; + } + } + String fsaConf = sb.toString().trim(); + if (StringUtils.isNotEmpty(fsaConf)) { + System.setProperty("FSA_CONFIGURATION", fsaConf); + } + } + + String errLogDir = commandLine.getOptionValue(OSA_ERR_LOG_DIR); + if (StringUtils.isNotEmpty(errLogDir)) { + System.setProperty("FSA_ERR_LOGS_PATH", errLogDir); + } + } + private String getRelevantCommand() { String oldCommandLineValue = commandLine.getOptionValue(LOCATION_FILES_EXCLUDE); String newCommandLineValue = commandLine.getOptionValue(INCLUDE_EXCLUDE_PATTERN); @@ -487,6 +516,19 @@ private String getRelevantCommand() { private void setOsaSpecificConfig(CxScanConfig scanConfig) { scanConfig.setOsaRunInstall(commandLine.hasOption(INSTALL_PACKAGE_MANAGER)); + scanConfig.setOsaFailOnError(commandLine.hasOption(OSA_FAIL_ON_ERROR)); + + String osaJsonFile = commandLine.getOptionValue(OSA_SCAN_JSON); + if (StringUtils.isNotEmpty(osaJsonFile)) { + if (verifyOsaJson(osaJsonFile)) { + String json = getFileContent(new File(osaJsonFile)); + scanConfig.setOsaDependenciesJson(json); + log.info("FSA resolver override SUCCESS, OSA dependencies json used: " + osaJsonFile); + } else { + log.error("FSA resolver override: FAILED, OSA dependencies json used: " + osaJsonFile); + scanConfig.setOsaDependenciesJson(EMPTY_JSON); + } + } String reportDir = commandLine.getOptionValue(OSA_JSON_REPORT); scanConfig.setReportsDir(reportDir != null ? new File(reportDir) : null); @@ -499,6 +541,31 @@ private void setOsaSpecificConfig(CxScanConfig scanConfig) { scanConfig.setOsaScanDepth(osaScanDepth); } + private boolean verifyOsaJson(String osaJsonFile) { + try { + File jsonFile = new File(osaJsonFile); + if (jsonFile.exists()) { + ObjectMapper jsonMapper = new ObjectMapper(); + String json = getFileContent(jsonFile); + Collection dependenciesObj = jsonMapper.readValue(json, jsonMapper.getTypeFactory().constructCollectionType(Collection.class, AgentProjectInfo.class)); + if (dependenciesObj != null) { + return true; + } + } + } catch (Exception e) { + log.error("Fail parse dependencies json file."); + } + return false; + } + + private String getFileContent(File file) { + try { + return IOUtils.toString(file.toURI(), StandardCharsets.UTF_8); + } catch (IOException e) { + log.error("Fail to get file content."); + return ""; + } + } private void setScaSpecificConfig(CxScanConfig scanConfig) throws CLIParsingException { AstScaConfig sca = new AstScaConfig(); @@ -513,29 +580,28 @@ private void setScaSpecificConfig(CxScanConfig scanConfig) throws CLIParsingExce sca.setWebAppUrl(webAppUrl); String envVariables = getOptionalParam(ENV_VARIABLE, ""); - if(StringUtils.isNotEmpty(envVariables)) - { + if (StringUtils.isNotEmpty(envVariables)) { sca.setEnvVariables(CxSCAFileSystemUtils.convertStringToKeyValueMap(envVariables)); } String configFilePaths = getOptionalParam(SCA_CONFIG_FILE, ""); - if (StringUtils.isNotEmpty(configFilePaths)) { - sca.setConfigFilePaths(Arrays.asList(configFilePaths.split("\\s*,\\s*"))); - } + if (StringUtils.isNotEmpty(configFilePaths)) { + sca.setConfigFilePaths(Arrays.asList(configFilePaths.split("\\s*,\\s*"))); + } configureScaWithSastDetails(sca); - - if (commandLine.hasOption(SCA_INCLUDE_SOURCE_FLAG)) { - sca.setIncludeSources(true); - } - - if (commandLine.hasOption(ENABLE_SCA_RESOLVER)) { - sca.setEnableScaResolver(true); + + if (commandLine.hasOption(SCA_INCLUDE_SOURCE_FLAG)) { + sca.setIncludeSources(true); + } + + if (commandLine.hasOption(ENABLE_SCA_RESOLVER)) { + sca.setEnableScaResolver(true); String pathToResolver = getRequiredParam(commandLine, PATH_TO_RESOLVER, null); String additionalParams = getRequiredParam(commandLine, SCA_RESOLVER_ADD_PARAMETERS, null); validateSCAResolverParams(); sca.setPathToScaResolver(pathToResolver); sca.setScaResolverAddParameters(additionalParams); - } + } sca.setUsername(getRequiredParam(commandLine, SCA_USERNAME, null)); sca.setPassword(getRequiredParam(commandLine, SCA_PASSWORD, null)); @@ -561,77 +627,76 @@ private void setScaSpecificConfig(CxScanConfig scanConfig) throws CLIParsingExce throw new CLIParsingException(reportDir + " directory doesn't exist."); } } + scanConfig.setAstScaConfig(sca); } - private void configureScaWithSastDetails(AstScaConfig sca) throws CLIParsingException - { - //We are in SCA function whether SCA alone or with SAST scan, start with SCA specific SAST params - String serverURL = getOptionalParam(SAST_SERVER_URL, ""); - String user = getOptionalParam(SAST_USER, ""); - String password = getOptionalParam(SAST_PASSWORD, ""); - String projectId = getOptionalParam(SAST_PROJECT_ID, ""); - String projectName = getOptionalParam(SAST_PROJECT_NAME, ""); - - - //SCA alone scan - if ((!commandLine.hasOption(SCA_ENABLED))) { - if (exploitablePathParamsIncomplete(serverURL, user, password, projectId, projectName)) { - if (!exploitablePathParamsEmpty(serverURL, user, password, projectId, projectName)) - throw new CLIParsingException( - "[CxConsole] For SCA exploitable path, CxSAST server details like url, user, password and full project path or project id are required. Received partial parameters."); - } - // set the SCA Params after the above validation is done for only - // SCA - else { - prepareExpPathScaConfig(sca, serverURL, user, password, projectId, projectName); - } - } - //SCA with SAST - else if (exploitablePathParamsEmpty(serverURL, user, password, projectId, projectName) || exploitablePathParamsIncomplete(serverURL,user,password,projectId,projectName)) { - // assign SAST values to scaconfig - prepareExpPathScaConfig(sca, getOptionalParam(SERVER_URL, ""), getOptionalParam(USER_NAME, ""), - getOptionalParam(USER_PASSWORD, ""), "", commandLine.getOptionValue(FULL_PROJECT_PATH)); - if (StringUtils.isNotEmpty(projectId)) { - // override SCA's SAST project ID - sca.setSastProjectId(projectId); - } - if (StringUtils.isNotEmpty(projectName)) { - // override SCA's SAST project Name - sca.setSastProjectName(projectName); - } - } else { - prepareExpPathScaConfig(sca, serverURL, user, password, projectId, projectName); - } - } - - private void prepareExpPathScaConfig(AstScaConfig sca, String serverURL, String user, String password, - String projectId, String projectName) { - sca.setSastServerUrl(serverURL); - sca.setSastUsername(user); - sca.setSastPassword(password); - sca.setSastProjectName(projectName); - sca.setSastProjectId(projectId); - - } - - private boolean exploitablePathParamsEmpty(String serverURL, String user, String password, String projectId, - String projectName) { - return StringUtils.isEmpty(serverURL) && StringUtils.isEmpty(user) && StringUtils.isEmpty(password) - && (StringUtils.isEmpty(projectId) && StringUtils.isEmpty(projectName)) ? true : false; - - } - - private boolean exploitablePathParamsIncomplete(String serverURL, String user, String password, String projectId, - String projectName) { - boolean partialParams = false; - partialParams = StringUtils.isNotEmpty(serverURL) && !partialParams ? false : true; - partialParams = StringUtils.isNotEmpty(user) && !partialParams ? false : true; - partialParams = StringUtils.isNotEmpty(password) && !partialParams ? false : true; - partialParams = (StringUtils.isNotEmpty(projectId) || StringUtils.isNotEmpty(projectName)) && !partialParams - ? false : true; - return partialParams; - } + private void configureScaWithSastDetails(AstScaConfig sca) throws CLIParsingException { + //We are in SCA function whether SCA alone or with SAST scan, start with SCA specific SAST params + String serverURL = getOptionalParam(SAST_SERVER_URL, ""); + String user = getOptionalParam(SAST_USER, ""); + String password = getOptionalParam(SAST_PASSWORD, ""); + String projectId = getOptionalParam(SAST_PROJECT_ID, ""); + String projectName = getOptionalParam(SAST_PROJECT_NAME, ""); + + + //SCA alone scan + if ((!commandLine.hasOption(SCA_ENABLED))) { + if (exploitablePathParamsIncomplete(serverURL, user, password, projectId, projectName)) { + if (!exploitablePathParamsEmpty(serverURL, user, password, projectId, projectName)) + throw new CLIParsingException( + "[CxConsole] For SCA exploitable path, CxSAST server details like url, user, password and full project path or project id are required. Received partial parameters."); + } + // set the SCA Params after the above validation is done for only + // SCA + else { + prepareExpPathScaConfig(sca, serverURL, user, password, projectId, projectName); + } + } + //SCA with SAST + else if (exploitablePathParamsEmpty(serverURL, user, password, projectId, projectName) || exploitablePathParamsIncomplete(serverURL, user, password, projectId, projectName)) { + // assign SAST values to scaconfig + prepareExpPathScaConfig(sca, getOptionalParam(SERVER_URL, ""), getOptionalParam(USER_NAME, ""), + getOptionalParam(USER_PASSWORD, ""), "", commandLine.getOptionValue(FULL_PROJECT_PATH)); + if (StringUtils.isNotEmpty(projectId)) { + // override SCA's SAST project ID + sca.setSastProjectId(projectId); + } + if (StringUtils.isNotEmpty(projectName)) { + // override SCA's SAST project Name + sca.setSastProjectName(projectName); + } + } else { + prepareExpPathScaConfig(sca, serverURL, user, password, projectId, projectName); + } + } + + private void prepareExpPathScaConfig(AstScaConfig sca, String serverURL, String user, String password, + String projectId, String projectName) { + sca.setSastServerUrl(serverURL); + sca.setSastUsername(user); + sca.setSastPassword(password); + sca.setSastProjectName(projectName); + sca.setSastProjectId(projectId); + + } + + private boolean exploitablePathParamsEmpty(String serverURL, String user, String password, String projectId, + String projectName) { + return StringUtils.isEmpty(serverURL) && StringUtils.isEmpty(user) && StringUtils.isEmpty(password) + && (StringUtils.isEmpty(projectId) && StringUtils.isEmpty(projectName)) ? true : false; + } + + private boolean exploitablePathParamsIncomplete(String serverURL, String user, String password, String projectId, + String projectName) { + boolean partialParams = false; + partialParams = StringUtils.isNotEmpty(serverURL) && !partialParams ? false : true; + partialParams = StringUtils.isNotEmpty(user) && !partialParams ? false : true; + partialParams = StringUtils.isNotEmpty(password) && !partialParams ? false : true; + partialParams = (StringUtils.isNotEmpty(projectId) || StringUtils.isNotEmpty(projectName)) && !partialParams + ? false : true; + return partialParams; + } private void setSharedDependencyScanConfig(CxScanConfig scanConfig) { setDependencyScanThresholds(scanConfig); @@ -842,11 +907,11 @@ private static String extractTeamPath(String fullPath, boolean isScaScan) throws throw new CLIParsingException("[CxConsole] No project path was specified"); } int lastIdx = getLastIndexOfTeam(fullPath, isScaScan); - if(lastIdx == -1) - return ""; + if (lastIdx == -1) + return ""; else - return fullPath.substring(0, lastIdx); - + return fullPath.substring(0, lastIdx); + } public static void printConfig(CommandLine commandLine) { @@ -898,36 +963,35 @@ private String getOptionalParam(String commandLineKey, String fallbackProperty) /** * This method validates SCA Resolver flow parameters + * * @return * @throws CLIParsingException */ - private boolean validateSCAResolverParams()throws CLIParsingException { + private boolean validateSCAResolverParams() throws CLIParsingException { boolean isValidParams = true; String pathToResolver = commandLine.getOptionValue(PATH_TO_RESOLVER); String additionalParams = commandLine.getOptionValue(SCA_RESOLVER_ADD_PARAMETERS); - + pathToResolver = pathToResolver + File.separator + "ScaResolver"; - if(!SystemUtils.IS_OS_UNIX) - pathToResolver = pathToResolver + ".exe"; - + if (!SystemUtils.IS_OS_UNIX) + pathToResolver = pathToResolver + ".exe"; + File file = new File(pathToResolver); - if(!file.exists()) - { - throw new CLIParsingException("SCA Resolver path does not exist. Path="+file.getAbsolutePath()); + if (!file.exists()) { + throw new CLIParsingException("SCA Resolver path does not exist. Path=" + file.getAbsolutePath()); } String[] arguments = additionalParams.split(" "); String dirPath; - for (int i = 0; i < arguments.length ; i++) { - if (arguments[i].equals("-r") || arguments[i].equals("-s") ) { + for (int i = 0; i < arguments.length; i++) { + if (arguments[i].equals("-r") || arguments[i].equals("-s")) { dirPath = arguments[i + 1]; - if(dirPath.endsWith(File.separator)){ - dirPath = dirPath.substring(0,dirPath.length()-2); + if (dirPath.endsWith(File.separator)) { + dirPath = dirPath.substring(0, dirPath.length() - 2); } File resultPath = new File(dirPath); - if(!resultPath.exists()) - { - if(arguments[i].equals("-s") ) { + if (!resultPath.exists()) { + if (arguments[i].equals("-s")) { throw new CLIParsingException("Source code path does not exist. " + resultPath.getAbsolutePath()); } } diff --git a/src/main/java/com/cx/plugin/cli/utils/ErrorParsingHelper.java b/src/main/java/com/cx/plugin/cli/utils/ErrorParsingHelper.java index 8f34adc..80776eb 100644 --- a/src/main/java/com/cx/plugin/cli/utils/ErrorParsingHelper.java +++ b/src/main/java/com/cx/plugin/cli/utils/ErrorParsingHelper.java @@ -4,10 +4,13 @@ import com.cx.restclient.dto.scansummary.ErrorSource; import com.cx.restclient.dto.scansummary.ScanSummary; import com.cx.restclient.dto.scansummary.ThresholdError; +import org.apache.commons.lang3.StringUtils; +import org.whitesource.agent.utils.CommandLineErrors; import java.util.Comparator; import java.util.HashMap; import java.util.Map; +import java.util.Set; import static com.cx.plugin.cli.errorsconstants.ErrorMessages.*; @@ -30,6 +33,8 @@ private static Map createMessageToCodeMap() { messageToCodeMap.put(INVALID_CREDENTIALS, Errors.LOGIN_FAILED_ERROR.getCode()); messageToCodeMap.put(SDLC_ERROR_MSG, Errors.SDLC_ERROR.getCode()); messageToCodeMap.put(NO_OSA_LICENSE_ERROR_MSG, Errors.NO_OSA_LICENSE_ERROR.getCode()); + messageToCodeMap.put(OSA_RESOLVE_ERROR_MSG, Errors.OSA_RESOLVE_ERROR.getCode()); + messageToCodeMap.put(OSA_NO_DEPENDENCIES_ERROR_MSG, Errors.OSA_NO_DEPENDENCIES_ERROR.getCode()); messageToCodeMap.put(NO_PROJECT_PRIOR_TO_OSA_SCAN_ERROR_MSG, Errors.NO_PROJECT_PRIOR_TO_OSA_SCAN_ERROR.getCode()); messageToCodeMap.put(REPORT_PARAMETER_IN_ASYNC_SCAN, Errors.GENERAL_ERROR.getCode()); messageToCodeMap.put(THRESHOLD_PARAMETER_IN_ASYNC_SCAN, Errors.GENERAL_ERROR.getCode()); @@ -43,6 +48,11 @@ private static Map createMessageToCodeMap() { messageToCodeMap.put(SAST_HIGH_THRESHOLD_ERROR_MSG, Errors.SAST_HIGH_THRESHOLD_ERROR.getCode()); messageToCodeMap.put(SAST_MEDIUM_THRESHOLD_ERROR_MSG, Errors.SAST_MEDIUM_THRESHOLD_ERROR.getCode()); messageToCodeMap.put(SAST_LOW_THRESHOLD_ERROR_MSG, Errors.SAST_LOW_THRESHOLD_ERROR.getCode()); + // OSA resolvers + messageToCodeMap.put(OSA_MAVEN_RESOLVE_ERROR_MSG, Errors.OSA_MAVEN_RESOLVE_ERROR.getCode()); + messageToCodeMap.put(OSA_GRADLE_RESOLVE_ERROR_MSG, Errors.OSA_GRADLE_RESOLVE_ERROR.getCode()); + messageToCodeMap.put(OSA_NPM_RESOLVE_ERROR_MSG, Errors.OSA_NPM_RESOLVE_ERROR.getCode()); + messageToCodeMap.put(OSA_NUGET_RESOLVE_ERROR_MSG, Errors.OSA_NUGET_RESOLVE_ERROR.getCode()); return messageToCodeMap; } @@ -64,9 +74,9 @@ public static Errors getErrorType(ScanSummary scanSummary) { } else if (sastMostSevere == null && osaMostSevere == null && scaMostSevere == null) { return Errors.SCAN_SUCCEEDED; } else { - if(sastMostSevere != null){ + if (sastMostSevere != null) { return toThresholdErrorCode(sastMostSevere); - }else { + } else { return toThresholdErrorCode(osaMostSevere != null ? osaMostSevere : scaMostSevere); } } @@ -107,8 +117,28 @@ public static int parseError(String errorMsg) { return Errors.GENERAL_ERROR.getCode(); } + if (StringUtils.containsIgnoreCase(errorMsg, OSA_RESOLVE_ERROR_MSG)) { + Set failedResolver = CommandLineErrors.getFailedResolver(); + if (failedResolver.size() > 1) { + return Errors.OSA_RESOLVE_ERROR.getCode(); + } + + String resolver = failedResolver.iterator().next(); + if (resolver.equalsIgnoreCase("Maven")) { + return Errors.OSA_MAVEN_RESOLVE_ERROR.getCode(); + } else if (resolver.equalsIgnoreCase("Gradle")) { + return Errors.OSA_GRADLE_RESOLVE_ERROR.getCode(); + } else if (resolver.equalsIgnoreCase("NPM")) { + return Errors.OSA_NPM_RESOLVE_ERROR.getCode(); + } else if (resolver.equalsIgnoreCase("DotNet") || resolver.equalsIgnoreCase("Nuget")) { + return Errors.OSA_NUGET_RESOLVE_ERROR.getCode(); + } + + return Errors.OSA_RESOLVE_ERROR.getCode(); + } + for (Map.Entry entry : errorMsgToCodeMap.entrySet()) { - if (errorMsg.toLowerCase().contains(entry.getKey().toLowerCase())) { + if (StringUtils.containsIgnoreCase(errorMsg, entry.getKey())) { return entry.getValue(); } }