diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 06d615c84..c40043547 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -136,6 +136,7 @@ const ( BranchPrimaryPrefix = "--branch-primary=" OverridePolicyManagement = "override-policy-management" defaultScanEnqueueRetryDelay = 5 + scaResolverCxOneAuthToken = "CXONE_AUTH_TOKEN" ) var ( @@ -1867,7 +1868,7 @@ func filterMatched(filters []string, fileName string) bool { return matched } -func runScaResolver(sourceDir, scaResolver, scaResolverParams, projectName string) error { +func runScaResolver(sourceDir, scaResolver, scaResolverParams, projectName string, featureFlagsWrapper wrappers.FeatureFlagsWrapper) error { if scaResolver != "" { scaFile, err := ioutil.TempFile("", "sca") scaResolverResultsFile = scaFile.Name() + ".json" @@ -1888,7 +1889,19 @@ func runScaResolver(sourceDir, scaResolver, scaResolverParams, projectName strin args = append(args, parsedscaResolverParams...) } log.Println(fmt.Sprintf("Using SCA resolver: %s %v", scaResolver, args)) - out, err := exec.Command(scaResolver, args...).Output() + cmd := exec.Command(scaResolver, args...) + scaDeltaScanEnabled, _ := wrappers.GetSpecificFeatureFlag(featureFlagsWrapper, wrappers.ScaDeltaScanEnabled) + if scaDeltaScanEnabled.Status { + accessToken, err := wrappers.GetAccessToken() + if err != nil { + return err + } + if accessToken != "" { + logger.PrintIfVerbose("Setting authorization token for SCA Delta Scan") + cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%s", scaResolverCxOneAuthToken, accessToken)) + } + } + out, err := cmd.Output() logger.PrintIfVerbose(string(out)) if err != nil { return errors.Errorf("%s", err) @@ -2001,7 +2014,7 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW // execute scaResolver only in sca type of scans if strings.Contains(actualScanTypes, commonParams.ScaType) { - scaErr := runScaResolver(directoryPath, scaResolver, scaResolverParams, projectName) + scaErr := runScaResolver(directoryPath, scaResolver, scaResolverParams, projectName, featureFlagsWrapper) if scaErr != nil { if unzip { _ = cleanTempUnzipDirectory(directoryPath) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index a88a2c78a..8d0ba7889 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -13,6 +13,7 @@ import ( "reflect" "strings" "testing" + "time" "github.com/checkmarx/ast-cli/internal/commands/util" errorConstants "github.com/checkmarx/ast-cli/internal/constants/errors" @@ -315,7 +316,8 @@ func TestCreateScanWithScaResolverParamsWrong(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - err := runScaResolver(tt.sourceDir, tt.scaResolver, tt.scaResolverParams, tt.projectName) + featureFlagsWrapper := &mock.FeatureFlagsMockWrapper{} + err := runScaResolver(tt.sourceDir, tt.scaResolver, tt.scaResolverParams, tt.projectName, featureFlagsWrapper) assert.Assert(t, strings.Contains(err.Error(), tt.expectedError), err.Error()) }) } @@ -326,10 +328,32 @@ func TestCreateScanWithScaResolverNoScaResolver(t *testing.T) { var scaResolver = "" var scaResolverParams = "params" var projectName = "ProjectName" - err := runScaResolver(sourceDir, scaResolver, scaResolverParams, projectName) + featureFlagsWrapper := &mock.FeatureFlagsMockWrapper{} + err := runScaResolver(sourceDir, scaResolver, scaResolverParams, projectName, featureFlagsWrapper) assert.Assert(t, err == nil) } +func TestScaResolverWithSCADeltaScanEnabled(t *testing.T) { + setupMockAccessToken() + defer cleanupMockAccessToken() + + mock.Flag = wrappers.FeatureFlagResponseModel{ + Name: wrappers.ScaDeltaScanEnabled, + Status: true, + } + defer func() { + mock.Flag = wrappers.FeatureFlagResponseModel{} + }() + var sourceDir = "/sourceDir" + var scaResolver = "./NonExistentScaResolver" + var scaResolverParams = "params" + var projectName = "ProjectName" + featureFlagsWrapper := &mock.FeatureFlagsMockWrapper{} + err := runScaResolver(sourceDir, scaResolver, scaResolverParams, projectName, featureFlagsWrapper) + assert.Assert(t, err != nil, "Expected error when resolver doesn't exist") + assert.Assert(t, strings.Contains(err.Error(), "ScaResolver"), "Error should mention ScaResolver: %v", err.Error()) +} + func TestCreateScanWithScanTypes(t *testing.T) { baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch"} execCmdNilAssertion(t, append(baseArgs, "--scan-types", "sast")...) @@ -4943,3 +4967,18 @@ func TestGetGitCommitHistoryValue_WithWarnings(t *testing.T) { }) } } + +func setupMockAccessToken() { + wrappers.CachedAccessToken = "mock-token-for-testing" + wrappers.CachedAccessTime = time.Now() + viper.Set(commonParams.TokenExpirySecondsKey, 300) +} + +func cleanupMockAccessToken() { + wrappers.CachedAccessToken = "" + wrappers.CachedAccessTime = time.Time{} + + wrappers.ClearCache() + // Reset to default value (300 seconds as per params/binds.go) + viper.Set(commonParams.TokenExpirySecondsKey, 300) +} diff --git a/internal/wrappers/feature-flags.go b/internal/wrappers/feature-flags.go index ad1b3afab..8b2579b27 100644 --- a/internal/wrappers/feature-flags.go +++ b/internal/wrappers/feature-flags.go @@ -19,6 +19,7 @@ const SscsCommitHistoryEnabled = "SSCS_COMMIT_HISTORY_ENABLED" const DirectAssociationEnabled = "DIRECT_APP_ASSOCIATION_ENABLED" const maxRetries = 3 const IncreaseFileUploadLimit = "INCREASE_FILE_UPLOAD_LIMIT" +const ScaDeltaScanEnabled = "SCA_DELTASCAN_ENABLED" var DefaultFFLoad bool = false