diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 7ccf33807..bc9a47a37 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -358,6 +358,9 @@ func scanCreateSubCommand( commonParams.BranchFlag, commonParams.BranchFlagSh, commonParams.Branch, commonParams.BranchFlagUsage, ) + createScanCmd.PersistentFlags().String(commonParams.SastFilterFlag, "", commonParams.SastFilterUsage) + createScanCmd.PersistentFlags().String(commonParams.KicsFilterFlag, "", commonParams.KicsFilterUsage) + createScanCmd.PersistentFlags().String(commonParams.ScaFilterFlag, "", commonParams.ScaFilterUsage) addResultFormatFlag( createScanCmd, printer.FormatSummaryConsole, @@ -517,15 +520,15 @@ func updateScanRequestValues( return err } } - var sastConfig = addSastScan(cmd) + sastConfig := addSastScan(cmd) if sastConfig != nil { configArr = append(configArr, sastConfig) } - var kicsConfig = addKicsScan() + var kicsConfig = addKicsScan(cmd) if kicsConfig != nil { configArr = append(configArr, kicsConfig) } - var scaConfig = addScaScan() + var scaConfig = addScaScan(cmd) if scaConfig != nil { configArr = append(configArr, scaConfig) } @@ -534,6 +537,45 @@ func updateScanRequestValues( return err } +func addSastScan(cmd *cobra.Command) map[string]interface{} { + if scanTypeEnabled("sast") { + sastMapConfig := make(map[string]interface{}) + sastConfig := wrappers.SastConfig{} + sastMapConfig["type"] = "sast" + incrementalVal, _ := cmd.Flags().GetBool(commonParams.IncrementalSast) + sastConfig.Incremental = strconv.FormatBool(incrementalVal) + sastConfig.PresetName, _ = cmd.Flags().GetString(commonParams.PresetName) + sastConfig.Filter, _ = cmd.Flags().GetString(commonParams.SastFilterFlag) + sastMapConfig["value"] = &sastConfig + return sastMapConfig + } + return nil +} + +func addKicsScan(cmd *cobra.Command) map[string]interface{} { + if scanTypeEnabled("kics") { + kicsMapConfig := make(map[string]interface{}) + kicsConfig := wrappers.KicsConfig{} + kicsMapConfig["type"] = "kics" + kicsConfig.Filter, _ = cmd.Flags().GetString(commonParams.KicsFilterFlag) + kicsMapConfig["value"] = &kicsConfig + return kicsMapConfig + } + return nil +} + +func addScaScan(cmd *cobra.Command) map[string]interface{} { + if scanTypeEnabled("sca") { + scaMapConfig := make(map[string]interface{}) + scaConfig := wrappers.ScaConfig{} + scaMapConfig["type"] = "sca" + scaConfig.Filter, _ = cmd.Flags().GetString(commonParams.ScaFilterFlag) + scaMapConfig["value"] = &scaConfig + return scaMapConfig + } + return nil +} + func determineScanTypes(cmd *cobra.Command) { userScanTypes, _ := cmd.Flags().GetString(commonParams.ScanTypes) if len(userScanTypes) > 0 { @@ -567,50 +609,6 @@ func scanTypeEnabled(scanType string) bool { return false } -func addSastScan(cmd *cobra.Command) map[string]interface{} { - if scanTypeEnabled("sast") { - var objArr map[string]interface{} - _ = json.Unmarshal([]byte("{}"), &objArr) - newIncremental, _ := cmd.Flags().GetBool(commonParams.IncrementalSast) - newPresetName, _ := cmd.Flags().GetString(commonParams.PresetName) - objArr["type"] = "sast" - var valueMap map[string]interface{} - _ = json.Unmarshal([]byte("{}"), &valueMap) - valueMap["incremental"] = fmt.Sprintf("%v", newIncremental) - if newPresetName != "" { - valueMap["presetName"] = newPresetName - } - - objArr["value"] = valueMap - return objArr - } - return nil -} - -func addKicsScan() map[string]interface{} { - if scanTypeEnabled("kics") { - var objArr map[string]interface{} - _ = json.Unmarshal([]byte("{}"), &objArr) - objArr["type"] = "kics" - var valueMap map[string]interface{} - _ = json.Unmarshal([]byte("{}"), &valueMap) - return objArr - } - return nil -} - -func addScaScan() map[string]interface{} { - if scanTypeEnabled("sca") { - var objArr map[string]interface{} - _ = json.Unmarshal([]byte("{}"), &objArr) - objArr["type"] = "sca" - var valueMap map[string]interface{} - _ = json.Unmarshal([]byte("{}"), &valueMap) - return objArr - } - return nil -} - func compressFolder(sourceDir, filter, userIncludeFilter, scaResolver string) (string, error) { scaToolPath := scaResolver outputFile, err := ioutil.TempFile(os.TempDir(), "cx-*.zip") diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index e7e6c9131..8d12507ae 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -228,3 +228,24 @@ func TestScanWorkflowMissingID(t *testing.T) { err := execCmdNotNilAssertion(t, "scan", "workflow") assert.Error(t, err, "Please provide a scan ID", err.Error()) } + +func TestScanWorkFlowWithSastFilter(t *testing.T) { + baseArgs := []string{"scan", "create", "--project-name", "sastFilterMock", "-b", "dummy_branch", "-s", dummyRepo, "--sast-filter", "!*.go"} + cmd := createASTTestCommand() + err := executeTestCommand(cmd, baseArgs...) + assert.NilError(t, err) +} + +func TestScanWorkFlowWithKicsFilter(t *testing.T) { + baseArgs := []string{"scan", "create", "--project-name", "kicsFilterMock", "-b", "dummy_branch", "-s", dummyRepo, "--kics-filter", "!Dockerfile"} + cmd := createASTTestCommand() + err := executeTestCommand(cmd, baseArgs...) + assert.NilError(t, err) +} + +func TestScanWorkFlowWithScaFilter(t *testing.T) { + baseArgs := []string{"scan", "create", "--project-name", "scaFilterMock", "-b", "dummy_branch", "-s", dummyRepo, "--sca-filter", "!jQuery"} + cmd := createASTTestCommand() + err := executeTestCommand(cmd, baseArgs...) + assert.NilError(t, err) +} diff --git a/internal/params/flags.go b/internal/params/flags.go index bc03b782a..77e3efc7d 100644 --- a/internal/params/flags.go +++ b/internal/params/flags.go @@ -98,6 +98,14 @@ const ( GitLabURLFlag = "url-gitlab" URLFlagUsage = "API base URL" QueryIDFlag = "query-id" + + // INDIVIDUAL FILTER FLAGS + SastFilterFlag = "sast-filter" + SastFilterUsage = "SAST filter" + KicsFilterFlag = "kics-filter" + KicsFilterUsage = "KICS filter" + ScaFilterFlag = "sca-filter" + ScaFilterUsage = "SCA filter" ) // Parameter values diff --git a/internal/wrappers/scans.go b/internal/wrappers/scans.go index 537ff036d..68d455d71 100644 --- a/internal/wrappers/scans.go +++ b/internal/wrappers/scans.go @@ -111,3 +111,20 @@ type ScansWrapper interface { Cancel(scanID string) (*ErrorModel, error) Tags() (map[string][]string, *ErrorModel, error) } + +type SastConfig struct { + Incremental string `json:"incremental,omitempty"` + Filter string `json:"filter,omitempty"` + EngineVerbose string `json:"engineVerbose,omitempty"` + LanguageMode string `json:"languageMode,omitempty"` + PresetName string `json:"presetName,omitempty"` +} + +type KicsConfig struct { + Filter string `json:"filter,omitempty"` + Platforms string `json:"platforms,omitempty"` +} + +type ScaConfig struct { + Filter string `json:"filter,omitempty"` +} diff --git a/test/integration/data/insecure.zip b/test/integration/data/insecure.zip new file mode 100644 index 000000000..3126b16db Binary files /dev/null and b/test/integration/data/insecure.zip differ diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index 189f7893d..223911504 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -6,8 +6,10 @@ import ( "bufio" "bytes" "context" + "encoding/json" "fmt" "io" + "io/ioutil" "log" "os" "strings" @@ -509,3 +511,39 @@ func TestFailedScanWithWrongPreset(t *testing.T) { err, _ := executeCommand(t, args...) assertError(t, err, "scan did not complete successfully") } + +func retrieveResultsFromScanId(t *testing.T, scanId string) (wrappers.ScanResultsCollection, error) { + resultsArgs := []string{ + "results", + "show", + flag(params.ScanIDFlag), + scanId, + } + executeCmdNilAssertion(t, "Getting results should pass", resultsArgs...) + file, err := ioutil.ReadFile("cx_result.json") + defer func() { + os.Remove("cx_result.json") + }() + if err != nil { + return wrappers.ScanResultsCollection{}, err + } + results := wrappers.ScanResultsCollection{} + _ = json.Unmarshal([]byte(file), &results) + return results, err +} + +func TestScanWorkFlowWithSastEngineFilter(t *testing.T) { + insecurePath := "data/insecure.zip" + args := getCreateArgsWithName(insecurePath, Tags, getProjectNameForScanTests(), "sast") + args = append(args, flag(params.SastFilterFlag), "!*.java") + scanId, projectId := executeCreateScan(t, args) + assert.Assert(t, scanId != "", "Scan ID should not be empty") + assert.Assert(t, projectId != "", "Project ID should not be empty") + results, err := retrieveResultsFromScanId(t, scanId) + assert.Assert(t, err == nil, "Results retrieved should not throw an error") + for _, result := range results.Results { + for _, node := range result.ScanResultData.Nodes { + assert.Assert(t, !strings.HasSuffix(node.FileName, "java"), "File name should not contain java") + } + } +}