Skip to content

Commit

Permalink
refactor: add formatters
Browse files Browse the repository at this point in the history
  • Loading branch information
elsapet committed Aug 25, 2023
1 parent a3942be commit 10995f7
Show file tree
Hide file tree
Showing 14 changed files with 498 additions and 286 deletions.
139 changes: 20 additions & 119 deletions pkg/commands/artifact/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"path/filepath"
"sort"
"strings"
"time"

"github.com/hhatto/gocloc"
"github.com/rs/zerolog/log"
Expand All @@ -28,13 +29,12 @@ import (
reportoutput "github.com/bearer/bearer/pkg/report/output"
"github.com/bearer/bearer/pkg/report/output/stats"
outputtypes "github.com/bearer/bearer/pkg/report/output/types"
"github.com/bearer/bearer/pkg/util/output"
outputhandler "github.com/bearer/bearer/pkg/util/output"

"github.com/bearer/bearer/pkg/types"
)

var ErrFileListEmpty = errors.New("We couldn't find any files to scan in the specified directory.")
var ErrFileListEmpty = errors.New("couldn't find any files to scan in the specified directory")

// TargetKind represents what kind of artifact bearer scans
type TargetKind string
Expand Down Expand Up @@ -143,7 +143,7 @@ func (r *runner) Scan(ctx context.Context, opts flag.Options) ([]files.File, *ba
}

if !opts.Quiet {
output.StdErrLog(fmt.Sprintf("Scanning target %s", opts.Target))
outputhandler.StdErrLog(fmt.Sprintf("Scanning target %s", opts.Target))
}

targetPath, err := filepath.Abs(opts.Target)
Expand Down Expand Up @@ -179,7 +179,7 @@ func (r *runner) Scan(ctx context.Context, opts flag.Options) ([]files.File, *ba
var baseBranchFindings *basebranchfindings.Findings
if err := repository.WithBaseBranch(func() error {
if !opts.Quiet {
output.StdErrLog(fmt.Sprintf("\nScanning base branch %s", opts.DiffBaseBranch))
outputhandler.StdErrLog(fmt.Sprintf("\nScanning base branch %s", opts.DiffBaseBranch))
}

if err := orchestrator.Scan(r.reportPath+".base", fileList.BaseFiles); err != nil {
Expand All @@ -196,7 +196,7 @@ func (r *runner) Scan(ctx context.Context, opts flag.Options) ([]files.File, *ba
baseBranchFindings = buildBaseBranchFindings(reportOutput, fileList)

if !opts.Quiet {
output.StdErrLog("\nScanning current branch")
outputhandler.StdErrLog("\nScanning current branch")
}

return nil
Expand Down Expand Up @@ -304,7 +304,7 @@ func (r *runner) Report(
files []files.File,
baseBranchFindings *basebranchfindings.Findings,
) (bool, error) {
// startTime := time.Now()
startTime := time.Now()
cacheUsed := r.CacheUsed()
reportPassed := true

Expand All @@ -330,7 +330,7 @@ func (r *runner) Report(
return false, err
}

// endTime := time.Now()
endTime := time.Now()

reportSupported, err := anySupportedLanguagesPresent(report.Inputgocloc, r.scanSettings)
if err != nil {
Expand All @@ -348,120 +348,21 @@ func (r *runner) Report(
return true, nil
}

// {
// "Security": interface.Format("JSON") string {} -> output data (JSON string)
// }

// var formatter generic.Formatter
// switch on report TYPE
// case Security
// formatter = security.NewFormatter(output, scanSettings, gocloc) *security.Formatter {}
//

// formatter.format(Report.Format)

// TODO: this should be a formatter that takes report output and format type
// switch r.scanSettings.Report.Format {
// case flag.FormatEmpty:
// if r.scanSettings.Report.Report == flag.ReportSecurity {
// reportStr := security.BuildReportString(
// output,
// r.scanSettings,
// report.Inputgocloc,
// )

// logger(reportStr.String())
// } else if r.scanSettings.Report.Report == flag.ReportPrivacy {
// // for privacy report, default report format is CSV
// content, err := reportoutput.GetPrivacyReportCSVOutput(output, report, r.scanSettings)
// if err != nil {
// return false, fmt.Errorf("error generating report %s", err)
// }

// logger(*content)
// } else {
// // for everything else, default report format is JSON
// content, err := outputhandler.ReportJSON(output)
// if err != nil {
// return false, fmt.Errorf("error generating report %s", err)
// }

// logger(*content)
// }
// case flag.FormatSarif:
// sarifContent, err := sarif.ReportSarif(output.Findings, r.scanSettings.Rules)
// if err != nil {
// return false, fmt.Errorf("error generating sarif report %s", err)
// }
// content, err := outputhandler.ReportJSON(sarifContent)
// if err != nil {
// return false, fmt.Errorf("error generating JSON report %s", err)
// }

// logger(*content)
// case flag.FormatReviewDog:
// sastContent, err := rdo.ReportReviewdog(output.Findings)
// if err != nil {
// return false, fmt.Errorf("error generating reviewdog report %s", err)
// }
// content, err := outputhandler.ReportJSON(sastContent)
// if err != nil {
// return false, fmt.Errorf("error generating JSON report %s", err)
// }

// logger(*content)
// case flag.FormatGitLabSast:

// sastContent, err := gitlab.ReportGitLab(output.Findings, startTime, endTime)
// if err != nil {
// return false, fmt.Errorf("error generating gitlab-sast report %s", err)
// }
// content, err := outputhandler.ReportJSON(sastContent)
// if err != nil {
// return false, fmt.Errorf("error generating JSON report %s", err)
// }

// logger(*content)
// case flag.FormatJSON:
// content, err := outputhandler.ReportJSON(output)
// if err != nil {
// return false, fmt.Errorf("error generating report %s", err)
// }

// logger(*content)
// case flag.FormatYAML:
// content, err := outputhandler.ReportYAML(output)
// if err != nil {
// return false, fmt.Errorf("error generating report %s", err)
// }

// logger(*content)
// case flag.FormatHTML:
// var body *string
// var err error
// var title string
// if r.scanSettings.Report.Report == flag.ReportPrivacy {
// title = "Privacy Report"
// body, err = reporthtml.ReportPrivacyHTML(output.PrivacyReport)
// } else {
// title = "Security Report"
// body, err = reporthtml.ReportSecurityHTML(output.Findings)
// }

// if err != nil {
// return false, fmt.Errorf("error generating report %s", err)
// }

// page, err := reporthtml.ReportHTMLWrapper(title, body)

// if err != nil {
// return false, fmt.Errorf("error generating report html page %s", err)
// }

// logger(*page)
// }
formatStr, err := reportoutput.FormatOutput(
output,
r.scanSettings,
report.Inputgocloc,
startTime,
endTime,
)
if err != nil {
return false, fmt.Errorf("error generating report %s", err)
}

logger(*formatStr)

outputCachedDataWarning(cacheUsed, r.scanSettings.Scan.Quiet)

return reportPassed, nil
}

Expand Down
37 changes: 37 additions & 0 deletions pkg/report/output/dataflow/formatter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package dataflow

import (
"fmt"

"github.com/bearer/bearer/pkg/commands/process/settings"
"github.com/bearer/bearer/pkg/flag"
outputtypes "github.com/bearer/bearer/pkg/report/output/types"
outputhandler "github.com/bearer/bearer/pkg/util/output"
)

type Formatter struct {
ReportData *outputtypes.ReportData
Config settings.Config
}

func NewFormatter(reportData *outputtypes.ReportData, config settings.Config) *Formatter {
return &Formatter{
ReportData: reportData,
Config: config,
}
}

func (f Formatter) Format(format string) (output *string, err error) {
switch format {
case flag.FormatEmpty:
output, err = outputhandler.ReportJSON(f.ReportData.Dataflow)
case flag.FormatJSON:
output, err = outputhandler.ReportJSON(f.ReportData.Dataflow)
case flag.FormatYAML:
output, err = outputhandler.ReportYAML(f.ReportData.Dataflow)
default:
err = fmt.Errorf(`--report flag "%s" is not supported`, f.Config.Report.Report)
}

return output, err
}
37 changes: 37 additions & 0 deletions pkg/report/output/detectors/formatter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package detectors

import (
"fmt"

"github.com/bearer/bearer/pkg/commands/process/settings"
"github.com/bearer/bearer/pkg/flag"
outputtypes "github.com/bearer/bearer/pkg/report/output/types"
outputhandler "github.com/bearer/bearer/pkg/util/output"
)

type Formatter struct {
ReportData *outputtypes.ReportData
Config settings.Config
}

func NewFormatter(reportData *outputtypes.ReportData, config settings.Config) *Formatter {
return &Formatter{
ReportData: reportData,
Config: config,
}
}

func (f Formatter) Format(format string) (output *string, err error) {
switch format {
case flag.FormatEmpty:
output, err = outputhandler.ReportJSON(f.ReportData.Detectors)
case flag.FormatJSON:
output, err = outputhandler.ReportJSON(f.ReportData.Detectors)
case flag.FormatYAML:
output, err = outputhandler.ReportYAML(f.ReportData.Detectors)
default:
err = fmt.Errorf(`--report flag "%s" is not supported`, f.Config.Report.Report)
}

return output, err
}
25 changes: 12 additions & 13 deletions pkg/report/output/html/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

html "github.com/bearer/bearer/pkg/report/output/html/types"
privacytypes "github.com/bearer/bearer/pkg/report/output/privacy/types"
"github.com/bearer/bearer/pkg/report/output/security"
securitytypes "github.com/bearer/bearer/pkg/report/output/security/types"
"github.com/bearer/bearer/pkg/util/maputil"
term "github.com/buildkite/terminal"
Expand Down Expand Up @@ -59,11 +58,11 @@ func ReportSecurityHTML(detections map[string][]securitytypes.Finding) (*string,
htmlContent := &strings.Builder{}

findingsTemplate, err := template.New("findingsTemplate").Funcs(template.FuncMap{
"kebabCase": KebabCase,
"markdownToHtml": MarkdownToHtml,
"joinCwe": JoinCwe,
"count": CountItems,
"displayExtract": DisplayExtract,
"kebabCase": kebabCase,
"markdownToHtml": markdownToHtml,
"joinCwe": joinCwe,
"count": countItems,
"displayExtract": displayExtract,
}).Parse(securityTemplate)
if err != nil {
return nil, err
Expand Down Expand Up @@ -112,7 +111,7 @@ func ReportPrivacyHTML(privacyReport *privacytypes.Report) (*string, error) {
}

subjectTemplate, err := template.New("subjectTemplate").Funcs(template.FuncMap{
"kebabCase": KebabCase,
"kebabCase": kebabCase,
}).Parse(privacyTemplate)
if err != nil {
return nil, err
Expand All @@ -127,24 +126,24 @@ func ReportPrivacyHTML(privacyReport *privacytypes.Report) (*string, error) {
return &content, nil
}

func KebabCase(s string) string {
func kebabCase(s string) string {
return strings.ReplaceAll(strings.ToLower(s), " ", "-")
}

func MarkdownToHtml(s string) string {
func markdownToHtml(s string) string {
html := blackfriday.MarkdownCommon([]byte(s))
return strings.ReplaceAll(string(html), "<h2", "<h4")
}

func JoinCwe(data []string) string {
func joinCwe(data []string) string {
var out = []string{}
for _, cwe := range data {
out = append(out, "CWE "+cwe)
}
return strings.Join(out, ", ")
}

func CountItems(arr interface{}) string {
func countItems(arr interface{}) string {
switch v := arr.(type) {
case []securitytypes.Finding:
return fmt.Sprint(len(v))
Expand All @@ -153,7 +152,7 @@ func CountItems(arr interface{}) string {
}
}

func DisplayExtract(result securitytypes.Finding) string {
terminalOutput := security.HighlightCodeExtract(result)
func displayExtract(finding securitytypes.Finding) string {
terminalOutput := finding.HighlightCodeExtract()
return string(term.Render([]byte(terminalOutput)))
}
Loading

0 comments on commit 10995f7

Please sign in to comment.