Skip to content

Commit 1e0b892

Browse files
Merge pull request #33 from snyk/feat/no-risk-score-for-licenses
feat: remove risk score line for license issues since they don't have one
2 parents 40aeece + e5f3943 commit 1e0b892

File tree

3 files changed

+170
-12
lines changed

3 files changed

+170
-12
lines changed

internal/presenters/funcs.go

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,23 @@ func getFieldValueFrom(data interface{}, path string) string {
9494

9595
// getVulnInfoURL returns the vulnerability information URL for a finding.
9696
func getVulnInfoURL(finding testapi.FindingData) string {
97-
if len(finding.Attributes.Problems) > 0 {
98-
problem := finding.Attributes.Problems[0]
99-
if p, err := problem.AsSnykVulnProblem(); err == nil {
100-
return "https://snyk.io/vuln/" + p.Id
101-
}
102-
if p, err := problem.AsSnykLicenseProblem(); err == nil {
103-
// License issues might have a different URL structure, but for now this is a safe bet.
104-
return "https://snyk.io/vuln/" + p.Id
97+
if finding.Attributes != nil {
98+
for _, problem := range finding.Attributes.Problems {
99+
disc, err := problem.Discriminator()
100+
if err != nil {
101+
continue
102+
}
103+
104+
switch disc {
105+
case string(testapi.SnykVuln):
106+
if p, err := problem.AsSnykVulnProblem(); err == nil {
107+
return "https://snyk.io/vuln/" + p.Id
108+
}
109+
case string(testapi.SnykLicense):
110+
if p, err := problem.AsSnykLicenseProblem(); err == nil {
111+
return "https://snyk.io/vuln/" + p.Id
112+
}
113+
}
105114
}
106115
}
107116
return ""
@@ -250,6 +259,7 @@ func getCliTemplateFuncMap(tmpl *template.Template) template.FuncMap {
250259
fnMap["divider"] = RenderDivider
251260
fnMap["title"] = RenderTitle
252261
fnMap["renderToString"] = renderTemplateToString(tmpl)
262+
fnMap["isLicenseFinding"] = isLicenseFinding
253263
fnMap["isOpenFinding"] = isOpenFinding
254264
fnMap["isPendingFinding"] = isPendingFinding
255265
fnMap["isIgnoredFinding"] = isIgnoredFinding
@@ -266,6 +276,27 @@ func getDefaultTemplateFuncMap(config configuration.Configuration, ri runtimeinf
266276
return nil
267277
}
268278
getFindingID := func(finding testapi.FindingData) string {
279+
if finding.Attributes != nil {
280+
for _, problem := range finding.Attributes.Problems {
281+
disc, err := problem.Discriminator()
282+
if err != nil {
283+
continue
284+
}
285+
286+
switch disc {
287+
case string(testapi.SnykVuln):
288+
if p, err := problem.AsSnykVulnProblem(); err == nil {
289+
return p.Id
290+
}
291+
case string(testapi.SnykLicense):
292+
if p, err := problem.AsSnykLicenseProblem(); err == nil {
293+
return p.Id
294+
}
295+
}
296+
}
297+
}
298+
299+
// fallback to top-level ID if no problem ID is found
269300
if finding.Id != nil {
270301
return finding.Id.String()
271302
}
@@ -295,10 +326,24 @@ func getDefaultTemplateFuncMap(config configuration.Configuration, ri runtimeinf
295326
defaultMap["getSourceLocation"] = getSourceLocation
296327
defaultMap["getFindingId"] = getFindingID
297328
defaultMap["hasPrefix"] = strings.HasPrefix
329+
defaultMap["isLicenseFinding"] = isLicenseFinding
298330

299331
return defaultMap
300332
}
301333

334+
// isLicenseFinding returns true if the finding is a license finding.
335+
func isLicenseFinding(finding testapi.FindingData) bool {
336+
if finding.Attributes != nil {
337+
for _, problem := range finding.Attributes.Problems {
338+
disc, err := problem.Discriminator()
339+
if err == nil && disc == string(testapi.SnykLicense) {
340+
return true
341+
}
342+
}
343+
}
344+
return false
345+
}
346+
302347
// reverse reverses the order of elements in a slice.
303348
func reverse(v interface{}) []interface{} {
304349
l, err := mustReverse(v)

internal/presenters/presenter_unified_finding_test.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@ import (
44
"bytes"
55
"testing"
66

7+
"github.com/google/uuid"
8+
"github.com/snyk/go-application-framework/pkg/apiclients/testapi"
9+
"github.com/snyk/go-application-framework/pkg/configuration"
10+
"github.com/snyk/go-application-framework/pkg/local_workflows/json_schemas"
711
"github.com/stretchr/testify/assert"
812

913
"github.com/snyk/cli-extension-os-flows/internal/presenters"
14+
"github.com/snyk/cli-extension-os-flows/internal/util"
1015
)
1116

1217
func TestJsonWriter(t *testing.T) {
@@ -42,3 +47,109 @@ func TestJsonWriter(t *testing.T) {
4247
assert.Equal(t, input, buffer.Bytes())
4348
})
4449
}
50+
51+
func TestUnifiedFindingPresenter_CliOutput(t *testing.T) {
52+
t.Run("license finding should not have risk score", func(t *testing.T) {
53+
// setup
54+
config := configuration.New()
55+
buffer := &bytes.Buffer{}
56+
57+
problemID := uuid.New().String()
58+
licenseFinding := testapi.FindingData{
59+
Id: util.Ptr(uuid.New()),
60+
Type: util.Ptr(testapi.Findings),
61+
Attributes: &testapi.FindingAttributes{
62+
Title: "GPL-3.0-only",
63+
Rating: testapi.Rating{
64+
Severity: testapi.Severity("medium"),
65+
},
66+
Problems: func() []testapi.Problem {
67+
var p testapi.Problem
68+
err := p.FromSnykLicenseProblem(testapi.SnykLicenseProblem{
69+
Id: problemID,
70+
License: "license",
71+
})
72+
assert.NoError(t, err)
73+
return []testapi.Problem{p}
74+
}(),
75+
},
76+
}
77+
78+
projectResult := &presenters.UnifiedProjectResult{
79+
Findings: []testapi.FindingData{licenseFinding},
80+
Summary: &json_schemas.TestSummary{
81+
SeverityOrderAsc: []string{"critical", "high", "medium", "low", "none"},
82+
Results: []json_schemas.TestSummaryResult{
83+
{
84+
Severity: "medium",
85+
Open: 1,
86+
},
87+
},
88+
},
89+
}
90+
91+
presenter := presenters.NewUnifiedFindingsRenderer(
92+
[]*presenters.UnifiedProjectResult{projectResult},
93+
config,
94+
buffer,
95+
)
96+
97+
// execute
98+
err := presenter.RenderTemplate(presenters.DefaultTemplateFiles, presenters.DefaultMimeType)
99+
100+
// assert
101+
assert.NoError(t, err)
102+
output := buffer.String()
103+
assert.NotContains(t, output, "Risk Score:")
104+
})
105+
106+
t.Run("vulnerability finding should have risk score", func(t *testing.T) {
107+
// setup
108+
config := configuration.New()
109+
buffer := &bytes.Buffer{}
110+
111+
riskScore := uint16(780)
112+
vulnFinding := testapi.FindingData{
113+
Id: util.Ptr(uuid.New()),
114+
Type: util.Ptr(testapi.Findings),
115+
Attributes: &testapi.FindingAttributes{
116+
Title: "High severity vulnerability",
117+
Risk: testapi.Risk{
118+
RiskScore: &testapi.RiskScore{
119+
Value: riskScore,
120+
},
121+
},
122+
Rating: testapi.Rating{
123+
Severity: testapi.Severity("high"),
124+
},
125+
},
126+
}
127+
128+
projectResult := &presenters.UnifiedProjectResult{
129+
Findings: []testapi.FindingData{vulnFinding},
130+
Summary: &json_schemas.TestSummary{
131+
SeverityOrderAsc: []string{"critical", "high", "medium", "low", "none"},
132+
Results: []json_schemas.TestSummaryResult{
133+
{
134+
Severity: "high",
135+
Open: 1,
136+
},
137+
},
138+
},
139+
}
140+
141+
presenter := presenters.NewUnifiedFindingsRenderer(
142+
[]*presenters.UnifiedProjectResult{projectResult},
143+
config,
144+
buffer,
145+
)
146+
147+
// execute
148+
err := presenter.RenderTemplate(presenters.DefaultTemplateFiles, presenters.DefaultMimeType)
149+
150+
// assert
151+
assert.NoError(t, err)
152+
output := buffer.String()
153+
assert.Contains(t, output, "Risk Score: 780")
154+
})
155+
}

internal/presenters/templates/unified_finding.tmpl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99
{{- with (getIntroducedThrough .) }}
1010
Introduced through: {{ . }}
1111
{{- end }}
12-
{{- $riskScore := getFieldValueFrom . "Attributes.Risk.RiskScore.Value" -}}
13-
{{- if $riskScore }}
12+
{{- if not (isLicenseFinding .) }}
13+
{{- $riskScore := getFieldValueFrom . "Attributes.Risk.RiskScore.Value" -}}
14+
{{- if $riskScore }}
1415
Risk Score: {{ $riskScore }}
15-
{{- else }}
16-
Risk Score: N/A (Risk score couldn't be computed)
16+
{{- else }}
17+
Risk Score: N/A
18+
{{- end }}
1719
{{- end }}
1820
{{- $isReachable := getFieldValueFrom . "Attributes.IsReachable" -}}
1921
{{- if eq $isReachable "true" }}

0 commit comments

Comments
 (0)