From 05659dae30e9d306fcc9aed128541f8e87e806d9 Mon Sep 17 00:00:00 2001 From: Pedro Lopes Date: Mon, 25 Sep 2023 15:23:48 +0100 Subject: [PATCH 1/5] handle async scans on reports --- internal/commands/result.go | 67 +++++++++++++++++----------- internal/wrappers/results-summary.go | 18 +++++++- 2 files changed, 57 insertions(+), 28 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 0af6307a8..9325e004c 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -331,7 +331,7 @@ func resultCodeBashing(codeBashingWrapper wrappers.CodeBashingWrapper) *cobra.Co return resultCmd } -func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel) (*wrappers.ResultSummary, error) { +func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWrapper wrappers.ResultsWrapper) (*wrappers.ResultSummary, error) { if scanInfo == nil { return nil, errors.New(failedCreatingSummary) } @@ -352,7 +352,7 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel) (*wrapper } } } - return &wrappers.ResultSummary{ + summary := &wrappers.ResultSummary{ ScanID: scanInfo.ID, Status: string(scanInfo.Status), CreatedAt: scanInfo.CreatedAt.Format("2006-01-02, 15:04:05"), @@ -370,18 +370,6 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel) (*wrapper ProjectName: scanInfo.ProjectName, BranchName: scanInfo.Branch, EnginesEnabled: scanInfo.Engines, - }, nil -} - -func summaryReport( - scan *wrappers.ScanResponseModel, - policies *wrappers.PolicyResponseModel, - risksOverviewWrapper wrappers.RisksOverviewWrapper, - resultsWrapper wrappers.ResultsWrapper, -) (*wrappers.ResultSummary, error) { - summary, err := convertScanToResultsSummary(scan) - if err != nil { - return nil, err } baseURI, err := resultsWrapper.GetResultsURL(summary.ProjectID) @@ -392,6 +380,16 @@ func summaryReport( summary.BaseURI = baseURI summary.BaseURI = generateScanSummaryURL(summary) + return summary, nil +} + +func summaryReport( + summary *wrappers.ResultSummary, + policies *wrappers.PolicyResponseModel, + risksOverviewWrapper wrappers.RisksOverviewWrapper, + resultsWrapper wrappers.ResultsWrapper, +) (*wrappers.ResultSummary, error) { + if summary.HasAPISecurity() { apiSecRisks, err := getResultsForAPISecScanner(risksOverviewWrapper, summary.ScanID) if err != nil { @@ -404,7 +402,7 @@ func summaryReport( summary.Policies = filterViolatedRules(*policies) } - err = enhanceWithScanSummary(summary, resultsWrapper) + err := enhanceWithScanSummary(summary, resultsWrapper) if err != nil { return nil, err } @@ -502,7 +500,7 @@ func writeHTMLSummary(targetFile string, summary *wrappers.ResultSummary) error } func writeMarkdownSummary(targetFile string, data *wrappers.ResultSummary) error { log.Println("Creating Markdown Summary Report: ", targetFile) - tmpl, err := template.New(printer.FormatSummaryMarkdown).Parse(wrappers.SummaryMarkdownTemplate) + tmpl, err := template.New(printer.FormatSummaryMarkdown).Parse(wrappers.SummaryMarkdownTemplate(isScanPending(data.Status))) if err != nil { return err } @@ -729,14 +727,20 @@ func CreateScanReport( ) error { reportList := strings.Split(reportTypes, ",") results := &wrappers.ScanResultsCollection{} - summary := &wrappers.ResultSummary{} - err := createDirectory(targetPath) + summary, err := convertScanToResultsSummary(scan, resultsWrapper) + if err != nil { + return err + } + + scanPending := isScanPending(summary.Status) + + err = createDirectory(targetPath) if err != nil { return err } isResultsNeeded := verifyFormatsByReportList(reportList, resultsFormats...) - if isResultsNeeded { + if isResultsNeeded && !scanPending { results, err = ReadResults(resultsWrapper, scan, params) if err != nil { return err @@ -744,8 +748,8 @@ func CreateScanReport( } isSummaryNeeded := verifyFormatsByReportList(reportList, summaryFormats...) - if isSummaryNeeded { - summary, err = summaryReport(scan, policyResponseModel, risksOverviewWrapper, resultsWrapper) + if isSummaryNeeded && !scanPending { + summary, err = summaryReport(summary, policyResponseModel, risksOverviewWrapper, resultsWrapper) if err != nil { return err } @@ -812,6 +816,15 @@ func isScanPending(scanStatus string) bool { ) || strings.EqualFold(scanStatus, "Failed")) } +func isValidScanStatus(status string, format string) bool { + if isScanPending(status) { + log.Printf("Result format file %s not create because scan status is %s", format, status) + return false + } + + return true +} + func createReport(format, formatPdfToEmail, formatPdfOptions, @@ -825,15 +838,15 @@ func createReport(format, useSCALocalFlow bool, retrySBOM int) error { - if printer.IsFormat(format, printer.FormatSarif) { + if printer.IsFormat(format, printer.FormatSarif) && isValidScanStatus(summary.Status, printer.FormatSarif) { sarifRpt := createTargetName(targetFile, targetPath, printer.FormatSarif) return exportSarifResults(sarifRpt, results) } - if printer.IsFormat(format, printer.FormatSonar) { + if printer.IsFormat(format, printer.FormatSonar) && isValidScanStatus(summary.Status, printer.FormatSarif) { sonarRpt := createTargetName(fmt.Sprintf("%s%s", targetFile, sonarTypeLabel), targetPath, printer.FormatJSON) return exportSonarResults(sonarRpt, results) } - if printer.IsFormat(format, printer.FormatJSON) { + if printer.IsFormat(format, printer.FormatJSON) && isValidScanStatus(summary.Status, printer.FormatSarif) { jsonRpt := createTargetName(targetFile, targetPath, printer.FormatJSON) return exportJSONResults(jsonRpt, results) } @@ -845,12 +858,12 @@ func createReport(format, convertNotAvailableNumberToZero(summary) return writeHTMLSummary(summaryRpt, summary) } - if printer.IsFormat(format, printer.FormatSummaryJSON) { + if printer.IsFormat(format, printer.FormatSummaryJSON) && isValidScanStatus(summary.Status, printer.FormatSarif) { summaryRpt := createTargetName(targetFile, targetPath, printer.FormatJSON) convertNotAvailableNumberToZero(summary) return exportJSONSummaryResults(summaryRpt, summary) } - if printer.IsFormat(format, printer.FormatPDF) { + if printer.IsFormat(format, printer.FormatPDF) && isValidScanStatus(summary.Status, printer.FormatSarif) { summaryRpt := createTargetName(targetFile, targetPath, printer.FormatPDF) return exportPdfResults(resultsPdfReportsWrapper, summary, summaryRpt, formatPdfToEmail, formatPdfOptions) } @@ -859,7 +872,7 @@ func createReport(format, convertNotAvailableNumberToZero(summary) return writeMarkdownSummary(summaryRpt, summary) } - if printer.IsFormat(format, printer.FormatSbom) { + if printer.IsFormat(format, printer.FormatSbom) && isValidScanStatus(summary.Status, printer.FormatSarif) { targetType := printer.FormatJSON if strings.Contains(strings.ToLower(formatSbomOptions), printer.FormatXML) { targetType = printer.FormatXML diff --git a/internal/wrappers/results-summary.go b/internal/wrappers/results-summary.go index dd6defeaa..d399e13a5 100644 --- a/internal/wrappers/results-summary.go +++ b/internal/wrappers/results-summary.go @@ -643,7 +643,15 @@ const summaryTemplateFooter = ` ` // nolint: lll -const SummaryMarkdownTemplate = ` +const SummaryMarkdownPendingTemplate = ` +{{- /* The '-' symbol at the start of the line is used to strip leading white space */ -}} +{{- /* ResultSummary template */ -}} +##### {{.ScanInfoMessage}} +{{end}} +` + +// nolint: lll +const SummaryMarkdownCompletedTemplate = ` {{- /* The '-' symbol at the start of the line is used to strip leading white space */ -}} {{- /* ResultSummary template */ -}} {{ $emoji := "⚪" }} @@ -687,6 +695,14 @@ const SummaryMarkdownTemplate = ` {{end}} ` +func SummaryMarkdownTemplate(isScanPending bool) string { + if isScanPending { + return SummaryMarkdownPendingTemplate + } + + return SummaryMarkdownCompletedTemplate +} + func SummaryTemplate(isScanPending bool) string { result := summaryTemplateHeader if !isScanPending { From 7a44bb1e2658531bb3bc0b685d9397c125f8084d Mon Sep 17 00:00:00 2001 From: Pedro Lopes Date: Mon, 25 Sep 2023 15:26:07 +0100 Subject: [PATCH 2/5] move scan info set --- internal/commands/result.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 9325e004c..aa42fbdae 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -379,6 +379,9 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr summary.BaseURI = baseURI summary.BaseURI = generateScanSummaryURL(summary) + if isScanPending(summary.Status) { + summary.ScanInfoMessage = scanPendingMessage + } return summary, nil } @@ -411,9 +414,7 @@ func summaryReport( setNotAvailableNumberIfZero(summary, &summary.ScaIssues, commonParams.ScaType) setNotAvailableNumberIfZero(summary, &summary.KicsIssues, commonParams.KicsType) setRiskMsgAndStyle(summary) - if isScanPending(summary.Status) { - summary.ScanInfoMessage = scanPendingMessage - } + return summary, nil } From 19ecf213da425c5721899bd861deca9c58b1bdbd Mon Sep 17 00:00:00 2001 From: Pedro Lopes Date: Mon, 25 Sep 2023 15:41:31 +0100 Subject: [PATCH 3/5] fix lint --- internal/commands/result.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index aa42fbdae..b8332ee44 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -392,7 +392,6 @@ func summaryReport( risksOverviewWrapper wrappers.RisksOverviewWrapper, resultsWrapper wrappers.ResultsWrapper, ) (*wrappers.ResultSummary, error) { - if summary.HasAPISecurity() { apiSecRisks, err := getResultsForAPISecScanner(risksOverviewWrapper, summary.ScanID) if err != nil { @@ -817,7 +816,7 @@ func isScanPending(scanStatus string) bool { ) || strings.EqualFold(scanStatus, "Failed")) } -func isValidScanStatus(status string, format string) bool { +func isValidScanStatus(status, format string) bool { if isScanPending(status) { log.Printf("Result format file %s not create because scan status is %s", format, status) return false From 992700390dccd4ca950089cdf11101b5144c022c Mon Sep 17 00:00:00 2001 From: Pedro Lopes Date: Mon, 25 Sep 2023 15:48:03 +0100 Subject: [PATCH 4/5] fix lint --- internal/commands/result.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index b8332ee44..0c8e5e5af 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -842,11 +842,11 @@ func createReport(format, sarifRpt := createTargetName(targetFile, targetPath, printer.FormatSarif) return exportSarifResults(sarifRpt, results) } - if printer.IsFormat(format, printer.FormatSonar) && isValidScanStatus(summary.Status, printer.FormatSarif) { + if printer.IsFormat(format, printer.FormatSonar) && isValidScanStatus(summary.Status, printer.FormatSonar) { sonarRpt := createTargetName(fmt.Sprintf("%s%s", targetFile, sonarTypeLabel), targetPath, printer.FormatJSON) return exportSonarResults(sonarRpt, results) } - if printer.IsFormat(format, printer.FormatJSON) && isValidScanStatus(summary.Status, printer.FormatSarif) { + if printer.IsFormat(format, printer.FormatJSON) && isValidScanStatus(summary.Status, printer.FormatJSON) { jsonRpt := createTargetName(targetFile, targetPath, printer.FormatJSON) return exportJSONResults(jsonRpt, results) } @@ -858,12 +858,12 @@ func createReport(format, convertNotAvailableNumberToZero(summary) return writeHTMLSummary(summaryRpt, summary) } - if printer.IsFormat(format, printer.FormatSummaryJSON) && isValidScanStatus(summary.Status, printer.FormatSarif) { + if printer.IsFormat(format, printer.FormatSummaryJSON) && isValidScanStatus(summary.Status, printer.FormatSummaryJSON) { summaryRpt := createTargetName(targetFile, targetPath, printer.FormatJSON) convertNotAvailableNumberToZero(summary) return exportJSONSummaryResults(summaryRpt, summary) } - if printer.IsFormat(format, printer.FormatPDF) && isValidScanStatus(summary.Status, printer.FormatSarif) { + if printer.IsFormat(format, printer.FormatPDF) && isValidScanStatus(summary.Status, printer.FormatPDF) { summaryRpt := createTargetName(targetFile, targetPath, printer.FormatPDF) return exportPdfResults(resultsPdfReportsWrapper, summary, summaryRpt, formatPdfToEmail, formatPdfOptions) } @@ -872,7 +872,7 @@ func createReport(format, convertNotAvailableNumberToZero(summary) return writeMarkdownSummary(summaryRpt, summary) } - if printer.IsFormat(format, printer.FormatSbom) && isValidScanStatus(summary.Status, printer.FormatSarif) { + if printer.IsFormat(format, printer.FormatSbom) && isValidScanStatus(summary.Status, printer.FormatSbom) { targetType := printer.FormatJSON if strings.Contains(strings.ToLower(formatSbomOptions), printer.FormatXML) { targetType = printer.FormatXML From ea58af59271c34d425dbe858acad28e342cf0ec4 Mon Sep 17 00:00:00 2001 From: igorlombacx Date: Tue, 26 Sep 2023 10:09:32 +0100 Subject: [PATCH 5/5] fixing SummaryMarkdownPendingTemplate --- go.mod | 2 +- go.sum | 2 ++ internal/wrappers/results-summary.go | 7 ++++--- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index abe69bcd4..bfc1481ca 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/MakeNowJust/heredoc v1.0.0 github.com/checkmarxDev/gpt-wrapper v0.0.0-20230721160222-85da2fd1cc4c github.com/golang-jwt/jwt v3.2.2+incompatible - github.com/gomarkdown/markdown v0.0.0-20230916125811-7478c230c7cd + github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/google/uuid v1.3.1 github.com/gookit/color v1.5.4 diff --git a/go.sum b/go.sum index 28b8e4578..96abdd6ec 100644 --- a/go.sum +++ b/go.sum @@ -96,6 +96,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/gomarkdown/markdown v0.0.0-20230916125811-7478c230c7cd h1:laCEzrtkKEkT2424vMTGl6N1m0xN8kq371hksD5Be+8= github.com/gomarkdown/markdown v0.0.0-20230916125811-7478c230c7cd/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= +github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 h1:EcQR3gusLHN46TAD+G+EbaaqJArt5vHhNpXAa12PQf4= +github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= diff --git a/internal/wrappers/results-summary.go b/internal/wrappers/results-summary.go index d399e13a5..f5765e6b6 100644 --- a/internal/wrappers/results-summary.go +++ b/internal/wrappers/results-summary.go @@ -644,10 +644,11 @@ const summaryTemplateFooter = ` // nolint: lll const SummaryMarkdownPendingTemplate = ` -{{- /* The '-' symbol at the start of the line is used to strip leading white space */ -}} -{{- /* ResultSummary template */ -}} +# Checkmarx One Scan Summary +*** ##### {{.ScanInfoMessage}} -{{end}} +##### [🔗 More details]({{.BaseURI}}) +*** ` // nolint: lll