Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug/ast 31056 filter settings fix #613

Merged
merged 9 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 33 additions & 51 deletions internal/commands/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ func summaryReport(
summary *wrappers.ResultSummary,
policies *wrappers.PolicyResponseModel,
risksOverviewWrapper wrappers.RisksOverviewWrapper,
resultsWrapper wrappers.ResultsWrapper,
results *wrappers.ScanResultsCollection,
) (*wrappers.ResultSummary, error) {
if summary.HasAPISecurity() {
apiSecRisks, err := getResultsForAPISecScanner(risksOverviewWrapper, summary.ScanID)
Expand All @@ -408,10 +408,7 @@ func summaryReport(
summary.Policies = filterViolatedRules(*policies)
}

err := enhanceWithScanSummary(summary, resultsWrapper)
if err != nil {
return nil, err
}
enhanceWithScanSummary(summary, results)

setNotAvailableNumberIfZero(summary, &summary.SastIssues, commonParams.SastType)
setNotAvailableNumberIfZero(summary, &summary.ScaIssues, commonParams.ScaType)
Expand Down Expand Up @@ -442,51 +439,11 @@ func setRiskMsgAndStyle(summary *wrappers.ResultSummary) {
}
}

func enhanceWithScanSummary(summary *wrappers.ResultSummary, resultsWrapper wrappers.ResultsWrapper) error {
scanSummary, errModel, err := resultsWrapper.GetScanSummariesByScanIDS(map[string]string{
commonParams.ScanIDsQueryParam: summary.ScanID,
})
if err != nil {
return err
}
if errModel != nil {
return errors.Errorf("%s: CODE: %d, %s", failedGettingScan, errModel.Code, errModel.Message)
}

if len(scanSummary.ScansSummaries) != 1 {
return errors.Errorf("error - scan summary is nil or has more than one element")
func enhanceWithScanSummary(summary *wrappers.ResultSummary, results *wrappers.ScanResultsCollection) {
for _, result := range results.Results {
countResult(summary, result)
}

updateSummaryWithScanSummary(summary, &scanSummary.ScansSummaries[0])
summary.TotalIssues = summary.SastIssues + summary.ScaIssues + summary.KicsIssues
return nil
}

func updateSummaryWithScanSummary(summary *wrappers.ResultSummary, scanSummary *wrappers.ScanSumaries) {
summary.SastIssues += scanSummary.SastCounters.TotalCounter
summary.KicsIssues += scanSummary.KicsCounters.TotalCounter
summary.ScaIssues += scanSummary.ScaCounters.TotalCounter
summary.ScaIssues += scanSummary.ScaContainersCounters.TotalVulnerabilitiesCounter

updateSeverityCounts(summary, scanSummary.SastCounters.SeverityCounters)
updateSeverityCounts(summary, scanSummary.KicsCounters.SeverityCounters)
updateSeverityCounts(summary, scanSummary.ScaCounters.SeverityCounters)
updateSeverityCounts(summary, scanSummary.ScaContainersCounters.SeverityCounters)
}

func updateSeverityCounts(summary *wrappers.ResultSummary, severityCounts []wrappers.SeverityCounters) {
for _, sev := range severityCounts {
switch strings.ToLower(sev.Severity) {
case highLabel:
summary.HighIssues += sev.Counter
case mediumLabel:
summary.MediumIssues += sev.Counter
case lowLabel:
summary.LowIssues += sev.Counter
case infoLabel:
summary.InfoIssues += sev.Counter
}
}
}

func writeHTMLSummary(targetFile string, summary *wrappers.ResultSummary) error {
Expand Down Expand Up @@ -743,8 +700,7 @@ func CreateScanReport(
if err != nil {
return err
}
isResultsNeeded := verifyFormatsByReportList(reportList, resultsFormats...)
if isResultsNeeded && !scanPending {
if !scanPending {
results, err = ReadResults(resultsWrapper, scan, params)
if err != nil {
return err
Expand All @@ -753,7 +709,7 @@ func CreateScanReport(
}
isSummaryNeeded := verifyFormatsByReportList(reportList, summaryFormats...)
if isSummaryNeeded && !scanPending {
summary, err = summaryReport(summary, policyResponseModel, risksOverviewWrapper, resultsWrapper)
summary, err = summaryReport(summary, policyResponseModel, risksOverviewWrapper, results)
if err != nil {
return err
}
Expand All @@ -768,6 +724,32 @@ func CreateScanReport(
return nil
}

func countResult(summary *wrappers.ResultSummary, result *wrappers.ScanResult) {
engineType := strings.TrimSpace(result.Type)
if contains(summary.EnginesEnabled, engineType) && isExploitable(result.State) {
if engineType == commonParams.SastType {
summary.SastIssues++
summary.TotalIssues++
} else if engineType == commonParams.ScaType {
summary.ScaIssues++
summary.TotalIssues++
} else if engineType == commonParams.KicsType {
summary.KicsIssues++
summary.TotalIssues++
}
severity := strings.ToLower(result.Severity)
if severity == highLabel {
summary.HighIssues++
} else if severity == lowLabel {
summary.LowIssues++
} else if severity == mediumLabel {
summary.MediumIssues++
} else if severity == infoLabel {
summary.InfoIssues++
}
}
}

func verifyFormatsByReportList(reportFormats []string, formats ...string) bool {
for _, reportFormat := range reportFormats {
for _, format := range formats {
Expand Down
7 changes: 0 additions & 7 deletions internal/commands/result_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,6 @@ func TestRunGetResultsByScanIdSummaryHtmlFormat(t *testing.T) {

func TestRunGetResultsByScanIdSummaryConsoleFormat(t *testing.T) {
execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryConsole")

// Testing errors
err := execCmdNotNilAssertion(t, "results", "show", "--scan-id", "MOCKERR", "--report-format", "summaryConsole")
assert.Equal(t, err.Error(), "mock error")

err = execCmdNotNilAssertion(t, "results", "show", "--scan-id", "MOCKWEBERR", "--report-format", "summaryConsole")
assert.ErrorContains(t, err, "web error")
}

func TestRunGetResultsByScanIdPDFFormat(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/util/help_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"testing"
)

//TODO: can we assert something?
// TODO: can we assert something?
func TestRootHelpFunc(t *testing.T) {
cmd := NewConfigCommand()
cmd.Long = ""
Expand Down
71 changes: 59 additions & 12 deletions internal/wrappers/results-http.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ const (
respStatusCode = "response status code %d"
sort = "sort"
sortResultsDefault = "-severity"
offset = "offset"
astAPIPageLen = 1000
astAPIPagingValue = "1000"
)

type ResultsHTTPWrapper struct {
Expand All @@ -40,14 +43,53 @@ func (r *ResultsHTTPWrapper) GetAllResultsByScanID(params map[string]string) (
*WebError,
error,
) {
clientTimeout := viper.GetUint(commonParams.ClientTimeoutKey)
// AST has a limit of 10000 results, this makes it get all of them
DefaultMapValue(params, limit, limitValue)
var scanModelslice []ScanResultsCollection
var scanModel ScanResultsCollection
DefaultMapValue(params, limit, astAPIPagingValue)
DefaultMapValue(params, sort, sortResultsDefault)

resp, err := SendPrivateHTTPRequestWithQueryParams(http.MethodGet, r.resultsPath, params, http.NoBody, clientTimeout)
webErr, err := getResultsWithPagination(r.resultsPath, params, &scanModelslice)
if err != nil {
return nil, nil, err
return &scanModel, nil, err
}
if webErr != nil {
return &scanModel, webErr, nil
}
for _, resultsPage := range scanModelslice {
scanModel.Results = append(scanModel.Results, resultsPage.Results...)
}
return &scanModel, nil, nil
}
func getResultsWithPagination(resultPath string, queryParams map[string]string, slice *[]ScanResultsCollection) (*WebError, error) {
clientTimeout := viper.GetUint(commonParams.ClientTimeoutKey)
var currentPage = 0
for {
queryParams[offset] = fmt.Sprintf("%d", currentPage)
target, hasNextPage, weberr, err := getResultsByOffset(resultPath, queryParams, clientTimeout)
if err != nil {
return nil, err
}

if weberr != nil {
return weberr, nil
}

*slice = append(*slice, *target)

if !hasNextPage {
break
}
if astAPIPageLen > int(target.TotalCount) {
break
}
currentPage++
}
return nil, nil
}
func getResultsByOffset(resultPath string, params map[string]string, clientTimeout uint) (*ScanResultsCollection, bool, *WebError, error) {
resp, err := SendPrivateHTTPRequestWithQueryParams(http.MethodGet, resultPath, params, http.NoBody, clientTimeout)
if err != nil {
return nil, false, nil, err
}

defer func() {
Expand All @@ -61,22 +103,26 @@ func (r *ResultsHTTPWrapper) GetAllResultsByScanID(params map[string]string) (
errorModel := WebError{}
err = decoder.Decode(&errorModel)
if err != nil {
return nil, nil, errors.Wrapf(err, failedToParseGetResults)
return nil, false, nil, errors.Wrapf(err, failedToParseGetResults)
}
return nil, &errorModel, nil
return nil, false, &errorModel, nil
case http.StatusOK:
model := ScanResultsCollection{}
err = decoder.Decode(&model)
if err != nil {
return nil, nil, errors.Wrapf(err, failedToParseGetResults)
return nil, false, nil, errors.Wrapf(err, failedToParseGetResults)
}

return &model, nil, nil
if err != nil {
return nil, false, nil, errors.Wrapf(err, failedToParseGetResults)
}
if len(model.Results) == 0 {
return &model, false, nil, nil
}
return &model, true, nil, nil
default:
return nil, nil, errors.Errorf(respStatusCode, resp.StatusCode)
return nil, false, nil, errors.Errorf(respStatusCode, resp.StatusCode)
}
}

func (r *ResultsHTTPWrapper) GetAllResultsPackageByScanID(params map[string]string) (
*[]ScaPackageCollection,
*WebError,
Expand Down Expand Up @@ -184,6 +230,7 @@ func (r *ResultsHTTPWrapper) GetResultsURL(projectID string) (string, error) {
return baseURI, nil
}

// GetScanSummariesByScanIDS will no longer be used because it does not support --filters flag
func (r *ResultsHTTPWrapper) GetScanSummariesByScanIDS(params map[string]string) (
*ScanSummariesModel,
*WebError,
Expand Down
2 changes: 1 addition & 1 deletion test/integration/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestMain(m *testing.M) {
log.Println("CLI integration tests started")
viper.SetDefault(resolverEnvVar, resolverEnvVarDefault)
exitVal := m.Run()
deleteScanAndProject()
//deleteScanAndProject()
log.Println("CLI integration tests done")
os.Exit(exitVal)
}
Expand Down
90 changes: 45 additions & 45 deletions test/integration/scan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -539,54 +539,54 @@ func pollScanUntilStatus(t *testing.T, scanID string, requiredStatus wrappers.Sc
}
}

// Get a scan workflow and assert its structure
//func TestScanWorkflow(t *testing.T) {
// scanID, _ := getRootScan(t)
//
// buffer := executeCmdNilAssertion(
// t, "Workflow should pass", "scan", "workflow",
// flag(params.ScanIDFlag), scanID,
// flag(params.FormatFlag), printer.FormatJSON,
// )
//
// var workflow []ScanWorkflowResponse
// _ = unmarshall(t, buffer, &workflow, "Reading workflow output should work")
//
// //assert.Assert(t, len(workflow) > 0, "At least one item should exist in the workflow response")
//}
// Get a scan workflow and assert it fails
func TestScanWorkflow(t *testing.T) {
scanID, _ := getRootScan(t)
args := []string{
"scan", "workflow",
flag(params.ScanIDFlag), scanID,
flag(params.FormatFlag), printer.FormatJSON,
}
cmd := createASTIntegrationTestCommand(t)
err := execute(cmd, args...)
assert.Assert(t, err != nil, "Failed showing a scan: response status code 404")
}

//func TestScanLogsSAST(t *testing.T) {
// scanID, _ := getRootScan(t)
//
// //executeCmdNilAssertion(
// // t, "Getting scan SAST log should pass",
// // "scan", "logs",
// // flag(params.ScanIDFlag), scanID,
// // flag(params.ScanTypeFlag), "sast",
// //)
//}
func TestScanLogsSAST(t *testing.T) {
scanID, _ := getRootScan(t)
args := []string{
"scan", "logs",
flag(params.ScanIDFlag), scanID,
flag(params.ScanTypeFlag), "sast",
}
cmd := createASTIntegrationTestCommand(t)
err := execute(cmd, args...)
assert.Assert(t, err != nil, "response status code 404")
}

//func TestScanLogsKICSDeprecated(t *testing.T) {
// scanID, _ := getRootScan(t)
//
// executeCmdNilAssertion(
// t, "Getting scan KICS log should pass",
// "scan", "logs",
// flag(params.ScanIDFlag), scanID,
// flag(params.ScanTypeFlag), "kics",
// )
//}
func TestScanLogsKICSDeprecated(t *testing.T) {
scanID, _ := getRootScan(t)
args := []string{
"scan", "logs",
flag(params.ScanIDFlag), scanID,
flag(params.ScanTypeFlag), "kics",
}
cmd := createASTIntegrationTestCommand(t)
err := execute(cmd, args...)
assert.Assert(t, err != nil, "response status code 404")
}

//func TestScanLogsKICS(t *testing.T) {
// scanID, _ := getRootScan(t)
//
// executeCmdNilAssertion(
// t, "Getting scan KICS log should pass",
// "scan", "logs",
// flag(params.ScanIDFlag), scanID,
// flag(params.ScanTypeFlag), "iac-security",
// )
//}
func TestScanLogsKICS(t *testing.T) {
scanID, _ := getRootScan(t)
args := []string{
"scan", "logs",
flag(params.ScanIDFlag), scanID,
flag(params.ScanTypeFlag), "iac-security",
}
cmd := createASTIntegrationTestCommand(t)
err := execute(cmd, args...)
assert.Assert(t, err != nil, "response status code 404")
}

func TestPartialScanWithWrongPreset(t *testing.T) {
_, projectName := getRootProject(t)
Expand Down
Loading