Skip to content

Commit

Permalink
change hasSBOMList to filter out deps.dev, add filter based on client…
Browse files Browse the repository at this point in the history
… usage

Signed-off-by: pxp928 <[email protected]>
  • Loading branch information
pxp928 committed Oct 18, 2024
1 parent 1a04f13 commit d2e2988
Show file tree
Hide file tree
Showing 9 changed files with 267 additions and 191 deletions.
310 changes: 175 additions & 135 deletions pkg/assembler/backends/ent/backend/sbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,17 @@ import (
"github.com/guacsec/guac/pkg/assembler/backends/ent/predicate"
"github.com/guacsec/guac/pkg/assembler/backends/helper"
"github.com/guacsec/guac/pkg/assembler/graphql/model"
"github.com/guacsec/guac/pkg/handler/collector/deps_dev"
"github.com/pkg/errors"
"github.com/vektah/gqlparser/v2/gqlerror"
)

const (
nodeIncludeSoftware = "edges.node.includedSoftware"
nodeIncludeDependencies = "edges.node.includedDependencies"
nodeIncludeOccurrences = "edges.node.includedOccurrences"
)

func hasSBOMGlobalID(id string) string {
return toGlobalID(billofmaterials.Table, id)
}
Expand All @@ -47,6 +54,24 @@ func bulkHasSBOMGlobalID(ids []string) []string {
}

func (b *EntBackend) HasSBOMList(ctx context.Context, spec model.HasSBOMSpec, after *string, first *int) (*model.HasSBOMConnection, error) {

var outputIncludeSoftware bool
var outputIncludeDependencies bool
var outputIncludedOccurrences bool
fields := helper.GetPreloads(ctx)

for _, f := range fields {
if f == nodeIncludeSoftware {
outputIncludeSoftware = true
}
if f == nodeIncludeDependencies {
outputIncludeDependencies = true
}
if f == nodeIncludeOccurrences {
outputIncludedOccurrences = true
}
}

var afterCursor *entgql.Cursor[uuid.UUID]

if after != nil {
Expand Down Expand Up @@ -106,153 +131,162 @@ func (b *EntBackend) HasSBOMList(ctx context.Context, spec model.HasSBOMSpec, af
var includedPackages []*ent.PackageVersion
var includedArtifacts []*ent.Artifact

depsChan := make(chan depResult, 1)
occursChan := make(chan occurResult, 1)
pkgVerChan := make(chan pkgVersionResult, 1)
artChan := make(chan artResult, 1)
var depsChan chan depResult
var occursChan chan occurResult
var pkgVerChan chan pkgVersionResult
var artChan chan artResult

sbomID := foundSBOM.Cursor.ID.String()

// query included packages

go func(ctx context.Context, b *EntBackend, sbomID string, first int, pkgChan chan<- pkgVersionResult) {
var afterCursor *entgql.Cursor[uuid.UUID]
defer close(pkgChan)
for {
pkgConn, err := b.client.PackageVersion.Query().
Where(packageversion.HasIncludedInSbomsWith([]predicate.BillOfMaterials{
optionalPredicate(&sbomID, IDEQ)}...)).
WithName(func(q *ent.PackageNameQuery) {}).Paginate(ctx, afterCursor, &first, nil, nil)
if err != nil {
pkgChan <- pkgVersionResult{pkgVersions: nil,
pkgVerErr: fmt.Errorf("failed included package query for hasSBOM with error: %w", err)}
}

// if not found break
if pkgConn == nil {
break
}

var paginatedPkgs []*ent.PackageVersion
for _, edge := range pkgConn.Edges {
paginatedPkgs = append(paginatedPkgs, edge.Node)
}

pkgChan <- pkgVersionResult{pkgVersions: paginatedPkgs, pkgVerErr: nil}

if !pkgConn.PageInfo.HasNextPage {
break
}
afterCursor = pkgConn.PageInfo.EndCursor
}
}(ctx, b, sbomID, includedFirst, pkgVerChan)

// query included artifacts
go func(ctx context.Context, b *EntBackend, sbomID string, first int, artChan chan<- artResult) {
var afterCursor *entgql.Cursor[uuid.UUID]
defer close(artChan)
for {
artConn, err := b.client.Artifact.Query().
Where(artifact.HasIncludedInSbomsWith([]predicate.BillOfMaterials{
optionalPredicate(&sbomID, IDEQ)}...)).Paginate(ctx, afterCursor, &first, nil, nil)

if err != nil {
artChan <- artResult{arts: nil,
artErr: fmt.Errorf("failed included artifacts query for hasSBOM with error: %w", err)}
}

// if not found break
if artConn == nil {
break
}

var paginatedArts []*ent.Artifact
for _, edge := range artConn.Edges {
paginatedArts = append(paginatedArts, edge.Node)
if outputIncludeSoftware {
pkgVerChan = make(chan pkgVersionResult, 1)
artChan = make(chan artResult, 1)
go func(ctx context.Context, b *EntBackend, sbomID string, first int, pkgChan chan<- pkgVersionResult) {
var afterCursor *entgql.Cursor[uuid.UUID]
defer close(pkgChan)
for {
pkgConn, err := b.client.PackageVersion.Query().
Where(packageversion.HasIncludedInSbomsWith([]predicate.BillOfMaterials{
optionalPredicate(&sbomID, IDEQ)}...)).
WithName(func(q *ent.PackageNameQuery) {}).Paginate(ctx, afterCursor, &first, nil, nil)
if err != nil {
pkgChan <- pkgVersionResult{pkgVersions: nil,
pkgVerErr: fmt.Errorf("failed included package query for hasSBOM with error: %w", err)}
}

// if not found break
if pkgConn == nil {
break
}

var paginatedPkgs []*ent.PackageVersion
for _, edge := range pkgConn.Edges {
paginatedPkgs = append(paginatedPkgs, edge.Node)
}

pkgChan <- pkgVersionResult{pkgVersions: paginatedPkgs, pkgVerErr: nil}

if !pkgConn.PageInfo.HasNextPage {
break
}
afterCursor = pkgConn.PageInfo.EndCursor
}

artChan <- artResult{arts: paginatedArts,
artErr: nil}

if !artConn.PageInfo.HasNextPage {
break
}(ctx, b, sbomID, includedFirst, pkgVerChan)

// query included artifacts
go func(ctx context.Context, b *EntBackend, sbomID string, first int, artChan chan<- artResult) {
var afterCursor *entgql.Cursor[uuid.UUID]
defer close(artChan)
for {
artConn, err := b.client.Artifact.Query().
Where(artifact.HasIncludedInSbomsWith([]predicate.BillOfMaterials{
optionalPredicate(&sbomID, IDEQ)}...)).Paginate(ctx, afterCursor, &first, nil, nil)

if err != nil {
artChan <- artResult{arts: nil,
artErr: fmt.Errorf("failed included artifacts query for hasSBOM with error: %w", err)}
}

// if not found break
if artConn == nil {
break
}

var paginatedArts []*ent.Artifact
for _, edge := range artConn.Edges {
paginatedArts = append(paginatedArts, edge.Node)
}

artChan <- artResult{arts: paginatedArts,
artErr: nil}

if !artConn.PageInfo.HasNextPage {
break
}
afterCursor = artConn.PageInfo.EndCursor
}
afterCursor = artConn.PageInfo.EndCursor
}

}(ctx, b, sbomID, includedFirst, artChan)
}(ctx, b, sbomID, includedFirst, artChan)
}

// query included dependencies
go func(ctx context.Context, b *EntBackend, sbomID string, first int, artChan chan<- depResult) {
var afterCursor *entgql.Cursor[uuid.UUID]
defer close(depsChan)
for {
isDepQuery := b.client.Dependency.Query().
Where(dependency.HasIncludedInSbomsWith([]predicate.BillOfMaterials{
optionalPredicate(&sbomID, IDEQ)}...))

depConnect, err := getIsDepObject(isDepQuery).
Paginate(ctx, afterCursor, &first, nil, nil)
if err != nil {
depsChan <- depResult{deps: nil,
depErr: fmt.Errorf("failed included dependency query for hasSBOM with error: %w", err)}
}

// if not found break
if depConnect == nil {
break
if outputIncludeDependencies {
depsChan = make(chan depResult, 1)
go func(ctx context.Context, b *EntBackend, sbomID string, first int, artChan chan<- depResult) {
var afterCursor *entgql.Cursor[uuid.UUID]
defer close(depsChan)
for {
isDepQuery := b.client.Dependency.Query().
Where(dependency.HasIncludedInSbomsWith([]predicate.BillOfMaterials{
optionalPredicate(&sbomID, IDEQ)}...))

depConnect, err := getIsDepObject(isDepQuery).
Paginate(ctx, afterCursor, &first, nil, nil)
if err != nil {
depsChan <- depResult{deps: nil,
depErr: fmt.Errorf("failed included dependency query for hasSBOM with error: %w", err)}
}

// if not found break
if depConnect == nil {
break
}

var paginatedDeps []*ent.Dependency
for _, edge := range depConnect.Edges {
paginatedDeps = append(paginatedDeps, edge.Node)
}

depsChan <- depResult{deps: paginatedDeps,
depErr: nil}

if !depConnect.PageInfo.HasNextPage {
break
}
afterCursor = depConnect.PageInfo.EndCursor
}

var paginatedDeps []*ent.Dependency
for _, edge := range depConnect.Edges {
paginatedDeps = append(paginatedDeps, edge.Node)
}

depsChan <- depResult{deps: paginatedDeps,
depErr: nil}

if !depConnect.PageInfo.HasNextPage {
break
}
afterCursor = depConnect.PageInfo.EndCursor
}
}(ctx, b, sbomID, includedFirst, depsChan)
}(ctx, b, sbomID, includedFirst, depsChan)
}

// query included occurrences
go func(ctx context.Context, b *EntBackend, sbomID string, first int, occursChan chan<- occurResult) {
var afterCursor *entgql.Cursor[uuid.UUID]
defer close(occursChan)
for {
occurQuery := b.client.Occurrence.Query().
Where(occurrence.HasIncludedInSbomsWith([]predicate.BillOfMaterials{
optionalPredicate(&sbomID, IDEQ)}...))

occurConnect, err := getOccurrenceObject(occurQuery).
Paginate(ctx, afterCursor, &first, nil, nil)
if err != nil {
occursChan <- occurResult{occurs: nil,
occurErr: fmt.Errorf("failed included occurrence query for hasSBOM with error: %w", err)}
}

// if not found break
if occurConnect == nil {
break
if outputIncludedOccurrences {
occursChan = make(chan occurResult, 1)
go func(ctx context.Context, b *EntBackend, sbomID string, first int, occursChan chan<- occurResult) {
var afterCursor *entgql.Cursor[uuid.UUID]
defer close(occursChan)
for {
occurQuery := b.client.Occurrence.Query().
Where(occurrence.HasIncludedInSbomsWith([]predicate.BillOfMaterials{
optionalPredicate(&sbomID, IDEQ)}...))

occurConnect, err := getOccurrenceObject(occurQuery).
Paginate(ctx, afterCursor, &first, nil, nil)
if err != nil {
occursChan <- occurResult{occurs: nil,
occurErr: fmt.Errorf("failed included occurrence query for hasSBOM with error: %w", err)}
}

// if not found break
if occurConnect == nil {
break
}

var paginatedOccurs []*ent.Occurrence
for _, edge := range occurConnect.Edges {
paginatedOccurs = append(paginatedOccurs, edge.Node)
}

occursChan <- occurResult{occurs: paginatedOccurs,
occurErr: nil}

if !occurConnect.PageInfo.HasNextPage {
break
}
afterCursor = occurConnect.PageInfo.EndCursor
}

var paginatedOccurs []*ent.Occurrence
for _, edge := range occurConnect.Edges {
paginatedOccurs = append(paginatedOccurs, edge.Node)
}

occursChan <- occurResult{occurs: paginatedOccurs,
occurErr: nil}

if !occurConnect.PageInfo.HasNextPage {
break
}
afterCursor = occurConnect.PageInfo.EndCursor
}
}(ctx, b, sbomID, includedFirst, occursChan)
}(ctx, b, sbomID, includedFirst, occursChan)
}

for art := range artChan {
if art.artErr != nil {
Expand Down Expand Up @@ -333,13 +367,19 @@ func hasSBOMQuery(spec model.HasSBOMSpec) predicate.BillOfMaterials {
optionalPredicate(toLowerPtr(spec.Algorithm), billofmaterials.AlgorithmEQ),
optionalPredicate(toLowerPtr(spec.Digest), billofmaterials.DigestEQ),
optionalPredicate(spec.URI, billofmaterials.URI),
optionalPredicate(spec.Collector, billofmaterials.CollectorEQ),
optionalPredicate(spec.DownloadLocation, billofmaterials.DownloadLocationEQ),
optionalPredicate(spec.Origin, billofmaterials.OriginEQ),
optionalPredicate(spec.KnownSince, billofmaterials.KnownSinceEQ),
optionalPredicate(spec.DocumentRef, billofmaterials.DocumentRefEQ),
}

// filter out deps.dev unless the user specifies a specific collector
if spec.Collector != nil {
predicates = append(predicates, optionalPredicate(spec.Collector, billofmaterials.CollectorEQ))
} else {
predicates = append(predicates, optionalPredicate(ptrfrom.String(deps_dev.DepsCollector), billofmaterials.CollectorNEQ))
}

if spec.Subject != nil {
if spec.Subject.Package != nil {
if spec.Subject.Package.ID != nil {
Expand Down
Loading

0 comments on commit d2e2988

Please sign in to comment.