diff --git a/cmd/whitesourceExecuteScan.go b/cmd/whitesourceExecuteScan.go index 17126cfb5..8350aacbb 100644 --- a/cmd/whitesourceExecuteScan.go +++ b/cmd/whitesourceExecuteScan.go @@ -585,16 +585,20 @@ func checkSecurityViolations(ctx context.Context, config *ScanOptions, scan *ws. allLibraries := []ws.Library{} for _, project := range scan.ScannedProjects() { // collect errors and aggregate vulnerabilities from all projects - if vulCount, alerts, err := checkProjectSecurityViolations(config, cvssSeverityLimit, project, sys, assessments, influx); err != nil { - allAlerts = append(allAlerts, alerts...) - vulnerabilitiesCount += vulCount + vulCount, alerts, err := checkProjectSecurityViolations(config, cvssSeverityLimit, project, sys, assessments, influx) + if err != nil { errorsOccured = append(errorsOccured, fmt.Sprint(err)) } + allAlerts = append(allAlerts, alerts...) + vulnerabilitiesCount += vulCount + // collect all libraries detected in all related projects and errors - if libraries, err := sys.GetProjectHierarchy(project.Token, true); err != nil { - allLibraries = append(allLibraries, libraries...) + libraries, err := sys.GetProjectHierarchy(project.Token, true) + if err != nil { errorsOccured = append(errorsOccured, fmt.Sprint(err)) } + log.Entry().Debugf("Collected %v libraries for project %v", len(libraries), project.Name) + allLibraries = append(allLibraries, libraries...) } log.Entry().Debugf("Aggregated %v alerts for scanned projects", len(allAlerts)) diff --git a/pkg/whitesource/reporting.go b/pkg/whitesource/reporting.go index 1c338e836..a8c5ff995 100644 --- a/pkg/whitesource/reporting.go +++ b/pkg/whitesource/reporting.go @@ -379,8 +379,9 @@ func CreateCycloneSBOM(scan *Scan, libraries *[]Library, alerts *[]Alert) ([]byt components := []cdx.Component{} flatUniqueLibrariesMap := map[string]Library{} - transformToUniqueFlatList(libraries, &flatUniqueLibrariesMap) + transformToUniqueFlatList(libraries, &flatUniqueLibrariesMap, 1) flatUniqueLibraries := piperutils.Values(flatUniqueLibrariesMap) + log.Entry().Debugf("Got %v unique libraries in condensed flat list", len(flatUniqueLibraries)) sort.Slice(flatUniqueLibraries, func(i, j int) bool { return flatUniqueLibraries[i].ToPackageUrl().ToString() < flatUniqueLibraries[j].ToPackageUrl().ToString() }) @@ -395,6 +396,7 @@ func CreateCycloneSBOM(scan *Scan, libraries *[]Library, alerts *[]Alert) ([]byt Name: lib.ArtifactID, Version: lib.Version, PackageURL: purl.ToString(), + Hashes: &[]cdx.Hash{{Algorithm: cdx.HashAlgoSHA1, Value: lib.Sha1}}, } components = append(components, component) } @@ -513,7 +515,8 @@ func WriteCycloneSBOM(sbom []byte, utils piperutils.FileUtils) ([]piperutils.Pat return paths, nil } -func transformToUniqueFlatList(libraries *[]Library, flatMapRef *map[string]Library) { +func transformToUniqueFlatList(libraries *[]Library, flatMapRef *map[string]Library, level int) { + log.Entry().Debugf("Got %v libraries reported on level %v", len(*libraries), level) for _, lib := range *libraries { key := lib.ToPackageUrl().ToString() flatMap := *flatMapRef @@ -521,7 +524,7 @@ func transformToUniqueFlatList(libraries *[]Library, flatMapRef *map[string]Libr if lookup.KeyID != lib.KeyID { flatMap[key] = lib if len(lib.Dependencies) > 0 { - transformToUniqueFlatList(&lib.Dependencies, flatMapRef) + transformToUniqueFlatList(&lib.Dependencies, flatMapRef, level+1) } } diff --git a/pkg/whitesource/reporting_test.go b/pkg/whitesource/reporting_test.go index b05607cf0..e38002569 100644 --- a/pkg/whitesource/reporting_test.go +++ b/pkg/whitesource/reporting_test.go @@ -273,7 +273,6 @@ func TestWriteSarifFile(t *testing.T) { } func TestCountSecurityVulnerabilities(t *testing.T) { - t.Parallel() alerts := []Alert{ {Vulnerability: Vulnerability{CVSS3Score: 7.1}}, diff --git a/pkg/whitesource/testdata/sbom.golden b/pkg/whitesource/testdata/sbom.golden index 2fafd88b3..273fb1a5b 100644 --- a/pkg/whitesource/testdata/sbom.golden +++ b/pkg/whitesource/testdata/sbom.golden @@ -17,24 +17,36 @@ apache-commons commons-lang 2.4.30 + + + pkg:maven/apache-commons/commons-lang@2.4.30 apache-commons commons-lang 3.15 + + + pkg:maven/apache-commons/commons-lang@3.15 apache-logging log4j 1.14 + + + pkg:maven/apache-logging/log4j@1.14 apache-logging log4j 3.25 + + + pkg:maven/apache-logging/log4j@3.25 diff --git a/pkg/whitesource/whitesource.go b/pkg/whitesource/whitesource.go index 67fc95bb1..3c490e600 100644 --- a/pkg/whitesource/whitesource.go +++ b/pkg/whitesource/whitesource.go @@ -92,22 +92,32 @@ func transformLibToPurlType(libType string) string { log.Entry().Debugf("LibType reported as %v", libType) switch strings.ToLower(libType) { case "java": + fallthrough + case "maven_artifact": return packageurl.TypeMaven case "javascript/node.js": + fallthrough + case "node_packaged_module": return packageurl.TypeNPM case "javascript/bower": return "bower" case "go": + fallthrough + case "go_package": return packageurl.TypeGolang case "python": + fallthrough + case "python_package": return packageurl.TypePyPi case "debian": + fallthrough + case "debian_package": return packageurl.TypeDebian case "docker": return packageurl.TypeDocker - case "source library": - return "src" case ".net": + fallthrough + case "dot_net_resource": return packageurl.TypeNuget } return packageurl.TypeGeneric diff --git a/pkg/whitesource/whitesource_test.go b/pkg/whitesource/whitesource_test.go index 75f764e31..a5e95cea9 100644 --- a/pkg/whitesource/whitesource_test.go +++ b/pkg/whitesource/whitesource_test.go @@ -10,6 +10,7 @@ import ( "time" piperhttp "github.com/SAP/jenkins-library/pkg/http" + "github.com/package-url/packageurl-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -295,6 +296,32 @@ func TestGetProductName(t *testing.T) { assert.Equal(t, "Test Product", productName) } +func TestTransformLibToPurlType(t *testing.T) { + tt := []struct { + libType string + expected string + }{ + {libType: "Java", expected: packageurl.TypeMaven}, + {libType: "MAVEN_ARTIFACT", expected: packageurl.TypeMaven}, + {libType: "javascript/Node.js", expected: packageurl.TypeNPM}, + {libType: "node_packaged_module", expected: packageurl.TypeNPM}, + {libType: "javascript/bower", expected: "bower"}, + {libType: "go", expected: packageurl.TypeGolang}, + {libType: "go_package", expected: packageurl.TypeGolang}, + {libType: "python", expected: packageurl.TypePyPi}, + {libType: "python_package", expected: packageurl.TypePyPi}, + {libType: "debian", expected: packageurl.TypeDebian}, + {libType: "debian_package", expected: packageurl.TypeDebian}, + {libType: "docker", expected: packageurl.TypeDocker}, + {libType: ".net", expected: packageurl.TypeNuget}, + {libType: "dot_net_resource", expected: packageurl.TypeNuget}, + } + + for i, test := range tt { + assert.Equalf(t, test.expected, transformLibToPurlType(test.libType), "run %v failed", i) + } +} + func TestGetProjectHierarchy(t *testing.T) { myTestClient := whitesourceMockClient{ responseBody: `{ @@ -411,7 +438,10 @@ func TestGetProjectHierarchy(t *testing.T) { } ] } - ] + ], + "warningMessages":[ + "Invalid input: orgToken" + ] }`, }