1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-01-18 05:18:24 +02:00

fix(whitesourceExecuteScan): properly handle policy violations (#4089)

* fix(whitesourceExecuteScan): properly handle policy violations

* update files

* update formatting

Co-authored-by: Sven Merk <33895725+nevskrem@users.noreply.github.com>
This commit is contained in:
Oliver Nocon 2022-11-07 11:16:07 +01:00 committed by GitHub
parent 2866ef5592
commit a2815c4567
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 411 additions and 184 deletions

View File

@ -260,9 +260,14 @@ func checkAndReportScanResults(ctx context.Context, config *ScanOptions, scan *w
checkErrors := []string{}
rPath, err := checkPolicyViolations(config, scan, sys, utils, reportPaths, influx)
rPath, err := checkPolicyViolations(ctx, config, scan, sys, utils, reportPaths, influx)
if err != nil {
checkErrors = append(checkErrors, fmt.Sprint(err))
if !config.FailOnSevereVulnerabilities && log.GetErrorCategory() == log.ErrorCompliance {
log.Entry().Infof("policy violation(s) found - step will only create data but not fail due to setting failOnSevereVulnerabilities: false")
} else {
checkErrors = append(checkErrors, fmt.Sprint(err))
}
}
reportPaths = append(reportPaths, rPath)
@ -270,7 +275,11 @@ func checkAndReportScanResults(ctx context.Context, config *ScanOptions, scan *w
rPaths, err := checkSecurityViolations(ctx, config, scan, sys, utils, influx)
reportPaths = append(reportPaths, rPaths...)
if err != nil {
checkErrors = append(checkErrors, fmt.Sprint(err))
if !config.FailOnSevereVulnerabilities && log.GetErrorCategory() == log.ErrorCompliance {
log.Entry().Infof("policy violation(s) found - step will only create data but not fail due to setting failOnSevereVulnerabilities: false")
} else {
checkErrors = append(checkErrors, fmt.Sprint(err))
}
}
}
@ -480,14 +489,16 @@ func executeScan(config *ScanOptions, scan *ws.Scan, utils whitesourceUtils) err
return nil
}
func checkPolicyViolations(config *ScanOptions, scan *ws.Scan, sys whitesource, utils whitesourceUtils, reportPaths []piperutils.Path, influx *whitesourceExecuteScanInflux) (piperutils.Path, error) {
func checkPolicyViolations(ctx context.Context, config *ScanOptions, scan *ws.Scan, sys whitesource, utils whitesourceUtils, reportPaths []piperutils.Path, influx *whitesourceExecuteScanInflux) (piperutils.Path, error) {
policyViolationCount := 0
allAlerts := []ws.Alert{}
for _, project := range scan.ScannedProjects() {
alerts, err := sys.GetProjectAlertsByType(project.Token, "REJECTED_BY_POLICY_RESOURCE")
if err != nil {
return piperutils.Path{}, fmt.Errorf("failed to retrieve project policy alerts from WhiteSource: %w", err)
}
policyViolationCount += len(alerts)
allAlerts = append(allAlerts, alerts...)
}
violations := struct {
@ -547,11 +558,24 @@ func checkPolicyViolations(config *ScanOptions, scan *ws.Scan, sys whitesource,
if policyViolationCount > 0 {
influx.whitesource_data.fields.policy_violations = policyViolationCount
if config.FailOnSevereVulnerabilities {
log.SetErrorCategory(log.ErrorCompliance)
return policyReport, fmt.Errorf("%v policy violation(s) found", policyViolationCount)
log.SetErrorCategory(log.ErrorCompliance)
if config.CreateResultIssue && policyViolationCount > 0 && len(config.GithubToken) > 0 && len(config.GithubAPIURL) > 0 && len(config.Owner) > 0 && len(config.Repository) > 0 {
log.Entry().Debugf("Creating result issues for %v alert(s)", policyViolationCount)
issueDetails := make([]reporting.IssueDetail, len(allAlerts))
piperutils.CopyAtoB(allAlerts, issueDetails)
gh := reporting.GitHub{
Owner: &config.Owner,
Repository: &config.Repository,
Assignees: &config.Assignees,
IssueService: utils.GetIssueService(),
SearchService: utils.GetSearchService(),
}
if err := gh.UploadMultipleReports(ctx, &issueDetails); err != nil {
return policyReport, fmt.Errorf("failed to upload reports to GitHub for %v policy violations: %w", policyViolationCount, err)
}
}
log.Entry().Infof("%v policy violation(s) found - step will only create data but not fail due to setting failOnSevereVulnerabilities: false", policyViolationCount)
return policyReport, fmt.Errorf("%v policy violation(s) found", policyViolationCount)
}
return policyReport, nil
@ -900,7 +924,6 @@ func persistScannedProjects(config *ScanOptions, scan *ws.Scan, commonPipelineEn
}
// create toolrecord file for whitesource
//
func createToolRecordWhitesource(utils whitesourceUtils, workspace string, config *whitesourceExecuteScanOptions, scan *ws.Scan) (string, error) {
record := toolrecord.New(utils, workspace, "whitesource", config.ServiceURL)
wsUiRoot := "https://saas.whitesourcesoftware.com"

View File

@ -377,6 +377,7 @@ func TestCheckPolicyViolations(t *testing.T) {
t.Parallel()
t.Run("success - no violations", func(t *testing.T) {
ctx := context.Background()
config := ScanOptions{ProductName: "mock-product", Version: "1"}
scan := newWhitesourceScan(&config)
if err := scan.AppendScannedProject("testProject1"); err != nil {
@ -391,7 +392,7 @@ func TestCheckPolicyViolations(t *testing.T) {
}
influx := whitesourceExecuteScanInflux{}
path, err := checkPolicyViolations(&config, scan, systemMock, utilsMock, reportPaths, &influx)
path, err := checkPolicyViolations(ctx, &config, scan, systemMock, utilsMock, reportPaths, &influx)
assert.NoError(t, err)
assert.Equal(t, filepath.Join(ws.ReportsDirectory, "whitesource-ip.json"), path.Target)
@ -405,6 +406,7 @@ func TestCheckPolicyViolations(t *testing.T) {
})
t.Run("success - no reports", func(t *testing.T) {
ctx := context.Background()
config := ScanOptions{}
scan := newWhitesourceScan(&config)
if err := scan.AppendScannedProject("testProject1"); err != nil {
@ -416,7 +418,7 @@ func TestCheckPolicyViolations(t *testing.T) {
reportPaths := []piperutils.Path{}
influx := whitesourceExecuteScanInflux{}
path, err := checkPolicyViolations(&config, scan, systemMock, utilsMock, reportPaths, &influx)
path, err := checkPolicyViolations(ctx, &config, scan, systemMock, utilsMock, reportPaths, &influx)
assert.NoError(t, err)
fileContent, _ := utilsMock.FileRead(path.Target)
@ -425,6 +427,7 @@ func TestCheckPolicyViolations(t *testing.T) {
})
t.Run("error - policy violations", func(t *testing.T) {
ctx := context.Background()
config := ScanOptions{FailOnSevereVulnerabilities: true}
scan := newWhitesourceScan(&config)
if err := scan.AppendScannedProject("testProject1"); err != nil {
@ -442,7 +445,7 @@ func TestCheckPolicyViolations(t *testing.T) {
}
influx := whitesourceExecuteScanInflux{}
path, err := checkPolicyViolations(&config, scan, systemMock, utilsMock, reportPaths, &influx)
path, err := checkPolicyViolations(ctx, &config, scan, systemMock, utilsMock, reportPaths, &influx)
assert.Contains(t, fmt.Sprint(err), "2 policy violation(s) found")
fileContent, _ := utilsMock.FileRead(path.Target)
@ -452,6 +455,7 @@ func TestCheckPolicyViolations(t *testing.T) {
})
t.Run("error - get alerts", func(t *testing.T) {
ctx := context.Background()
config := ScanOptions{}
scan := newWhitesourceScan(&config)
if err := scan.AppendScannedProject("testProject1"); err != nil {
@ -463,11 +467,12 @@ func TestCheckPolicyViolations(t *testing.T) {
reportPaths := []piperutils.Path{}
influx := whitesourceExecuteScanInflux{}
_, err := checkPolicyViolations(&config, scan, systemMock, utilsMock, reportPaths, &influx)
_, err := checkPolicyViolations(ctx, &config, scan, systemMock, utilsMock, reportPaths, &influx)
assert.Contains(t, fmt.Sprint(err), "failed to retrieve project policy alerts from WhiteSource")
})
t.Run("error - write file", func(t *testing.T) {
ctx := context.Background()
config := ScanOptions{}
scan := newWhitesourceScan(&config)
if err := scan.AppendScannedProject("testProject1"); err != nil {
@ -480,11 +485,12 @@ func TestCheckPolicyViolations(t *testing.T) {
reportPaths := []piperutils.Path{}
influx := whitesourceExecuteScanInflux{}
_, err := checkPolicyViolations(&config, scan, systemMock, utilsMock, reportPaths, &influx)
_, err := checkPolicyViolations(ctx, &config, scan, systemMock, utilsMock, reportPaths, &influx)
assert.Contains(t, fmt.Sprint(err), "failed to write policy violation report:")
})
t.Run("failed to write json report", func(t *testing.T) {
ctx := context.Background()
config := ScanOptions{ProductName: "mock-product", Version: "1"}
scan := newWhitesourceScan(&config)
if err := scan.AppendScannedProject("testProject1"); err != nil {
@ -499,7 +505,7 @@ func TestCheckPolicyViolations(t *testing.T) {
reportPaths := []piperutils.Path{}
influx := whitesourceExecuteScanInflux{}
_, err := checkPolicyViolations(&config, scan, systemMock, utilsMock, reportPaths, &influx)
_, err := checkPolicyViolations(ctx, &config, scan, systemMock, utilsMock, reportPaths, &influx)
assert.Contains(t, fmt.Sprint(err), "failed to write json report")
})
}

View File

@ -0,0 +1,93 @@
package reporting
import (
"bytes"
"fmt"
"text/template"
"time"
"github.com/SAP/jenkins-library/pkg/orchestrator"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
type PolicyViolationReport struct {
ArtifactID string
Branch string
CommitID string
Description string
DirectDependency string
Footer string
Group string
PackageURL string
PipelineName string
PipelineLink string
Version string
}
const policyViolationMdTemplate string = `# Policy Violation - {{ .PackageURL }}
## Description
{{ .Description }}
## Context
{{if .PipelineLink -}}
### Pipeline
Pipeline run: [{{ .PipelineName }}]({{ .PipelineLink }})
{{- end}}
### Detected in
{{if .Branch}}**Branch:** {{ .Branch }}{{- end}}
{{if .CommitID}}**CommitId:** {{ .CommitID }}{{- end}}
{{if .DirectDependency}}**Dependency:** {{if (eq .DirectDependency "true")}}direct{{ else }}indirect{{ end }}{{- end}}
{{if .ArtifactID}}**ArtifactId:** {{ .ArtifactID }}{{- end}}
{{if .Group}}**Group:** {{ .Group }}{{- end}}
{{if .Version}}**Version:** {{ .Version }}{{- end}}
{{if .PackageURL}}**Package URL:** {{ .PackageURL }}{{- end}}
---
{{.Footer}}
`
func (p *PolicyViolationReport) ToMarkdown() ([]byte, error) {
funcMap := template.FuncMap{
"date": func(t time.Time) string {
return t.Format("2006-01-02")
},
"title": func(s string) string {
caser := cases.Title(language.AmericanEnglish)
return caser.String(s)
},
}
// only fill with orchestrator information if orchestrator can be identified properly
if provider, err := orchestrator.NewOrchestratorSpecificConfigProvider(); err == nil {
// only add information if not yet provided
if len(p.CommitID) == 0 {
p.CommitID = provider.GetCommit()
}
if len(p.PipelineLink) == 0 {
p.PipelineLink = provider.GetJobURL()
p.PipelineName = provider.GetJobName()
}
}
md := []byte{}
tmpl, err := template.New("report").Funcs(funcMap).Parse(policyViolationMdTemplate)
if err != nil {
return md, fmt.Errorf("failed to create markdown issue template: %w", err)
}
buf := new(bytes.Buffer)
err = tmpl.Execute(buf, p)
if err != nil {
return md, fmt.Errorf("failed to execute markdown issue template: %w", err)
}
md = buf.Bytes()
return md, nil
}

View File

@ -0,0 +1,43 @@
package reporting
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
func TestPolicyViolationToMarkdown(t *testing.T) {
t.Parallel()
t.Run("success - empty", func(t *testing.T) {
t.Parallel()
policyReport := PolicyViolationReport{}
_, err := policyReport.ToMarkdown()
assert.NoError(t, err)
})
t.Run("success - filled", func(t *testing.T) {
t.Parallel()
policyReport := PolicyViolationReport{
ArtifactID: "theArtifact",
Branch: "main",
CommitID: "acb123",
Description: "This is the test description.",
DirectDependency: "true",
Footer: "This is the test footer",
Group: "the.group",
PipelineName: "thePipelineName",
PipelineLink: "https://the.link.to.the.pipeline",
Version: "1.2.3",
PackageURL: "pkg:generic/the.group/theArtifact@1.2.3",
}
goldenFilePath := filepath.Join("testdata", "markdownPolicyViolation.golden")
expected, err := os.ReadFile(goldenFilePath)
assert.NoError(t, err)
res, err := policyReport.ToMarkdown()
assert.NoError(t, err)
assert.Equal(t, string(expected), string(res))
})
}

View File

@ -7,11 +7,7 @@ import (
"text/template"
"time"
"github.com/SAP/jenkins-library/pkg/orchestrator"
"github.com/pkg/errors"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
// IssueDetail represents any content that can be transformed into the body of a GitHub issue
@ -21,101 +17,6 @@ type IssueDetail interface {
ToTxt() string
}
// VulnerabilityReport represents metadata for a report on a vulnerability
type VulnerabilityReport struct {
ArtifactID string
Branch string
CommitID string
Description string
DirectDependency string
Footer string
Group string
PackageURL string
PipelineName string
PipelineLink string
PublishDate string
Resolution string
Score float64
Severity string
Version string
VulnerabilityLink string
VulnerabilityName string
}
const vulnerabilityMdTemplate string = `# {{title .Severity }} ({{ .Score }}) Vulnerability {{ .VulnerabilityName }} - {{ .ArtifactID }}
**Vulnerability link:** [{{ .VulnerabilityLink }}]({{ .VulnerabilityLink }})
## Fix
**{{ .Resolution }}**
## Context
{{if .PipelineLink -}}
### Pipeline
Pipeline run: [{{ .PipelineName }}]({{ .PipelineLink }})
{{- end}}
### Detected in
{{if .Branch}}**Branch:** {{ .Branch }}{{- end}}
{{if .CommitID}}**CommitId:** {{ .CommitID }}{{- end}}
{{if .DirectDependency}}**Dependency:** {{if (eq .DirectDependency "true")}}direct{{ else }}indirect{{ end }}{{- end}}
{{if .ArtifactID}}**ArtifactId:** {{ .ArtifactID }}{{- end}}
{{if .Group}}**Group:** {{ .Group }}{{- end}}
{{if .Version}}**Version:** {{ .Version }}{{- end}}
{{if .PackageURL}}**Package URL:** {{ .PackageURL }}{{- end}}
{{if .PublishDate}}**Publishing date:** {{.PublishDate }}{{- end}}
## Description
{{ .Description }}
---
{{.Footer}}
`
// ToMarkdown creates a vulnerability in markdown format which can be used in GitHub issues
func (v *VulnerabilityReport) ToMarkdown() ([]byte, error) {
funcMap := template.FuncMap{
"date": func(t time.Time) string {
return t.Format("2006-01-02")
},
"title": func(s string) string {
caser := cases.Title(language.AmericanEnglish)
return caser.String(s)
},
}
// only fill with orchestrator information if orchestrator can be identified properly
if provider, err := orchestrator.NewOrchestratorSpecificConfigProvider(); err == nil {
// only add information if not yet provided
if len(v.CommitID) == 0 {
v.CommitID = provider.GetCommit()
}
if len(v.PipelineLink) == 0 {
v.PipelineLink = provider.GetJobURL()
v.PipelineName = provider.GetJobName()
}
}
md := []byte{}
tmpl, err := template.New("report").Funcs(funcMap).Parse(vulnerabilityMdTemplate)
if err != nil {
return md, fmt.Errorf("failed to create markdown issue template: %w", err)
}
buf := new(bytes.Buffer)
err = tmpl.Execute(buf, v)
if err != nil {
return md, fmt.Errorf("failed to execute markdown issue template: %w", err)
}
md = buf.Bytes()
return md, nil
}
// ScanReport defines the elements of a scan report used by various scan steps
type ScanReport struct {
StepName string `json:"stepName"`
@ -426,10 +327,7 @@ func drawCell(cell ScanCell) string {
}
func shouldDrawTable(table ScanDetailTable) bool {
if len(table.Headers) > 0 {
return true
}
return false
return len(table.Headers) > 0
}
func drawOverviewRow(row OverviewRow) string {

View File

@ -1,54 +1,12 @@
package reporting
import (
"io/ioutil"
"path/filepath"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestVulToMarkdown(t *testing.T) {
t.Parallel()
t.Run("success - empty", func(t *testing.T) {
t.Parallel()
vulReport := VulnerabilityReport{}
_, err := vulReport.ToMarkdown()
assert.NoError(t, err)
})
t.Run("success - filled", func(t *testing.T) {
t.Parallel()
vulReport := VulnerabilityReport{
ArtifactID: "theArtifact",
Branch: "main",
CommitID: "acb123",
Description: "This is the test description.",
DirectDependency: "true",
Footer: "This is the test footer",
Group: "the.group",
PipelineName: "thePipelineName",
PipelineLink: "https://the.link.to.the.pipeline",
PublishDate: "2022-06-30",
Resolution: "This is the test resolution.",
Score: 7.8,
Severity: "high",
Version: "1.2.3",
PackageURL: "pkg:generic/the.group/theArtifact@1.2.3",
VulnerabilityLink: "https://the.link/to/the/vulnerability",
VulnerabilityName: "CVE-Test-001",
}
goldenFilePath := filepath.Join("testdata", "markdownVulnerability.golden")
expected, err := ioutil.ReadFile(goldenFilePath)
assert.NoError(t, err)
res, err := vulReport.ToMarkdown()
assert.NoError(t, err)
assert.Equal(t, string(expected), string(res))
})
}
func TestToHTML(t *testing.T) {
t.Run("empty table", func(t *testing.T) {
report := ScanReport{

View File

@ -0,0 +1,108 @@
package reporting
import (
"bytes"
"fmt"
"text/template"
"time"
"github.com/SAP/jenkins-library/pkg/orchestrator"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
// VulnerabilityReport represents metadata for a report on a vulnerability
type VulnerabilityReport struct {
ArtifactID string
Branch string
CommitID string
Description string
DirectDependency string
Footer string
Group string
PackageURL string
PipelineName string
PipelineLink string
PublishDate string
Resolution string
Score float64
Severity string
Version string
VulnerabilityLink string
VulnerabilityName string
}
const vulnerabilityMdTemplate string = `# {{title .Severity }} ({{ .Score }}) Vulnerability {{ .VulnerabilityName }} - {{ .ArtifactID }}
**Vulnerability link:** [{{ .VulnerabilityLink }}]({{ .VulnerabilityLink }})
## Fix
**{{ .Resolution }}**
## Context
{{if .PipelineLink -}}
### Pipeline
Pipeline run: [{{ .PipelineName }}]({{ .PipelineLink }})
{{- end}}
### Detected in
{{if .Branch}}**Branch:** {{ .Branch }}{{- end}}
{{if .CommitID}}**CommitId:** {{ .CommitID }}{{- end}}
{{if .DirectDependency}}**Dependency:** {{if (eq .DirectDependency "true")}}direct{{ else }}indirect{{ end }}{{- end}}
{{if .ArtifactID}}**ArtifactId:** {{ .ArtifactID }}{{- end}}
{{if .Group}}**Group:** {{ .Group }}{{- end}}
{{if .Version}}**Version:** {{ .Version }}{{- end}}
{{if .PackageURL}}**Package URL:** {{ .PackageURL }}{{- end}}
{{if .PublishDate}}**Publishing date:** {{.PublishDate }}{{- end}}
## Description
{{ .Description }}
---
{{.Footer}}
`
// ToMarkdown creates a vulnerability in markdown format which can be used in GitHub issues
func (v *VulnerabilityReport) ToMarkdown() ([]byte, error) {
funcMap := template.FuncMap{
"date": func(t time.Time) string {
return t.Format("2006-01-02")
},
"title": func(s string) string {
caser := cases.Title(language.AmericanEnglish)
return caser.String(s)
},
}
// only fill with orchestrator information if orchestrator can be identified properly
if provider, err := orchestrator.NewOrchestratorSpecificConfigProvider(); err == nil {
// only add information if not yet provided
if len(v.CommitID) == 0 {
v.CommitID = provider.GetCommit()
}
if len(v.PipelineLink) == 0 {
v.PipelineLink = provider.GetJobURL()
v.PipelineName = provider.GetJobName()
}
}
md := []byte{}
tmpl, err := template.New("report").Funcs(funcMap).Parse(vulnerabilityMdTemplate)
if err != nil {
return md, fmt.Errorf("failed to create markdown issue template: %w", err)
}
buf := new(bytes.Buffer)
err = tmpl.Execute(buf, v)
if err != nil {
return md, fmt.Errorf("failed to execute markdown issue template: %w", err)
}
md = buf.Bytes()
return md, nil
}

View File

@ -0,0 +1,49 @@
package reporting
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
func TestVulnerabilityReportToMarkdown(t *testing.T) {
t.Parallel()
t.Run("success - empty", func(t *testing.T) {
t.Parallel()
vulReport := VulnerabilityReport{}
_, err := vulReport.ToMarkdown()
assert.NoError(t, err)
})
t.Run("success - filled", func(t *testing.T) {
t.Parallel()
vulReport := VulnerabilityReport{
ArtifactID: "theArtifact",
Branch: "main",
CommitID: "acb123",
Description: "This is the test description.",
DirectDependency: "true",
Footer: "This is the test footer",
Group: "the.group",
PipelineName: "thePipelineName",
PipelineLink: "https://the.link.to.the.pipeline",
PublishDate: "2022-06-30",
Resolution: "This is the test resolution.",
Score: 7.8,
Severity: "high",
Version: "1.2.3",
PackageURL: "pkg:generic/the.group/theArtifact@1.2.3",
VulnerabilityLink: "https://the.link/to/the/vulnerability",
VulnerabilityName: "CVE-Test-001",
}
goldenFilePath := filepath.Join("testdata", "markdownVulnerability.golden")
expected, err := os.ReadFile(goldenFilePath)
assert.NoError(t, err)
res, err := vulReport.ToMarkdown()
assert.NoError(t, err)
assert.Equal(t, string(expected), string(res))
})
}

View File

@ -0,0 +1,25 @@
# Policy Violation - pkg:generic/the.group/theArtifact@1.2.3
## Description
This is the test description.
## Context
### Pipeline
Pipeline run: [thePipelineName](https://the.link.to.the.pipeline)
### Detected in
**Branch:** main
**CommitId:** acb123
**Dependency:** direct
**ArtifactId:** theArtifact
**Group:** the.group
**Version:** 1.2.3
**Package URL:** pkg:generic/the.group/theArtifact@1.2.3
---
This is the test footer

View File

@ -305,7 +305,7 @@ func mvnProjectExcludes(buildDescriptorExcludeList []string, utils Utils) []stri
return []string{}
}
//ToDo: Check if we want to optionally allow auto generation for unknown projects
// ToDo: Check if we want to optionally allow auto generation for unknown projects
func autoGenerateWhitesourceConfig(config *ScanOptions, utils Utils) error {
// TODO: Should we rely on -detect, or set the parameters manually?
if err := utils.RunExecutable("java", "-jar", config.AgentFileName, "-d", ".", "-detect"); err != nil {

View File

@ -64,6 +64,8 @@ type Alert struct {
func (a *Alert) Title() string {
if a.Type == "SECURITY_VULNERABILITY" {
return fmt.Sprintf("Security Vulnerability %v %v", a.Vulnerability.Name, a.Library.ArtifactID)
} else if a.Type == "REJECTED_BY_POLICY_RESOURCE" {
return fmt.Sprintf("Policy Violation %v %v", a.Vulnerability.Name, a.Library.ArtifactID)
}
return fmt.Sprintf("%v %v %v ", a.Type, a.Vulnerability.Name, a.Library.ArtifactID)
}
@ -144,32 +146,54 @@ func consolidate(cvss2severity, cvss3severity string, cvss2score, cvss3score flo
// ToMarkdown returns the markdown representation of the contents
func (a *Alert) ToMarkdown() ([]byte, error) {
score := consolidateScores(a.Vulnerability.Score, a.Vulnerability.CVSS3Score)
vul := reporting.VulnerabilityReport{
ArtifactID: a.Library.ArtifactID,
// no information available about branch and commit, yet
Branch: "",
CommitID: "",
Description: a.Vulnerability.Description,
DirectDependency: fmt.Sprint(a.DirectDependency),
// no information available about footer, yet
Footer: "",
Group: a.Library.GroupID,
// no information available about pipeline name and link, yet
PipelineName: "",
PipelineLink: "",
PublishDate: a.Vulnerability.PublishDate,
Resolution: a.Vulnerability.TopFix.FixResolution,
Score: score,
Severity: consolidate(a.Vulnerability.Severity, a.Vulnerability.CVSS3Severity, a.Vulnerability.Score, a.Vulnerability.CVSS3Score),
Version: a.Library.Version,
PackageURL: a.Library.ToPackageUrl().ToString(),
VulnerabilityLink: a.Vulnerability.URL,
VulnerabilityName: a.Vulnerability.Name,
if a.Type == "SECURITY_VULNERABILITY" {
score := consolidateScores(a.Vulnerability.Score, a.Vulnerability.CVSS3Score)
vul := reporting.VulnerabilityReport{
ArtifactID: a.Library.ArtifactID,
// no information available about branch and commit, yet
Branch: "",
CommitID: "",
Description: a.Vulnerability.Description,
DirectDependency: fmt.Sprint(a.DirectDependency),
// no information available about footer, yet
Footer: "",
Group: a.Library.GroupID,
// no information available about pipeline name and link, yet
PipelineName: "",
PipelineLink: "",
PublishDate: a.Vulnerability.PublishDate,
Resolution: a.Vulnerability.TopFix.FixResolution,
Score: score,
Severity: consolidate(a.Vulnerability.Severity, a.Vulnerability.CVSS3Severity, a.Vulnerability.Score, a.Vulnerability.CVSS3Score),
Version: a.Library.Version,
PackageURL: a.Library.ToPackageUrl().ToString(),
VulnerabilityLink: a.Vulnerability.URL,
VulnerabilityName: a.Vulnerability.Name,
}
return vul.ToMarkdown()
} else if a.Type == "REJECTED_BY_POLICY_RESOURCE" {
policyReport := reporting.PolicyViolationReport{
ArtifactID: a.Library.ArtifactID,
// no information available about branch and commit, yet
Branch: "",
CommitID: "",
Description: a.Vulnerability.Description,
DirectDependency: fmt.Sprint(a.DirectDependency),
// no information available about footer, yet
Footer: "",
Group: a.Library.GroupID,
// no information available about pipeline name and link, yet
PipelineName: "",
PipelineLink: "",
Version: a.Library.Version,
PackageURL: a.Library.ToPackageUrl().ToString(),
}
return policyReport.ToMarkdown()
}
return vul.ToMarkdown()
return []byte{}, nil
}
// ToTxt returns the textual representation of the contents