diff --git a/.github/workflows/ai-code-review.yml b/.github/workflows/ai-code-review.yml index a26010653..29446d224 100644 --- a/.github/workflows/ai-code-review.yml +++ b/.github/workflows/ai-code-review.yml @@ -8,7 +8,7 @@ on: jobs: code_review: - uses: Checkmarx/plugins-release-workflow/.github/workflows/ai-code-review.yml@add-ai-code-review + uses: Checkmarx/plugins-release-workflow/.github/workflows/ai-code-review.yml@main with: open_ai_model: "gpt-4-1106-preview" exclude_pattern: "" diff --git a/internal/commands/scan.go b/internal/commands/scan.go index d04a0727f..501f6c67b 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1086,13 +1086,6 @@ func validateScanTypes(cmd *cobra.Command, jwtWrapper wrappers.JWTWrapper, featu userScanTypes = strings.Replace(strings.ToLower(userScanTypes), commonParams.ContainersTypeFlag, commonParams.ContainersType, 1) userSCSScanTypes = strings.Replace(strings.ToLower(userSCSScanTypes), commonParams.SCSEnginesFlag, commonParams.ScsType, 1) - SCSScanTypes = strings.Split(userSCSScanTypes, ",") - if slices.Contains(SCSScanTypes, ScsSecretDetectionType) && !allowedEngines[commonParams.EnterpriseSecretsType] { - keys := reflect.ValueOf(allowedEngines).MapKeys() - err = errors.Errorf(engineNotAllowed, ScsSecretDetectionType, ScsSecretDetectionType, keys) - return err - } - scanTypes = strings.Split(userScanTypes, ",") for _, scanType := range scanTypes { if !allowedEngines[scanType] || (scanType == commonParams.ContainersType && !(containerEngineCLIEnabled.Status)) { @@ -1101,6 +1094,14 @@ func validateScanTypes(cmd *cobra.Command, jwtWrapper wrappers.JWTWrapper, featu return err } } + + SCSScanTypes = strings.Split(userSCSScanTypes, ",") + if slices.Contains(SCSScanTypes, ScsSecretDetectionType) && !allowedEngines[commonParams.EnterpriseSecretsType] { + keys := reflect.ValueOf(allowedEngines).MapKeys() + err = errors.Errorf(engineNotAllowed, ScsSecretDetectionType, ScsSecretDetectionType, keys) + return err + } + } else { for k := range allowedEngines { if k == commonParams.ContainersType && !(containerEngineCLIEnabled.Status) { diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index dae99aa11..0eeb211a8 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -1888,3 +1888,60 @@ func TestAddSastScan_ScanFlags(t *testing.T) { }) } } + +func TestValidateScanTypes(t *testing.T) { + tests := []struct { + name string + userScanTypes string + userSCSScanTypes string + allowedEngines map[string]bool + containerEngineCLIEnabled bool + expectedError string + }{ + { + name: "No licenses available", + userScanTypes: "scs", + userSCSScanTypes: "sast,secret-detection", + allowedEngines: map[string]bool{"scs": false, "enterprise-secrets": false}, + containerEngineCLIEnabled: true, + expectedError: "It looks like the \"scs\" scan type does", + }, + { + name: "SCS license available, secret-detection not available", + userScanTypes: "scs", + userSCSScanTypes: "secret-detection", + allowedEngines: map[string]bool{"scs": true, "enterprise-secrets": false}, + containerEngineCLIEnabled: true, + expectedError: "It looks like the \"secret-detection\" scan type does not exist", + }, + { + name: "All licenses available", + userScanTypes: "scs", + userSCSScanTypes: "secret-detection", + allowedEngines: map[string]bool{"scs": true, "enterprise-secrets": true}, + containerEngineCLIEnabled: true, + expectedError: "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{} + cmd.Flags().String(commonParams.ScanTypes, tt.userScanTypes, "") + cmd.Flags().String(commonParams.SCSEnginesFlag, tt.userSCSScanTypes, "") + + jwtWrapper := &mock.JWTMockWrapper{ + CustomGetAllowedEngines: func(featureFlagsWrapper wrappers.FeatureFlagsWrapper) (map[string]bool, error) { + return tt.allowedEngines, nil + }, + } + featureFlagsWrapper := &mock.FeatureFlagsMockWrapper{} + err := validateScanTypes(cmd, jwtWrapper, featureFlagsWrapper) + if tt.expectedError != "" { + assert.ErrorContains(t, err, tt.expectedError) + } else { + assert.NilError(t, err) + } + }) + } +} diff --git a/internal/wrappers/mock/jwt-helper-mock.go b/internal/wrappers/mock/jwt-helper-mock.go index 3b2e4b923..2d35286a3 100644 --- a/internal/wrappers/mock/jwt-helper-mock.go +++ b/internal/wrappers/mock/jwt-helper-mock.go @@ -7,13 +7,17 @@ import ( ) type JWTMockWrapper struct { - AIEnabled int + AIEnabled int + CustomGetAllowedEngines func(wrappers.FeatureFlagsWrapper) (map[string]bool, error) } const AIProtectionDisabled = 1 // GetAllowedEngines mock for tests -func (*JWTMockWrapper) GetAllowedEngines(featureFlagsWrapper wrappers.FeatureFlagsWrapper) (allowedEngines map[string]bool, err error) { +func (j *JWTMockWrapper) GetAllowedEngines(featureFlagsWrapper wrappers.FeatureFlagsWrapper) (allowedEngines map[string]bool, err error) { + if j.CustomGetAllowedEngines != nil { + return j.CustomGetAllowedEngines(featureFlagsWrapper) + } allowedEngines = make(map[string]bool) engines := []string{"sast", "iac-security", "sca", "api-security", "containers", "scs"} for _, value := range engines {