From af7ff5913ffcaa54586989dca0e367f45231e4b0 Mon Sep 17 00:00:00 2001 From: foobar Date: Sun, 15 Oct 2023 21:29:54 +0100 Subject: [PATCH 01/24] add the ability to enrich sbom document with security scorecard score --- components/enrichers/depsdev/README.md | 4 +- components/enrichers/depsdev/main.go | 87 +++++++++++++++++++++----- components/enrichers/depsdev/task.yaml | 7 ++- 3 files changed, 79 insertions(+), 19 deletions(-) diff --git a/components/enrichers/depsdev/README.md b/components/enrichers/depsdev/README.md index 955e9f6e5..d80ba1f6d 100644 --- a/components/enrichers/depsdev/README.md +++ b/components/enrichers/depsdev/README.md @@ -4,9 +4,7 @@ _Because Go licenses must be detected, there's always a chance of the detected license being wrong_. The licenses detected for GO might not be 100% accurate. Please ensure you validate the results if you intent to use them in a legally binding way. This enricher implements a rudimentary client for Google's [Open Source Insights](https://deps.dev) project. -It *ONLY* works with issues containing SBOMs and at its current version adds missing licensing information to each package in the SBOM. - - +It *ONLY* works with issues containing CycloneDXSBOMs and at its current version adds missing licensing information and ScoreCard scan results to each package in the SBOM. ## Future steps diff --git a/components/enrichers/depsdev/main.go b/components/enrichers/depsdev/main.go index 72a0c17a2..177efec64 100644 --- a/components/enrichers/depsdev/main.go +++ b/components/enrichers/depsdev/main.go @@ -26,6 +26,7 @@ var ( writePath string depsdevBaseURL = "https://deps.dev" licensesInEvidence string + scoreCardInfo string annotation string ) @@ -96,38 +97,65 @@ func lookupEnvOrString(key string, defaultVal string) string { return defaultVal } -func makeURL(component cdx.Component) (string, error) { +func makeURL(component cdx.Component, api bool) (string, error) { instance, err := packageurl.FromString(component.PackageURL) if err != nil { return "", err } - baseURL := fmt.Sprintf("%s/_/s", depsdevBaseURL) + ecosystem := "" version := url.QueryEscape(component.Version) switch instance.Type { case packageurl.TypeGolang: - baseURL += "/go" + ecosystem += "/go" version = "v" + version case packageurl.TypePyPi: - baseURL += "/pypi" + ecosystem += "/pypi" case packageurl.TypeMaven: - baseURL += "/maven" + ecosystem += "/maven" // case packageurl.TypeCargo: - // baseURL += "/cargo" + // ecosystem += "/cargo" case packageurl.TypeNPM: - baseURL += "/npm" + ecosystem += "/npm" case packageurl.TypeNuget: - baseURL += "/nuget" + ecosystem += "/nuget" default: log.Println(instance.Namespace, "not supported by this enricher") } - baseURL += fmt.Sprintf("/p/%s/v/%s", url.QueryEscape(component.Name), version) - return baseURL, nil + resultURL := "" + if api { + resultURL = fmt.Sprintf("%s/_/s%s/p/%s/v/%s", depsdevBaseURL, ecosystem, url.QueryEscape(component.Name), version) + } else { + resultURL = fmt.Sprintf("%s/%s/p/%s/v/%s", depsdevBaseURL, ecosystem, url.QueryEscape(component.Name), version) + } + return resultURL, nil +} +func addDepsDevLink(component cdx.Component) (cdx.Component, error) { + url, err := makeURL(component, false) + if err != nil { + return component, err + } + log.Println("url is", url) + + depsDevRef := cdx.ExternalReference{ + Type: cdx.ERTypeOther, + URL: url, + } + + if component.ExternalReferences != nil && len(*component.ExternalReferences) > 0 { + refs := append(*component.ExternalReferences, depsDevRef) + component.ExternalReferences = &refs + } else { + refs := []cdx.ExternalReference{depsDevRef} + component.ExternalReferences = &refs + } + + return component, nil } -func addLicenses(component cdx.Component, annotations map[string]string) (cdx.Component, map[string]string, error) { +func addDepsDevInfo(component cdx.Component, annotations map[string]string) (cdx.Component, map[string]string, error) { var depsResp Response licenses := cdx.Licenses{} - url, err := makeURL(component) + url, err := makeURL(component, true) if err != nil { return component, annotations, err } @@ -142,8 +170,8 @@ func addLicenses(component cdx.Component, annotations map[string]string) (cdx.Co } if len(depsResp.Version.Licenses) == 0 { log.Println("could not find license for component", component.Name) - // log.Println(resp.Header, resp.StatusCode, depsResp) } + for _, lic := range depsResp.Version.Licenses { licenseName := cdx.License{ Name: lic, @@ -151,6 +179,29 @@ func addLicenses(component cdx.Component, annotations map[string]string) (cdx.Co licenses = append(licenses, cdx.LicenseChoice{License: &licenseName}) log.Println("found license", lic, "for component", component.Name) } + if scoreCardInfo == "true" { + for _, project := range depsResp.Version.Projects { + if project.ScorecardV2.Date != "" && len(project.ScorecardV2.Check) != 0 && project.ScorecardV2.Score >= 0 { + scoreCardInfo, err := json.MarshalIndent(project.ScorecardV2, "", "\t") + if err != nil { + log.Println("could not marshal score card information, err:", err) + continue + } + properties := []cdx.Property{ + { + Name: "ScorecardScore", + Value: fmt.Sprintf("%f", project.ScorecardV2.Score), + }, + { + Name: "ScorecardInfo", + Value: string(scoreCardInfo), + }, + } + props := append(*component.Properties, properties...) + component.Properties = &props + } + } + } if licensesInEvidence == "true" { evid := cdx.Evidence{ Licenses: &licenses, @@ -181,13 +232,18 @@ func enrichIssue(i *v1.Issue) (*v1.EnrichedIssue, error) { for index, component := range *bom.Components { if component.Type == cdx.ComponentTypeLibrary { if component.Licenses == nil { - (*bom.Components)[index], annotations, err = addLicenses(component, annotations) + (*bom.Components)[index], annotations, err = addDepsDevInfo(component, annotations) + if err != nil { + log.Println(err) + continue + } + (*bom.Components)[index], err = addDepsDevLink(component) if err != nil { log.Println(err) continue } } - // TODO(): enrich with vulnerability and scorecard info whenever a consumer supports showing arbitrary properties in components + // TODO(): enrich with vulnerability info whenever a consumer supports showing arbitrary properties in components } } @@ -254,6 +310,7 @@ func main() { flag.StringVar(&readPath, "read_path", lookupEnvOrString("READ_PATH", ""), "where to find producer results") flag.StringVar(&writePath, "write_path", lookupEnvOrString("WRITE_PATH", ""), "where to put enriched results") flag.StringVar(&annotation, "annotation", lookupEnvOrString("ANNOTATION", defaultAnnotation), "what is the annotation this enricher will add to the issues, by default `Enriched Licenses`") + flag.StringVar(&scoreCardInfo, "scoreCardInfo", lookupEnvOrString("SCORECARD_INFO", "false"), "add security score card scan results from deps.dev to the components of the SBOM as properties") flag.StringVar(&licensesInEvidence, "licensesInEvidence", lookupEnvOrString("LICENSES_IN_EVIDENCE", ""), `If this flag is provided and set to "true", the enricher will populate the 'evidence' CycloneDX field with license information instead of the license field. This means that the result conforms to the CycloneDX intention of providing accurate information when licensing information cannot be guaranteed to be accurate. diff --git a/components/enrichers/depsdev/task.yaml b/components/enrichers/depsdev/task.yaml index 0923540c7..825cf665f 100644 --- a/components/enrichers/depsdev/task.yaml +++ b/components/enrichers/depsdev/task.yaml @@ -10,6 +10,9 @@ spec: - name: enricher-depsdev-licenses-in-evidence type: string default: "false" + - name: enricher-depsdev-scorecard-info + type: string + default: "true" - name: enricher-depsdev-annotation type: string default: "" @@ -30,4 +33,6 @@ spec: - name: LICENSES_IN_EVIDENCE value: "$(params.enricher-depsdev-licenses-in-evidence)" - name: ANNOTATION - value: "$(params.enricher-depsdev-annotation)" \ No newline at end of file + value: "$(params.enricher-depsdev-annotation)" + - name: SCORECARD_INFO + value: "$(params.enricher-depsdev-scorecard-info)" From 627d7673e9d4154532d3ec03b46b7f79e9503cc8 Mon Sep 17 00:00:00 2001 From: foobar Date: Sun, 15 Oct 2023 21:30:28 +0100 Subject: [PATCH 02/24] lint: --- components/enrichers/depsdev/main.go | 1 + go.mod | 3 ++- go.sum | 7 +++++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/components/enrichers/depsdev/main.go b/components/enrichers/depsdev/main.go index 177efec64..01bcdf028 100644 --- a/components/enrichers/depsdev/main.go +++ b/components/enrichers/depsdev/main.go @@ -129,6 +129,7 @@ func makeURL(component cdx.Component, api bool) (string, error) { } return resultURL, nil } + func addDepsDevLink(component cdx.Component) (cdx.Component, error) { url, err := makeURL(component, false) if err != nil { diff --git a/go.mod b/go.mod index 147dc8401..b80df1fc4 100644 --- a/go.mod +++ b/go.mod @@ -13,13 +13,14 @@ require ( github.com/golang-migrate/migrate/v4 v4.15.1 github.com/golang/protobuf v1.5.2 github.com/google/uuid v1.3.0 + github.com/hairyhenderson/go-codeowners v0.4.0 github.com/jmoiron/sqlx v1.3.5 github.com/lib/pq v1.10.5 github.com/owenrumney/go-sarif/v2 v2.1.2 github.com/package-url/packageurl-go v0.1.0 github.com/spf13/cobra v1.4.0 github.com/spf13/viper v1.11.0 - github.com/stretchr/testify v1.8.1 + github.com/stretchr/testify v1.8.4 github.com/trivago/tgo v1.0.7 go.mongodb.org/mongo-driver v1.10.0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d diff --git a/go.sum b/go.sum index f97560e1e..33c375216 100644 --- a/go.sum +++ b/go.sum @@ -589,6 +589,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= +github.com/hairyhenderson/go-codeowners v0.4.0 h1:Wx/tRXb07sCyHeC8mXfio710Iu35uAy5KYiBdLHdv4Q= +github.com/hairyhenderson/go-codeowners v0.4.0/go.mod h1:iJgZeCt+W/GzXo5uchFCqvVHZY2T4TAIpvuVlKVkLxc= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -709,7 +711,7 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= @@ -972,8 +974,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= From 0554b5e0741b4c100a1460001e8088b71195aaeb Mon Sep 17 00:00:00 2001 From: foobar Date: Mon, 16 Oct 2023 18:37:28 +0100 Subject: [PATCH 03/24] fix logging --- components/enrichers/depsdev/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/enrichers/depsdev/main.go b/components/enrichers/depsdev/main.go index 01bcdf028..f644a0397 100644 --- a/components/enrichers/depsdev/main.go +++ b/components/enrichers/depsdev/main.go @@ -289,7 +289,7 @@ func run() { log.Fatal(err) } } else { - log.Println("no enriched issues were created") + log.Println("no enriched issues were created for", r.GetToolName()) } if len(r.GetIssues()) > 0 { scanStartTime := r.GetScanInfo().GetScanStartTime().AsTime() From 22355d2bc4f3b554d4d9f07d42dddd57bd7c7317 Mon Sep 17 00:00:00 2001 From: foobar Date: Wed, 18 Oct 2023 19:26:32 +0100 Subject: [PATCH 04/24] fix depsdev + tests --- components/enrichers/depsdev/main.go | 101 ++++++++--------- components/enrichers/depsdev/main_test.go | 125 ++++++++++++++++++---- 2 files changed, 160 insertions(+), 66 deletions(-) diff --git a/components/enrichers/depsdev/main.go b/components/enrichers/depsdev/main.go index f644a0397..74341cece 100644 --- a/components/enrichers/depsdev/main.go +++ b/components/enrichers/depsdev/main.go @@ -30,6 +30,43 @@ var ( annotation string ) +type Check struct { + Name string `json:"name,omitempty"` + Documentation struct { + Short string `json:"short,omitempty"` + URL string `json:"url,omitempty"` + } `json:"documentation,omitempty"` + Score int `json:"score,omitempty"` + Reason string `json:"reason,omitempty"` + Details []interface{} `json:"details,omitempty"` +} +type ScorecardV2 struct { + Date string `json:"date,omitempty"` + Repo struct { + Name string `json:"name,omitempty"` + Commit string `json:"commit,omitempty"` + } `json:"repo,omitempty"` + Scorecard struct { + Version string `json:"version,omitempty"` + Commit string `json:"commit,omitempty"` + } `json:"scorecard,omitempty"` + Check []Check `json:"check,omitempty"` + Metadata []interface{} `json:"metadata,omitempty"` + Score float64 `json:"score,omitempty"` +} +type Project struct { + Type string `json:"type,omitempty"` + Name string `json:"name,omitempty"` + ObservedAt int `json:"observedAt,omitempty"` + Issues int `json:"issues,omitempty"` + Forks int `json:"forks,omitempty"` + Stars int `json:"stars,omitempty"` + Description string `json:"description,omitempty"` + License string `json:"license,omitempty"` + DisplayName string `json:"displayName,omitempty"` + Link string `json:"link,omitempty"` + ScorecardV2 ScorecardV2 `json:"scorecardV2,omitempty"` +} type Version struct { Version string `json:"version,omitempty"` SymbolicVersions []interface{} `json:"symbolicVersions,omitempty"` @@ -42,41 +79,7 @@ type Version struct { Links struct { Origins []string `json:"origins,omitempty"` } `json:"links,omitempty"` - Projects []struct { - Type string `json:"type,omitempty"` - Name string `json:"name,omitempty"` - ObservedAt int `json:"observedAt,omitempty"` - Issues int `json:"issues,omitempty"` - Forks int `json:"forks,omitempty"` - Stars int `json:"stars,omitempty"` - Description string `json:"description,omitempty"` - License string `json:"license,omitempty"` - DisplayName string `json:"displayName,omitempty"` - Link string `json:"link,omitempty"` - ScorecardV2 struct { - Date string `json:"date,omitempty"` - Repo struct { - Name string `json:"name,omitempty"` - Commit string `json:"commit,omitempty"` - } `json:"repo,omitempty"` - Scorecard struct { - Version string `json:"version,omitempty"` - Commit string `json:"commit,omitempty"` - } `json:"scorecard,omitempty"` - Check []struct { - Name string `json:"name,omitempty"` - Documentation struct { - Short string `json:"short,omitempty"` - URL string `json:"url,omitempty"` - } `json:"documentation,omitempty"` - Score int `json:"score,omitempty"` - Reason string `json:"reason,omitempty"` - Details []interface{} `json:"details,omitempty"` - } `json:"check,omitempty"` - Metadata []interface{} `json:"metadata,omitempty"` - Score float64 `json:"score,omitempty"` - } `json:"scorecardV2,omitempty"` - } `json:"projects,omitempty"` + Projects []Project `json:"projects,omitempty"` Advisories []interface{} `json:"advisories,omitempty"` RelatedPackages struct{} `json:"relatedPackages,omitempty"` } @@ -125,7 +128,7 @@ func makeURL(component cdx.Component, api bool) (string, error) { if api { resultURL = fmt.Sprintf("%s/_/s%s/p/%s/v/%s", depsdevBaseURL, ecosystem, url.QueryEscape(component.Name), version) } else { - resultURL = fmt.Sprintf("%s/%s/p/%s/v/%s", depsdevBaseURL, ecosystem, url.QueryEscape(component.Name), version) + resultURL = fmt.Sprintf("%s%s/p/%s/v/%s", depsdevBaseURL, ecosystem, url.QueryEscape(component.Name), version) } return resultURL, nil } @@ -135,8 +138,6 @@ func addDepsDevLink(component cdx.Component) (cdx.Component, error) { if err != nil { return component, err } - log.Println("url is", url) - depsDevRef := cdx.ExternalReference{ Type: cdx.ERTypeOther, URL: url, @@ -161,7 +162,6 @@ func addDepsDevInfo(component cdx.Component, annotations map[string]string) (cdx return component, annotations, err } resp, err := http.Get(url) // nolint: gosec, url get constructed above with a hardcoded domain and relatively trusted data - log.Println("url is", url) if err != nil { return component, annotations, err } @@ -181,6 +181,7 @@ func addDepsDevInfo(component cdx.Component, annotations map[string]string) (cdx log.Println("found license", lic, "for component", component.Name) } if scoreCardInfo == "true" { + log.Println("adding scorecard info") for _, project := range depsResp.Version.Projects { if project.ScorecardV2.Date != "" && len(project.ScorecardV2.Check) != 0 && project.ScorecardV2.Score >= 0 { scoreCardInfo, err := json.MarshalIndent(project.ScorecardV2, "", "\t") @@ -204,6 +205,7 @@ func addDepsDevInfo(component cdx.Component, annotations map[string]string) (cdx } } if licensesInEvidence == "true" { + log.Println("adding Licenses in the 'Evidence' field") evid := cdx.Evidence{ Licenses: &licenses, } @@ -215,7 +217,6 @@ func addDepsDevInfo(component cdx.Component, annotations map[string]string) (cdx } else { component.Licenses = &licenses } - annotations[annotation] = "True" return component, annotations, nil } @@ -230,24 +231,28 @@ func enrichIssue(i *v1.Issue) (*v1.EnrichedIssue, error) { if bom == nil || *bom.Components == nil { return &enrichedIssue, errors.New("bom does not have components") } - for index, component := range *bom.Components { + newComponents := (*bom.Components)[:0] + for _, component := range *bom.Components { + newComp := component if component.Type == cdx.ComponentTypeLibrary { if component.Licenses == nil { - (*bom.Components)[index], annotations, err = addDepsDevInfo(component, annotations) - if err != nil { - log.Println(err) - continue - } - (*bom.Components)[index], err = addDepsDevLink(component) + newComp, annotations, err = addDepsDevInfo(component, annotations) if err != nil { log.Println(err) continue } } + newComp, err = addDepsDevLink(newComp) + if err != nil { + log.Println(err) + continue + } + // TODO(): enrich with vulnerability info whenever a consumer supports showing arbitrary properties in components } + newComponents = append(newComponents, newComp) } - + bom.Components = &newComponents marshalled, err := json.Marshal(bom) if err != nil { return &enrichedIssue, err diff --git a/components/enrichers/depsdev/main_test.go b/components/enrichers/depsdev/main_test.go index 8ce23f22c..875b4a8f9 100644 --- a/components/enrichers/depsdev/main_test.go +++ b/components/enrichers/depsdev/main_test.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "fmt" "io/ioutil" "log" "net/http" @@ -9,6 +10,7 @@ import ( "testing" "time" + cdx "github.com/CycloneDX/cyclonedx-go" "github.com/google/uuid" v1 "github.com/ocurity/dracon/api/proto/v1" "github.com/ocurity/dracon/pkg/cyclonedx" @@ -70,23 +72,122 @@ func prepareIssue() string { func MockServer(t *testing.T) { } -func TestParseIssuesLicensesWritten(t *testing.T) { +// TODO make this be the common setup method +// todo add test for deps dev and scorecard stuff +func setup(t *testing.T) (string, *httptest.Server) { dir := prepareIssue() // setup server response := Response{ Version: Version{ Licenses: []string{license}, + Projects: []Project{ + { + ScorecardV2: ScorecardV2{ + Score: 5.5, + Check: []Check{ + { + Name: "foo", + Score: 2, + Reason: "bar", + }, + }, + }, + }, + }, }, } - svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Contains(t, r.URL.String(), "/_/s/go/p/") json.NewEncoder(w).Encode(response) })) - defer svr.Close() - depsdevBaseURL = svr.URL + depsdevBaseURL = srv.URL + return dir, srv +} +func TestParseIssuesDepsDevScoreCardInfoWritten(t *testing.T) { + dir, srv := setup(t) + defer srv.Close() + + // run enricher run() + assert.FileExists(t, dir+"/depsdevSAT.depsdev.enriched.pb", "file was not created") + + // load *enriched.pb + pbBytes, err := ioutil.ReadFile(dir + "/depsdevSAT.depsdev.enriched.pb") + assert.NoError(t, err, "could not read enriched file") + res := v1.EnrichedLaunchToolResponse{} + proto.Unmarshal(pbBytes, &res) + expectedExternalReferences := []cdx.ExternalReference{ + { + URL: "http://127.0.0.1:46679//go/p/cloud.google.com%2Fgo%2Fcompute/v/v1.14.0", + Type: "other", + }, { + URL: "http://127.0.0.1:46679//go/p/cloud.google.com%2Fgo%2Fcompute%2Fmetadata/v/v0.2.3", + Type: "other", + }, { + URL: "http://127.0.0.1:46679//go/p/github.com%2FAzure%2Fazure-pipeline-go/v/v0.2.3", + Type: "other", + }, + } + // ensure every component has a license attached to it + for _, finding := range res.Issues { + bom, err := cyclonedx.FromDracon(finding.RawIssue) + assert.NoError(t, err, "Could not read enriched cyclone dx info") + + externalReferences := []cdx.ExternalReference{} + + for _, component := range *bom.Components { + externalReferences = append(externalReferences, *component.ExternalReferences...) + } + assert.Equal(t, externalReferences, expectedExternalReferences) + } +} +func TestParseIssuesDepsDevExternalReferenceLinksWritten(t *testing.T) { + dir, srv := setup(t) + defer srv.Close() + // run enricher + run() + assert.FileExists(t, dir+"/depsdevSAT.depsdev.enriched.pb", "file was not created") + + // load *enriched.pb + pbBytes, err := ioutil.ReadFile(dir + "/depsdevSAT.depsdev.enriched.pb") + assert.NoError(t, err, "could not read enriched file") + res := v1.EnrichedLaunchToolResponse{} + proto.Unmarshal(pbBytes, &res) + expectedExternalReferences := []cdx.ExternalReference{ + { + URL: fmt.Sprintf("%s/go/p/cloud.google.com%%2Fgo%%2Fcompute/v/v1.14.0", srv.URL), + Type: "other", + }, { + URL: fmt.Sprintf("%s/go/p/cloud.google.com%%2Fgo%%2Fcompute%%2Fmetadata/v/v0.2.3", srv.URL), + Type: "other", + }, { + URL: fmt.Sprintf("%s/go/p/github.com%%2FAzure%%2Fazure-pipeline-go/v/v0.2.3", srv.URL), + Type: "other", + }, + } + // ensure every component has a license attached to it + for _, finding := range res.Issues { + bom, err := cyclonedx.FromDracon(finding.RawIssue) + assert.NoError(t, err, "Could not read enriched cyclone dx info") + + externalReferences := []cdx.ExternalReference{} + + for _, component := range *bom.Components { + externalReferences = append(externalReferences, *component.ExternalReferences...) + } + assert.Equal(t, externalReferences, expectedExternalReferences) + } +} +func TestParseIssuesLicensesWritten(t *testing.T) { + dir, srv := setup(t) + defer srv.Close() + + licensesInEvidence = "false" + + // run enricher + run() assert.FileExists(t, dir+"/depsdevSAT.depsdev.enriched.pb", "file was not created") // load *enriched.pb @@ -112,20 +213,8 @@ func TestParseIssuesLicensesWritten(t *testing.T) { } func TestParseIssuesLicensesWrittenACcurateLicenses(t *testing.T) { - dir := prepareIssue() - - // setup server - response := Response{ - Version: Version{ - Licenses: []string{license}, - }, - } - svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - assert.Contains(t, r.URL.String(), "/_/s/go/p/") - json.NewEncoder(w).Encode(response) - })) - defer svr.Close() - depsdevBaseURL = svr.URL + dir, srv := setup(t) + defer srv.Close() licensesInEvidence = "true" run() From 4bd109fc9065e1ec72f0941d8b0fc6225c176b41 Mon Sep 17 00:00:00 2001 From: foobar Date: Wed, 18 Oct 2023 19:29:48 +0100 Subject: [PATCH 05/24] dependency track owner tagging --- .../consumers/dependency-track/README.md | 4 +- .../dependency-track/kustomization.yaml | 5 + components/consumers/dependency-track/main.go | 69 ++++++++++--- .../consumers/dependency-track/main_test.go | 97 +++++++++++++++++-- .../consumers/dependency-track/task.yaml | 6 +- components/enrichers/policy/main.go | 2 +- pkg/cyclonedx/cyclonedx.go | 1 + 7 files changed, 157 insertions(+), 27 deletions(-) diff --git a/components/consumers/dependency-track/README.md b/components/consumers/dependency-track/README.md index 41c391789..68cf6673d 100644 --- a/components/consumers/dependency-track/README.md +++ b/components/consumers/dependency-track/README.md @@ -2,8 +2,10 @@ This producer imports SBOM results from Dracon producers into [owasp/dependency-track](https://owasp.org/www-project-dependency-track/). It ignores all other results as dependency-track does not do vulnerability management and Dracon does not have any VEX producers yet. -You can use this producer to generate or keep up to date SBOMs for your projects. +You can use this consumer to generate or keep up to date SBOMs for your projects. +This consumer recognises the annotation from the codeowners enricher and will add a project tag with each username found in the codeowners annotations. +The tag format is `Owner:` ## Testing without Dracon diff --git a/components/consumers/dependency-track/kustomization.yaml b/components/consumers/dependency-track/kustomization.yaml index 91fad87de..c22776c41 100644 --- a/components/consumers/dependency-track/kustomization.yaml +++ b/components/consumers/dependency-track/kustomization.yaml @@ -33,6 +33,8 @@ patches: value: $(params.consumer-dependency-track-token) - name: consumer-dependency-track-project-uuid value: $(params.consumer-dependency-track-project-uuid) + - name: consumer-dependency-track-owner-annotation + value: $(params.consumer-dependency-track-owner-annotation) params: - name: consumer-dependency-track-api-url type: string @@ -44,6 +46,9 @@ patches: type: string - name: consumer-dependency-track-project-uuid type: string + - name: consumer-dependency-track-owner-annotation + type: string + default: Owner target: kind: Pipeline # Add anchors to Task. diff --git a/components/consumers/dependency-track/main.go b/components/consumers/dependency-track/main.go index bf503a073..a5dc8f64e 100644 --- a/components/consumers/dependency-track/main.go +++ b/components/consumers/dependency-track/main.go @@ -4,7 +4,9 @@ import ( "context" "encoding/base64" "flag" + "fmt" "log" + "strings" dtrack "github.com/DependencyTrack/client-go" "github.com/google/uuid" @@ -14,12 +16,13 @@ import ( ) var ( - authURL string - apiKey string - projectName string - projectVersion string - projectUUID string - client *dtrack.Client + authURL string + apiKey string + projectName string + projectVersion string + projectUUID string + client *dtrack.Client + ownerAnnotation string ) func init() { @@ -28,6 +31,7 @@ func init() { flag.StringVar(&projectName, "projectName", "", "dependency track project name") flag.StringVar(&projectUUID, "projectUUID", "", "dependency track project name") flag.StringVar(&projectVersion, "projectVersion", "", "dependency track project version") + flag.StringVar(&ownerAnnotation, "ownerAnnotation", "", "if this consumer is in running after any enricher that adds ownership annotations, then provide the annotation-key for this enricher so it can tag owners as tags") flag.Parse() } @@ -66,25 +70,38 @@ func main() { func uploadBOMSFromEnriched(responses []*v1.EnrichedLaunchToolResponse) ([]string, error) { var tokens []string for _, res := range responses { - var bomIssue *v1.Issue + var bomIssue *v1.EnrichedIssue for _, issue := range res.GetIssues() { if issue.GetRawIssue().GetCycloneDXSBOM() != "" && bomIssue == nil { - bomIssue = issue.GetRawIssue() - } else if bomIssue != nil && *bomIssue.CycloneDXSBOM != "" { - log.Fatalf("Tool response for tool %s is malformed, we expected a single issue with an SBOM as part of the tool, got something else instead", + bomIssue = issue + } else if bomIssue != nil && bomIssue.GetRawIssue().GetCycloneDXSBOM() != "" { + log.Printf("Tool response for tool %s is malformed, we expected a single issue with an SBOM as part of the tool, got something else instead", res.GetOriginalResults().GetToolName()) + continue } } - cdxbom, err := cyclonedx.FromDracon(bomIssue) + cdxbom, err := cyclonedx.FromDracon(bomIssue.GetRawIssue()) if err != nil { return tokens, err } - token, err := uploadBOM(bomIssue.GetCycloneDXSBOM(), cdxbom.Metadata.Component.Version) + token, err := uploadBOM(bomIssue.GetRawIssue().GetCycloneDXSBOM(), cdxbom.Metadata.Component.Version) if err != nil { log.Fatal("could not upload bom to dependency track, err:", err) } log.Println("upload token is", token) tokens = append(tokens, token) + if ownerAnnotation != "" { + log.Println("tagging owners") + owners := []string{} + for key, value := range bomIssue.Annotations { + if strings.Contains(key, ownerAnnotation) { + owners = append(owners, value) + } + } + if err := addOwnersTags(owners); err != nil { + log.Println("could not tag owners, err:", err) + } + } } return tokens, nil } @@ -97,8 +114,9 @@ func uploadBOMsFromRaw(responses []*v1.LaunchToolResponse) ([]string, error) { if *issue.CycloneDXSBOM != "" && bomIssue == nil { bomIssue = issue } else if bomIssue != nil && *bomIssue.CycloneDXSBOM != "" { - log.Fatalf("Tool response for tool %s is malformed, we expected a single issue with an SBOM as part of the tool, got multiple issues with sboms instead", + log.Printf("Tool response for tool %s is malformed, we expected a single issue with an SBOM as part of the tool, got multiple issues with sboms instead", res.GetToolName()) + continue } } cdxbom, err := cyclonedx.FromDracon(bomIssue) @@ -114,7 +132,30 @@ func uploadBOMsFromRaw(responses []*v1.LaunchToolResponse) ([]string, error) { } return tokens, nil } - +func addOwnersTags(owners []string) error { + // addOwnersTags expects a map of -: tagging owners + // it then adds to the projectUUID the owners in the following tag format: Owner: + uuid := uuid.MustParse(projectUUID) + project, err := client.Project.Get(context.Background(), uuid) + if err != nil { + log.Println("could not add project tags error getting project by uuid, err:", err) + return err + } + for _, owner := range owners { + found := false + for _, t := range project.Tags { + if t.Name == fmt.Sprintf("%s:%s", ownerAnnotation, owner) { + found = true + break + } + } + if !found { + project.Tags = append(project.Tags, dtrack.Tag{Name: fmt.Sprintf("%s:%s", ownerAnnotation, owner)}) + } + } + _, err = client.Project.Update(context.Background(), project) + return err +} func uploadBOM(bom string, projectVersion string) (string, error) { if projectVersion == "" { projectVersion = "Unknown" diff --git a/components/consumers/dependency-track/main_test.go b/components/consumers/dependency-track/main_test.go index d98bf250c..5c11840a6 100644 --- a/components/consumers/dependency-track/main_test.go +++ b/components/consumers/dependency-track/main_test.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "io" "io/ioutil" "net/http" "net/http/httptest" @@ -15,10 +16,10 @@ import ( ) func TestUploadBomsFromRaw(t *testing.T) { - projUIID := uuid.MustParse("7c78f6c9-b4b0-493c-a912-0bb0a4f221f1") + projUUID := uuid.MustParse("7c78f6c9-b4b0-493c-a912-0bb0a4f221f1") expectedRequest := dtrack.BOMUploadRequest{ ProjectName: "test", - ProjectUUID: &projUIID, + ProjectUUID: &projUUID, ProjectVersion: "2022-1", AutoCreate: false, BOM: "eyJib21Gb3JtYXQiOiJDeWNsb25lRFgiLCJzcGVjVmVyc2lvbiI6IjEuNCIsInNlcmlhbE51bWJlciI6InVybjp1dWlkOjNlNjcxNjg3LTM5NWItNDFmNS1hMzBmLWE1ODkyMWE2OWI3OSIsInZlcnNpb24iOjEsIm1ldGFkYXRhIjp7InRpbWVzdGFtcCI6IjIwMjEtMDEtMTBUMTI6MDA6MDBaIiwiY29tcG9uZW50Ijp7ImJvbS1yZWYiOiJhY21lLWFwcGxpY2F0aW9uIiwidHlwZSI6ImFwcGxpY2F0aW9uIiwibmFtZSI6IkFjbWUgQ2xvdWQgRXhhbXBsZSIsInZlcnNpb24iOiIyMDIyLTEifX0sInNlcnZpY2VzIjpbeyJib20tcmVmIjoiYXBpLWdhdGV3YXkiLCJwcm92aWRlciI6eyJuYW1lIjoiQWNtZSBJbmMiLCJ1cmwiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbSJdfSwiZ3JvdXAiOiJjb20uZXhhbXBsZSIsIm5hbWUiOiJBUEkgR2F0ZXdheSIsInZlcnNpb24iOiIyMDIyLTEiLCJkZXNjcmlwdGlvbiI6IkV4YW1wbGUgQVBJIEdhdGV3YXkiLCJlbmRwb2ludHMiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbS8iLCJodHRwczovL2V4YW1wbGUuY29tL2FwcCJdLCJhdXRoZW50aWNhdGVkIjpmYWxzZSwieC10cnVzdC1ib3VuZGFyeSI6dHJ1ZSwiZGF0YSI6W3siZmxvdyI6ImJpLWRpcmVjdGlvbmFsIiwiY2xhc3NpZmljYXRpb24iOiJQSUkifSx7ImZsb3ciOiJiaS1kaXJlY3Rpb25hbCIsImNsYXNzaWZpY2F0aW9uIjoiUElGSSJ9LHsiZmxvdyI6ImJpLWRpcmVjdGlvbmFsIiwiY2xhc3NpZmljYXRpb24iOiJQdWJsaWMifV0sImV4dGVybmFsUmVmZXJlbmNlcyI6W3sidXJsIjoiaHR0cDovL2V4YW1wbGUuY29tL2FwcC9zd2FnZ2VyIiwidHlwZSI6ImRvY3VtZW50YXRpb24ifV0sInNlcnZpY2VzIjpbeyJib20tcmVmIjoibXMtMS5leGFtcGxlLmNvbSIsInByb3ZpZGVyIjp7Im5hbWUiOiJBY21lIEluYyIsInVybCI6WyJodHRwczovL2V4YW1wbGUuY29tIl19LCJncm91cCI6ImNvbS5leGFtcGxlIiwibmFtZSI6Ik1pY3Jvc2VydmljZSAxIiwidmVyc2lvbiI6IjIwMjItMSIsImRlc2NyaXB0aW9uIjoiRXhhbXBsZSBNaWNyb3NlcnZpY2UiLCJlbmRwb2ludHMiOlsiaHR0cHM6Ly9tcy0xLmV4YW1wbGUuY29tIl0sImF1dGhlbnRpY2F0ZWQiOnRydWUsIngtdHJ1c3QtYm91bmRhcnkiOmZhbHNlLCJkYXRhIjpbeyJmbG93IjoiYmktZGlyZWN0aW9uYWwiLCJjbGFzc2lmaWNhdGlvbiI6IlBJSSJ9XSwiZXh0ZXJuYWxSZWZlcmVuY2VzIjpbeyJ1cmwiOiJodHRwczovL21zLTEuZXhhbXBsZS5jb20vc3dhZ2dlciIsInR5cGUiOiJkb2N1bWVudGF0aW9uIn1dfSx7ImJvbS1yZWYiOiJtcy0yLmV4YW1wbGUuY29tIiwicHJvdmlkZXIiOnsibmFtZSI6IkFjbWUgSW5jIiwidXJsIjpbImh0dHBzOi8vZXhhbXBsZS5jb20iXX0sImdyb3VwIjoiY29tLmV4YW1wbGUiLCJuYW1lIjoiTWljcm9zZXJ2aWNlIDIiLCJ2ZXJzaW9uIjoiMjAyMi0xIiwiZGVzY3JpcHRpb24iOiJFeGFtcGxlIE1pY3Jvc2VydmljZSIsImVuZHBvaW50cyI6WyJodHRwczovL21zLTIuZXhhbXBsZS5jb20iXSwiYXV0aGVudGljYXRlZCI6dHJ1ZSwieC10cnVzdC1ib3VuZGFyeSI6ZmFsc2UsImRhdGEiOlt7ImZsb3ciOiJiaS1kaXJlY3Rpb25hbCIsImNsYXNzaWZpY2F0aW9uIjoiUElGSSJ9XSwiZXh0ZXJuYWxSZWZlcmVuY2VzIjpbeyJ1cmwiOiJodHRwczovL21zLTIuZXhhbXBsZS5jb20vc3dhZ2dlciIsInR5cGUiOiJkb2N1bWVudGF0aW9uIn1dfSx7ImJvbS1yZWYiOiJtcy0zLmV4YW1wbGUuY29tIiwicHJvdmlkZXIiOnsibmFtZSI6IkFjbWUgSW5jIiwidXJsIjpbImh0dHBzOi8vZXhhbXBsZS5jb20iXX0sImdyb3VwIjoiY29tLmV4YW1wbGUiLCJuYW1lIjoiTWljcm9zZXJ2aWNlIDMiLCJ2ZXJzaW9uIjoiMjAyMi0xIiwiZGVzY3JpcHRpb24iOiJFeGFtcGxlIE1pY3Jvc2VydmljZSIsImVuZHBvaW50cyI6WyJodHRwczovL21zLTMuZXhhbXBsZS5jb20iXSwiYXV0aGVudGljYXRlZCI6dHJ1ZSwieC10cnVzdC1ib3VuZGFyeSI6ZmFsc2UsImRhdGEiOlt7ImZsb3ciOiJiaS1kaXJlY3Rpb25hbCIsImNsYXNzaWZpY2F0aW9uIjoiUHVibGljIn1dLCJleHRlcm5hbFJlZmVyZW5jZXMiOlt7InVybCI6Imh0dHBzOi8vbXMtMy5leGFtcGxlLmNvbS9zd2FnZ2VyIiwidHlwZSI6ImRvY3VtZW50YXRpb24ifV19LHsiYm9tLXJlZiI6Im1zLTEtcGdzcWwuZXhhbXBsZS5jb20iLCJncm91cCI6Im9yZy5wb3N0Z3Jlc3FsIiwibmFtZSI6IlBvc3RncmVzIiwidmVyc2lvbiI6IjE0LjEiLCJkZXNjcmlwdGlvbiI6IlBvc3RncmVzIGRhdGFiYXNlIGZvciBNaWNyb3NlcnZpY2UgIzEiLCJlbmRwb2ludHMiOlsiaHR0cHM6Ly9tcy0xLXBnc3FsLmV4YW1wbGUuY29tOjU0MzIiXSwiYXV0aGVudGljYXRlZCI6dHJ1ZSwieC10cnVzdC1ib3VuZGFyeSI6ZmFsc2UsImRhdGEiOlt7ImZsb3ciOiJiaS1kaXJlY3Rpb25hbCIsImNsYXNzaWZpY2F0aW9uIjoiUElJIn1dfSx7ImJvbS1yZWYiOiJzMy1leGFtcGxlLmFtYXpvbi5jb20iLCJncm91cCI6ImNvbS5hbWF6b24iLCJuYW1lIjoiUzMiLCJkZXNjcmlwdGlvbiI6IlMzIGJ1Y2tldCIsImVuZHBvaW50cyI6WyJodHRwczovL3MzLWV4YW1wbGUuYW1hem9uLmNvbSJdLCJhdXRoZW50aWNhdGVkIjp0cnVlLCJ4LXRydXN0LWJvdW5kYXJ5Ijp0cnVlLCJkYXRhIjpbeyJmbG93IjoiYmktZGlyZWN0aW9uYWwiLCJjbGFzc2lmaWNhdGlvbiI6IlB1YmxpYyJ9XX1dfV0sImRlcGVuZGVuY2llcyI6W3sicmVmIjoiYWNtZS1hcHBsaWNhdGlvbiIsImRlcGVuZHNPbiI6WyJhcGktZ2F0ZXdheSJdfSx7InJlZiI6ImFwaS1nYXRld2F5IiwiZGVwZW5kc09uIjpbIm1zLTEuZXhhbXBsZS5jb20iLCJtcy0yLmV4YW1wbGUuY29tIiwibXMtMy5leGFtcGxlLmNvbSJdfSx7InJlZiI6Im1zLTEuZXhhbXBsZS5jb20iLCJkZXBlbmRzT24iOlsibXMtMS1wZ3NxbC5leGFtcGxlLmNvbSJdfSx7InJlZiI6Im1zLTIuZXhhbXBsZS5jb20iLCJkZXBlbmRzT24iOltdfSx7InJlZiI6Im1zLTMuZXhhbXBsZS5jb20iLCJkZXBlbmRzT24iOlsiczMtZXhhbXBsZS5hbWF6b24uY29tIl19XX0=", @@ -32,11 +33,9 @@ func TestUploadBomsFromRaw(t *testing.T) { json.Unmarshal(body, &actualRequest) assert.Equal(t, expectedRequest, actualRequest) w.Write([]byte("{\"Token\":\"" + expectedToken + "\"}")) - w.WriteHeader(http.StatusOK) })) defer ts.Close() - - projectUUID = "7c78f6c9-b4b0-493c-a912-0bb0a4f221f1" + projectUUID = projUUID.String() apiKey = "test" projectName = "test" c, err := dtrack.NewClient(ts.URL, dtrack.WithAPIKey(apiKey)) @@ -56,15 +55,14 @@ func TestUploadBomsFromRaw(t *testing.T) { } func TestUploadBomsFromEnriched(t *testing.T) { - projUIID := uuid.MustParse("7c78f6c9-b4b0-493c-a912-0bb0a4f221f1") + projUUID := uuid.MustParse("7c78f6c9-b4b0-493c-a912-0bb0a4f221f1") expectedRequest := dtrack.BOMUploadRequest{ ProjectName: "test", - ProjectUUID: &projUIID, + ProjectUUID: &projUUID, ProjectVersion: "2022-1", AutoCreate: false, BOM: "eyJib21Gb3JtYXQiOiJDeWNsb25lRFgiLCJzcGVjVmVyc2lvbiI6IjEuNCIsInNlcmlhbE51bWJlciI6InVybjp1dWlkOjNlNjcxNjg3LTM5NWItNDFmNS1hMzBmLWE1ODkyMWE2OWI3OSIsInZlcnNpb24iOjEsIm1ldGFkYXRhIjp7InRpbWVzdGFtcCI6IjIwMjEtMDEtMTBUMTI6MDA6MDBaIiwiY29tcG9uZW50Ijp7ImJvbS1yZWYiOiJhY21lLWFwcGxpY2F0aW9uIiwidHlwZSI6ImFwcGxpY2F0aW9uIiwibmFtZSI6IkFjbWUgQ2xvdWQgRXhhbXBsZSIsInZlcnNpb24iOiIyMDIyLTEifX0sInNlcnZpY2VzIjpbeyJib20tcmVmIjoiYXBpLWdhdGV3YXkiLCJwcm92aWRlciI6eyJuYW1lIjoiQWNtZSBJbmMiLCJ1cmwiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbSJdfSwiZ3JvdXAiOiJjb20uZXhhbXBsZSIsIm5hbWUiOiJBUEkgR2F0ZXdheSIsInZlcnNpb24iOiIyMDIyLTEiLCJkZXNjcmlwdGlvbiI6IkV4YW1wbGUgQVBJIEdhdGV3YXkiLCJlbmRwb2ludHMiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbS8iLCJodHRwczovL2V4YW1wbGUuY29tL2FwcCJdLCJhdXRoZW50aWNhdGVkIjpmYWxzZSwieC10cnVzdC1ib3VuZGFyeSI6dHJ1ZSwiZGF0YSI6W3siZmxvdyI6ImJpLWRpcmVjdGlvbmFsIiwiY2xhc3NpZmljYXRpb24iOiJQSUkifSx7ImZsb3ciOiJiaS1kaXJlY3Rpb25hbCIsImNsYXNzaWZpY2F0aW9uIjoiUElGSSJ9LHsiZmxvdyI6ImJpLWRpcmVjdGlvbmFsIiwiY2xhc3NpZmljYXRpb24iOiJQdWJsaWMifV0sImV4dGVybmFsUmVmZXJlbmNlcyI6W3sidXJsIjoiaHR0cDovL2V4YW1wbGUuY29tL2FwcC9zd2FnZ2VyIiwidHlwZSI6ImRvY3VtZW50YXRpb24ifV0sInNlcnZpY2VzIjpbeyJib20tcmVmIjoibXMtMS5leGFtcGxlLmNvbSIsInByb3ZpZGVyIjp7Im5hbWUiOiJBY21lIEluYyIsInVybCI6WyJodHRwczovL2V4YW1wbGUuY29tIl19LCJncm91cCI6ImNvbS5leGFtcGxlIiwibmFtZSI6Ik1pY3Jvc2VydmljZSAxIiwidmVyc2lvbiI6IjIwMjItMSIsImRlc2NyaXB0aW9uIjoiRXhhbXBsZSBNaWNyb3NlcnZpY2UiLCJlbmRwb2ludHMiOlsiaHR0cHM6Ly9tcy0xLmV4YW1wbGUuY29tIl0sImF1dGhlbnRpY2F0ZWQiOnRydWUsIngtdHJ1c3QtYm91bmRhcnkiOmZhbHNlLCJkYXRhIjpbeyJmbG93IjoiYmktZGlyZWN0aW9uYWwiLCJjbGFzc2lmaWNhdGlvbiI6IlBJSSJ9XSwiZXh0ZXJuYWxSZWZlcmVuY2VzIjpbeyJ1cmwiOiJodHRwczovL21zLTEuZXhhbXBsZS5jb20vc3dhZ2dlciIsInR5cGUiOiJkb2N1bWVudGF0aW9uIn1dfSx7ImJvbS1yZWYiOiJtcy0yLmV4YW1wbGUuY29tIiwicHJvdmlkZXIiOnsibmFtZSI6IkFjbWUgSW5jIiwidXJsIjpbImh0dHBzOi8vZXhhbXBsZS5jb20iXX0sImdyb3VwIjoiY29tLmV4YW1wbGUiLCJuYW1lIjoiTWljcm9zZXJ2aWNlIDIiLCJ2ZXJzaW9uIjoiMjAyMi0xIiwiZGVzY3JpcHRpb24iOiJFeGFtcGxlIE1pY3Jvc2VydmljZSIsImVuZHBvaW50cyI6WyJodHRwczovL21zLTIuZXhhbXBsZS5jb20iXSwiYXV0aGVudGljYXRlZCI6dHJ1ZSwieC10cnVzdC1ib3VuZGFyeSI6ZmFsc2UsImRhdGEiOlt7ImZsb3ciOiJiaS1kaXJlY3Rpb25hbCIsImNsYXNzaWZpY2F0aW9uIjoiUElGSSJ9XSwiZXh0ZXJuYWxSZWZlcmVuY2VzIjpbeyJ1cmwiOiJodHRwczovL21zLTIuZXhhbXBsZS5jb20vc3dhZ2dlciIsInR5cGUiOiJkb2N1bWVudGF0aW9uIn1dfSx7ImJvbS1yZWYiOiJtcy0zLmV4YW1wbGUuY29tIiwicHJvdmlkZXIiOnsibmFtZSI6IkFjbWUgSW5jIiwidXJsIjpbImh0dHBzOi8vZXhhbXBsZS5jb20iXX0sImdyb3VwIjoiY29tLmV4YW1wbGUiLCJuYW1lIjoiTWljcm9zZXJ2aWNlIDMiLCJ2ZXJzaW9uIjoiMjAyMi0xIiwiZGVzY3JpcHRpb24iOiJFeGFtcGxlIE1pY3Jvc2VydmljZSIsImVuZHBvaW50cyI6WyJodHRwczovL21zLTMuZXhhbXBsZS5jb20iXSwiYXV0aGVudGljYXRlZCI6dHJ1ZSwieC10cnVzdC1ib3VuZGFyeSI6ZmFsc2UsImRhdGEiOlt7ImZsb3ciOiJiaS1kaXJlY3Rpb25hbCIsImNsYXNzaWZpY2F0aW9uIjoiUHVibGljIn1dLCJleHRlcm5hbFJlZmVyZW5jZXMiOlt7InVybCI6Imh0dHBzOi8vbXMtMy5leGFtcGxlLmNvbS9zd2FnZ2VyIiwidHlwZSI6ImRvY3VtZW50YXRpb24ifV19LHsiYm9tLXJlZiI6Im1zLTEtcGdzcWwuZXhhbXBsZS5jb20iLCJncm91cCI6Im9yZy5wb3N0Z3Jlc3FsIiwibmFtZSI6IlBvc3RncmVzIiwidmVyc2lvbiI6IjE0LjEiLCJkZXNjcmlwdGlvbiI6IlBvc3RncmVzIGRhdGFiYXNlIGZvciBNaWNyb3NlcnZpY2UgIzEiLCJlbmRwb2ludHMiOlsiaHR0cHM6Ly9tcy0xLXBnc3FsLmV4YW1wbGUuY29tOjU0MzIiXSwiYXV0aGVudGljYXRlZCI6dHJ1ZSwieC10cnVzdC1ib3VuZGFyeSI6ZmFsc2UsImRhdGEiOlt7ImZsb3ciOiJiaS1kaXJlY3Rpb25hbCIsImNsYXNzaWZpY2F0aW9uIjoiUElJIn1dfSx7ImJvbS1yZWYiOiJzMy1leGFtcGxlLmFtYXpvbi5jb20iLCJncm91cCI6ImNvbS5hbWF6b24iLCJuYW1lIjoiUzMiLCJkZXNjcmlwdGlvbiI6IlMzIGJ1Y2tldCIsImVuZHBvaW50cyI6WyJodHRwczovL3MzLWV4YW1wbGUuYW1hem9uLmNvbSJdLCJhdXRoZW50aWNhdGVkIjp0cnVlLCJ4LXRydXN0LWJvdW5kYXJ5Ijp0cnVlLCJkYXRhIjpbeyJmbG93IjoiYmktZGlyZWN0aW9uYWwiLCJjbGFzc2lmaWNhdGlvbiI6IlB1YmxpYyJ9XX1dfV0sImRlcGVuZGVuY2llcyI6W3sicmVmIjoiYWNtZS1hcHBsaWNhdGlvbiIsImRlcGVuZHNPbiI6WyJhcGktZ2F0ZXdheSJdfSx7InJlZiI6ImFwaS1nYXRld2F5IiwiZGVwZW5kc09uIjpbIm1zLTEuZXhhbXBsZS5jb20iLCJtcy0yLmV4YW1wbGUuY29tIiwibXMtMy5leGFtcGxlLmNvbSJdfSx7InJlZiI6Im1zLTEuZXhhbXBsZS5jb20iLCJkZXBlbmRzT24iOlsibXMtMS1wZ3NxbC5leGFtcGxlLmNvbSJdfSx7InJlZiI6Im1zLTIuZXhhbXBsZS5jb20iLCJkZXBlbmRzT24iOltdfSx7InJlZiI6Im1zLTMuZXhhbXBsZS5jb20iLCJkZXBlbmRzT24iOlsiczMtZXhhbXBsZS5hbWF6b24uY29tIl19XX0=", } - expectedToken := "7c78f6c9-token" ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { body, _ := ioutil.ReadAll(r.Body) @@ -72,11 +70,10 @@ func TestUploadBomsFromEnriched(t *testing.T) { json.Unmarshal(body, &actualRequest) assert.Equal(t, expectedRequest, actualRequest) w.Write([]byte("{\"Token\":\"" + expectedToken + "\"}")) - w.WriteHeader(http.StatusOK) })) defer ts.Close() - projectUUID = "7c78f6c9-b4b0-493c-a912-0bb0a4f221f1" + projectUUID = projUUID.String() apiKey = "test" projectName = "test" c, err := dtrack.NewClient(ts.URL, dtrack.WithAPIKey(apiKey)) @@ -100,6 +97,86 @@ func TestUploadBomsFromEnriched(t *testing.T) { assert.Nil(t, err) assert.Equal(t, tokens, []string{expectedToken}) } +func TestUploadBomsFromEnrichedWithOwners(t *testing.T) { + projUUID := uuid.MustParse("7c78f6c9-b4b0-493c-a912-0bb0a4f221f1") + expectedRequest := dtrack.BOMUploadRequest{ + ProjectName: "test", + ProjectUUID: &projUUID, + ProjectVersion: "2022-1", + AutoCreate: false, + BOM: "eyJib21Gb3JtYXQiOiJDeWNsb25lRFgiLCJzcGVjVmVyc2lvbiI6IjEuNCIsInNlcmlhbE51bWJlciI6InVybjp1dWlkOjNlNjcxNjg3LTM5NWItNDFmNS1hMzBmLWE1ODkyMWE2OWI3OSIsInZlcnNpb24iOjEsIm1ldGFkYXRhIjp7InRpbWVzdGFtcCI6IjIwMjEtMDEtMTBUMTI6MDA6MDBaIiwiY29tcG9uZW50Ijp7ImJvbS1yZWYiOiJhY21lLWFwcGxpY2F0aW9uIiwidHlwZSI6ImFwcGxpY2F0aW9uIiwibmFtZSI6IkFjbWUgQ2xvdWQgRXhhbXBsZSIsInZlcnNpb24iOiIyMDIyLTEifX0sInNlcnZpY2VzIjpbeyJib20tcmVmIjoiYXBpLWdhdGV3YXkiLCJwcm92aWRlciI6eyJuYW1lIjoiQWNtZSBJbmMiLCJ1cmwiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbSJdfSwiZ3JvdXAiOiJjb20uZXhhbXBsZSIsIm5hbWUiOiJBUEkgR2F0ZXdheSIsInZlcnNpb24iOiIyMDIyLTEiLCJkZXNjcmlwdGlvbiI6IkV4YW1wbGUgQVBJIEdhdGV3YXkiLCJlbmRwb2ludHMiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbS8iLCJodHRwczovL2V4YW1wbGUuY29tL2FwcCJdLCJhdXRoZW50aWNhdGVkIjpmYWxzZSwieC10cnVzdC1ib3VuZGFyeSI6dHJ1ZSwiZGF0YSI6W3siZmxvdyI6ImJpLWRpcmVjdGlvbmFsIiwiY2xhc3NpZmljYXRpb24iOiJQSUkifSx7ImZsb3ciOiJiaS1kaXJlY3Rpb25hbCIsImNsYXNzaWZpY2F0aW9uIjoiUElGSSJ9LHsiZmxvdyI6ImJpLWRpcmVjdGlvbmFsIiwiY2xhc3NpZmljYXRpb24iOiJQdWJsaWMifV0sImV4dGVybmFsUmVmZXJlbmNlcyI6W3sidXJsIjoiaHR0cDovL2V4YW1wbGUuY29tL2FwcC9zd2FnZ2VyIiwidHlwZSI6ImRvY3VtZW50YXRpb24ifV0sInNlcnZpY2VzIjpbeyJib20tcmVmIjoibXMtMS5leGFtcGxlLmNvbSIsInByb3ZpZGVyIjp7Im5hbWUiOiJBY21lIEluYyIsInVybCI6WyJodHRwczovL2V4YW1wbGUuY29tIl19LCJncm91cCI6ImNvbS5leGFtcGxlIiwibmFtZSI6Ik1pY3Jvc2VydmljZSAxIiwidmVyc2lvbiI6IjIwMjItMSIsImRlc2NyaXB0aW9uIjoiRXhhbXBsZSBNaWNyb3NlcnZpY2UiLCJlbmRwb2ludHMiOlsiaHR0cHM6Ly9tcy0xLmV4YW1wbGUuY29tIl0sImF1dGhlbnRpY2F0ZWQiOnRydWUsIngtdHJ1c3QtYm91bmRhcnkiOmZhbHNlLCJkYXRhIjpbeyJmbG93IjoiYmktZGlyZWN0aW9uYWwiLCJjbGFzc2lmaWNhdGlvbiI6IlBJSSJ9XSwiZXh0ZXJuYWxSZWZlcmVuY2VzIjpbeyJ1cmwiOiJodHRwczovL21zLTEuZXhhbXBsZS5jb20vc3dhZ2dlciIsInR5cGUiOiJkb2N1bWVudGF0aW9uIn1dfSx7ImJvbS1yZWYiOiJtcy0yLmV4YW1wbGUuY29tIiwicHJvdmlkZXIiOnsibmFtZSI6IkFjbWUgSW5jIiwidXJsIjpbImh0dHBzOi8vZXhhbXBsZS5jb20iXX0sImdyb3VwIjoiY29tLmV4YW1wbGUiLCJuYW1lIjoiTWljcm9zZXJ2aWNlIDIiLCJ2ZXJzaW9uIjoiMjAyMi0xIiwiZGVzY3JpcHRpb24iOiJFeGFtcGxlIE1pY3Jvc2VydmljZSIsImVuZHBvaW50cyI6WyJodHRwczovL21zLTIuZXhhbXBsZS5jb20iXSwiYXV0aGVudGljYXRlZCI6dHJ1ZSwieC10cnVzdC1ib3VuZGFyeSI6ZmFsc2UsImRhdGEiOlt7ImZsb3ciOiJiaS1kaXJlY3Rpb25hbCIsImNsYXNzaWZpY2F0aW9uIjoiUElGSSJ9XSwiZXh0ZXJuYWxSZWZlcmVuY2VzIjpbeyJ1cmwiOiJodHRwczovL21zLTIuZXhhbXBsZS5jb20vc3dhZ2dlciIsInR5cGUiOiJkb2N1bWVudGF0aW9uIn1dfSx7ImJvbS1yZWYiOiJtcy0zLmV4YW1wbGUuY29tIiwicHJvdmlkZXIiOnsibmFtZSI6IkFjbWUgSW5jIiwidXJsIjpbImh0dHBzOi8vZXhhbXBsZS5jb20iXX0sImdyb3VwIjoiY29tLmV4YW1wbGUiLCJuYW1lIjoiTWljcm9zZXJ2aWNlIDMiLCJ2ZXJzaW9uIjoiMjAyMi0xIiwiZGVzY3JpcHRpb24iOiJFeGFtcGxlIE1pY3Jvc2VydmljZSIsImVuZHBvaW50cyI6WyJodHRwczovL21zLTMuZXhhbXBsZS5jb20iXSwiYXV0aGVudGljYXRlZCI6dHJ1ZSwieC10cnVzdC1ib3VuZGFyeSI6ZmFsc2UsImRhdGEiOlt7ImZsb3ciOiJiaS1kaXJlY3Rpb25hbCIsImNsYXNzaWZpY2F0aW9uIjoiUHVibGljIn1dLCJleHRlcm5hbFJlZmVyZW5jZXMiOlt7InVybCI6Imh0dHBzOi8vbXMtMy5leGFtcGxlLmNvbS9zd2FnZ2VyIiwidHlwZSI6ImRvY3VtZW50YXRpb24ifV19LHsiYm9tLXJlZiI6Im1zLTEtcGdzcWwuZXhhbXBsZS5jb20iLCJncm91cCI6Im9yZy5wb3N0Z3Jlc3FsIiwibmFtZSI6IlBvc3RncmVzIiwidmVyc2lvbiI6IjE0LjEiLCJkZXNjcmlwdGlvbiI6IlBvc3RncmVzIGRhdGFiYXNlIGZvciBNaWNyb3NlcnZpY2UgIzEiLCJlbmRwb2ludHMiOlsiaHR0cHM6Ly9tcy0xLXBnc3FsLmV4YW1wbGUuY29tOjU0MzIiXSwiYXV0aGVudGljYXRlZCI6dHJ1ZSwieC10cnVzdC1ib3VuZGFyeSI6ZmFsc2UsImRhdGEiOlt7ImZsb3ciOiJiaS1kaXJlY3Rpb25hbCIsImNsYXNzaWZpY2F0aW9uIjoiUElJIn1dfSx7ImJvbS1yZWYiOiJzMy1leGFtcGxlLmFtYXpvbi5jb20iLCJncm91cCI6ImNvbS5hbWF6b24iLCJuYW1lIjoiUzMiLCJkZXNjcmlwdGlvbiI6IlMzIGJ1Y2tldCIsImVuZHBvaW50cyI6WyJodHRwczovL3MzLWV4YW1wbGUuYW1hem9uLmNvbSJdLCJhdXRoZW50aWNhdGVkIjp0cnVlLCJ4LXRydXN0LWJvdW5kYXJ5Ijp0cnVlLCJkYXRhIjpbeyJmbG93IjoiYmktZGlyZWN0aW9uYWwiLCJjbGFzc2lmaWNhdGlvbiI6IlB1YmxpYyJ9XX1dfV0sImRlcGVuZGVuY2llcyI6W3sicmVmIjoiYWNtZS1hcHBsaWNhdGlvbiIsImRlcGVuZHNPbiI6WyJhcGktZ2F0ZXdheSJdfSx7InJlZiI6ImFwaS1nYXRld2F5IiwiZGVwZW5kc09uIjpbIm1zLTEuZXhhbXBsZS5jb20iLCJtcy0yLmV4YW1wbGUuY29tIiwibXMtMy5leGFtcGxlLmNvbSJdfSx7InJlZiI6Im1zLTEuZXhhbXBsZS5jb20iLCJkZXBlbmRzT24iOlsibXMtMS1wZ3NxbC5leGFtcGxlLmNvbSJdfSx7InJlZiI6Im1zLTIuZXhhbXBsZS5jb20iLCJkZXBlbmRzT24iOltdfSx7InJlZiI6Im1zLTMuZXhhbXBsZS5jb20iLCJkZXBlbmRzT24iOlsiczMtZXhhbXBsZS5hbWF6b24uY29tIl19XX0=", + } + expectedProjectUpdate := dtrack.Project{ + UUID: projUUID, + Name: "fooProj", + PURL: "pkg://npm/xyz/asdf@v1.2.2", + Properties: []dtrack.ProjectProperty(nil), + Tags: []dtrack.Tag{ + {Name: "foo:bar"}, + {Name: "Owner:foo"}, + {Name: "Owner:bar"}}, + } + expectedToken := "7c78f6c9-token" + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + + if r.URL.String() == "/api/v1/bom" { + body, _ := io.ReadAll(r.Body) + var actualRequest dtrack.BOMUploadRequest + json.Unmarshal(body, &actualRequest) + assert.Equal(t, expectedRequest, actualRequest) + w.Write([]byte("{\"Token\":\"" + expectedToken + "\"}")) + } else if r.URL.String() == "/api/v1/project/7c78f6c9-b4b0-493c-a912-0bb0a4f221f1" { + project := dtrack.Project{ + UUID: projUUID, + Name: "fooProj", + PURL: "pkg://npm/xyz/asdf@v1.2.2", + Tags: []dtrack.Tag{{Name: "foo:bar"}, {Name: "Owner:foo"}}, + } + res, _ := json.Marshal(project) + w.Write(res) + w.WriteHeader(http.StatusOK) + } else if r.URL.String() == "/api/v1/project" && r.Method == http.MethodPost { + body, _ := io.ReadAll(r.Body) + var req dtrack.Project + json.Unmarshal(body, &req) + assert.Equal(t, req.Tags, expectedProjectUpdate.Tags) + } else { + assert.Fail(t, r.URL.String()) + } //if r.URL.String() == "" + })) + defer ts.Close() + + projectUUID = projUUID.String() + apiKey = "test" + projectName = "test" + c, err := dtrack.NewClient(ts.URL, dtrack.WithAPIKey(apiKey)) + assert.Nil(t, err) + + client = c + issues, err := cyclonedx.ToDracon([]byte(saasBOM), "json") + + assert.Nil(t, err) + ltr := v1.LaunchToolResponse{ + ToolName: "SAT", + Issues: issues, + } + eltr := v1.EnrichedLaunchToolResponse{ + OriginalResults: <r, + Issues: []*v1.EnrichedIssue{ + { + RawIssue: issues[0], + Annotations: map[string]string{ + "Owner-0": "foo", + "Owner-1": "bar", + }, + }, + }, + } + ownerAnnotation = "Owner" + tokens, err := uploadBOMSFromEnriched([]*v1.EnrichedLaunchToolResponse{&eltr}) + assert.Nil(t, err) + assert.Equal(t, tokens, []string{expectedToken}) +} const saasBOM = `{ "bomFormat": "CycloneDX", diff --git a/components/consumers/dependency-track/task.yaml b/components/consumers/dependency-track/task.yaml index ccf4e2d4d..7ea3ebd41 100644 --- a/components/consumers/dependency-track/task.yaml +++ b/components/consumers/dependency-track/task.yaml @@ -17,6 +17,9 @@ spec: type: string - name: consumer-dependency-track-project-uuid type: string + - name: consumer-dependency-track-owner-annotation + type: string + default: "Owner" workspaces: - name: source-code-ws description: The workspace containing the source-code to scan. @@ -31,5 +34,6 @@ spec: "-apiKey", "$(params.consumer-dependency-track-token)", "-projectName", "$(params.consumer-dependency-track-project-name)", "-projectVersion", "$(params.consumer-dependency-track-project-version)", - "-projectUUID", "$(params.consumer-dependency-track-project-uuid)" + "-projectUUID", "$(params.consumer-dependency-track-project-uuid)", + "-ownerAnnotation","$(params.consumer-dependency-track-owner-annotation)" ] diff --git a/components/enrichers/policy/main.go b/components/enrichers/policy/main.go index 21a072dc0..f0119d8e1 100644 --- a/components/enrichers/policy/main.go +++ b/components/enrichers/policy/main.go @@ -99,7 +99,7 @@ func run() { log.Fatal(err) } } else { - log.Println("no enriched issues were created") + log.Println("no enriched issues were created for", r.GetToolName()) } if len(r.GetIssues()) > 0 { scanStartTime := r.GetScanInfo().GetScanStartTime().AsTime() diff --git a/pkg/cyclonedx/cyclonedx.go b/pkg/cyclonedx/cyclonedx.go index c3bc3ce9a..82e7eaf86 100644 --- a/pkg/cyclonedx/cyclonedx.go +++ b/pkg/cyclonedx/cyclonedx.go @@ -39,6 +39,7 @@ func ToDracon(inFile []byte, format string) ([]*v1.Issue, error) { } else { target = bom.Metadata.Component.PackageURL } + return []*v1.Issue{ { CycloneDXSBOM: &result, From 4e8a96d43dd71dd20c8f46414db53bfb3aa01233 Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:11:56 +0100 Subject: [PATCH 06/24] Update components/consumers/dependency-track/main.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/consumers/dependency-track/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/consumers/dependency-track/main.go b/components/consumers/dependency-track/main.go index a5dc8f64e..2b704147e 100644 --- a/components/consumers/dependency-track/main.go +++ b/components/consumers/dependency-track/main.go @@ -132,6 +132,7 @@ func uploadBOMsFromRaw(responses []*v1.LaunchToolResponse) ([]string, error) { } return tokens, nil } + func addOwnersTags(owners []string) error { // addOwnersTags expects a map of -: tagging owners // it then adds to the projectUUID the owners in the following tag format: Owner: From c6ed2a196353ae3c0fdb99e4d050184cad965672 Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:12:23 +0100 Subject: [PATCH 07/24] Update components/consumers/dependency-track/main_test.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/consumers/dependency-track/main_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/consumers/dependency-track/main_test.go b/components/consumers/dependency-track/main_test.go index 5c11840a6..e9fa5d704 100644 --- a/components/consumers/dependency-track/main_test.go +++ b/components/consumers/dependency-track/main_test.go @@ -97,6 +97,7 @@ func TestUploadBomsFromEnriched(t *testing.T) { assert.Nil(t, err) assert.Equal(t, tokens, []string{expectedToken}) } + func TestUploadBomsFromEnrichedWithOwners(t *testing.T) { projUUID := uuid.MustParse("7c78f6c9-b4b0-493c-a912-0bb0a4f221f1") expectedRequest := dtrack.BOMUploadRequest{ From da7c9028ed0948579ec4c6bfab3dc8c2eef100c3 Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:12:32 +0100 Subject: [PATCH 08/24] Update components/consumers/dependency-track/main_test.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/consumers/dependency-track/main_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/consumers/dependency-track/main_test.go b/components/consumers/dependency-track/main_test.go index e9fa5d704..de5107b21 100644 --- a/components/consumers/dependency-track/main_test.go +++ b/components/consumers/dependency-track/main_test.go @@ -115,7 +115,8 @@ func TestUploadBomsFromEnrichedWithOwners(t *testing.T) { Tags: []dtrack.Tag{ {Name: "foo:bar"}, {Name: "Owner:foo"}, - {Name: "Owner:bar"}}, + {Name: "Owner:bar"}, + }, } expectedToken := "7c78f6c9-token" ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { From a71558bec9a743f778d90c107c7f50ffe767bbef Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:12:40 +0100 Subject: [PATCH 09/24] Update components/consumers/dependency-track/main_test.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/consumers/dependency-track/main_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/components/consumers/dependency-track/main_test.go b/components/consumers/dependency-track/main_test.go index de5107b21..5ad4a9879 100644 --- a/components/consumers/dependency-track/main_test.go +++ b/components/consumers/dependency-track/main_test.go @@ -120,7 +120,6 @@ func TestUploadBomsFromEnrichedWithOwners(t *testing.T) { } expectedToken := "7c78f6c9-token" ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.URL.String() == "/api/v1/bom" { body, _ := io.ReadAll(r.Body) var actualRequest dtrack.BOMUploadRequest From 0cb0d142f729eaa0ba28c2d304a3e65f1e183e10 Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:12:49 +0100 Subject: [PATCH 10/24] Update components/consumers/dependency-track/main_test.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/consumers/dependency-track/main_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/consumers/dependency-track/main_test.go b/components/consumers/dependency-track/main_test.go index 5ad4a9879..f94ee48bf 100644 --- a/components/consumers/dependency-track/main_test.go +++ b/components/consumers/dependency-track/main_test.go @@ -143,7 +143,7 @@ func TestUploadBomsFromEnrichedWithOwners(t *testing.T) { assert.Equal(t, req.Tags, expectedProjectUpdate.Tags) } else { assert.Fail(t, r.URL.String()) - } //if r.URL.String() == "" + } // if r.URL.String() == "" })) defer ts.Close() From 887253767bc8ccc41cdc4e596df7c49e8f42f0ea Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:13:03 +0100 Subject: [PATCH 11/24] Update components/consumers/dependency-track/main.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/consumers/dependency-track/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/consumers/dependency-track/main.go b/components/consumers/dependency-track/main.go index 2b704147e..acce7371a 100644 --- a/components/consumers/dependency-track/main.go +++ b/components/consumers/dependency-track/main.go @@ -133,6 +133,7 @@ func uploadBOMsFromRaw(responses []*v1.LaunchToolResponse) ([]string, error) { return tokens, nil } + func addOwnersTags(owners []string) error { // addOwnersTags expects a map of -: tagging owners // it then adds to the projectUUID the owners in the following tag format: Owner: From 08ea1a35f4fe9119d5eb08bb50b614d19b2cd5c3 Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:13:35 +0100 Subject: [PATCH 12/24] Update components/consumers/dependency-track/main_test.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/consumers/dependency-track/main_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/consumers/dependency-track/main_test.go b/components/consumers/dependency-track/main_test.go index f94ee48bf..72baea673 100644 --- a/components/consumers/dependency-track/main_test.go +++ b/components/consumers/dependency-track/main_test.go @@ -98,6 +98,7 @@ func TestUploadBomsFromEnriched(t *testing.T) { assert.Equal(t, tokens, []string{expectedToken}) } + func TestUploadBomsFromEnrichedWithOwners(t *testing.T) { projUUID := uuid.MustParse("7c78f6c9-b4b0-493c-a912-0bb0a4f221f1") expectedRequest := dtrack.BOMUploadRequest{ From 73deb59c229b5e9a108879811c74a70cb10c9d1e Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:13:44 +0100 Subject: [PATCH 13/24] Update components/enrichers/depsdev/main_test.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/enrichers/depsdev/main_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/enrichers/depsdev/main_test.go b/components/enrichers/depsdev/main_test.go index 875b4a8f9..4a329896c 100644 --- a/components/enrichers/depsdev/main_test.go +++ b/components/enrichers/depsdev/main_test.go @@ -104,6 +104,7 @@ func setup(t *testing.T) (string, *httptest.Server) { depsdevBaseURL = srv.URL return dir, srv } + func TestParseIssuesDepsDevScoreCardInfoWritten(t *testing.T) { dir, srv := setup(t) defer srv.Close() From 341ba685d3a336ed6a28eaba73c2d44ea1a14f89 Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:14:38 +0100 Subject: [PATCH 14/24] Update components/enrichers/depsdev/main_test.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/enrichers/depsdev/main_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/enrichers/depsdev/main_test.go b/components/enrichers/depsdev/main_test.go index 4a329896c..a41843fba 100644 --- a/components/enrichers/depsdev/main_test.go +++ b/components/enrichers/depsdev/main_test.go @@ -143,6 +143,7 @@ func TestParseIssuesDepsDevScoreCardInfoWritten(t *testing.T) { assert.Equal(t, externalReferences, expectedExternalReferences) } } + func TestParseIssuesDepsDevExternalReferenceLinksWritten(t *testing.T) { dir, srv := setup(t) defer srv.Close() From 1e54471bdbaf716e5cdf324c3f9f6deae4f73d39 Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:14:45 +0100 Subject: [PATCH 15/24] Update components/enrichers/depsdev/main_test.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/enrichers/depsdev/main_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/enrichers/depsdev/main_test.go b/components/enrichers/depsdev/main_test.go index a41843fba..56a693293 100644 --- a/components/enrichers/depsdev/main_test.go +++ b/components/enrichers/depsdev/main_test.go @@ -105,6 +105,7 @@ func setup(t *testing.T) (string, *httptest.Server) { return dir, srv } + func TestParseIssuesDepsDevScoreCardInfoWritten(t *testing.T) { dir, srv := setup(t) defer srv.Close() From 38115f8b3a5ea458a5b517639862eed6efa27224 Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:14:53 +0100 Subject: [PATCH 16/24] Update components/enrichers/depsdev/main_test.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/enrichers/depsdev/main_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/enrichers/depsdev/main_test.go b/components/enrichers/depsdev/main_test.go index 56a693293..dddbdeb5c 100644 --- a/components/enrichers/depsdev/main_test.go +++ b/components/enrichers/depsdev/main_test.go @@ -183,6 +183,7 @@ func TestParseIssuesDepsDevExternalReferenceLinksWritten(t *testing.T) { assert.Equal(t, externalReferences, expectedExternalReferences) } } + func TestParseIssuesLicensesWritten(t *testing.T) { dir, srv := setup(t) defer srv.Close() From e23bf7b47ac0eb687c5ee8f307f537b3ad795fa2 Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:15:19 +0100 Subject: [PATCH 17/24] Update components/enrichers/depsdev/main_test.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/enrichers/depsdev/main_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/enrichers/depsdev/main_test.go b/components/enrichers/depsdev/main_test.go index dddbdeb5c..7625ee1fe 100644 --- a/components/enrichers/depsdev/main_test.go +++ b/components/enrichers/depsdev/main_test.go @@ -145,6 +145,7 @@ func TestParseIssuesDepsDevScoreCardInfoWritten(t *testing.T) { } } + func TestParseIssuesDepsDevExternalReferenceLinksWritten(t *testing.T) { dir, srv := setup(t) defer srv.Close() From bcff58bf45059e482ede42f9946c6b4f92f1f43d Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:15:28 +0100 Subject: [PATCH 18/24] Update components/enrichers/depsdev/main_test.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/enrichers/depsdev/main_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/enrichers/depsdev/main_test.go b/components/enrichers/depsdev/main_test.go index 7625ee1fe..7aae60287 100644 --- a/components/enrichers/depsdev/main_test.go +++ b/components/enrichers/depsdev/main_test.go @@ -185,6 +185,7 @@ func TestParseIssuesDepsDevExternalReferenceLinksWritten(t *testing.T) { } } + func TestParseIssuesLicensesWritten(t *testing.T) { dir, srv := setup(t) defer srv.Close() From ac3a3be61137f7ab944076ba9b971a6088c8d63a Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:15:40 +0100 Subject: [PATCH 19/24] Update components/consumers/dependency-track/main_test.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/consumers/dependency-track/main_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/consumers/dependency-track/main_test.go b/components/consumers/dependency-track/main_test.go index 72baea673..1e2ba7da8 100644 --- a/components/consumers/dependency-track/main_test.go +++ b/components/consumers/dependency-track/main_test.go @@ -99,6 +99,7 @@ func TestUploadBomsFromEnriched(t *testing.T) { } + func TestUploadBomsFromEnrichedWithOwners(t *testing.T) { projUUID := uuid.MustParse("7c78f6c9-b4b0-493c-a912-0bb0a4f221f1") expectedRequest := dtrack.BOMUploadRequest{ From 2eca5da4ab156caaa2b5f4a65cbe788fff70f183 Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:15:51 +0100 Subject: [PATCH 20/24] Update components/consumers/dependency-track/main.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/consumers/dependency-track/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/consumers/dependency-track/main.go b/components/consumers/dependency-track/main.go index acce7371a..382042e65 100644 --- a/components/consumers/dependency-track/main.go +++ b/components/consumers/dependency-track/main.go @@ -134,6 +134,7 @@ func uploadBOMsFromRaw(responses []*v1.LaunchToolResponse) ([]string, error) { } + func addOwnersTags(owners []string) error { // addOwnersTags expects a map of -: tagging owners // it then adds to the projectUUID the owners in the following tag format: Owner: From ad3de34e22b5798784ac0b1bc22c9521427583f3 Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:19:28 +0100 Subject: [PATCH 21/24] Update components/consumers/dependency-track/main_test.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/consumers/dependency-track/main_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/consumers/dependency-track/main_test.go b/components/consumers/dependency-track/main_test.go index 1e2ba7da8..ea1a61c47 100644 --- a/components/consumers/dependency-track/main_test.go +++ b/components/consumers/dependency-track/main_test.go @@ -100,6 +100,7 @@ func TestUploadBomsFromEnriched(t *testing.T) { + func TestUploadBomsFromEnrichedWithOwners(t *testing.T) { projUUID := uuid.MustParse("7c78f6c9-b4b0-493c-a912-0bb0a4f221f1") expectedRequest := dtrack.BOMUploadRequest{ From f68e8fae83820181aac61d35e6243f3a4ba090be Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:19:45 +0100 Subject: [PATCH 22/24] Update components/consumers/dependency-track/main.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/consumers/dependency-track/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/consumers/dependency-track/main.go b/components/consumers/dependency-track/main.go index 382042e65..25fd36e6c 100644 --- a/components/consumers/dependency-track/main.go +++ b/components/consumers/dependency-track/main.go @@ -135,6 +135,7 @@ func uploadBOMsFromRaw(responses []*v1.LaunchToolResponse) ([]string, error) { + func addOwnersTags(owners []string) error { // addOwnersTags expects a map of -: tagging owners // it then adds to the projectUUID the owners in the following tag format: Owner: From a2ce9abd8a03b8e2001652480ab94d29cae47cca Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:23:49 +0100 Subject: [PATCH 23/24] Update components/consumers/dependency-track/main.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/consumers/dependency-track/main.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/components/consumers/dependency-track/main.go b/components/consumers/dependency-track/main.go index 25fd36e6c..2b704147e 100644 --- a/components/consumers/dependency-track/main.go +++ b/components/consumers/dependency-track/main.go @@ -133,9 +133,6 @@ func uploadBOMsFromRaw(responses []*v1.LaunchToolResponse) ([]string, error) { return tokens, nil } - - - func addOwnersTags(owners []string) error { // addOwnersTags expects a map of -: tagging owners // it then adds to the projectUUID the owners in the following tag format: Owner: From 2d5cbdc916ed0f4b811096b9b967df9abba4b9a0 Mon Sep 17 00:00:00 2001 From: Spyros Date: Wed, 18 Oct 2023 23:23:56 +0100 Subject: [PATCH 24/24] Update components/consumers/dependency-track/main_test.go Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- components/consumers/dependency-track/main_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/components/consumers/dependency-track/main_test.go b/components/consumers/dependency-track/main_test.go index ea1a61c47..f94ee48bf 100644 --- a/components/consumers/dependency-track/main_test.go +++ b/components/consumers/dependency-track/main_test.go @@ -98,9 +98,6 @@ func TestUploadBomsFromEnriched(t *testing.T) { assert.Equal(t, tokens, []string{expectedToken}) } - - - func TestUploadBomsFromEnrichedWithOwners(t *testing.T) { projUUID := uuid.MustParse("7c78f6c9-b4b0-493c-a912-0bb0a4f221f1") expectedRequest := dtrack.BOMUploadRequest{