diff --git a/internal/commands/result.go b/internal/commands/result.go index 2ba0b41c4..b3e64be6f 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -188,6 +188,7 @@ func NewResultsCommand( scsScanOverviewWrapper wrappers.ScanOverviewWrapper, policyWrapper wrappers.PolicyWrapper, featureFlagsWrapper wrappers.FeatureFlagsWrapper, + jwtWrapper wrappers.JWTWrapper, ) *cobra.Command { resultCmd := &cobra.Command{ Use: "results", @@ -201,7 +202,7 @@ func NewResultsCommand( }, } showResultCmd := resultShowSubCommand(resultsWrapper, scanWrapper, exportWrapper, resultsPdfReportsWrapper, resultsJSONReportsWrapper, - risksOverviewWrapper, scsScanOverviewWrapper, policyWrapper, featureFlagsWrapper) + risksOverviewWrapper, scsScanOverviewWrapper, policyWrapper, featureFlagsWrapper, jwtWrapper) codeBashingCmd := resultCodeBashing(codeBashingWrapper) bflResultCmd := resultBflSubCommand(bflWrapper) exitCodeSubcommand := exitCodeSubCommand(scanWrapper) @@ -263,6 +264,7 @@ func resultShowSubCommand( scsScanOverviewWrapper wrappers.ScanOverviewWrapper, policyWrapper wrappers.PolicyWrapper, featureFlagsWrapper wrappers.FeatureFlagsWrapper, + jwtWrapper wrappers.JWTWrapper, ) *cobra.Command { resultShowCmd := &cobra.Command{ Use: "show", @@ -273,7 +275,7 @@ func resultShowSubCommand( $ cx results show --scan-id `, ), - RunE: runGetResultCommand(resultsWrapper, scanWrapper, exportWrapper, resultsPdfReportsWrapper, resultsJSONReportsWrapper, risksOverviewWrapper, scsScanOverviewWrapper, policyWrapper, featureFlagsWrapper), + RunE: runGetResultCommand(resultsWrapper, scanWrapper, exportWrapper, resultsPdfReportsWrapper, resultsJSONReportsWrapper, risksOverviewWrapper, scsScanOverviewWrapper, policyWrapper, featureFlagsWrapper, jwtWrapper), } addScanIDFlag(resultShowCmd, "ID to report on") addResultFormatFlag( @@ -309,8 +311,7 @@ func resultShowSubCommand( commonParams.ResultPolicyDefaultTimeout, "Cancel the policy evaluation and fail after the timeout in minutes", ) - resultShowCmd.PersistentFlags().Bool(commonParams.IgnorePolicyFlag, false, "Do not evaluate policies") - _ = resultShowCmd.PersistentFlags().MarkHidden(commonParams.IgnorePolicyFlag) + resultShowCmd.PersistentFlags().Bool(commonParams.IgnorePolicyFlag, false, "Skip policy evaluation. Requires override-policy-management permission.") resultShowCmd.PersistentFlags().Bool(commonParams.SastRedundancyFlag, false, "Populate SAST results 'data.redundancy' with values '"+fixLabel+"' (to fix) or '"+redundantLabel+"' (no need to fix)") resultShowCmd.PersistentFlags().Bool(commonParams.ScaHideDevAndTestDepFlag, false, scaHideDevAndTestDepFlagDescription) @@ -853,7 +854,7 @@ func writeMarkdownSummary(targetFile string, data *wrappers.ResultSummary) error } // nolint: whitespace -func writeConsoleSummary(summary *wrappers.ResultSummary, featureFlagsWrapper wrappers.FeatureFlagsWrapper) error { +func writeConsoleSummary(summary *wrappers.ResultSummary, featureFlagsWrapper wrappers.FeatureFlagsWrapper, ignorePolicyFlagOmit bool) error { if !isScanPending(summary.Status) { fmt.Printf(" Scan Summary: \n") fmt.Printf(" Created At: %s\n", summary.CreatedAt) @@ -865,7 +866,7 @@ func writeConsoleSummary(summary *wrappers.ResultSummary, featureFlagsWrapper wr summary.RiskMsg, ) if summary.Policies != nil && !strings.EqualFold(summary.Policies.Status, policeManagementNoneStatus) { - printPoliciesSummary(summary) + printPoliciesSummary(summary, ignorePolicyFlagOmit) } printResultsSummaryTable(summary) @@ -886,7 +887,7 @@ func writeConsoleSummary(summary *wrappers.ResultSummary, featureFlagsWrapper wr return nil } -func printPoliciesSummary(summary *wrappers.ResultSummary) { +func printPoliciesSummary(summary *wrappers.ResultSummary, ignorePolicyFlagOmit bool) { hasViolations := false for _, policy := range summary.Policies.Policies { if len(policy.RulesViolated) > 0 { @@ -896,6 +897,9 @@ func printPoliciesSummary(summary *wrappers.ResultSummary) { } if hasViolations { fmt.Printf(tableLine + "\n") + if ignorePolicyFlagOmit { + printWarningIfIgnorePolicyOmiited() + } if summary.Policies.BreakBuild { fmt.Printf(" Policy Management Violation - Break Build Enabled: \n") } else { @@ -1017,6 +1021,7 @@ func runGetResultCommand( scsScanOverviewWrapper wrappers.ScanOverviewWrapper, policyWrapper wrappers.PolicyWrapper, featureFlagsWrapper wrappers.FeatureFlagsWrapper, + jwtWrapper wrappers.JWTWrapper, ) func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { targetFile, _ := cmd.Flags().GetString(commonParams.TargetFlag) @@ -1028,6 +1033,19 @@ func runGetResultCommand( sastRedundancy, _ := cmd.Flags().GetBool(commonParams.SastRedundancyFlag) agent, _ := cmd.Flags().GetString(commonParams.AgentFlag) scaHideDevAndTestDep, _ := cmd.Flags().GetBool(commonParams.ScaHideDevAndTestDepFlag) + ignorePolicy, _ := cmd.Flags().GetBool(commonParams.IgnorePolicyFlag) + // Check if the user has permission to override policy management if --ignore-policy is set + ignorePolicyFlagOmit := false + if ignorePolicy { + overridePolicyManagementPer, err := jwtWrapper.CheckPermissionByAccessToken(OverridePolicyManagement) + if err != nil { + return err + } + if !overridePolicyManagementPer { + ignorePolicyFlagOmit = true + ignorePolicy = false + } + } waitDelay, _ := cmd.Flags().GetInt(commonParams.WaitDelayFlag) policyTimeout, _ := cmd.Flags().GetInt(commonParams.PolicyTimeoutFlag) @@ -1055,7 +1073,7 @@ func runGetResultCommand( var policyResponseModel *wrappers.PolicyResponseModel if !isScanPending(string(scan.Status)) { - policyResponseModel, err = services.HandlePolicyEvaluation(cmd, policyWrapper, scan, agent, waitDelay, policyTimeout) + policyResponseModel, err = services.HandlePolicyEvaluation(cmd, policyWrapper, scan, ignorePolicy, agent, waitDelay, policyTimeout) if err != nil { return err } @@ -1069,7 +1087,7 @@ func runGetResultCommand( _, err = CreateScanReport(resultsWrapper, risksOverviewWrapper, scsScanOverviewWrapper, exportWrapper, policyResponseModel, resultsPdfReportsWrapper, resultsJSONReportsWrapper, scan, format, formatPdfToEmail, formatPdfOptions, - formatSbomOptions, targetFile, targetPath, agent, resultsParams, featureFlagsWrapper) + formatSbomOptions, targetFile, targetPath, agent, resultsParams, featureFlagsWrapper, ignorePolicyFlagOmit) return err } } @@ -1176,6 +1194,7 @@ func CreateScanReport( agent string, resultsParams map[string]string, featureFlagsWrapper wrappers.FeatureFlagsWrapper, + ignorePolicyFlagOmit bool, ) (*wrappers.ScanResultsCollection, error) { reportList := strings.Split(reportTypes, ",") results := &wrappers.ScanResultsCollection{} @@ -1206,7 +1225,7 @@ func CreateScanReport( } for _, reportType := range reportList { err = createReport(reportType, formatPdfToEmail, formatPdfOptions, formatSbomOptions, targetFile, - targetPath, results, summary, exportWrapper, resultsPdfReportsWrapper, resultsJSONReportsWrapper, featureFlagsWrapper, agent) + targetPath, results, summary, exportWrapper, resultsPdfReportsWrapper, resultsJSONReportsWrapper, featureFlagsWrapper, ignorePolicyFlagOmit) if err != nil { return nil, err } @@ -1386,7 +1405,7 @@ func createReport(format, resultsPdfReportsWrapper wrappers.ResultsPdfWrapper, resultsJSONReportsWrapper wrappers.ResultsJSONWrapper, featureFlagsWrapper wrappers.FeatureFlagsWrapper, - agent string) error { + ignorePolicyFlagOmit bool) error { if printer.IsFormat(format, printer.FormatIndentedJSON) { return nil } @@ -1416,7 +1435,7 @@ func createReport(format, } if printer.IsFormat(format, printer.FormatSummaryConsole) { - return writeConsoleSummary(summary, featureFlagsWrapper) + return writeConsoleSummary(summary, featureFlagsWrapper, ignorePolicyFlagOmit) } if printer.IsFormat(format, printer.FormatSummary) { summaryRpt := createTargetName(targetFile, targetPath, printer.FormatHTML) @@ -2867,3 +2886,7 @@ type ScannerResponse struct { Details string `json:"Details,omitempty"` ErrorCode string `json:"ErrorCode,omitempty"` } + +func printWarningIfIgnorePolicyOmiited() { + fmt.Printf("\n Warning: The --ignore-policy flag was not implemented because you don’t have the required permission.\n Only users with 'override-policy-management' permission can use this flag. \n\n") +} diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index ec9e71018..e60a35d14 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -1314,7 +1314,7 @@ func TestPrintPoliciesSummary_WhenNoRolViolated_ShouldNotContainPolicyViolation( old := os.Stdout os.Stdout = w - printPoliciesSummary(summary) + printPoliciesSummary(summary, false) w.Close() os.Stdout = old @@ -1629,3 +1629,71 @@ func Test_addPackageInformation_DependencyTypes(t *testing.T) { assert.Equal(t, false, testPackage.IsDevelopmentDependency, "Second package should not be marked as development dependency") assert.Equal(t, true, testPackage.IsTestDependency, "Second package should be marked as test dependency") } + +func TestIgnorePolicyWithNoPermission(t *testing.T) { + policyResponseModel := wrappers.PolicyResponseModel{} + policyResponseModel.BreakBuild = false + + policy := wrappers.Policy{} + policy.Name = "MOCK_NAME1" + policy.RulesViolated = make([]string, 1) + policy.BreakBuild = true + policy.Description = "MOCK_DESC1" + policy.Tags = make([]string, 0) + + var policies []wrappers.Policy + policies = append(policies, policy) + policyResponseModel.Policies = policies + summary := &wrappers.ResultSummary{ + Policies: &policyResponseModel, + } + r, w, _ := os.Pipe() + old := os.Stdout + os.Stdout = w + + printPoliciesSummary(summary, true) + + w.Close() + os.Stdout = old + + var buf bytes.Buffer + if _, err := io.Copy(&buf, r); err != nil { + t.Fatalf("failed to copy output: %v", err) // Handle the error if io.Copy fails + } + output := buf.String() + assert.Assert(t, strings.Contains(output, "Warning: The --ignore-policy flag was not implemented because you don’t have the required permission."), "'Ignore Policy flag omitted because you dont have permission' should not be present in the output") +} + +func TestIgnorePolicyWithPermission(t *testing.T) { + policyResponseModel := wrappers.PolicyResponseModel{} + policyResponseModel.BreakBuild = false + + policy := wrappers.Policy{} + policy.Name = "MOCK_NAME2" + policy.RulesViolated = make([]string, 1) + policy.BreakBuild = true + policy.Description = "MOCK_DESC2" + policy.Tags = make([]string, 0) + + var policies []wrappers.Policy + policies = append(policies, policy) + policyResponseModel.Policies = policies + summary := &wrappers.ResultSummary{ + Policies: &policyResponseModel, + } + r, w, _ := os.Pipe() + old := os.Stdout + os.Stdout = w + + printPoliciesSummary(summary, false) + + w.Close() + os.Stdout = old + + var buf bytes.Buffer + if _, err := io.Copy(&buf, r); err != nil { + t.Fatalf("failed to copy output: %v", err) // Handle the error if io.Copy fails + } + output := buf.String() + assert.Assert(t, !strings.Contains(output, "Warning: The --ignore-policy flag was not implemented because you don’t have the required permission."), "'Ignore Policy flag omitted because you dont have permission' should not be present in the output") +} diff --git a/internal/commands/root.go b/internal/commands/root.go index 288f3b946..dfeb2de76 100644 --- a/internal/commands/root.go +++ b/internal/commands/root.go @@ -195,6 +195,7 @@ func NewAstCLI( scsScanOverviewWrapper, policyWrapper, featureFlagsWrapper, + jwtWrapper, ) versionCmd := util.NewVersionCommand() diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 525c6db6a..268cb5874 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -120,10 +120,11 @@ const ( "--scs-repo-url your_repo_url --scs-repo-token your_repo_token" ScsScorecardUnsupportedHostWarningMsg = "SCS scan warning: Unable to run Scorecard scanner due to unsupported repo host. Currently, Scorecard can only run on GitHub Cloud repos." - jsonExt = ".json" - xmlExt = ".xml" - sbomScanTypeErrMsg = "The --sbom-only flag can only be used when the scan type is sca" - BranchPrimaryPrefix = "--branch-primary=" + jsonExt = ".json" + xmlExt = ".xml" + sbomScanTypeErrMsg = "The --sbom-only flag can only be used when the scan type is sca" + BranchPrimaryPrefix = "--branch-primary=" + OverridePolicyManagement = "override-policy-management" ) var ( @@ -845,8 +846,7 @@ func scanCreateSubCommand( commonParams.ScanPolicyDefaultTimeout, "Cancel the policy evaluation and fail after the timeout in minutes", ) - createScanCmd.PersistentFlags().Bool(commonParams.IgnorePolicyFlag, false, "Do not evaluate policies") - _ = createScanCmd.PersistentFlags().MarkHidden(commonParams.IgnorePolicyFlag) + createScanCmd.PersistentFlags().Bool(commonParams.IgnorePolicyFlag, false, "Skip policy evaluation. Requires override-policy-management permission.") createScanCmd.PersistentFlags().String(commonParams.ApplicationName, "", "Name of the application to assign with the project") // Link the environment variables to the CLI argument(s). @@ -2041,6 +2041,20 @@ func runCreateScanCommand( if err != nil { return err } + ignorePolicy, _ := cmd.Flags().GetBool(commonParams.IgnorePolicyFlag) + + // Check if the user has permission to override policy management if --ignore-policy is set + ignorePolicyFlagOmit := false + if ignorePolicy { + overridePolicyManagementPer, err := jwtWrapper.CheckPermissionByAccessToken(OverridePolicyManagement) + if err != nil { + return err + } + if !overridePolicyManagementPer { + ignorePolicyFlagOmit = true + ignorePolicy = false + } + } timeoutMinutes, _ := cmd.Flags().GetInt(commonParams.ScanTimeoutFlag) if timeoutMinutes < 0 { return errors.Errorf("--%s should be equal or higher than 0", commonParams.ScanTimeoutFlag) @@ -2097,20 +2111,21 @@ func runCreateScanCommand( resultsWrapper, risksOverviewWrapper, scsScanOverviewWrapper, - featureFlagsWrapper) + featureFlagsWrapper, + ignorePolicyFlagOmit) if err != nil { return err } agent, _ := cmd.Flags().GetString(commonParams.AgentFlag) policyTimeout, _ := cmd.Flags().GetInt(commonParams.PolicyTimeoutFlag) - policyResponseModel, err = services.HandlePolicyEvaluation(cmd, policyWrapper, scanResponseModel, agent, waitDelay, policyTimeout) + policyResponseModel, err = services.HandlePolicyEvaluation(cmd, policyWrapper, scanResponseModel, ignorePolicy, agent, waitDelay, policyTimeout) if err != nil { return err } results, reportErr := createReportsAfterScan(cmd, scanResponseModel.ID, scansWrapper, exportWrapper, resultsPdfReportsWrapper, resultsJSONReportsWrapper, - resultsWrapper, risksOverviewWrapper, scsScanOverviewWrapper, policyResponseModel, featureFlagsWrapper) + resultsWrapper, risksOverviewWrapper, scsScanOverviewWrapper, policyResponseModel, featureFlagsWrapper, ignorePolicyFlagOmit) if reportErr != nil { return reportErr } @@ -2122,7 +2137,7 @@ func runCreateScanCommand( } } else { _, err = createReportsAfterScan(cmd, scanResponseModel.ID, scansWrapper, exportWrapper, resultsPdfReportsWrapper, resultsJSONReportsWrapper, resultsWrapper, - risksOverviewWrapper, scsScanOverviewWrapper, nil, featureFlagsWrapper) + risksOverviewWrapper, scsScanOverviewWrapper, nil, featureFlagsWrapper, ignorePolicyFlagOmit) if err != nil { return err } @@ -2131,7 +2146,7 @@ func runCreateScanCommand( // verify break build from policy if policyResponseModel != nil && len(policyResponseModel.Policies) > 0 && policyResponseModel.BreakBuild { logger.PrintIfVerbose("Breaking the build due to policy violation") - return errors.Errorf("Policy Violation - Break Build Enabled.") + return errors.Errorf("Policy Violation - Break Build Enabled. To bypass the policy evaluation and continue with the build, you can use the `--ignore-policy` flag.") } return nil } @@ -2284,6 +2299,7 @@ func handleWait( risksOverviewWrapper wrappers.RisksOverviewWrapper, scsScanOverviewWrapper wrappers.ScanOverviewWrapper, featureFlagsWrapper wrappers.FeatureFlagsWrapper, + ignorePolicyFlagOmit bool, ) error { err := waitForScanCompletion( scanResponseModel, @@ -2297,7 +2313,8 @@ func handleWait( risksOverviewWrapper, scsScanOverviewWrapper, cmd, - featureFlagsWrapper) + featureFlagsWrapper, + ignorePolicyFlagOmit) if err != nil { verboseFlag, _ := cmd.Flags().GetBool(commonParams.DebugFlag) if verboseFlag { @@ -2322,6 +2339,7 @@ func createReportsAfterScan( scsScanOverviewWrapper wrappers.ScanOverviewWrapper, policyResponseModel *wrappers.PolicyResponseModel, featureFlagsWrapper wrappers.FeatureFlagsWrapper, + ignorePolicyFlagOmit bool, ) (*wrappers.ScanResultsCollection, error) { // Create the required reports targetFile, _ := cmd.Flags().GetString(commonParams.TargetFlag) @@ -2370,6 +2388,7 @@ func createReportsAfterScan( agent, resultsParams, featureFlagsWrapper, + ignorePolicyFlagOmit, ) } @@ -2517,6 +2536,7 @@ func waitForScanCompletion( scsScanOverviewWrapper wrappers.ScanOverviewWrapper, cmd *cobra.Command, featureFlagsWrapper wrappers.FeatureFlagsWrapper, + ignorePolicyFlagOmit bool, ) error { log.Println("Wait for scan to complete", scanResponseModel.ID, scanResponseModel.Status) timeout := time.Now().Add(time.Duration(timeoutMinutes) * time.Minute) @@ -2531,7 +2551,7 @@ func waitForScanCompletion( logger.PrintfIfVerbose("Sleeping %v before polling", waitDuration) time.Sleep(waitDuration) running, err := isScanRunning(scansWrapper, exportWrapper, resultsPdfReportsWrapper, resultsJSONReportsWrapper, resultsWrapper, - risksOverviewWrapper, scsScanOverviewWrapper, scanResponseModel.ID, cmd, featureFlagsWrapper) + risksOverviewWrapper, scsScanOverviewWrapper, scanResponseModel.ID, cmd, featureFlagsWrapper, ignorePolicyFlagOmit) if err != nil { return err } @@ -2566,6 +2586,7 @@ func isScanRunning( scanID string, cmd *cobra.Command, featureFlagsWrapper wrappers.FeatureFlagsWrapper, + ignorePolicyFlagOmit bool, ) (bool, error) { var scanResponseModel *wrappers.ScanResponseModel var errorModel *wrappers.ErrorModel @@ -2595,7 +2616,7 @@ func isScanRunning( resultsWrapper, risksOverViewWrapper, scsScanOverviewWrapper, - nil, featureFlagsWrapper) // check this partial case, how to handle it + nil, featureFlagsWrapper, ignorePolicyFlagOmit) // check this partial case, how to handle it if reportErr != nil { return false, errors.New("unable to create report for partial scan") } @@ -3156,7 +3177,6 @@ func validateCreateScanFlags(cmd *cobra.Command) error { } } } - return nil } diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index ab1e5c179..7f953e155 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -2732,3 +2732,10 @@ a*cation-jira.yml`)) gitIgnoreFilter, _ := getGitignorePatterns("", zipPath) assert.Assert(t, len(gitIgnoreFilter) > 0, "Expected patterns from .gitignore file") } + +func Test_CreateScanWithIgnorePolicyFlag(t *testing.T) { + execCmdNilAssertion( + t, + "scan", "create", "--project-name", "MOCK", "-s", "data/sources.zip", "--branch", "dummy_branch", "--ignore-policy", + ) +} diff --git a/internal/services/policy-management.go b/internal/services/policy-management.go index 293b1df59..1c73b94ca 100644 --- a/internal/services/policy-management.go +++ b/internal/services/policy-management.go @@ -13,10 +13,11 @@ import ( var noPolicyEvaluatingIDEs = []string{commonParams.EclipseAgent, commonParams.JetbrainsAgent, commonParams.VSCodeAgent, commonParams.VisualStudioAgent} -func HandlePolicyEvaluation(cmd *cobra.Command, policyWrapper wrappers.PolicyWrapper, scan *wrappers.ScanResponseModel, agent string, waitDelay, policyTimeout int) (*wrappers.PolicyResponseModel, error) { +func HandlePolicyEvaluation(cmd *cobra.Command, policyWrapper wrappers.PolicyWrapper, scan *wrappers.ScanResponseModel, + ignorePolicy bool, agent string, waitDelay, policyTimeout int) (*wrappers.PolicyResponseModel, error) { policyResponseModel := &wrappers.PolicyResponseModel{} - if slices.Contains(noPolicyEvaluatingIDEs, agent) { + if ignorePolicy || slices.Contains(noPolicyEvaluatingIDEs, agent) { logger.PrintIfVerbose("Skipping policy evaluation") return policyResponseModel, nil } diff --git a/internal/services/policy-management_test.go b/internal/services/policy-management_test.go index bfbbdc26e..2e9d2877b 100644 --- a/internal/services/policy-management_test.go +++ b/internal/services/policy-management_test.go @@ -22,6 +22,7 @@ func TestHandlePolicyEvaluation(t *testing.T) { cmd: &cobra.Command{}, policyWrapper: policyWrapper, scan: scanResults, + ignorePolicy: false, waitDelay: 1, policyTimeout: 1, } @@ -38,6 +39,7 @@ func TestHandlePolicyEvaluation(t *testing.T) { cmd: commonArgs.cmd, policyWrapper: commonArgs.policyWrapper, scan: commonArgs.scan, + ignorePolicy: commonArgs.ignorePolicy, agent: params.DefaultAgent, waitDelay: commonArgs.waitDelay, policyTimeout: commonArgs.policyTimeout, @@ -51,6 +53,7 @@ func TestHandlePolicyEvaluation(t *testing.T) { cmd: commonArgs.cmd, policyWrapper: commonArgs.policyWrapper, scan: commonArgs.scan, + ignorePolicy: commonArgs.ignorePolicy, agent: params.EclipseAgent, waitDelay: commonArgs.waitDelay, policyTimeout: commonArgs.policyTimeout, @@ -64,6 +67,7 @@ func TestHandlePolicyEvaluation(t *testing.T) { cmd: commonArgs.cmd, policyWrapper: commonArgs.policyWrapper, scan: commonArgs.scan, + ignorePolicy: commonArgs.ignorePolicy, agent: params.VSCodeAgent, waitDelay: commonArgs.waitDelay, policyTimeout: commonArgs.policyTimeout, @@ -77,6 +81,7 @@ func TestHandlePolicyEvaluation(t *testing.T) { cmd: commonArgs.cmd, policyWrapper: commonArgs.policyWrapper, scan: commonArgs.scan, + ignorePolicy: commonArgs.ignorePolicy, agent: params.VisualStudioAgent, waitDelay: commonArgs.waitDelay, policyTimeout: commonArgs.policyTimeout, @@ -90,6 +95,7 @@ func TestHandlePolicyEvaluation(t *testing.T) { cmd: commonArgs.cmd, policyWrapper: commonArgs.policyWrapper, scan: commonArgs.scan, + ignorePolicy: commonArgs.ignorePolicy, agent: params.JetbrainsAgent, waitDelay: commonArgs.waitDelay, policyTimeout: commonArgs.policyTimeout, @@ -106,6 +112,7 @@ func TestHandlePolicyEvaluation(t *testing.T) { tc.args.cmd, tc.args.policyWrapper, tc.args.scan, + tc.args.ignorePolicy, tc.args.agent, tc.args.waitDelay, tc.args.policyTimeout, diff --git a/internal/wrappers/jwt-helper.go b/internal/wrappers/jwt-helper.go index 07a77aca3..9a964529d 100644 --- a/internal/wrappers/jwt-helper.go +++ b/internal/wrappers/jwt-helper.go @@ -17,7 +17,8 @@ type JWTStruct struct { AllowedEngines []string `json:"allowedEngines"` } `json:"LicenseData"` } `json:"ast-license"` - jwt.RegisteredClaims // Embedding the standard claims + ASTRoles []string `json:"roles_ast"` + jwt.RegisteredClaims // Embedding the standard claims } var enabledEngines = []string{"sast", "sca", "api-security", "iac-security", "scs", "containers", "enterprise-secrets"} @@ -36,6 +37,7 @@ type JWTWrapper interface { GetAllowedEngines(featureFlagsWrapper FeatureFlagsWrapper) (allowedEngines map[string]bool, err error) IsAllowedEngine(engine string) (bool, error) ExtractTenantFromToken() (tenant string, err error) + CheckPermissionByAccessToken(requiredPermission string) (permission bool, err error) } func NewJwtWrapper() JWTWrapper { @@ -119,3 +121,17 @@ func (*JWTStruct) ExtractTenantFromToken() (tenant string, err error) { } return jwtStruct.Tenant, nil } +func (*JWTStruct) CheckPermissionByAccessToken(requiredPermission string) (hasPermission bool, err error) { + jwtStruct, err := getJwtStruct() + if err != nil { + return false, err + } + permission := false + for _, role := range jwtStruct.ASTRoles { + if role == requiredPermission { + permission = true + break + } + } + return permission, nil +} diff --git a/internal/wrappers/mock/jwt-helper-mock.go b/internal/wrappers/mock/jwt-helper-mock.go index 6aee52afe..b7ed88970 100644 --- a/internal/wrappers/mock/jwt-helper-mock.go +++ b/internal/wrappers/mock/jwt-helper-mock.go @@ -52,3 +52,7 @@ func (j *JWTMockWrapper) IsAllowedEngine(engine string) (bool, error) { } return true, nil } + +func (j *JWTMockWrapper) CheckPermissionByAccessToken(requiredPermission string) (permission bool, err error) { + return true, nil +}