Skip to content

Commit

Permalink
feat: refactor to extract report data object
Browse files Browse the repository at this point in the history
  • Loading branch information
elsapet committed Aug 23, 2023
1 parent 309aa22 commit e943c64
Show file tree
Hide file tree
Showing 33 changed files with 630 additions and 703 deletions.
2 changes: 1 addition & 1 deletion new/detector/composition/testhelper/testhelper.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func (runner *Runner) scanSingleFile(t *testing.T, testDataPath string, fileRela
t.Fatalf("failed to get output: %s", err)
}

report, err := util.ReportYAML(output.Data)
report, err := util.ReportYAML(output.Dataflow)
if err != nil {
t.Fatalf("failed to encoded to yaml: %s", err)
}
Expand Down
240 changes: 122 additions & 118 deletions pkg/commands/artifact/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"path/filepath"
"sort"
"strings"
"time"

"github.com/hhatto/gocloc"
"github.com/rs/zerolog/log"
Expand All @@ -27,12 +26,6 @@ import (
"github.com/bearer/bearer/pkg/github_api"
"github.com/bearer/bearer/pkg/report/basebranchfindings"
reportoutput "github.com/bearer/bearer/pkg/report/output"
"github.com/bearer/bearer/pkg/report/output/gitlab"
reporthtml "github.com/bearer/bearer/pkg/report/output/html"
"github.com/bearer/bearer/pkg/report/output/privacy"
rdo "github.com/bearer/bearer/pkg/report/output/reviewdog"
"github.com/bearer/bearer/pkg/report/output/sarif"
"github.com/bearer/bearer/pkg/report/output/security"
"github.com/bearer/bearer/pkg/report/output/stats"
outputtypes "github.com/bearer/bearer/pkg/report/output/types"
"github.com/bearer/bearer/pkg/util/output"
Expand Down Expand Up @@ -200,7 +193,7 @@ func (r *runner) Scan(ctx context.Context, opts flag.Options) ([]files.File, *ba
return err
}

baseBranchFindings = buildBaseBranchFindings(fileList, reportOutput.Data)
baseBranchFindings = buildBaseBranchFindings(reportOutput, fileList)

if !opts.Quiet {
output.StdErrLog("\nScanning current branch")
Expand Down Expand Up @@ -311,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 @@ -337,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 @@ -346,7 +339,7 @@ func (r *runner) Report(

if !reportSupported && r.scanSettings.Report.Report != flag.ReportPrivacy {
var placeholderStr *strings.Builder
placeholderStr, err = getPlaceholderOutput(report, r.scanSettings, report.Inputgocloc)
placeholderStr, err = getPlaceholderOutput(output, report, r.scanSettings, report.Inputgocloc)
if err != nil {
return false, err
}
Expand All @@ -355,106 +348,118 @@ func (r *runner) Report(
return true, nil
}

// output report string for type and format
switch r.scanSettings.Report.Format {
case flag.FormatEmpty:
if r.scanSettings.Report.Report == flag.ReportSecurity {
reportStr := security.BuildReportString(
r.scanSettings,
outputtypes.ToSpecific[security.Results](output),
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(report, output.Dataflow, 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.Data)
if err != nil {
return false, fmt.Errorf("error generating report %s", err)
}

logger(*content)
}
case flag.FormatSarif:
sarifContent, err := sarif.ReportSarif(output.Data.(security.Results), 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.Data.(security.Results))
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.Data.(security.Results), 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.Data)
if err != nil {
return false, fmt.Errorf("error generating report %s", err)
}

logger(*content)
case flag.FormatYAML:
content, err := outputhandler.ReportYAML(output.Data)
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.Data.(*privacy.Report))
} else {
title = "Security Report"
body, err = reporthtml.ReportSecurityHTML(output.Data.(security.Results))
}

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)
}
// {
// "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)
// }

outputCachedDataWarning(cacheUsed, r.scanSettings.Scan.Quiet)
return reportPassed, nil
Expand Down Expand Up @@ -501,13 +506,12 @@ func anySupportedLanguagesPresent(inputgocloc *gocloc.Result, config settings.Co
return false, nil
}

func getPlaceholderOutput(report types.Report, config settings.Config, inputgocloc *gocloc.Result) (outputStr *strings.Builder, err error) {
dataflowOutput, err := reportoutput.GetDataflow(report, config, true)
if err != nil {
return
func getPlaceholderOutput(reportOutput *outputtypes.ReportData, report types.Report, config settings.Config, inputgocloc *gocloc.Result) (outputStr *strings.Builder, err error) {
if err := reportoutput.GetDataflow(reportOutput, report, config, true); err != nil {
return nil, err
}

return stats.GetPlaceholderOutput(inputgocloc, dataflowOutput.Dataflow, config)
return stats.GetPlaceholderOutput(reportOutput, inputgocloc, config)
}

func FormatFoundLanguages(languages map[string]*gocloc.Language) (foundLanguages []string) {
Expand All @@ -527,10 +531,10 @@ func FormatFoundLanguages(languages map[string]*gocloc.Language) (foundLanguages
return keys
}

func buildBaseBranchFindings(fileList *files.List, detections any) *basebranchfindings.Findings {
func buildBaseBranchFindings(reportOutput *outputtypes.ReportData, fileList *files.List) *basebranchfindings.Findings {
result := basebranchfindings.New(fileList)

for _, findings := range *detections.(*security.Results) {
for _, findings := range reportOutput.FindingsBySeverity {
for _, finding := range findings {
result.Add(
finding.Rule.Id,
Expand Down
15 changes: 7 additions & 8 deletions pkg/report/output/dataflow/components/components_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/bearer/bearer/pkg/report/output/dataflow"
"github.com/bearer/bearer/pkg/report/output/dataflow/types"
"github.com/bearer/bearer/pkg/report/output/detectors"
outputtypes "github.com/bearer/bearer/pkg/report/output/types"
globaltypes "github.com/bearer/bearer/pkg/types"
"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -129,22 +130,20 @@ func TestDataflowComponents(t *testing.T) {
}
file.Close()

detectorsOutput, err := detectors.GetOutput(globaltypes.Report{
output := &outputtypes.ReportData{}
if err = detectors.AddReportData(output, globaltypes.Report{
Path: file.Name(),
}, settings.Config{})
if err != nil {
}, settings.Config{}); err != nil {
t.Fatalf("failed to get detectors output %s", err)
return
}

output, err := dataflow.GetOutput(detectorsOutput.Data, settings.Config{}, false)
if err != nil {
t.Fatalf("failed to get detectors output %s", err)
if err = dataflow.AddReportData(output, settings.Config{}, false); err != nil {
t.Fatalf("failed to get dataflow output %s", err)
return
}

assert.Equal(t, output.Data, output.Dataflow)
assert.Equal(t, test.Want, output.Data.Components)
assert.Equal(t, test.Want, output.Dataflow.Components)
})
}
}
Loading

0 comments on commit e943c64

Please sign in to comment.