diff --git a/.github/scripts/excluded_from_copyright b/.github/scripts/excluded_from_copyright index 5a7f1f7eff..a1d260a896 100644 --- a/.github/scripts/excluded_from_copyright +++ b/.github/scripts/excluded_from_copyright @@ -191,6 +191,7 @@ ./pkg/assembler/graphql/generated/builder.generated.go ./pkg/assembler/graphql/generated/certifyBad.generated.go ./pkg/assembler/graphql/generated/certifyGood.generated.go +./pkg/assembler/graphql/generated/certifyLegal.generated.go ./pkg/assembler/graphql/generated/certifyScorecard.generated.go ./pkg/assembler/graphql/generated/certifyVEXStatement.generated.go ./pkg/assembler/graphql/generated/certifyVuln.generated.go @@ -203,6 +204,7 @@ ./pkg/assembler/graphql/generated/hashEqual.generated.go ./pkg/assembler/graphql/generated/isDependency.generated.go ./pkg/assembler/graphql/generated/isOccurrence.generated.go +./pkg/assembler/graphql/generated/license.generated.go ./pkg/assembler/graphql/generated/isVulnerability.generated.go ./pkg/assembler/graphql/generated/metadata.generated.go ./pkg/assembler/graphql/generated/osv.generated.go @@ -221,6 +223,7 @@ ./pkg/assembler/graphql/resolvers/builder.resolvers.go ./pkg/assembler/graphql/resolvers/certifyBad.resolvers.go ./pkg/assembler/graphql/resolvers/certifyGood.resolvers.go +./pkg/assembler/graphql/resolvers/certifyLegal.resolvers.go ./pkg/assembler/graphql/resolvers/certifyScorecard.resolvers.go ./pkg/assembler/graphql/resolvers/certifyVEXStatement.resolvers.go ./pkg/assembler/graphql/resolvers/certifyVuln.resolvers.go @@ -234,6 +237,7 @@ ./pkg/assembler/graphql/resolvers/isDependency.resolvers.go ./pkg/assembler/graphql/resolvers/isOccurrence.resolvers.go ./pkg/assembler/graphql/resolvers/isVulnerability.resolvers.go +./pkg/assembler/graphql/resolvers/license.resolvers.go ./pkg/assembler/graphql/resolvers/metadata.resolvers.go ./pkg/assembler/graphql/resolvers/osv.resolvers.go ./pkg/assembler/graphql/resolvers/package.resolvers.go diff --git a/internal/testing/mocks/backend.go b/internal/testing/mocks/backend.go index 3c6eae234d..910c447d38 100644 --- a/internal/testing/mocks/backend.go +++ b/internal/testing/mocks/backend.go @@ -95,6 +95,21 @@ func (mr *MockBackendMockRecorder) CertifyGood(ctx, certifyGoodSpec interface{}) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CertifyGood", reflect.TypeOf((*MockBackend)(nil).CertifyGood), ctx, certifyGoodSpec) } +// CertifyLegal mocks base method. +func (m *MockBackend) CertifyLegal(ctx context.Context, certifyLegalSpec *model.CertifyLegalSpec) ([]*model.CertifyLegal, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CertifyLegal", ctx, certifyLegalSpec) + ret0, _ := ret[0].([]*model.CertifyLegal) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CertifyLegal indicates an expected call of CertifyLegal. +func (mr *MockBackendMockRecorder) CertifyLegal(ctx, certifyLegalSpec interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CertifyLegal", reflect.TypeOf((*MockBackend)(nil).CertifyLegal), ctx, certifyLegalSpec) +} + // CertifyVEXStatement mocks base method. func (m *MockBackend) CertifyVEXStatement(ctx context.Context, certifyVEXStatementSpec *model.CertifyVEXStatementSpec) ([]*model.CertifyVEXStatement, error) { m.ctrl.T.Helper() @@ -335,6 +350,36 @@ func (mr *MockBackendMockRecorder) IngestCertifyGoods(ctx, subjects, pkgMatchTyp return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IngestCertifyGoods", reflect.TypeOf((*MockBackend)(nil).IngestCertifyGoods), ctx, subjects, pkgMatchType, certifyGoods) } +// IngestCertifyLegal mocks base method. +func (m *MockBackend) IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses, discoveredLicenses []*model.LicenseInputSpec, certifyLegal *model.CertifyLegalInputSpec) (*model.CertifyLegal, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IngestCertifyLegal", ctx, subject, declaredLicenses, discoveredLicenses, certifyLegal) + ret0, _ := ret[0].(*model.CertifyLegal) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// IngestCertifyLegal indicates an expected call of IngestCertifyLegal. +func (mr *MockBackendMockRecorder) IngestCertifyLegal(ctx, subject, declaredLicenses, discoveredLicenses, certifyLegal interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IngestCertifyLegal", reflect.TypeOf((*MockBackend)(nil).IngestCertifyLegal), ctx, subject, declaredLicenses, discoveredLicenses, certifyLegal) +} + +// IngestCertifyLegals mocks base method. +func (m *MockBackend) IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) ([]*model.CertifyLegal, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IngestCertifyLegals", ctx, subjects, declaredLicensesList, discoveredLicensesList, certifyLegals) + ret0, _ := ret[0].([]*model.CertifyLegal) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// IngestCertifyLegals indicates an expected call of IngestCertifyLegals. +func (mr *MockBackendMockRecorder) IngestCertifyLegals(ctx, subjects, declaredLicensesList, discoveredLicensesList, certifyLegals interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IngestCertifyLegals", reflect.TypeOf((*MockBackend)(nil).IngestCertifyLegals), ctx, subjects, declaredLicensesList, discoveredLicensesList, certifyLegals) +} + // IngestCertifyVuln mocks base method. func (m *MockBackend) IngestCertifyVuln(ctx context.Context, pkg model.PkgInputSpec, vulnerability model.VulnerabilityInputSpec, certifyVuln model.ScanMetadataInput) (*model.CertifyVuln, error) { m.ctrl.T.Helper() @@ -485,6 +530,36 @@ func (mr *MockBackendMockRecorder) IngestHashEquals(ctx, artifacts, otherArtifac return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IngestHashEquals", reflect.TypeOf((*MockBackend)(nil).IngestHashEquals), ctx, artifacts, otherArtifacts, hashEquals) } +// IngestLicense mocks base method. +func (m *MockBackend) IngestLicense(ctx context.Context, license *model.LicenseInputSpec) (*model.License, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IngestLicense", ctx, license) + ret0, _ := ret[0].(*model.License) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// IngestLicense indicates an expected call of IngestLicense. +func (mr *MockBackendMockRecorder) IngestLicense(ctx, license interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IngestLicense", reflect.TypeOf((*MockBackend)(nil).IngestLicense), ctx, license) +} + +// IngestLicenses mocks base method. +func (m *MockBackend) IngestLicenses(ctx context.Context, licenses []*model.LicenseInputSpec) ([]*model.License, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IngestLicenses", ctx, licenses) + ret0, _ := ret[0].([]*model.License) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// IngestLicenses indicates an expected call of IngestLicenses. +func (mr *MockBackendMockRecorder) IngestLicenses(ctx, licenses interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IngestLicenses", reflect.TypeOf((*MockBackend)(nil).IngestLicenses), ctx, licenses) +} + // IngestOccurrence mocks base method. func (m *MockBackend) IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.ArtifactInputSpec, occurrence model.IsOccurrenceInputSpec) (*model.IsOccurrence, error) { m.ctrl.T.Helper() @@ -800,6 +875,21 @@ func (mr *MockBackendMockRecorder) IsOccurrence(ctx, isOccurrenceSpec interface{ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsOccurrence", reflect.TypeOf((*MockBackend)(nil).IsOccurrence), ctx, isOccurrenceSpec) } +// Licenses mocks base method. +func (m *MockBackend) Licenses(ctx context.Context, licenseSpec *model.LicenseSpec) ([]*model.License, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Licenses", ctx, licenseSpec) + ret0, _ := ret[0].([]*model.License) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Licenses indicates an expected call of Licenses. +func (mr *MockBackendMockRecorder) Licenses(ctx, licenseSpec interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Licenses", reflect.TypeOf((*MockBackend)(nil).Licenses), ctx, licenseSpec) +} + // Neighbors mocks base method. func (m *MockBackend) Neighbors(ctx context.Context, node string, usingOnly []model.Edge) ([]model.Node, error) { m.ctrl.T.Helper() diff --git a/pkg/assembler/backends/arangodb/backend.go b/pkg/assembler/backends/arangodb/backend.go index 67927a15d3..08954c25ca 100644 --- a/pkg/assembler/backends/arangodb/backend.go +++ b/pkg/assembler/backends/arangodb/backend.go @@ -794,6 +794,25 @@ func (c *arangoClient) Path(ctx context.Context, subject string, target string, panic(fmt.Errorf("not implemented: Path - Path")) } +func (c *arangoClient) Licenses(ctx context.Context, licenseSpec *model.LicenseSpec) ([]*model.License, error) { + panic(fmt.Errorf("not implemented: Licenses")) +} +func (c *arangoClient) IngestLicense(ctx context.Context, license *model.LicenseInputSpec) (*model.License, error) { + panic(fmt.Errorf("not implemented: IngestLicense")) +} +func (c *arangoClient) IngestLicenses(ctx context.Context, licenses []*model.LicenseInputSpec) ([]*model.License, error) { + panic(fmt.Errorf("not implemented: IngestLicenses")) +} +func (c *arangoClient) CertifyLegal(ctx context.Context, certifyLegalSpec *model.CertifyLegalSpec) ([]*model.CertifyLegal, error) { + panic(fmt.Errorf("not implemented: CertifyLegal")) +} +func (c *arangoClient) IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, certifyLegal *model.CertifyLegalInputSpec) (*model.CertifyLegal, error) { + panic(fmt.Errorf("not implemented: IngestCertifyLegal")) +} +func (c *arangoClient) IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.LicenseInputSpec, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) ([]*model.CertifyLegal, error) { + panic(fmt.Errorf("not implemented: IngestCertifyLegals")) +} + func ptrfromArangoSearchNGramStreamType(s driver.ArangoSearchNGramStreamType) *driver.ArangoSearchNGramStreamType { return &s } diff --git a/pkg/assembler/backends/backends.go b/pkg/assembler/backends/backends.go index 3e53cb8277..09b50b78f3 100644 --- a/pkg/assembler/backends/backends.go +++ b/pkg/assembler/backends/backends.go @@ -31,12 +31,14 @@ type Backend interface { Vulnerabilities(ctx context.Context, vulnSpec *model.VulnerabilitySpec) ([]*model.Vulnerability, error) Packages(ctx context.Context, pkgSpec *model.PkgSpec) ([]*model.Package, error) Sources(ctx context.Context, sourceSpec *model.SourceSpec) ([]*model.Source, error) + Licenses(ctx context.Context, licenseSpec *model.LicenseSpec) ([]*model.License, error) // Retrieval read-only queries for evidence trees CertifyBad(ctx context.Context, certifyBadSpec *model.CertifyBadSpec) ([]*model.CertifyBad, error) CertifyGood(ctx context.Context, certifyGoodSpec *model.CertifyGoodSpec) ([]*model.CertifyGood, error) CertifyVEXStatement(ctx context.Context, certifyVEXStatementSpec *model.CertifyVEXStatementSpec) ([]*model.CertifyVEXStatement, error) CertifyVuln(ctx context.Context, certifyVulnSpec *model.CertifyVulnSpec) ([]*model.CertifyVuln, error) + CertifyLegal(ctx context.Context, certifyLegalSpec *model.CertifyLegalSpec) ([]*model.CertifyLegal, error) HasSBOM(ctx context.Context, hasSBOMSpec *model.HasSBOMSpec) ([]*model.HasSbom, error) HasSlsa(ctx context.Context, hasSLSASpec *model.HasSLSASpec) ([]*model.HasSlsa, error) HasSourceAt(ctx context.Context, hasSourceAtSpec *model.HasSourceAtSpec) ([]*model.HasSourceAt, error) @@ -61,6 +63,8 @@ type Backend interface { IngestPackages(ctx context.Context, pkgs []*model.PkgInputSpec) ([]*model.Package, error) IngestSource(ctx context.Context, source model.SourceInputSpec) (*model.Source, error) IngestSources(ctx context.Context, sources []*model.SourceInputSpec) ([]*model.Source, error) + IngestLicense(ctx context.Context, license *model.LicenseInputSpec) (*model.License, error) + IngestLicenses(ctx context.Context, licenses []*model.LicenseInputSpec) ([]*model.License, error) // Mutations for evidence trees (read-write queries, assume software trees ingested) IngestScorecard(ctx context.Context, source model.SourceInputSpec, scorecard model.ScorecardInputSpec) (*model.CertifyScorecard, error) @@ -86,6 +90,8 @@ type Backend interface { IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.VulnerabilityInputSpec, vexStatements []*model.VexStatementInputSpec) ([]string, error) IngestCertifyVuln(ctx context.Context, pkg model.PkgInputSpec, vulnerability model.VulnerabilityInputSpec, certifyVuln model.ScanMetadataInput) (*model.CertifyVuln, error) IngestCertifyVulns(ctx context.Context, pkgs []*model.PkgInputSpec, vulnerabilities []*model.VulnerabilityInputSpec, certifyVulns []*model.ScanMetadataInput) ([]*model.CertifyVuln, error) + IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, certifyLegal *model.CertifyLegalInputSpec) (*model.CertifyLegal, error) + IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.LicenseInputSpec, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) ([]*model.CertifyLegal, error) IngestHasMetadata(ctx context.Context, subject model.PackageSourceOrArtifactInput, pkgMatchType *model.MatchFlags, hasMetadata model.HasMetadataInputSpec) (*model.HasMetadata, error) IngestPointOfContact(ctx context.Context, subject model.PackageSourceOrArtifactInput, pkgMatchType *model.MatchFlags, pointOfContact model.PointOfContactInputSpec) (*model.PointOfContact, error) IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.VulnerabilityInputSpec, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) diff --git a/pkg/assembler/backends/helper/validation.go b/pkg/assembler/backends/helper/validation.go index 374d1b6d7f..426fd71168 100644 --- a/pkg/assembler/backends/helper/validation.go +++ b/pkg/assembler/backends/helper/validation.go @@ -127,6 +127,30 @@ func ValidatePackageOrArtifactQueryFilter(subject *model.PackageOrArtifactSpec) return nil } +func ValidateLicenseInput(license *model.LicenseInputSpec) error { + var inline string + var listVersion string + if license.Inline != nil { + inline = *license.Inline + } + if license.ListVersion != nil { + listVersion = *license.ListVersion + } + if inline == "" && listVersion == "" { + return gqlerror.Errorf("Neither Inline nor ListVersion are provided.") + } + if inline != "" && listVersion != "" { + return gqlerror.Errorf("Both Inline and ListVersion are provided.") + } + if inline == "" && strings.HasPrefix(license.Name, "LicenseRef") { + return gqlerror.Errorf("LicenseRef name provided without inline.") + } + if listVersion == "" && !strings.HasPrefix(license.Name, "LicenseRef") { + return gqlerror.Errorf("Inline provided provided with non LicenseRef name.") + } + return nil +} + // ValidateVexInput /* For [status] “not_affected”, a VEX statement SHOULD provide a [justification]. diff --git a/pkg/assembler/backends/inmem/backend.go b/pkg/assembler/backends/inmem/backend.go index a450161ce2..4d475de789 100644 --- a/pkg/assembler/backends/inmem/backend.go +++ b/pkg/assembler/backends/inmem/backend.go @@ -72,55 +72,45 @@ func (c *demoClient) getNextID() uint32 { } type demoClient struct { - id uint32 - m sync.RWMutex + id uint32 + m sync.RWMutex + index indexType + + artifacts artMap + builders builderMap + licenses licMap + packages pkgTypeMap + sources srcTypeMap + vulnerabilities vulnTypeMap - artifacts artMap - builders builderMap certifyBads badList certifyGoods goodList - pkgEquals pkgEqualList - vulnerabilities vulnTypeMap - vulnerabilityEquals vulnerabilityEqualList - vulnerabilityMetadatas vulnerabilityMetadataList + certifyLegals certifyLegalList + certifyVulnerabilities certifyVulnerabilityList hasMetadatas hasMetadataList - pointOfContacts pointOfContactList hasSBOMs hasSBOMList hasSLSAs hasSLSAList hasSources hasSrcList hashEquals hashEqualList - index indexType isDependencies isDependencyList occurrences isOccurrenceList - packages pkgTypeMap + pkgEquals pkgEqualList + pointOfContacts pointOfContactList scorecards scorecardList - sources srcTypeMap vexs vexList - certifyVulnerabilities certifyVulnerabilityList + vulnerabilityEquals vulnerabilityEqualList + vulnerabilityMetadatas vulnerabilityMetadataList } func GetBackend(args backends.BackendArgs) (backends.Backend, error) { client := &demoClient{ - artifacts: artMap{}, - builders: builderMap{}, - certifyBads: badList{}, - certifyGoods: goodList{}, - pkgEquals: pkgEqualList{}, - vulnerabilities: vulnTypeMap{}, - vulnerabilityEquals: vulnerabilityEqualList{}, - vulnerabilityMetadatas: vulnerabilityMetadataList{}, - hasSBOMs: hasSBOMList{}, - hasSLSAs: hasSLSAList{}, - hasSources: hasSrcList{}, - hashEquals: hashEqualList{}, - index: indexType{}, - isDependencies: isDependencyList{}, - occurrences: isOccurrenceList{}, - packages: pkgTypeMap{}, - scorecards: scorecardList{}, - sources: srcTypeMap{}, - vexs: vexList{}, - certifyVulnerabilities: certifyVulnerabilityList{}, + artifacts: artMap{}, + builders: builderMap{}, + index: indexType{}, + licenses: licMap{}, + packages: pkgTypeMap{}, + sources: srcTypeMap{}, + vulnerabilities: vulnTypeMap{}, } return client, nil diff --git a/pkg/assembler/backends/inmem/certifyLegal.go b/pkg/assembler/backends/inmem/certifyLegal.go new file mode 100644 index 0000000000..092fce7478 --- /dev/null +++ b/pkg/assembler/backends/inmem/certifyLegal.go @@ -0,0 +1,482 @@ +// +// Copyright 2023 The GUAC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package inmem + +import ( + "context" + "strconv" + "time" + + "github.com/vektah/gqlparser/v2/gqlerror" + "golang.org/x/exp/slices" + + "github.com/guacsec/guac/pkg/assembler/graphql/model" +) + +// Internal certifyLegal + +type certifyLegalList []*certifyLegalStruct +type certifyLegalStruct struct { + id uint32 + pkg uint32 + source uint32 + declaredLicense string + declaredLicenses []uint32 + discoveredLicense string + discoveredLicenses []uint32 + attribution string + justification string + timeScanned time.Time + origin string + collector string +} + +func (n *certifyLegalStruct) ID() uint32 { return n.id } + +func (n *certifyLegalStruct) Neighbors(allowedEdges edgeMap) []uint32 { + out := make([]uint32, 0, 2) + if n.pkg != 0 && allowedEdges[model.EdgeCertifyLegalPackage] { + out = append(out, n.pkg) + } + if n.source != 0 && allowedEdges[model.EdgeCertifyLegalSource] { + out = append(out, n.source) + } + if allowedEdges[model.EdgeCertifyLegalLicense] { + out = append(out, n.declaredLicenses...) + out = append(out, n.discoveredLicenses...) + } + return out +} + +func (n *certifyLegalStruct) BuildModelNode(c *demoClient) (model.Node, error) { + return c.convLegal(n) +} + +func (c *demoClient) IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.LicenseInputSpec, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) ([]*model.CertifyLegal, error) { + // FIXME move to resolver + // valuesDefined := 0 + // if len(subjects.Packages) > 0 { + // if len(subjects.Packages) != len(artifacts) { + // return nil, gqlerror.Errorf("uneven packages and artifacts for ingestion") + // } + // if len(subjects.Packages) != len(occurrences) { + // return nil, gqlerror.Errorf("uneven packages and occurrence for ingestion") + // } + // valuesDefined = valuesDefined + 1 + // } + // if len(subjects.Sources) > 0 { + // if len(subjects.Sources) != len(artifacts) { + // return nil, gqlerror.Errorf("uneven Sources and artifacts for ingestion") + // } + // if len(subjects.Sources) != len(occurrences) { + // return nil, gqlerror.Errorf("uneven Sources and occurrence for ingestion") + // } + // valuesDefined = valuesDefined + 1 + // } + // if valuesDefined != 1 { + // return nil, gqlerror.Errorf("must specify at most packages or sources for %v", "IngestOccurrences") + // } + + var rv []*model.CertifyLegal + + for i, v := range certifyLegals { + var l *model.CertifyLegal + var err error + if len(subjects.Packages) > 0 { + subject := model.PackageOrSourceInput{Package: subjects.Packages[i]} + l, err = c.IngestCertifyLegal(ctx, subject, declaredLicensesList[i], discoveredLicensesList[i], v) + if err != nil { + return nil, gqlerror.Errorf("IngestCertifyLegals failed with err: %v", err) + } + } else { + subject := model.PackageOrSourceInput{Source: subjects.Sources[i]} + l, err = c.IngestCertifyLegal(ctx, subject, declaredLicensesList[i], discoveredLicensesList[i], v) + if err != nil { + return nil, gqlerror.Errorf("IngestCertifyLegals failed with err: %v", err) + } + } + rv = append(rv, l) + } + return rv, nil +} + +func (c *demoClient) IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, certifyLegal *model.CertifyLegalInputSpec) (*model.CertifyLegal, error) { + return c.ingestCertifyLegal(ctx, subject, declaredLicenses, discoveredLicenses, certifyLegal, true) +} + +func (c *demoClient) ingestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, certifyLegal *model.CertifyLegalInputSpec, readOnly bool) (*model.CertifyLegal, error) { + funcName := "IngestCertifyLegal" + // FIXME move to resolver + // if err := helper.ValidatePackageOrSourceInput(&subject, "IngestOccurrence"); err != nil { + // return nil, gqlerror.Errorf("%v :: %s", funcName, err) + // } + + lock(&c.m, readOnly) + defer unlock(&c.m, readOnly) + + var dec []uint32 + for _, lis := range declaredLicenses { + l, ok := c.licenses[licenseKey(lis.Name, lis.ListVersion)] + if !ok { + return nil, gqlerror.Errorf("%v :: License not found %s", funcName, lis.Name) + } + dec = append(dec, l.id) + } + slices.Sort(dec) + var dis []uint32 + for _, lis := range discoveredLicenses { + l, ok := c.licenses[licenseKey(lis.Name, lis.ListVersion)] + if !ok { + return nil, gqlerror.Errorf("%v :: License not found %s", funcName, lis.Name) + } + dis = append(dis, l.id) + } + slices.Sort(dis) + + var backedgeSearch []uint32 + var packageID uint32 + var pkg *pkgVersionNode + if subject.Package != nil { + var pmt model.MatchFlags + pmt.Pkg = model.PkgMatchTypeSpecificVersion + pid, err := getPackageIDFromInput(c, *subject.Package, pmt) + if err != nil { + return nil, gqlerror.Errorf("%v :: %v", funcName, err) + } + packageID = pid + pkg, err = byID[*pkgVersionNode](packageID, c) + if err != nil { + return nil, gqlerror.Errorf("%v :: %s", funcName, err) + } + backedgeSearch = pkg.certifyLegals + } + + var sourceID uint32 + var src *srcNameNode + if subject.Source != nil { + sid, err := getSourceIDFromInput(c, *subject.Source) + if err != nil { + return nil, gqlerror.Errorf("%v :: %v", funcName, err) + } + sourceID = sid + src, err = byID[*srcNameNode](sourceID, c) + if err != nil { + return nil, gqlerror.Errorf("%v :: %s", funcName, err) + } + backedgeSearch = src.certifyLegals + } + + for _, id := range backedgeSearch { + cl, err := byID[*certifyLegalStruct](id, c) + if err != nil { + return nil, gqlerror.Errorf("%v :: %s", funcName, err) + } + if cl.pkg == packageID && + cl.source == sourceID && + cl.declaredLicense == certifyLegal.DeclaredLicense && + slices.Equal(cl.declaredLicenses, dec) && + cl.discoveredLicense == certifyLegal.DiscoveredLicense && + slices.Equal(cl.discoveredLicenses, dis) && + cl.attribution == certifyLegal.Attribution && + cl.timeScanned.Equal(certifyLegal.TimeScanned) && + cl.justification == certifyLegal.Justification && + cl.origin == certifyLegal.Origin && + cl.collector == certifyLegal.Collector { + return c.convLegal(cl) + } + } + if readOnly { + c.m.RUnlock() + o, err := c.ingestCertifyLegal(ctx, subject, declaredLicenses, discoveredLicenses, certifyLegal, false) + c.m.RLock() // relock so that defer unlock does not panic + return o, err + } + cl := &certifyLegalStruct{ + id: c.getNextID(), + pkg: packageID, + source: sourceID, + declaredLicense: certifyLegal.DeclaredLicense, + declaredLicenses: dec, + discoveredLicense: certifyLegal.DiscoveredLicense, + discoveredLicenses: dis, + attribution: certifyLegal.Attribution, + timeScanned: certifyLegal.TimeScanned, + justification: certifyLegal.Justification, + origin: certifyLegal.Origin, + collector: certifyLegal.Collector, + } + c.index[cl.id] = cl + if packageID != 0 { + pkg.setCertifyLegals(cl.id) + } else { + src.setCertifyLegals(cl.id) + } + for _, lid := range dec { + l, err := byID[*licStruct](lid, c) + if err != nil { + return nil, gqlerror.Errorf("%v :: %s", funcName, err) + } + l.setCertifyLegals(cl.id) + } + for _, lid := range dis { + l, err := byID[*licStruct](lid, c) + if err != nil { + return nil, gqlerror.Errorf("%v :: %s", funcName, err) + } + l.setCertifyLegals(cl.id) + } + c.certifyLegals = append(c.certifyLegals, cl) + + return c.convLegal(cl) +} + +func (c *demoClient) convLegal(in *certifyLegalStruct) (*model.CertifyLegal, error) { + cl := &model.CertifyLegal{ + ID: nodeID(in.id), + DeclaredLicense: in.declaredLicense, + DiscoveredLicense: in.discoveredLicense, + Attribution: in.attribution, + Justification: in.justification, + TimeScanned: in.timeScanned, + Origin: in.origin, + Collector: in.collector, + } + for _, lid := range in.declaredLicenses { + l, err := byID[*licStruct](lid, c) + if err != nil { + return nil, err + } + cl.DeclaredLicenses = append(cl.DeclaredLicenses, c.convLicense(l)) + } + for _, lid := range in.discoveredLicenses { + l, err := byID[*licStruct](lid, c) + if err != nil { + return nil, err + } + cl.DiscoveredLicenses = append(cl.DiscoveredLicenses, c.convLicense(l)) + } + if in.pkg != 0 { + p, err := c.buildPackageResponse(in.pkg, nil) + if err != nil { + return nil, err + } + cl.Subject = p + } else { + s, err := c.buildSourceResponse(in.source, nil) + if err != nil { + return nil, err + } + cl.Subject = s + } + return cl, nil +} + +func (c *demoClient) CertifyLegal(ctx context.Context, filter *model.CertifyLegalSpec) ([]*model.CertifyLegal, error) { + funcName := "CertifyLegal" + // FIXME move to resolver + // if filter != nil { + // if err := helper.ValidatePackageOrSourceQueryFilter(filter.Subject); err != nil { + // return nil, gqlerror.Errorf("%v :: %v", funcName, err) + // } + // } + + c.m.RLock() + defer c.m.RUnlock() + + if filter != nil && filter.ID != nil { + id64, err := strconv.ParseUint(*filter.ID, 10, 32) + if err != nil { + return nil, gqlerror.Errorf("%v :: invalid ID %s", funcName, err) + } + id := uint32(id64) + link, err := byID[*certifyLegalStruct](id, c) + if err != nil { + // Not found + return nil, nil + } + // If found by id, ignore rest of fields in spec and return as a match + o, err := c.convLegal(link) + if err != nil { + return nil, gqlerror.Errorf("%v :: %v", funcName, err) + } + return []*model.CertifyLegal{o}, nil + } + + var search []uint32 + foundOne := false + if !foundOne && filter != nil && filter.Subject != nil && filter.Subject.Package != nil { + exactPackage, err := c.exactPackageVersion(filter.Subject.Package) + if err != nil { + return nil, gqlerror.Errorf("%v :: %v", funcName, err) + } + if exactPackage != nil { + search = append(search, exactPackage.certifyLegals...) + foundOne = true + } + } + if !foundOne && filter != nil && filter.Subject != nil && filter.Subject.Source != nil { + exactSource, err := c.exactSource(filter.Subject.Source) + if err != nil { + return nil, gqlerror.Errorf("%v :: %v", funcName, err) + } + if exactSource != nil { + search = append(search, exactSource.certifyLegals...) + foundOne = true + } + } + if !foundOne && filter != nil { + for _, lSpec := range filter.DeclaredLicenses { + exactLicense, err := c.licenseExact(lSpec) + if err != nil { + return nil, gqlerror.Errorf("%v :: %v", funcName, err) + } + if exactLicense != nil { + search = append(search, exactLicense.certifyLegals...) + foundOne = true + break + } + } + } + if !foundOne && filter != nil { + for _, lSpec := range filter.DiscoveredLicenses { + exactLicense, err := c.licenseExact(lSpec) + if err != nil { + return nil, gqlerror.Errorf("%v :: %v", funcName, err) + } + if exactLicense != nil { + search = append(search, exactLicense.certifyLegals...) + foundOne = true + break + } + } + } + + var out []*model.CertifyLegal + if foundOne { + for _, id := range search { + link, err := byID[*certifyLegalStruct](id, c) + if err != nil { + return nil, gqlerror.Errorf("%v :: %v", funcName, err) + } + out, err = c.addLegalIfMatch(out, filter, link) + if err != nil { + return nil, gqlerror.Errorf("%v :: %v", funcName, err) + } + } + } else { + for _, link := range c.certifyLegals { + var err error + out, err = c.addLegalIfMatch(out, filter, link) + if err != nil { + return nil, gqlerror.Errorf("%v :: %v", funcName, err) + } + } + } + return out, nil +} + +func (c *demoClient) addLegalIfMatch(out []*model.CertifyLegal, + filter *model.CertifyLegalSpec, link *certifyLegalStruct) ( + []*model.CertifyLegal, error) { + + if noMatch(filter.DeclaredLicense, link.declaredLicense) || + noMatch(filter.DiscoveredLicense, link.discoveredLicense) || + noMatch(filter.Attribution, link.attribution) || + noMatch(filter.Justification, link.justification) || + noMatch(filter.Origin, link.origin) || + noMatch(filter.Collector, link.collector) || + (filter.TimeScanned != nil && !link.timeScanned.Equal(*filter.TimeScanned)) || + !c.matchLicenses(filter.DeclaredLicenses, link.declaredLicenses) || + !c.matchLicenses(filter.DiscoveredLicenses, link.discoveredLicenses) { + return out, nil + } + if filter.Subject != nil { + if filter.Subject.Package != nil { + if link.pkg == 0 { + return out, nil + } + p, err := c.buildPackageResponse(link.pkg, filter.Subject.Package) + if err != nil { + return nil, err + } + if p == nil { + return out, nil + } + } else if filter.Subject.Source != nil { + if link.source == 0 { + return out, nil + } + s, err := c.buildSourceResponse(link.source, filter.Subject.Source) + if err != nil { + return nil, err + } + if s == nil { + return out, nil + } + } + } + o, err := c.convLegal(link) + if err != nil { + return nil, err + } + return append(out, o), nil +} + +func (c *demoClient) matchLicenses(filter []*model.LicenseSpec, value []uint32) bool { + val := slices.Clone(value) + var matchID []uint32 + var matchPartial []*model.LicenseSpec + for _, aSpec := range filter { + if aSpec == nil { + continue + } + a, _ := c.licenseExact(aSpec) + // drop error here if ID is bad + if a != nil { + matchID = append(matchID, a.id) + } else { + matchPartial = append(matchPartial, aSpec) + } + } + for _, m := range matchID { + if !slices.Contains(val, m) { + return false + } + val = slices.Delete(val, slices.Index(val, m), slices.Index(val, m)+1) + } + for _, m := range matchPartial { + match := false + remove := -1 + for i, v := range val { + a, err := byID[*licStruct](v, c) + if err != nil { + return false + } + if (m.Name == nil || *m.Name == a.name) && + (m.ListVersion == nil || *m.ListVersion == a.listVersion) && + (m.Inline == nil || *m.Inline == a.inline) { + match = true + remove = i + break + } + } + if !match { + return false + } + val = slices.Delete(val, remove, remove+1) + } + return true +} diff --git a/pkg/assembler/backends/inmem/certifyLegal_test.go b/pkg/assembler/backends/inmem/certifyLegal_test.go new file mode 100644 index 0000000000..eae872fa84 --- /dev/null +++ b/pkg/assembler/backends/inmem/certifyLegal_test.go @@ -0,0 +1,745 @@ +// +// Copyright 2023 The GUAC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package inmem_test + +import ( + "context" + "strings" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "golang.org/x/exp/slices" + + "github.com/guacsec/guac/internal/testing/ptrfrom" + "github.com/guacsec/guac/pkg/assembler/backends/inmem" + "github.com/guacsec/guac/pkg/assembler/graphql/model" +) + +var t2 = time.Unix(1e9, 0) +var t3 = time.Unix(1e9+5, 0) + +func TestLegal(t *testing.T) { + type call struct { + PkgSrc model.PackageOrSourceInput + Dec []*model.LicenseInputSpec + Dis []*model.LicenseInputSpec + Legal *model.CertifyLegalInputSpec + } + tests := []struct { + Name string + InPkg []*model.PkgInputSpec + InSrc []*model.SourceInputSpec + InLic []*model.LicenseInputSpec + Calls []call + Query *model.CertifyLegalSpec + ExpLegal []*model.CertifyLegal + ExpIngestErr bool + ExpQueryErr bool + }{ + { + Name: "HappyPath", + InPkg: []*model.PkgInputSpec{p1}, + InLic: []*model.LicenseInputSpec{l1}, + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Dec: []*model.LicenseInputSpec{l1}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + }, + Query: &model.CertifyLegalSpec{ + Justification: ptrfrom.String("test justification"), + }, + ExpLegal: []*model.CertifyLegal{ + { + Subject: p1out, + DeclaredLicenses: []*model.License{l1out}, + Justification: "test justification", + }, + }, + }, + { + Name: "Ingest same twice", + InPkg: []*model.PkgInputSpec{p1}, + InLic: []*model.LicenseInputSpec{l1}, + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Dec: []*model.LicenseInputSpec{l1}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Dec: []*model.LicenseInputSpec{l1}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + }, + Query: &model.CertifyLegalSpec{ + Justification: ptrfrom.String("test justification"), + }, + ExpLegal: []*model.CertifyLegal{ + { + Subject: p1out, + DeclaredLicenses: []*model.License{l1out}, + Justification: "test justification", + }, + }, + }, + { + Name: "Query on Justification", + InPkg: []*model.PkgInputSpec{p1}, + InLic: []*model.LicenseInputSpec{l1}, + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Dec: []*model.LicenseInputSpec{l1}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Dec: []*model.LicenseInputSpec{l1}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification 2", + }, + }, + }, + Query: &model.CertifyLegalSpec{ + Justification: ptrfrom.String("test justification 2"), + }, + ExpLegal: []*model.CertifyLegal{ + { + Subject: p1out, + DeclaredLicenses: []*model.License{l1out}, + Justification: "test justification 2", + }, + }, + }, + { + Name: "Query on Package", + InPkg: []*model.PkgInputSpec{p1, p2}, + InLic: []*model.LicenseInputSpec{l1}, + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Dec: []*model.LicenseInputSpec{l1}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + { + PkgSrc: model.PackageOrSourceInput{ + Package: p2, + }, + Dec: []*model.LicenseInputSpec{l1}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + }, + Query: &model.CertifyLegalSpec{ + Subject: &model.PackageOrSourceSpec{ + Package: &model.PkgSpec{ + Version: ptrfrom.String(""), + }, + }, + }, + ExpLegal: []*model.CertifyLegal{ + { + Subject: p1out, + DeclaredLicenses: []*model.License{l1out}, + Justification: "test justification", + }, + }, + }, + { + Name: "Query on Source", + InSrc: []*model.SourceInputSpec{s1, s2}, + InLic: []*model.LicenseInputSpec{l1}, + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInput{ + Source: s1, + }, + Dec: []*model.LicenseInputSpec{l1}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + { + PkgSrc: model.PackageOrSourceInput{ + Source: s2, + }, + Dec: []*model.LicenseInputSpec{l1}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + }, + Query: &model.CertifyLegalSpec{ + Subject: &model.PackageOrSourceSpec{ + Source: &model.SourceSpec{ + Name: ptrfrom.String("myrepo"), + }, + }, + }, + ExpLegal: []*model.CertifyLegal{ + { + Subject: s1out, + DeclaredLicenses: []*model.License{l1out}, + Justification: "test justification", + }, + }, + }, + { + Name: "Query on License", + InSrc: []*model.SourceInputSpec{s1}, + InLic: []*model.LicenseInputSpec{l1, l2, l3}, + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInput{ + Source: s1, + }, + Dec: []*model.LicenseInputSpec{l1, l2}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + { + PkgSrc: model.PackageOrSourceInput{ + Source: s1, + }, + Dec: []*model.LicenseInputSpec{l3}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + }, + Query: &model.CertifyLegalSpec{ + DeclaredLicenses: []*model.LicenseSpec{ + {Name: ptrfrom.String("GPL-2.0-or-later")}, + }, + }, + ExpLegal: []*model.CertifyLegal{ + { + Subject: s1out, + DeclaredLicenses: []*model.License{l1out, l2out}, + Justification: "test justification", + }, + }, + }, + { + Name: "Query on License inline", + InSrc: []*model.SourceInputSpec{s1}, + InLic: []*model.LicenseInputSpec{l1, l2, l4}, + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInput{ + Source: s1, + }, + Dec: []*model.LicenseInputSpec{l1, l4}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + { + PkgSrc: model.PackageOrSourceInput{ + Source: s1, + }, + Dec: []*model.LicenseInputSpec{l2}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + }, + Query: &model.CertifyLegalSpec{ + DeclaredLicenses: []*model.LicenseSpec{ + {Inline: &inlineLicense}, + }, + }, + ExpLegal: []*model.CertifyLegal{ + { + Subject: s1out, + DeclaredLicenses: []*model.License{l1out, l4out}, + Justification: "test justification", + }, + }, + }, + { + Name: "Query on expression", + InPkg: []*model.PkgInputSpec{p1}, + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Legal: &model.CertifyLegalInputSpec{ + DeclaredLicense: "GPL OR MIT", + }, + }, + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Legal: &model.CertifyLegalInputSpec{ + DeclaredLicense: "GPL AND MIT", + }, + }, + }, + Query: &model.CertifyLegalSpec{ + DeclaredLicense: ptrfrom.String("GPL AND MIT"), + }, + ExpLegal: []*model.CertifyLegal{ + { + Subject: p1out, + DeclaredLicense: "GPL AND MIT", + }, + }, + }, + { + Name: "Query on attribution", + InPkg: []*model.PkgInputSpec{p1}, + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Legal: &model.CertifyLegalInputSpec{ + Attribution: "Copyright Jeff", + }, + }, + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Legal: &model.CertifyLegalInputSpec{ + Attribution: "Copyright Bob", + }, + }, + }, + Query: &model.CertifyLegalSpec{ + Attribution: ptrfrom.String("Copyright Jeff"), + }, + ExpLegal: []*model.CertifyLegal{ + { + Subject: p1out, + Attribution: "Copyright Jeff", + }, + }, + }, + { + Name: "Query on time", + InPkg: []*model.PkgInputSpec{p1}, + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Legal: &model.CertifyLegalInputSpec{ + TimeScanned: t3, + }, + }, + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Legal: &model.CertifyLegalInputSpec{ + TimeScanned: t2, + }, + }, + }, + Query: &model.CertifyLegalSpec{ + TimeScanned: &t2, + }, + ExpLegal: []*model.CertifyLegal{ + { + Subject: p1out, + TimeScanned: t2, + }, + }, + }, + { + Name: "Query multiple", + InPkg: []*model.PkgInputSpec{p1, p2, p3}, + InLic: []*model.LicenseInputSpec{l1}, + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Dec: []*model.LicenseInputSpec{l1}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + { + PkgSrc: model.PackageOrSourceInput{ + Package: p2, + }, + Dec: []*model.LicenseInputSpec{l1}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + { + PkgSrc: model.PackageOrSourceInput{ + Package: p3, + }, + Dec: []*model.LicenseInputSpec{l1}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification other", + }, + }, + }, + Query: &model.CertifyLegalSpec{ + Justification: ptrfrom.String("test justification"), + }, + ExpLegal: []*model.CertifyLegal{ + { + Subject: p1out, + DeclaredLicenses: []*model.License{l1out}, + Justification: "test justification", + }, + { + Subject: p2out, + DeclaredLicenses: []*model.License{l1out}, + Justification: "test justification", + }, + }, + }, + { + Name: "Ingest without Package", + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Legal: &model.CertifyLegalInputSpec{}, + }, + }, + ExpIngestErr: true, + }, + { + Name: "Ingest without Source", + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInput{ + Source: s1, + }, + Legal: &model.CertifyLegalInputSpec{}, + }, + }, + ExpIngestErr: true, + }, + { + Name: "Ingest without License", + InPkg: []*model.PkgInputSpec{p1}, + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Dec: []*model.LicenseInputSpec{l1}, + Legal: &model.CertifyLegalInputSpec{}, + }, + }, + ExpIngestErr: true, + }, + } + ignoreID := cmp.FilterPath(func(p cmp.Path) bool { + return strings.Compare(".ID", p[len(p)-1].String()) == 0 + }, cmp.Ignore()) + ctx := context.Background() + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + b, err := inmem.GetBackend(nil) + if err != nil { + t.Fatalf("Could not instantiate testing backend: %v", err) + } + for _, p := range test.InPkg { + if _, err := b.IngestPackage(ctx, *p); err != nil { + t.Fatalf("Could not ingest package: %v", err) + } + } + for _, s := range test.InSrc { + if _, err := b.IngestSource(ctx, *s); err != nil { + t.Fatalf("Could not ingest source: %v", err) + } + } + for _, a := range test.InLic { + if _, err := b.IngestLicense(ctx, a); err != nil { + t.Fatalf("Could not ingest license: %v", err) + } + } + for _, o := range test.Calls { + _, err := b.IngestCertifyLegal(ctx, o.PkgSrc, o.Dec, o.Dis, o.Legal) + if (err != nil) != test.ExpIngestErr { + t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) + } + if err != nil { + return + } + } + got, err := b.CertifyLegal(ctx, test.Query) + if (err != nil) != test.ExpQueryErr { + t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) + } + if err != nil { + return + } + if diff := cmp.Diff(test.ExpLegal, got, ignoreID); diff != "" { + t.Errorf("Unexpected results. (-want +got):\n%s", diff) + } + }) + } +} + +func TestLegals(t *testing.T) { + type call struct { + PkgSrc model.PackageOrSourceInputs + Dec [][]*model.LicenseInputSpec + Dis [][]*model.LicenseInputSpec + Legal []*model.CertifyLegalInputSpec + } + tests := []struct { + Name string + InPkg []*model.PkgInputSpec + InSrc []*model.SourceInputSpec + InLic []*model.LicenseInputSpec + Calls []call + Query *model.CertifyLegalSpec + ExpLegal []*model.CertifyLegal + ExpIngestErr bool + ExpQueryErr bool + }{ + { + Name: "HappyPath", + InPkg: []*model.PkgInputSpec{p1, p2}, + InLic: []*model.LicenseInputSpec{l1}, + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInputs{ + Packages: []*model.PkgInputSpec{p1, p2}, + }, + Dec: [][]*model.LicenseInputSpec{{l1}, {l1}}, + Dis: [][]*model.LicenseInputSpec{{}, {}}, + Legal: []*model.CertifyLegalInputSpec{ + {Justification: "test justification"}, + {Justification: "test justification"}, + }, + }, + }, + Query: &model.CertifyLegalSpec{ + Justification: ptrfrom.String("test justification"), + }, + ExpLegal: []*model.CertifyLegal{ + { + Subject: p1out, + DeclaredLicenses: []*model.License{l1out}, + Justification: "test justification", + }, + { + Subject: p2out, + DeclaredLicenses: []*model.License{l1out}, + Justification: "test justification", + }, + }, + }, + } + ignoreID := cmp.FilterPath(func(p cmp.Path) bool { + return strings.Compare(".ID", p[len(p)-1].String()) == 0 + }, cmp.Ignore()) + ctx := context.Background() + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + b, err := inmem.GetBackend(nil) + if err != nil { + t.Fatalf("Could not instantiate testing backend: %v", err) + } + for _, p := range test.InPkg { + if _, err := b.IngestPackage(ctx, *p); err != nil { + t.Fatalf("Could not ingest package: %v", err) + } + } + for _, s := range test.InSrc { + if _, err := b.IngestSource(ctx, *s); err != nil { + t.Fatalf("Could not ingest source: %v", err) + } + } + for _, a := range test.InLic { + if _, err := b.IngestLicense(ctx, a); err != nil { + t.Fatalf("Could not ingest license: %v", err) + } + } + for _, o := range test.Calls { + _, err := b.IngestCertifyLegals(ctx, o.PkgSrc, o.Dec, o.Dis, o.Legal) + if (err != nil) != test.ExpIngestErr { + t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) + } + if err != nil { + return + } + } + got, err := b.CertifyLegal(ctx, test.Query) + if (err != nil) != test.ExpQueryErr { + t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) + } + if err != nil { + return + } + if diff := cmp.Diff(test.ExpLegal, got, ignoreID); diff != "" { + t.Errorf("Unexpected results. (-want +got):\n%s", diff) + } + }) + } +} + +func TestLegalNeighbors(t *testing.T) { + type call struct { + PkgSrc model.PackageOrSourceInput + Dec []*model.LicenseInputSpec + Dis []*model.LicenseInputSpec + Legal *model.CertifyLegalInputSpec + } + tests := []struct { + Name string + InPkg []*model.PkgInputSpec + InSrc []*model.SourceInputSpec + InLic []*model.LicenseInputSpec + Calls []call + ExpNeighbors map[string][]string + }{ + { + Name: "HappyPath", + InPkg: []*model.PkgInputSpec{p1}, + InLic: []*model.LicenseInputSpec{l1}, + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Dec: []*model.LicenseInputSpec{l1}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + }, + ExpNeighbors: map[string][]string{ + "1": []string{"1"}, + "2": []string{"1", "1"}, + "3": []string{"1", "1"}, + "4": []string{"1", "6"}, // pkg version + "5": []string{"6"}, // license + "6": []string{"1", "5"}, // certifyLegal + }, + }, + { + Name: "Two Certify Legals", + InPkg: []*model.PkgInputSpec{p1, p2}, + InLic: []*model.LicenseInputSpec{l1, l2, l3}, + Calls: []call{ + { + PkgSrc: model.PackageOrSourceInput{ + Package: p1, + }, + Dec: []*model.LicenseInputSpec{l1, l2}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + { + PkgSrc: model.PackageOrSourceInput{ + Package: p2, + }, + Dec: []*model.LicenseInputSpec{l1, l3}, + Legal: &model.CertifyLegalInputSpec{ + Justification: "test justification", + }, + }, + }, + ExpNeighbors: map[string][]string{ + "4": []string{"1", "9"}, // pkg version 1 + "5": []string{"1", "10"}, // pkg version 2 + "6": []string{"9", "10"}, // license 1 + "7": []string{"9"}, // license 2 + "8": []string{"10"}, // license 2 + "9": []string{"1", "6", "7"}, // certLegal 1 + "10": []string{"1", "6", "8"}, // certLegal 2 + }, + }, + } + ctx := context.Background() + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + b, err := inmem.GetBackend(nil) + if err != nil { + t.Fatalf("Could not instantiate testing backend: %v", err) + } + for _, p := range test.InPkg { + if _, err := b.IngestPackage(ctx, *p); err != nil { + t.Fatalf("Could not ingest package: %v", err) + } + } + for _, s := range test.InSrc { + if _, err := b.IngestSource(ctx, *s); err != nil { + t.Fatalf("Could not ingest source: %v", err) + } + } + for _, a := range test.InLic { + if _, err := b.IngestLicense(ctx, a); err != nil { + t.Fatalf("Could not ingest license: %v", err) + } + } + for _, o := range test.Calls { + if _, err := b.IngestCertifyLegal(ctx, o.PkgSrc, o.Dec, o.Dis, o.Legal); err != nil { + t.Fatalf("Could not ingest CertifyLegal: %s", err) + } + } + for q, r := range test.ExpNeighbors { + got, err := b.Neighbors(ctx, q, nil) + if err != nil { + t.Fatalf("Could not query neighbors: %s", err) + } + gotIDs := convNodes(got) + slices.Sort(r) + slices.Sort(gotIDs) + if diff := cmp.Diff(r, gotIDs); diff != "" { + t.Errorf("Unexpected results. (-want +got):\n%s", diff) + } + } + }) + } +} diff --git a/pkg/assembler/backends/inmem/license.go b/pkg/assembler/backends/inmem/license.go new file mode 100644 index 0000000000..fa597677c8 --- /dev/null +++ b/pkg/assembler/backends/inmem/license.go @@ -0,0 +1,183 @@ +// +// Copyright 2023 The GUAC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package inmem + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/vektah/gqlparser/v2/gqlerror" + + "github.com/guacsec/guac/pkg/assembler/graphql/model" +) + +// Internal data: Licenses +type licMap map[string]*licStruct +type licStruct struct { + id uint32 + name string + inline string + listVersion string + certifyLegals []uint32 +} + +func (n *licStruct) ID() uint32 { return n.id } + +func (n *licStruct) Neighbors(allowedEdges edgeMap) []uint32 { + if allowedEdges[model.EdgeLicenseCertifyLegal] { + return n.certifyLegals + } + return nil +} + +func (n *licStruct) BuildModelNode(c *demoClient) (model.Node, error) { + return c.convLicense(n), nil +} + +func (n *licStruct) setCertifyLegals(id uint32) { n.certifyLegals = append(n.certifyLegals, id) } + +// Ingest Licenses + +func (c *demoClient) IngestLicenses(ctx context.Context, licenses []*model.LicenseInputSpec) ([]*model.License, error) { + var modelLicenses []*model.License + for _, lic := range licenses { + modelLic, err := c.IngestLicense(ctx, lic) + if err != nil { + return nil, gqlerror.Errorf("ingestLicense failed with err: %v", err) + } + modelLicenses = append(modelLicenses, modelLic) + } + return modelLicenses, nil +} + +func (c *demoClient) IngestLicense(ctx context.Context, license *model.LicenseInputSpec) (*model.License, error) { + return c.ingestLicense(ctx, license, true) +} + +func (c *demoClient) ingestLicense(ctx context.Context, license *model.LicenseInputSpec, readOnly bool) (*model.License, error) { + lock(&c.m, readOnly) + defer unlock(&c.m, readOnly) + + a, ok := c.licenses[licenseKey(license.Name, license.ListVersion)] + if !ok { + if readOnly { + c.m.RUnlock() + a, err := c.ingestLicense(ctx, license, false) + c.m.RLock() // relock so that defer unlock does not panic + return a, err + } + a = &licStruct{ + id: c.getNextID(), + name: license.Name, + } + if license.Inline != nil { + a.inline = *license.Inline + } + if license.ListVersion != nil { + a.listVersion = *license.ListVersion + } + c.index[a.id] = a + c.licenses[licenseKey(license.Name, license.ListVersion)] = a + } + + return c.convLicense(a), nil +} + +func licenseKey(name string, listVersion *string) string { + key := name + if !strings.HasPrefix(name, "LicenseRef") { + key = strings.Join([]string{name, *listVersion}, ":") + } + return key +} + +func (c *demoClient) licenseExact(licenseSpec *model.LicenseSpec) (*licStruct, error) { + + // If ID is provided, try to look up + if licenseSpec.ID != nil { + id64, err := strconv.ParseUint(*licenseSpec.ID, 10, 32) + if err != nil { + return nil, fmt.Errorf("couldn't parse id %w", err) + } + id := uint32(id64) + a, err := byID[*licStruct](id, c) + if err != nil { + // Not found + return nil, nil + } + // If found by id, ignore rest of fields in spec and return as a match + return a, nil + } + + if licenseSpec.Name != nil && strings.HasPrefix(*licenseSpec.Name, "LicenseRef") { + if l, ok := c.licenses[licenseKey(*licenseSpec.Name, nil)]; ok { + if licenseSpec.Inline == nil || + (licenseSpec.Inline != nil && *licenseSpec.Inline == l.inline) { + return l, nil + } + } + } + if licenseSpec.Name != nil && + !strings.HasPrefix(*licenseSpec.Name, "LicenseRef") && + licenseSpec.ListVersion != nil && + licenseSpec.Inline == nil { + if l, ok := c.licenses[licenseKey(*licenseSpec.Name, licenseSpec.ListVersion)]; ok { + return l, nil + } + } + return nil, nil +} + +// Query Licenses + +func (c *demoClient) Licenses(ctx context.Context, licenseSpec *model.LicenseSpec) ([]*model.License, error) { + c.m.RLock() + defer c.m.RUnlock() + a, err := c.licenseExact(licenseSpec) + if err != nil { + return nil, gqlerror.Errorf("Licenses :: invalid spec %s", err) + } + if a != nil { + return []*model.License{c.convLicense(a)}, nil + } + + var rv []*model.License + for _, l := range c.licenses { + if noMatch(licenseSpec.Name, l.name) || + noMatch(licenseSpec.ListVersion, l.listVersion) || + noMatch(licenseSpec.Inline, l.inline) { + continue + } + rv = append(rv, c.convLicense(l)) + } + return rv, nil +} + +func (c *demoClient) convLicense(a *licStruct) *model.License { + rv := &model.License{ + ID: nodeID(a.id), + Name: a.name, + } + if a.inline != "" { + rv.Inline = &a.inline + } + if a.listVersion != "" { + rv.ListVersion = &a.listVersion + } + return rv +} diff --git a/pkg/assembler/backends/inmem/license_test.go b/pkg/assembler/backends/inmem/license_test.go new file mode 100644 index 0000000000..7b248a651f --- /dev/null +++ b/pkg/assembler/backends/inmem/license_test.go @@ -0,0 +1,218 @@ +// +// Copyright 2023 The GUAC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package inmem_test + +import ( + "context" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/guacsec/guac/internal/testing/ptrfrom" + "github.com/guacsec/guac/pkg/assembler/backends/inmem" + "github.com/guacsec/guac/pkg/assembler/graphql/model" + "golang.org/x/exp/slices" +) + +var l1 = &model.LicenseInputSpec{ + Name: "BSD-3-Clause", + ListVersion: ptrfrom.String("3.21 2023-06-18"), +} +var l1out = &model.License{ + Name: "BSD-3-Clause", + ListVersion: ptrfrom.String("3.21 2023-06-18"), +} +var l2 = &model.LicenseInputSpec{ + Name: "GPL-2.0-or-later", + ListVersion: ptrfrom.String("3.21 2023-06-18"), +} +var l2out = &model.License{ + Name: "GPL-2.0-or-later", + ListVersion: ptrfrom.String("3.21 2023-06-18"), +} +var l3 = &model.LicenseInputSpec{ + Name: "MPL-2.0", + ListVersion: ptrfrom.String("1.23 2020"), +} +var l3out = &model.License{ + Name: "MPL-2.0", + ListVersion: ptrfrom.String("1.23 2020"), +} + +var inlineLicense = ` +Redistribution and use of the MAME code or any derivative works are permitted provided that the following conditions are met: +* Redistributions may not be sold, nor may they be used in a commercial product or activity. +* Redistributions that are modified from the original source must include the complete source code, including the source code for all components used by a binary built from the modified sources. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. +* Redistributions must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +` + +var l4 = &model.LicenseInputSpec{ + Name: "LicenseRef-d58b4101", + Inline: &inlineLicense, +} +var l4out = &model.License{ + Name: "LicenseRef-d58b4101", + Inline: &inlineLicense, +} + +func TestLicense(t *testing.T) { + tests := []struct { + Name string + Ingests []*model.LicenseInputSpec + ExpIngestErr bool + Query *model.LicenseSpec + Exp []*model.License + ExpQueryErr bool + }{ + { + Name: "HappyPath", + Ingests: []*model.LicenseInputSpec{l1}, + Query: &model.LicenseSpec{}, + Exp: []*model.License{l1out}, + }, + { + Name: "Multiple", + Ingests: []*model.LicenseInputSpec{l1, l2}, + Query: &model.LicenseSpec{}, + Exp: []*model.License{l1out, l2out}, + }, + { + Name: "Duplicates", + Ingests: []*model.LicenseInputSpec{l1, l1, l1}, + Query: &model.LicenseSpec{}, + Exp: []*model.License{l1out}, + }, + { + Name: "Query by Name", + Ingests: []*model.LicenseInputSpec{l1, l2, l3}, + Query: &model.LicenseSpec{ + Name: ptrfrom.String("BSD-3-Clause"), + }, + Exp: []*model.License{l1out}, + }, + { + Name: "Query by Inline", + Ingests: []*model.LicenseInputSpec{l2, l3, l4}, + Query: &model.LicenseSpec{ + Inline: &inlineLicense, + }, + Exp: []*model.License{l4out}, + }, + { + Name: "Query by ListVersion", + Ingests: []*model.LicenseInputSpec{l2, l3, l4}, + Query: &model.LicenseSpec{ + ListVersion: ptrfrom.String("1.23 2020"), + }, + Exp: []*model.License{l3out}, + }, + { + Name: "Query by ID", + Ingests: []*model.LicenseInputSpec{l2, l3, l4}, + Query: &model.LicenseSpec{ + ID: ptrfrom.String("2"), + }, + Exp: []*model.License{l3out}, + }, + { + Name: "Query None", + Ingests: []*model.LicenseInputSpec{l2, l3, l4}, + Query: &model.LicenseSpec{ + ListVersion: ptrfrom.String("foo"), + }, + Exp: nil, + }, + { + Name: "Query invalid ID", + Ingests: []*model.LicenseInputSpec{l1, l2, l3}, + Query: &model.LicenseSpec{ + ID: ptrfrom.String("asdf"), + }, + ExpQueryErr: true, + }, + } + ignoreID := cmp.FilterPath(func(p cmp.Path) bool { + return strings.Compare(".ID", p[len(p)-1].String()) == 0 + }, cmp.Ignore()) + ctx := context.Background() + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + b, err := inmem.GetBackend(nil) + if err != nil { + t.Fatalf("Could not instantiate testing backend: %v", err) + } + for _, i := range test.Ingests { + _, err := b.IngestLicense(ctx, i) + if (err != nil) != test.ExpIngestErr { + t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) + } + if err != nil { + return + } + } + got, err := b.Licenses(ctx, test.Query) + if (err != nil) != test.ExpQueryErr { + t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) + } + if err != nil { + return + } + slices.SortFunc(got, lessLic) + if diff := cmp.Diff(test.Exp, got, ignoreID); diff != "" { + t.Errorf("Unexpected results. (-want +got):\n%s", diff) + } + }) + } +} + +func lessLic(a, b *model.License) bool { + return a.Name < b.Name +} + +func TestIngestLicenses(t *testing.T) { + tests := []struct { + name string + ingests []*model.LicenseInputSpec + exp []*model.License + }{ + { + name: "Multiple", + ingests: []*model.LicenseInputSpec{l1, l2, l3, l4}, + exp: []*model.License{l1out, l2out, l3out, l4out}, + }, + } + ignoreID := cmp.FilterPath(func(p cmp.Path) bool { + return strings.Compare(".ID", p[len(p)-1].String()) == 0 + }, cmp.Ignore()) + ctx := context.Background() + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + b, err := inmem.GetBackend(nil) + if err != nil { + t.Fatalf("Could not instantiate testing backend: %v", err) + } + got, err := b.IngestLicenses(ctx, test.ingests) + if err != nil { + t.Fatalf("ingest error: %v", err) + return + } + if diff := cmp.Diff(test.exp, got, ignoreID); diff != "" { + t.Errorf("Unexpected results. (-want +got):\n%s", diff) + } + }) + } +} diff --git a/pkg/assembler/backends/inmem/pkg.go b/pkg/assembler/backends/inmem/pkg.go index 7948189bb7..f7593ad34f 100644 --- a/pkg/assembler/backends/inmem/pkg.go +++ b/pkg/assembler/backends/inmem/pkg.go @@ -124,6 +124,7 @@ type pkgVersionNode struct { hasMetadataLinks []uint32 pointOfContactLinks []uint32 pkgEquals []uint32 + certifyLegals []uint32 } // Be type safe, don't use any / interface{} @@ -228,6 +229,9 @@ func (n *pkgVersionNode) Neighbors(allowedEdges edgeMap) []uint32 { if allowedEdges[model.EdgePackagePointOfContact] { out = append(out, n.pointOfContactLinks...) } + if allowedEdges[model.EdgePackageCertifyLegal] { + out = append(out, n.certifyLegals...) + } return out } @@ -315,6 +319,8 @@ func (p *pkgVersionNode) getPointOfContactLinks() []uint32 { return p.pointOfC // pkgEqual back edges func (p *pkgVersionNode) setPkgEquals(id uint32) { p.pkgEquals = append(p.pkgEquals, id) } +func (p *pkgVersionNode) setCertifyLegals(id uint32) { p.certifyLegals = append(p.certifyLegals, id) } + // Ingest Package func (c *demoClient) IngestPackages(ctx context.Context, pkgs []*model.PkgInputSpec) ([]*model.Package, error) { diff --git a/pkg/assembler/backends/inmem/src.go b/pkg/assembler/backends/inmem/src.go index f3db8ad3da..673543fa97 100644 --- a/pkg/assembler/backends/inmem/src.go +++ b/pkg/assembler/backends/inmem/src.go @@ -88,6 +88,7 @@ type srcNameNode struct { goodLinks []uint32 hasMetadataLinks []uint32 pointOfContactLinks []uint32 + certifyLegals []uint32 } func (n *srcNamespaceStruct) ID() uint32 { return n.id } @@ -133,6 +134,9 @@ func (n *srcNameNode) Neighbors(allowedEdges edgeMap) []uint32 { if allowedEdges[model.EdgeSourcePointOfContact] { out = append(out, n.pointOfContactLinks...) } + if allowedEdges[model.EdgeSourceCertifyLegal] { + out = append(out, n.certifyLegals...) + } return out } @@ -152,6 +156,7 @@ func (p *srcNameNode) setScorecardLinks(id uint32) { p.scorecardLinks = append func (p *srcNameNode) setOccurrenceLinks(id uint32) { p.occurrences = append(p.occurrences, id) } func (p *srcNameNode) setCertifyBadLinks(id uint32) { p.badLinks = append(p.badLinks, id) } func (p *srcNameNode) setCertifyGoodLinks(id uint32) { p.goodLinks = append(p.goodLinks, id) } +func (p *srcNameNode) setCertifyLegals(id uint32) { p.certifyLegals = append(p.certifyLegals, id) } func (p *srcNameNode) setHasMetadataLinks(id uint32) { p.hasMetadataLinks = append(p.hasMetadataLinks, id) } diff --git a/pkg/assembler/backends/neo4j/backend.go b/pkg/assembler/backends/neo4j/backend.go index d332731532..a9af40d136 100644 --- a/pkg/assembler/backends/neo4j/backend.go +++ b/pkg/assembler/backends/neo4j/backend.go @@ -17,10 +17,12 @@ package neo4j import ( "context" + "fmt" "strings" "github.com/99designs/gqlgen/graphql" "github.com/guacsec/guac/pkg/assembler/backends" + "github.com/guacsec/guac/pkg/assembler/graphql/model" "github.com/neo4j/neo4j-go-driver/v4/neo4j" ) @@ -153,3 +155,22 @@ func getPreloadString(prefix, name string) string { } return name } + +func (c *neo4jClient) Licenses(ctx context.Context, licenseSpec *model.LicenseSpec) ([]*model.License, error) { + panic(fmt.Errorf("not implemented: Licenses")) +} +func (c *neo4jClient) IngestLicense(ctx context.Context, license *model.LicenseInputSpec) (*model.License, error) { + panic(fmt.Errorf("not implemented: IngestLicense")) +} +func (c *neo4jClient) IngestLicenses(ctx context.Context, licenses []*model.LicenseInputSpec) ([]*model.License, error) { + panic(fmt.Errorf("not implemented: IngestLicenses")) +} +func (c *neo4jClient) CertifyLegal(ctx context.Context, certifyLegalSpec *model.CertifyLegalSpec) ([]*model.CertifyLegal, error) { + panic(fmt.Errorf("not implemented: CertifyLegal")) +} +func (c *neo4jClient) IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, certifyLegal *model.CertifyLegalInputSpec) (*model.CertifyLegal, error) { + panic(fmt.Errorf("not implemented: IngestCertifyLegal")) +} +func (c *neo4jClient) IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.LicenseInputSpec, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) ([]*model.CertifyLegal, error) { + panic(fmt.Errorf("not implemented: IngestCertifyLegals")) +} diff --git a/pkg/assembler/clients/generated/operations.go b/pkg/assembler/clients/generated/operations.go index f782ef52bf..782f0517d3 100644 --- a/pkg/assembler/clients/generated/operations.go +++ b/pkg/assembler/clients/generated/operations.go @@ -991,6 +991,640 @@ func (v *AllCertifyGoodSubjectSource) __premarshalJSON() (*__premarshalAllCertif return &retval, nil } +// AllCertifyLegalTree includes the GraphQL fields of CertifyLegal requested by the fragment AllCertifyLegalTree. +// The GraphQL type's documentation follows. +// +// CertifyLegal is an attestation to attach legal information to a package or source. +// +// The certification information is either copied from an attestation found in an +// SBOM or created by a collector/scanner. +// +// Discovered license is also known as Concluded. More information: +// https://docs.clearlydefined.io/curation-guidelines#the-difference-between-declared-and-discovered-licenses +// +// Attribution is also known as Copyright Text. It is what could be displayed to +// comply with notice +// requirements. https://www.nexb.com/oss-attribution-best-practices/ +// +// License expressions follow this format: +// https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/ +type AllCertifyLegalTree struct { + Id string `json:"id"` + // The package version or source that is attested + Subject AllCertifyLegalTreeSubjectPackageOrSource `json:"-"` + // The license expression as delcared + DeclaredLicense string `json:"declaredLicense"` + // A list of license objects found in the declared license expression + DeclaredLicenses []AllCertifyLegalTreeDeclaredLicensesLicense `json:"declaredLicenses"` + // The license expression as discovered by scan + DiscoveredLicense string `json:"discoveredLicense"` + // A list of license objects found in the discovered license expression + DiscoveredLicenses []AllCertifyLegalTreeDiscoveredLicensesLicense `json:"discoveredLicenses"` + // Attribution text of the subject + Attribution string `json:"attribution"` + // Extra justification for the certification + Justification string `json:"justification"` + // Time of scan (in RFC 3339 format) + TimeScanned time.Time `json:"timeScanned"` + // Document from which this attestation is generated from + Origin string `json:"origin"` + // GUAC collector for the document + Collector string `json:"collector"` +} + +// GetId returns AllCertifyLegalTree.Id, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTree) GetId() string { return v.Id } + +// GetSubject returns AllCertifyLegalTree.Subject, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTree) GetSubject() AllCertifyLegalTreeSubjectPackageOrSource { + return v.Subject +} + +// GetDeclaredLicense returns AllCertifyLegalTree.DeclaredLicense, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTree) GetDeclaredLicense() string { return v.DeclaredLicense } + +// GetDeclaredLicenses returns AllCertifyLegalTree.DeclaredLicenses, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTree) GetDeclaredLicenses() []AllCertifyLegalTreeDeclaredLicensesLicense { + return v.DeclaredLicenses +} + +// GetDiscoveredLicense returns AllCertifyLegalTree.DiscoveredLicense, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTree) GetDiscoveredLicense() string { return v.DiscoveredLicense } + +// GetDiscoveredLicenses returns AllCertifyLegalTree.DiscoveredLicenses, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTree) GetDiscoveredLicenses() []AllCertifyLegalTreeDiscoveredLicensesLicense { + return v.DiscoveredLicenses +} + +// GetAttribution returns AllCertifyLegalTree.Attribution, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTree) GetAttribution() string { return v.Attribution } + +// GetJustification returns AllCertifyLegalTree.Justification, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTree) GetJustification() string { return v.Justification } + +// GetTimeScanned returns AllCertifyLegalTree.TimeScanned, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTree) GetTimeScanned() time.Time { return v.TimeScanned } + +// GetOrigin returns AllCertifyLegalTree.Origin, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTree) GetOrigin() string { return v.Origin } + +// GetCollector returns AllCertifyLegalTree.Collector, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTree) GetCollector() string { return v.Collector } + +func (v *AllCertifyLegalTree) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *AllCertifyLegalTree + Subject json.RawMessage `json:"subject"` + graphql.NoUnmarshalJSON + } + firstPass.AllCertifyLegalTree = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Subject + src := firstPass.Subject + if len(src) != 0 && string(src) != "null" { + err = __unmarshalAllCertifyLegalTreeSubjectPackageOrSource( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal AllCertifyLegalTree.Subject: %w", err) + } + } + } + return nil +} + +type __premarshalAllCertifyLegalTree struct { + Id string `json:"id"` + + Subject json.RawMessage `json:"subject"` + + DeclaredLicense string `json:"declaredLicense"` + + DeclaredLicenses []AllCertifyLegalTreeDeclaredLicensesLicense `json:"declaredLicenses"` + + DiscoveredLicense string `json:"discoveredLicense"` + + DiscoveredLicenses []AllCertifyLegalTreeDiscoveredLicensesLicense `json:"discoveredLicenses"` + + Attribution string `json:"attribution"` + + Justification string `json:"justification"` + + TimeScanned time.Time `json:"timeScanned"` + + Origin string `json:"origin"` + + Collector string `json:"collector"` +} + +func (v *AllCertifyLegalTree) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *AllCertifyLegalTree) __premarshalJSON() (*__premarshalAllCertifyLegalTree, error) { + var retval __premarshalAllCertifyLegalTree + + retval.Id = v.Id + { + + dst := &retval.Subject + src := v.Subject + var err error + *dst, err = __marshalAllCertifyLegalTreeSubjectPackageOrSource( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal AllCertifyLegalTree.Subject: %w", err) + } + } + retval.DeclaredLicense = v.DeclaredLicense + retval.DeclaredLicenses = v.DeclaredLicenses + retval.DiscoveredLicense = v.DiscoveredLicense + retval.DiscoveredLicenses = v.DiscoveredLicenses + retval.Attribution = v.Attribution + retval.Justification = v.Justification + retval.TimeScanned = v.TimeScanned + retval.Origin = v.Origin + retval.Collector = v.Collector + return &retval, nil +} + +// AllCertifyLegalTreeDeclaredLicensesLicense includes the requested fields of the GraphQL type License. +// The GraphQL type's documentation follows. +// +// License represents a particular license. If the license is found on the SPDX +// license list (https://spdx.org/licenses/) then the fields should be: +// +// Name: SPDX license identifier +// Inline: empty +// ListVersion: SPDX license list version +// +// example: +// +// Name: AGPL-3.0-or-later +// Inline: "" +// ListVersion: 3.21 2023-06-18 +// +// If the license is not on the SPDX license list, then a new guid should be +// created and the license text placed inline: +// +// Name: LicenseRef- +// Inline: Full license text +// ListVersion: empty +// +// example: +// +// Name: LicenseRef-1a2b3c +// Inline: Permission to use, copy, modify, and/or distribute ... +// ListVersion: "" +type AllCertifyLegalTreeDeclaredLicensesLicense struct { + AllLicenseTree `json:"-"` +} + +// GetId returns AllCertifyLegalTreeDeclaredLicensesLicense.Id, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTreeDeclaredLicensesLicense) GetId() string { return v.AllLicenseTree.Id } + +// GetName returns AllCertifyLegalTreeDeclaredLicensesLicense.Name, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTreeDeclaredLicensesLicense) GetName() string { return v.AllLicenseTree.Name } + +// GetInline returns AllCertifyLegalTreeDeclaredLicensesLicense.Inline, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTreeDeclaredLicensesLicense) GetInline() *string { + return v.AllLicenseTree.Inline +} + +// GetListVersion returns AllCertifyLegalTreeDeclaredLicensesLicense.ListVersion, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTreeDeclaredLicensesLicense) GetListVersion() *string { + return v.AllLicenseTree.ListVersion +} + +func (v *AllCertifyLegalTreeDeclaredLicensesLicense) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *AllCertifyLegalTreeDeclaredLicensesLicense + graphql.NoUnmarshalJSON + } + firstPass.AllCertifyLegalTreeDeclaredLicensesLicense = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AllLicenseTree) + if err != nil { + return err + } + return nil +} + +type __premarshalAllCertifyLegalTreeDeclaredLicensesLicense struct { + Id string `json:"id"` + + Name string `json:"name"` + + Inline *string `json:"inline"` + + ListVersion *string `json:"listVersion"` +} + +func (v *AllCertifyLegalTreeDeclaredLicensesLicense) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *AllCertifyLegalTreeDeclaredLicensesLicense) __premarshalJSON() (*__premarshalAllCertifyLegalTreeDeclaredLicensesLicense, error) { + var retval __premarshalAllCertifyLegalTreeDeclaredLicensesLicense + + retval.Id = v.AllLicenseTree.Id + retval.Name = v.AllLicenseTree.Name + retval.Inline = v.AllLicenseTree.Inline + retval.ListVersion = v.AllLicenseTree.ListVersion + return &retval, nil +} + +// AllCertifyLegalTreeDiscoveredLicensesLicense includes the requested fields of the GraphQL type License. +// The GraphQL type's documentation follows. +// +// License represents a particular license. If the license is found on the SPDX +// license list (https://spdx.org/licenses/) then the fields should be: +// +// Name: SPDX license identifier +// Inline: empty +// ListVersion: SPDX license list version +// +// example: +// +// Name: AGPL-3.0-or-later +// Inline: "" +// ListVersion: 3.21 2023-06-18 +// +// If the license is not on the SPDX license list, then a new guid should be +// created and the license text placed inline: +// +// Name: LicenseRef- +// Inline: Full license text +// ListVersion: empty +// +// example: +// +// Name: LicenseRef-1a2b3c +// Inline: Permission to use, copy, modify, and/or distribute ... +// ListVersion: "" +type AllCertifyLegalTreeDiscoveredLicensesLicense struct { + AllLicenseTree `json:"-"` +} + +// GetId returns AllCertifyLegalTreeDiscoveredLicensesLicense.Id, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTreeDiscoveredLicensesLicense) GetId() string { return v.AllLicenseTree.Id } + +// GetName returns AllCertifyLegalTreeDiscoveredLicensesLicense.Name, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTreeDiscoveredLicensesLicense) GetName() string { return v.AllLicenseTree.Name } + +// GetInline returns AllCertifyLegalTreeDiscoveredLicensesLicense.Inline, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTreeDiscoveredLicensesLicense) GetInline() *string { + return v.AllLicenseTree.Inline +} + +// GetListVersion returns AllCertifyLegalTreeDiscoveredLicensesLicense.ListVersion, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTreeDiscoveredLicensesLicense) GetListVersion() *string { + return v.AllLicenseTree.ListVersion +} + +func (v *AllCertifyLegalTreeDiscoveredLicensesLicense) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *AllCertifyLegalTreeDiscoveredLicensesLicense + graphql.NoUnmarshalJSON + } + firstPass.AllCertifyLegalTreeDiscoveredLicensesLicense = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AllLicenseTree) + if err != nil { + return err + } + return nil +} + +type __premarshalAllCertifyLegalTreeDiscoveredLicensesLicense struct { + Id string `json:"id"` + + Name string `json:"name"` + + Inline *string `json:"inline"` + + ListVersion *string `json:"listVersion"` +} + +func (v *AllCertifyLegalTreeDiscoveredLicensesLicense) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *AllCertifyLegalTreeDiscoveredLicensesLicense) __premarshalJSON() (*__premarshalAllCertifyLegalTreeDiscoveredLicensesLicense, error) { + var retval __premarshalAllCertifyLegalTreeDiscoveredLicensesLicense + + retval.Id = v.AllLicenseTree.Id + retval.Name = v.AllLicenseTree.Name + retval.Inline = v.AllLicenseTree.Inline + retval.ListVersion = v.AllLicenseTree.ListVersion + return &retval, nil +} + +// AllCertifyLegalTreeSubjectPackage includes the requested fields of the GraphQL type Package. +// The GraphQL type's documentation follows. +// +// Package represents the root of the package trie/tree. +// +// We map package information to a trie, closely matching the pURL specification +// (https://github.com/package-url/purl-spec/blob/0dd92f26f8bb11956ffdf5e8acfcee71e8560407/README.rst), +// but deviating from it where GUAC heuristics allow for better representation of +// package information. Each path in the trie fully represents a package; we split +// the trie based on the pURL components. +// +// This node matches a pkg: partial pURL. The type field matches the +// pURL types but we might also use "guac" for the cases where the pURL +// representation is not complete or when we have custom rules. +// +// Since this node is at the root of the package trie, it is named Package, not +// PackageType. +type AllCertifyLegalTreeSubjectPackage struct { + Typename *string `json:"__typename"` + AllPkgTree `json:"-"` +} + +// GetTypename returns AllCertifyLegalTreeSubjectPackage.Typename, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTreeSubjectPackage) GetTypename() *string { return v.Typename } + +// GetId returns AllCertifyLegalTreeSubjectPackage.Id, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTreeSubjectPackage) GetId() string { return v.AllPkgTree.Id } + +// GetType returns AllCertifyLegalTreeSubjectPackage.Type, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTreeSubjectPackage) GetType() string { return v.AllPkgTree.Type } + +// GetNamespaces returns AllCertifyLegalTreeSubjectPackage.Namespaces, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTreeSubjectPackage) GetNamespaces() []AllPkgTreeNamespacesPackageNamespace { + return v.AllPkgTree.Namespaces +} + +func (v *AllCertifyLegalTreeSubjectPackage) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *AllCertifyLegalTreeSubjectPackage + graphql.NoUnmarshalJSON + } + firstPass.AllCertifyLegalTreeSubjectPackage = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AllPkgTree) + if err != nil { + return err + } + return nil +} + +type __premarshalAllCertifyLegalTreeSubjectPackage struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Type string `json:"type"` + + Namespaces []AllPkgTreeNamespacesPackageNamespace `json:"namespaces"` +} + +func (v *AllCertifyLegalTreeSubjectPackage) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *AllCertifyLegalTreeSubjectPackage) __premarshalJSON() (*__premarshalAllCertifyLegalTreeSubjectPackage, error) { + var retval __premarshalAllCertifyLegalTreeSubjectPackage + + retval.Typename = v.Typename + retval.Id = v.AllPkgTree.Id + retval.Type = v.AllPkgTree.Type + retval.Namespaces = v.AllPkgTree.Namespaces + return &retval, nil +} + +// AllCertifyLegalTreeSubjectPackageOrSource includes the requested fields of the GraphQL interface PackageOrSource. +// +// AllCertifyLegalTreeSubjectPackageOrSource is implemented by the following types: +// AllCertifyLegalTreeSubjectPackage +// AllCertifyLegalTreeSubjectSource +// The GraphQL type's documentation follows. +// +// PackageOrSource is a union of Package and Source. +type AllCertifyLegalTreeSubjectPackageOrSource interface { + implementsGraphQLInterfaceAllCertifyLegalTreeSubjectPackageOrSource() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string +} + +func (v *AllCertifyLegalTreeSubjectPackage) implementsGraphQLInterfaceAllCertifyLegalTreeSubjectPackageOrSource() { +} +func (v *AllCertifyLegalTreeSubjectSource) implementsGraphQLInterfaceAllCertifyLegalTreeSubjectPackageOrSource() { +} + +func __unmarshalAllCertifyLegalTreeSubjectPackageOrSource(b []byte, v *AllCertifyLegalTreeSubjectPackageOrSource) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Package": + *v = new(AllCertifyLegalTreeSubjectPackage) + return json.Unmarshal(b, *v) + case "Source": + *v = new(AllCertifyLegalTreeSubjectSource) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing PackageOrSource.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for AllCertifyLegalTreeSubjectPackageOrSource: "%v"`, tn.TypeName) + } +} + +func __marshalAllCertifyLegalTreeSubjectPackageOrSource(v *AllCertifyLegalTreeSubjectPackageOrSource) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *AllCertifyLegalTreeSubjectPackage: + typename = "Package" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalAllCertifyLegalTreeSubjectPackage + }{typename, premarshaled} + return json.Marshal(result) + case *AllCertifyLegalTreeSubjectSource: + typename = "Source" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalAllCertifyLegalTreeSubjectSource + }{typename, premarshaled} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for AllCertifyLegalTreeSubjectPackageOrSource: "%T"`, v) + } +} + +// AllCertifyLegalTreeSubjectSource includes the requested fields of the GraphQL type Source. +// The GraphQL type's documentation follows. +// +// Source represents the root of the source trie/tree. +// +// We map source information to a trie, as a derivative of the pURL specification: +// each path in the trie represents a type, namespace, name and an optional +// qualifier that stands for tag/commit information. +// +// This node represents the type part of the trie path. It is used to represent +// the version control system that is being used. +// +// Since this node is at the root of the source trie, it is named Source, not +// SourceType. +type AllCertifyLegalTreeSubjectSource struct { + Typename *string `json:"__typename"` + AllSourceTree `json:"-"` +} + +// GetTypename returns AllCertifyLegalTreeSubjectSource.Typename, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTreeSubjectSource) GetTypename() *string { return v.Typename } + +// GetId returns AllCertifyLegalTreeSubjectSource.Id, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTreeSubjectSource) GetId() string { return v.AllSourceTree.Id } + +// GetType returns AllCertifyLegalTreeSubjectSource.Type, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTreeSubjectSource) GetType() string { return v.AllSourceTree.Type } + +// GetNamespaces returns AllCertifyLegalTreeSubjectSource.Namespaces, and is useful for accessing the field via an interface. +func (v *AllCertifyLegalTreeSubjectSource) GetNamespaces() []AllSourceTreeNamespacesSourceNamespace { + return v.AllSourceTree.Namespaces +} + +func (v *AllCertifyLegalTreeSubjectSource) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *AllCertifyLegalTreeSubjectSource + graphql.NoUnmarshalJSON + } + firstPass.AllCertifyLegalTreeSubjectSource = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AllSourceTree) + if err != nil { + return err + } + return nil +} + +type __premarshalAllCertifyLegalTreeSubjectSource struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Type string `json:"type"` + + Namespaces []AllSourceTreeNamespacesSourceNamespace `json:"namespaces"` +} + +func (v *AllCertifyLegalTreeSubjectSource) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *AllCertifyLegalTreeSubjectSource) __premarshalJSON() (*__premarshalAllCertifyLegalTreeSubjectSource, error) { + var retval __premarshalAllCertifyLegalTreeSubjectSource + + retval.Typename = v.Typename + retval.Id = v.AllSourceTree.Id + retval.Type = v.AllSourceTree.Type + retval.Namespaces = v.AllSourceTree.Namespaces + return &retval, nil +} + // AllCertifyScorecard includes the GraphQL fields of CertifyScorecard requested by the fragment AllCertifyScorecard. // The GraphQL type's documentation follows. // @@ -3757,6 +4391,53 @@ func (v *AllIsOccurrencesTreeSubjectSource) __premarshalJSON() (*__premarshalAll return &retval, nil } +// AllLicenseTree includes the GraphQL fields of License requested by the fragment AllLicenseTree. +// The GraphQL type's documentation follows. +// +// License represents a particular license. If the license is found on the SPDX +// license list (https://spdx.org/licenses/) then the fields should be: +// +// Name: SPDX license identifier +// Inline: empty +// ListVersion: SPDX license list version +// +// example: +// +// Name: AGPL-3.0-or-later +// Inline: "" +// ListVersion: 3.21 2023-06-18 +// +// If the license is not on the SPDX license list, then a new guid should be +// created and the license text placed inline: +// +// Name: LicenseRef- +// Inline: Full license text +// ListVersion: empty +// +// example: +// +// Name: LicenseRef-1a2b3c +// Inline: Permission to use, copy, modify, and/or distribute ... +// ListVersion: "" +type AllLicenseTree struct { + Id string `json:"id"` + Name string `json:"name"` + Inline *string `json:"inline"` + ListVersion *string `json:"listVersion"` +} + +// GetId returns AllLicenseTree.Id, and is useful for accessing the field via an interface. +func (v *AllLicenseTree) GetId() string { return v.Id } + +// GetName returns AllLicenseTree.Name, and is useful for accessing the field via an interface. +func (v *AllLicenseTree) GetName() string { return v.Name } + +// GetInline returns AllLicenseTree.Inline, and is useful for accessing the field via an interface. +func (v *AllLicenseTree) GetInline() *string { return v.Inline } + +// GetListVersion returns AllLicenseTree.ListVersion, and is useful for accessing the field via an interface. +func (v *AllLicenseTree) GetListVersion() *string { return v.ListVersion } + // AllPkgEqual includes the GraphQL fields of PkgEqual requested by the fragment AllPkgEqual. // The GraphQL type's documentation follows. // @@ -5576,60 +6257,343 @@ type CertifyGoodArtifactsResponse struct { IngestCertifyGoods []string `json:"ingestCertifyGoods"` } -// GetIngestCertifyGoods returns CertifyGoodArtifactsResponse.IngestCertifyGoods, and is useful for accessing the field via an interface. -func (v *CertifyGoodArtifactsResponse) GetIngestCertifyGoods() []string { return v.IngestCertifyGoods } +// GetIngestCertifyGoods returns CertifyGoodArtifactsResponse.IngestCertifyGoods, and is useful for accessing the field via an interface. +func (v *CertifyGoodArtifactsResponse) GetIngestCertifyGoods() []string { return v.IngestCertifyGoods } + +// CertifyGoodInputSpec represents the mutation input to ingest a CertifyGood evidence. +type CertifyGoodInputSpec struct { + Justification string `json:"justification"` + Origin string `json:"origin"` + Collector string `json:"collector"` +} + +// GetJustification returns CertifyGoodInputSpec.Justification, and is useful for accessing the field via an interface. +func (v *CertifyGoodInputSpec) GetJustification() string { return v.Justification } + +// GetOrigin returns CertifyGoodInputSpec.Origin, and is useful for accessing the field via an interface. +func (v *CertifyGoodInputSpec) GetOrigin() string { return v.Origin } + +// GetCollector returns CertifyGoodInputSpec.Collector, and is useful for accessing the field via an interface. +func (v *CertifyGoodInputSpec) GetCollector() string { return v.Collector } + +// CertifyGoodPkgResponse is returned by CertifyGoodPkg on success. +type CertifyGoodPkgResponse struct { + // Adds a certification that a package, source or artifact is considered good. The returned ID can be empty string. + IngestCertifyGood string `json:"ingestCertifyGood"` +} + +// GetIngestCertifyGood returns CertifyGoodPkgResponse.IngestCertifyGood, and is useful for accessing the field via an interface. +func (v *CertifyGoodPkgResponse) GetIngestCertifyGood() string { return v.IngestCertifyGood } + +// CertifyGoodPkgsResponse is returned by CertifyGoodPkgs on success. +type CertifyGoodPkgsResponse struct { + // Adds bulk certifications that a package, source or artifact is considered good. The returned array of IDs can be a an array of empty string. + IngestCertifyGoods []string `json:"ingestCertifyGoods"` +} + +// GetIngestCertifyGoods returns CertifyGoodPkgsResponse.IngestCertifyGoods, and is useful for accessing the field via an interface. +func (v *CertifyGoodPkgsResponse) GetIngestCertifyGoods() []string { return v.IngestCertifyGoods } + +// CertifyGoodSrcResponse is returned by CertifyGoodSrc on success. +type CertifyGoodSrcResponse struct { + // Adds a certification that a package, source or artifact is considered good. The returned ID can be empty string. + IngestCertifyGood string `json:"ingestCertifyGood"` +} + +// GetIngestCertifyGood returns CertifyGoodSrcResponse.IngestCertifyGood, and is useful for accessing the field via an interface. +func (v *CertifyGoodSrcResponse) GetIngestCertifyGood() string { return v.IngestCertifyGood } + +// CertifyGoodSrcsResponse is returned by CertifyGoodSrcs on success. +type CertifyGoodSrcsResponse struct { + // Adds bulk certifications that a package, source or artifact is considered good. The returned array of IDs can be a an array of empty string. + IngestCertifyGoods []string `json:"ingestCertifyGoods"` +} + +// GetIngestCertifyGoods returns CertifyGoodSrcsResponse.IngestCertifyGoods, and is useful for accessing the field via an interface. +func (v *CertifyGoodSrcsResponse) GetIngestCertifyGoods() []string { return v.IngestCertifyGoods } + +// CertifyLegalInputSpec represents the input for certifying legal information in +// mutations. +type CertifyLegalInputSpec struct { + DeclaredLicense string `json:"declaredLicense"` + DiscoveredLicense string `json:"discoveredLicense"` + Attribution string `json:"attribution"` + Justification string `json:"justification"` + TimeScanned time.Time `json:"timeScanned"` + Origin string `json:"origin"` + Collector string `json:"collector"` +} + +// GetDeclaredLicense returns CertifyLegalInputSpec.DeclaredLicense, and is useful for accessing the field via an interface. +func (v *CertifyLegalInputSpec) GetDeclaredLicense() string { return v.DeclaredLicense } + +// GetDiscoveredLicense returns CertifyLegalInputSpec.DiscoveredLicense, and is useful for accessing the field via an interface. +func (v *CertifyLegalInputSpec) GetDiscoveredLicense() string { return v.DiscoveredLicense } + +// GetAttribution returns CertifyLegalInputSpec.Attribution, and is useful for accessing the field via an interface. +func (v *CertifyLegalInputSpec) GetAttribution() string { return v.Attribution } + +// GetJustification returns CertifyLegalInputSpec.Justification, and is useful for accessing the field via an interface. +func (v *CertifyLegalInputSpec) GetJustification() string { return v.Justification } + +// GetTimeScanned returns CertifyLegalInputSpec.TimeScanned, and is useful for accessing the field via an interface. +func (v *CertifyLegalInputSpec) GetTimeScanned() time.Time { return v.TimeScanned } + +// GetOrigin returns CertifyLegalInputSpec.Origin, and is useful for accessing the field via an interface. +func (v *CertifyLegalInputSpec) GetOrigin() string { return v.Origin } + +// GetCollector returns CertifyLegalInputSpec.Collector, and is useful for accessing the field via an interface. +func (v *CertifyLegalInputSpec) GetCollector() string { return v.Collector } + +// CertifyLegalPkgResponse is returned by CertifyLegalPkg on success. +type CertifyLegalPkgResponse struct { + // Adds a legal certification to a package or source. + IngestCertifyLegal string `json:"ingestCertifyLegal"` +} + +// GetIngestCertifyLegal returns CertifyLegalPkgResponse.IngestCertifyLegal, and is useful for accessing the field via an interface. +func (v *CertifyLegalPkgResponse) GetIngestCertifyLegal() string { return v.IngestCertifyLegal } + +// CertifyLegalPkgsResponse is returned by CertifyLegalPkgs on success. +type CertifyLegalPkgsResponse struct { + // Bulk add legal certifications to packages or sources, not both at same time. + IngestCertifyLegals []string `json:"ingestCertifyLegals"` +} + +// GetIngestCertifyLegals returns CertifyLegalPkgsResponse.IngestCertifyLegals, and is useful for accessing the field via an interface. +func (v *CertifyLegalPkgsResponse) GetIngestCertifyLegals() []string { return v.IngestCertifyLegals } + +// CertifyLegalSpec allows filtering the list of legal certifications to +// return in a query. +// +// Specifying just the package allows to query for all certifications associated +// with the package. +type CertifyLegalSpec struct { + Id *string `json:"id"` + Subject *PackageOrSourceSpec `json:"subject"` + DeclaredLicense *string `json:"declaredLicense"` + DeclaredLicenses []LicenseSpec `json:"declaredLicenses"` + DiscoveredLicense *string `json:"discoveredLicense"` + DiscoveredLicenses []LicenseSpec `json:"discoveredLicenses"` + Attribution *string `json:"attribution"` + Justification *string `json:"justification"` + TimeScanned *time.Time `json:"timeScanned"` + Origin *string `json:"origin"` + Collector *string `json:"collector"` +} + +// GetId returns CertifyLegalSpec.Id, and is useful for accessing the field via an interface. +func (v *CertifyLegalSpec) GetId() *string { return v.Id } + +// GetSubject returns CertifyLegalSpec.Subject, and is useful for accessing the field via an interface. +func (v *CertifyLegalSpec) GetSubject() *PackageOrSourceSpec { return v.Subject } + +// GetDeclaredLicense returns CertifyLegalSpec.DeclaredLicense, and is useful for accessing the field via an interface. +func (v *CertifyLegalSpec) GetDeclaredLicense() *string { return v.DeclaredLicense } + +// GetDeclaredLicenses returns CertifyLegalSpec.DeclaredLicenses, and is useful for accessing the field via an interface. +func (v *CertifyLegalSpec) GetDeclaredLicenses() []LicenseSpec { return v.DeclaredLicenses } + +// GetDiscoveredLicense returns CertifyLegalSpec.DiscoveredLicense, and is useful for accessing the field via an interface. +func (v *CertifyLegalSpec) GetDiscoveredLicense() *string { return v.DiscoveredLicense } + +// GetDiscoveredLicenses returns CertifyLegalSpec.DiscoveredLicenses, and is useful for accessing the field via an interface. +func (v *CertifyLegalSpec) GetDiscoveredLicenses() []LicenseSpec { return v.DiscoveredLicenses } + +// GetAttribution returns CertifyLegalSpec.Attribution, and is useful for accessing the field via an interface. +func (v *CertifyLegalSpec) GetAttribution() *string { return v.Attribution } + +// GetJustification returns CertifyLegalSpec.Justification, and is useful for accessing the field via an interface. +func (v *CertifyLegalSpec) GetJustification() *string { return v.Justification } + +// GetTimeScanned returns CertifyLegalSpec.TimeScanned, and is useful for accessing the field via an interface. +func (v *CertifyLegalSpec) GetTimeScanned() *time.Time { return v.TimeScanned } + +// GetOrigin returns CertifyLegalSpec.Origin, and is useful for accessing the field via an interface. +func (v *CertifyLegalSpec) GetOrigin() *string { return v.Origin } + +// GetCollector returns CertifyLegalSpec.Collector, and is useful for accessing the field via an interface. +func (v *CertifyLegalSpec) GetCollector() *string { return v.Collector } + +// CertifyLegalSrcResponse is returned by CertifyLegalSrc on success. +type CertifyLegalSrcResponse struct { + // Adds a legal certification to a package or source. + IngestCertifyLegal string `json:"ingestCertifyLegal"` +} + +// GetIngestCertifyLegal returns CertifyLegalSrcResponse.IngestCertifyLegal, and is useful for accessing the field via an interface. +func (v *CertifyLegalSrcResponse) GetIngestCertifyLegal() string { return v.IngestCertifyLegal } + +// CertifyLegalSrcsResponse is returned by CertifyLegalSrcs on success. +type CertifyLegalSrcsResponse struct { + // Bulk add legal certifications to packages or sources, not both at same time. + IngestCertifyLegals []string `json:"ingestCertifyLegals"` +} + +// GetIngestCertifyLegals returns CertifyLegalSrcsResponse.IngestCertifyLegals, and is useful for accessing the field via an interface. +func (v *CertifyLegalSrcsResponse) GetIngestCertifyLegals() []string { return v.IngestCertifyLegals } + +// CertifyLegalsCertifyLegal includes the requested fields of the GraphQL type CertifyLegal. +// The GraphQL type's documentation follows. +// +// CertifyLegal is an attestation to attach legal information to a package or source. +// +// The certification information is either copied from an attestation found in an +// SBOM or created by a collector/scanner. +// +// Discovered license is also known as Concluded. More information: +// https://docs.clearlydefined.io/curation-guidelines#the-difference-between-declared-and-discovered-licenses +// +// Attribution is also known as Copyright Text. It is what could be displayed to +// comply with notice +// requirements. https://www.nexb.com/oss-attribution-best-practices/ +// +// License expressions follow this format: +// https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/ +type CertifyLegalsCertifyLegal struct { + AllCertifyLegalTree `json:"-"` +} + +// GetId returns CertifyLegalsCertifyLegal.Id, and is useful for accessing the field via an interface. +func (v *CertifyLegalsCertifyLegal) GetId() string { return v.AllCertifyLegalTree.Id } + +// GetSubject returns CertifyLegalsCertifyLegal.Subject, and is useful for accessing the field via an interface. +func (v *CertifyLegalsCertifyLegal) GetSubject() AllCertifyLegalTreeSubjectPackageOrSource { + return v.AllCertifyLegalTree.Subject +} + +// GetDeclaredLicense returns CertifyLegalsCertifyLegal.DeclaredLicense, and is useful for accessing the field via an interface. +func (v *CertifyLegalsCertifyLegal) GetDeclaredLicense() string { + return v.AllCertifyLegalTree.DeclaredLicense +} + +// GetDeclaredLicenses returns CertifyLegalsCertifyLegal.DeclaredLicenses, and is useful for accessing the field via an interface. +func (v *CertifyLegalsCertifyLegal) GetDeclaredLicenses() []AllCertifyLegalTreeDeclaredLicensesLicense { + return v.AllCertifyLegalTree.DeclaredLicenses +} + +// GetDiscoveredLicense returns CertifyLegalsCertifyLegal.DiscoveredLicense, and is useful for accessing the field via an interface. +func (v *CertifyLegalsCertifyLegal) GetDiscoveredLicense() string { + return v.AllCertifyLegalTree.DiscoveredLicense +} + +// GetDiscoveredLicenses returns CertifyLegalsCertifyLegal.DiscoveredLicenses, and is useful for accessing the field via an interface. +func (v *CertifyLegalsCertifyLegal) GetDiscoveredLicenses() []AllCertifyLegalTreeDiscoveredLicensesLicense { + return v.AllCertifyLegalTree.DiscoveredLicenses +} + +// GetAttribution returns CertifyLegalsCertifyLegal.Attribution, and is useful for accessing the field via an interface. +func (v *CertifyLegalsCertifyLegal) GetAttribution() string { return v.AllCertifyLegalTree.Attribution } + +// GetJustification returns CertifyLegalsCertifyLegal.Justification, and is useful for accessing the field via an interface. +func (v *CertifyLegalsCertifyLegal) GetJustification() string { + return v.AllCertifyLegalTree.Justification +} + +// GetTimeScanned returns CertifyLegalsCertifyLegal.TimeScanned, and is useful for accessing the field via an interface. +func (v *CertifyLegalsCertifyLegal) GetTimeScanned() time.Time { + return v.AllCertifyLegalTree.TimeScanned +} + +// GetOrigin returns CertifyLegalsCertifyLegal.Origin, and is useful for accessing the field via an interface. +func (v *CertifyLegalsCertifyLegal) GetOrigin() string { return v.AllCertifyLegalTree.Origin } + +// GetCollector returns CertifyLegalsCertifyLegal.Collector, and is useful for accessing the field via an interface. +func (v *CertifyLegalsCertifyLegal) GetCollector() string { return v.AllCertifyLegalTree.Collector } + +func (v *CertifyLegalsCertifyLegal) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CertifyLegalsCertifyLegal + graphql.NoUnmarshalJSON + } + firstPass.CertifyLegalsCertifyLegal = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AllCertifyLegalTree) + if err != nil { + return err + } + return nil +} + +type __premarshalCertifyLegalsCertifyLegal struct { + Id string `json:"id"` + + Subject json.RawMessage `json:"subject"` + + DeclaredLicense string `json:"declaredLicense"` + + DeclaredLicenses []AllCertifyLegalTreeDeclaredLicensesLicense `json:"declaredLicenses"` -// CertifyGoodInputSpec represents the mutation input to ingest a CertifyGood evidence. -type CertifyGoodInputSpec struct { - Justification string `json:"justification"` - Origin string `json:"origin"` - Collector string `json:"collector"` -} + DiscoveredLicense string `json:"discoveredLicense"` -// GetJustification returns CertifyGoodInputSpec.Justification, and is useful for accessing the field via an interface. -func (v *CertifyGoodInputSpec) GetJustification() string { return v.Justification } + DiscoveredLicenses []AllCertifyLegalTreeDiscoveredLicensesLicense `json:"discoveredLicenses"` -// GetOrigin returns CertifyGoodInputSpec.Origin, and is useful for accessing the field via an interface. -func (v *CertifyGoodInputSpec) GetOrigin() string { return v.Origin } + Attribution string `json:"attribution"` -// GetCollector returns CertifyGoodInputSpec.Collector, and is useful for accessing the field via an interface. -func (v *CertifyGoodInputSpec) GetCollector() string { return v.Collector } + Justification string `json:"justification"` -// CertifyGoodPkgResponse is returned by CertifyGoodPkg on success. -type CertifyGoodPkgResponse struct { - // Adds a certification that a package, source or artifact is considered good. The returned ID can be empty string. - IngestCertifyGood string `json:"ingestCertifyGood"` -} + TimeScanned time.Time `json:"timeScanned"` -// GetIngestCertifyGood returns CertifyGoodPkgResponse.IngestCertifyGood, and is useful for accessing the field via an interface. -func (v *CertifyGoodPkgResponse) GetIngestCertifyGood() string { return v.IngestCertifyGood } + Origin string `json:"origin"` -// CertifyGoodPkgsResponse is returned by CertifyGoodPkgs on success. -type CertifyGoodPkgsResponse struct { - // Adds bulk certifications that a package, source or artifact is considered good. The returned array of IDs can be a an array of empty string. - IngestCertifyGoods []string `json:"ingestCertifyGoods"` + Collector string `json:"collector"` } -// GetIngestCertifyGoods returns CertifyGoodPkgsResponse.IngestCertifyGoods, and is useful for accessing the field via an interface. -func (v *CertifyGoodPkgsResponse) GetIngestCertifyGoods() []string { return v.IngestCertifyGoods } - -// CertifyGoodSrcResponse is returned by CertifyGoodSrc on success. -type CertifyGoodSrcResponse struct { - // Adds a certification that a package, source or artifact is considered good. The returned ID can be empty string. - IngestCertifyGood string `json:"ingestCertifyGood"` +func (v *CertifyLegalsCertifyLegal) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) } -// GetIngestCertifyGood returns CertifyGoodSrcResponse.IngestCertifyGood, and is useful for accessing the field via an interface. -func (v *CertifyGoodSrcResponse) GetIngestCertifyGood() string { return v.IngestCertifyGood } +func (v *CertifyLegalsCertifyLegal) __premarshalJSON() (*__premarshalCertifyLegalsCertifyLegal, error) { + var retval __premarshalCertifyLegalsCertifyLegal -// CertifyGoodSrcsResponse is returned by CertifyGoodSrcs on success. -type CertifyGoodSrcsResponse struct { - // Adds bulk certifications that a package, source or artifact is considered good. The returned array of IDs can be a an array of empty string. - IngestCertifyGoods []string `json:"ingestCertifyGoods"` + retval.Id = v.AllCertifyLegalTree.Id + { + + dst := &retval.Subject + src := v.AllCertifyLegalTree.Subject + var err error + *dst, err = __marshalAllCertifyLegalTreeSubjectPackageOrSource( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal CertifyLegalsCertifyLegal.AllCertifyLegalTree.Subject: %w", err) + } + } + retval.DeclaredLicense = v.AllCertifyLegalTree.DeclaredLicense + retval.DeclaredLicenses = v.AllCertifyLegalTree.DeclaredLicenses + retval.DiscoveredLicense = v.AllCertifyLegalTree.DiscoveredLicense + retval.DiscoveredLicenses = v.AllCertifyLegalTree.DiscoveredLicenses + retval.Attribution = v.AllCertifyLegalTree.Attribution + retval.Justification = v.AllCertifyLegalTree.Justification + retval.TimeScanned = v.AllCertifyLegalTree.TimeScanned + retval.Origin = v.AllCertifyLegalTree.Origin + retval.Collector = v.AllCertifyLegalTree.Collector + return &retval, nil } -// GetIngestCertifyGoods returns CertifyGoodSrcsResponse.IngestCertifyGoods, and is useful for accessing the field via an interface. -func (v *CertifyGoodSrcsResponse) GetIngestCertifyGoods() []string { return v.IngestCertifyGoods } +// CertifyLegalsResponse is returned by CertifyLegals on success. +type CertifyLegalsResponse struct { + // Returns all legal certifications matching the input filter. + CertifyLegal []CertifyLegalsCertifyLegal `json:"CertifyLegal"` +} + +// GetCertifyLegal returns CertifyLegalsResponse.CertifyLegal, and is useful for accessing the field via an interface. +func (v *CertifyLegalsResponse) GetCertifyLegal() []CertifyLegalsCertifyLegal { return v.CertifyLegal } // CertifyScorecardResponse is returned by CertifyScorecard on success. type CertifyScorecardResponse struct { @@ -5732,47 +6696,56 @@ const ( EdgeArtifactCertifyGood Edge = "ARTIFACT_CERTIFY_GOOD" EdgeArtifactCertifyVexStatement Edge = "ARTIFACT_CERTIFY_VEX_STATEMENT" EdgeArtifactHashEqual Edge = "ARTIFACT_HASH_EQUAL" + EdgeArtifactHasMetadata Edge = "ARTIFACT_HAS_METADATA" EdgeArtifactHasSbom Edge = "ARTIFACT_HAS_SBOM" EdgeArtifactHasSlsa Edge = "ARTIFACT_HAS_SLSA" EdgeArtifactIsOccurrence Edge = "ARTIFACT_IS_OCCURRENCE" - EdgeArtifactHasMetadata Edge = "ARTIFACT_HAS_METADATA" EdgeArtifactPointOfContact Edge = "ARTIFACT_POINT_OF_CONTACT" EdgeBuilderHasSlsa Edge = "BUILDER_HAS_SLSA" - EdgeVulnerabilityCertifyVexStatement Edge = "VULNERABILITY_CERTIFY_VEX_STATEMENT" - EdgeVulnerabilityCertifyVuln Edge = "VULNERABILITY_CERTIFY_VULN" - EdgeVulnerabilityVulnEqual Edge = "VULNERABILITY_VULN_EQUAL" - EdgeVulnerabilityVulnMetadata Edge = "VULNERABILITY_VULN_METADATA" + EdgeLicenseCertifyLegal Edge = "LICENSE_CERTIFY_LEGAL" EdgePackageCertifyBad Edge = "PACKAGE_CERTIFY_BAD" EdgePackageCertifyGood Edge = "PACKAGE_CERTIFY_GOOD" + EdgePackageCertifyLegal Edge = "PACKAGE_CERTIFY_LEGAL" EdgePackageCertifyVexStatement Edge = "PACKAGE_CERTIFY_VEX_STATEMENT" EdgePackageCertifyVuln Edge = "PACKAGE_CERTIFY_VULN" + EdgePackageHasMetadata Edge = "PACKAGE_HAS_METADATA" EdgePackageHasSbom Edge = "PACKAGE_HAS_SBOM" EdgePackageHasSourceAt Edge = "PACKAGE_HAS_SOURCE_AT" EdgePackageIsDependency Edge = "PACKAGE_IS_DEPENDENCY" EdgePackageIsOccurrence Edge = "PACKAGE_IS_OCCURRENCE" EdgePackagePkgEqual Edge = "PACKAGE_PKG_EQUAL" - EdgePackageHasMetadata Edge = "PACKAGE_HAS_METADATA" EdgePackagePointOfContact Edge = "PACKAGE_POINT_OF_CONTACT" EdgeSourceCertifyBad Edge = "SOURCE_CERTIFY_BAD" EdgeSourceCertifyGood Edge = "SOURCE_CERTIFY_GOOD" + EdgeSourceCertifyLegal Edge = "SOURCE_CERTIFY_LEGAL" EdgeSourceCertifyScorecard Edge = "SOURCE_CERTIFY_SCORECARD" + EdgeSourceHasMetadata Edge = "SOURCE_HAS_METADATA" EdgeSourceHasSourceAt Edge = "SOURCE_HAS_SOURCE_AT" EdgeSourceIsOccurrence Edge = "SOURCE_IS_OCCURRENCE" - EdgeSourceHasMetadata Edge = "SOURCE_HAS_METADATA" EdgeSourcePointOfContact Edge = "SOURCE_POINT_OF_CONTACT" + EdgeVulnerabilityCertifyVexStatement Edge = "VULNERABILITY_CERTIFY_VEX_STATEMENT" + EdgeVulnerabilityCertifyVuln Edge = "VULNERABILITY_CERTIFY_VULN" + EdgeVulnerabilityVulnEqual Edge = "VULNERABILITY_VULN_EQUAL" + EdgeVulnerabilityVulnMetadata Edge = "VULNERABILITY_VULN_METADATA" EdgeCertifyBadArtifact Edge = "CERTIFY_BAD_ARTIFACT" EdgeCertifyBadPackage Edge = "CERTIFY_BAD_PACKAGE" EdgeCertifyBadSource Edge = "CERTIFY_BAD_SOURCE" EdgeCertifyGoodArtifact Edge = "CERTIFY_GOOD_ARTIFACT" EdgeCertifyGoodPackage Edge = "CERTIFY_GOOD_PACKAGE" EdgeCertifyGoodSource Edge = "CERTIFY_GOOD_SOURCE" + EdgeCertifyLegalLicense Edge = "CERTIFY_LEGAL_LICENSE" + EdgeCertifyLegalPackage Edge = "CERTIFY_LEGAL_PACKAGE" + EdgeCertifyLegalSource Edge = "CERTIFY_LEGAL_SOURCE" EdgeCertifyScorecardSource Edge = "CERTIFY_SCORECARD_SOURCE" EdgeCertifyVexStatementArtifact Edge = "CERTIFY_VEX_STATEMENT_ARTIFACT" - EdgeCertifyVexStatementVulnerability Edge = "CERTIFY_VEX_STATEMENT_VULNERABILITY" EdgeCertifyVexStatementPackage Edge = "CERTIFY_VEX_STATEMENT_PACKAGE" - EdgeCertifyVulnVulnerability Edge = "CERTIFY_VULN_VULNERABILITY" + EdgeCertifyVexStatementVulnerability Edge = "CERTIFY_VEX_STATEMENT_VULNERABILITY" EdgeCertifyVulnPackage Edge = "CERTIFY_VULN_PACKAGE" + EdgeCertifyVulnVulnerability Edge = "CERTIFY_VULN_VULNERABILITY" EdgeHashEqualArtifact Edge = "HASH_EQUAL_ARTIFACT" + EdgeHasMetadataArtifact Edge = "HAS_METADATA_ARTIFACT" + EdgeHasMetadataPackage Edge = "HAS_METADATA_PACKAGE" + EdgeHasMetadataSource Edge = "HAS_METADATA_SOURCE" EdgeHasSbomArtifact Edge = "HAS_SBOM_ARTIFACT" EdgeHasSbomPackage Edge = "HAS_SBOM_PACKAGE" EdgeHasSlsaBuiltBy Edge = "HAS_SLSA_BUILT_BY" @@ -5784,14 +6757,11 @@ const ( EdgeIsOccurrenceArtifact Edge = "IS_OCCURRENCE_ARTIFACT" EdgeIsOccurrencePackage Edge = "IS_OCCURRENCE_PACKAGE" EdgeIsOccurrenceSource Edge = "IS_OCCURRENCE_SOURCE" - EdgeVulnEqualVulnerability Edge = "VULN_EQUAL_VULNERABILITY" EdgePkgEqualPackage Edge = "PKG_EQUAL_PACKAGE" - EdgeHasMetadataPackage Edge = "HAS_METADATA_PACKAGE" - EdgeHasMetadataArtifact Edge = "HAS_METADATA_ARTIFACT" - EdgeHasMetadataSource Edge = "HAS_METADATA_SOURCE" - EdgePointOfContactPackage Edge = "POINT_OF_CONTACT_PACKAGE" EdgePointOfContactArtifact Edge = "POINT_OF_CONTACT_ARTIFACT" + EdgePointOfContactPackage Edge = "POINT_OF_CONTACT_PACKAGE" EdgePointOfContactSource Edge = "POINT_OF_CONTACT_SOURCE" + EdgeVulnEqualVulnerability Edge = "VULN_EQUAL_VULNERABILITY" EdgeVulnMetadataVulnerability Edge = "VULN_METADATA_VULNERABILITY" ) @@ -6472,6 +7442,24 @@ type IngestBuildersResponse struct { // GetIngestBuilders returns IngestBuildersResponse.IngestBuilders, and is useful for accessing the field via an interface. func (v *IngestBuildersResponse) GetIngestBuilders() []string { return v.IngestBuilders } +// IngestLicenseResponse is returned by IngestLicense on success. +type IngestLicenseResponse struct { + // Ingests a new license and returns it. + IngestLicense string `json:"ingestLicense"` +} + +// GetIngestLicense returns IngestLicenseResponse.IngestLicense, and is useful for accessing the field via an interface. +func (v *IngestLicenseResponse) GetIngestLicense() string { return v.IngestLicense } + +// IngestLicensesResponse is returned by IngestLicenses on success. +type IngestLicensesResponse struct { + // Bulk ingests new licenses and returns a list of them. + IngestLicenses []string `json:"ingestLicenses"` +} + +// GetIngestLicenses returns IngestLicensesResponse.IngestLicenses, and is useful for accessing the field via an interface. +func (v *IngestLicensesResponse) GetIngestLicenses() []string { return v.IngestLicenses } + // IngestPackageResponse is returned by IngestPackage on success. type IngestPackageResponse struct { // Ingests a new package and returns the corresponding package trie path. The returned ID can be empty string. @@ -6623,6 +7611,149 @@ type IsOccurrencesSrcResponse struct { // GetIngestOccurrences returns IsOccurrencesSrcResponse.IngestOccurrences, and is useful for accessing the field via an interface. func (v *IsOccurrencesSrcResponse) GetIngestOccurrences() []string { return v.IngestOccurrences } +// LicenseInputSpec specifies an license for mutations. One of inline or +// listVersion should be empty or missing. +type LicenseInputSpec struct { + Name string `json:"name"` + Inline *string `json:"inline"` + ListVersion *string `json:"listVersion"` +} + +// GetName returns LicenseInputSpec.Name, and is useful for accessing the field via an interface. +func (v *LicenseInputSpec) GetName() string { return v.Name } + +// GetInline returns LicenseInputSpec.Inline, and is useful for accessing the field via an interface. +func (v *LicenseInputSpec) GetInline() *string { return v.Inline } + +// GetListVersion returns LicenseInputSpec.ListVersion, and is useful for accessing the field via an interface. +func (v *LicenseInputSpec) GetListVersion() *string { return v.ListVersion } + +// LicenseSpec allows filtering the list of licenses to return in a query. +type LicenseSpec struct { + Id *string `json:"id"` + Name *string `json:"name"` + Inline *string `json:"inline"` + ListVersion *string `json:"listVersion"` +} + +// GetId returns LicenseSpec.Id, and is useful for accessing the field via an interface. +func (v *LicenseSpec) GetId() *string { return v.Id } + +// GetName returns LicenseSpec.Name, and is useful for accessing the field via an interface. +func (v *LicenseSpec) GetName() *string { return v.Name } + +// GetInline returns LicenseSpec.Inline, and is useful for accessing the field via an interface. +func (v *LicenseSpec) GetInline() *string { return v.Inline } + +// GetListVersion returns LicenseSpec.ListVersion, and is useful for accessing the field via an interface. +func (v *LicenseSpec) GetListVersion() *string { return v.ListVersion } + +// LicensesLicensesLicense includes the requested fields of the GraphQL type License. +// The GraphQL type's documentation follows. +// +// License represents a particular license. If the license is found on the SPDX +// license list (https://spdx.org/licenses/) then the fields should be: +// +// Name: SPDX license identifier +// Inline: empty +// ListVersion: SPDX license list version +// +// example: +// +// Name: AGPL-3.0-or-later +// Inline: "" +// ListVersion: 3.21 2023-06-18 +// +// If the license is not on the SPDX license list, then a new guid should be +// created and the license text placed inline: +// +// Name: LicenseRef- +// Inline: Full license text +// ListVersion: empty +// +// example: +// +// Name: LicenseRef-1a2b3c +// Inline: Permission to use, copy, modify, and/or distribute ... +// ListVersion: "" +type LicensesLicensesLicense struct { + AllLicenseTree `json:"-"` +} + +// GetId returns LicensesLicensesLicense.Id, and is useful for accessing the field via an interface. +func (v *LicensesLicensesLicense) GetId() string { return v.AllLicenseTree.Id } + +// GetName returns LicensesLicensesLicense.Name, and is useful for accessing the field via an interface. +func (v *LicensesLicensesLicense) GetName() string { return v.AllLicenseTree.Name } + +// GetInline returns LicensesLicensesLicense.Inline, and is useful for accessing the field via an interface. +func (v *LicensesLicensesLicense) GetInline() *string { return v.AllLicenseTree.Inline } + +// GetListVersion returns LicensesLicensesLicense.ListVersion, and is useful for accessing the field via an interface. +func (v *LicensesLicensesLicense) GetListVersion() *string { return v.AllLicenseTree.ListVersion } + +func (v *LicensesLicensesLicense) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *LicensesLicensesLicense + graphql.NoUnmarshalJSON + } + firstPass.LicensesLicensesLicense = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AllLicenseTree) + if err != nil { + return err + } + return nil +} + +type __premarshalLicensesLicensesLicense struct { + Id string `json:"id"` + + Name string `json:"name"` + + Inline *string `json:"inline"` + + ListVersion *string `json:"listVersion"` +} + +func (v *LicensesLicensesLicense) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *LicensesLicensesLicense) __premarshalJSON() (*__premarshalLicensesLicensesLicense, error) { + var retval __premarshalLicensesLicensesLicense + + retval.Id = v.AllLicenseTree.Id + retval.Name = v.AllLicenseTree.Name + retval.Inline = v.AllLicenseTree.Inline + retval.ListVersion = v.AllLicenseTree.ListVersion + return &retval, nil +} + +// LicensesResponse is returned by Licenses on success. +type LicensesResponse struct { + // Returns all licenses matching a filter. + Licenses []LicensesLicensesLicense `json:"licenses"` +} + +// GetLicenses returns LicensesResponse.Licenses, and is useful for accessing the field via an interface. +func (v *LicensesResponse) GetLicenses() []LicensesLicensesLicense { return v.Licenses } + // MatchFlags is used to input the PkgMatchType enum. type MatchFlags struct { Pkg PkgMatchType `json:"pkg"` @@ -6911,39 +8042,185 @@ type NeighborsNeighborsCertifyGood struct { AllCertifyGood `json:"-"` } -// GetTypename returns NeighborsNeighborsCertifyGood.Typename, and is useful for accessing the field via an interface. -func (v *NeighborsNeighborsCertifyGood) GetTypename() *string { return v.Typename } +// GetTypename returns NeighborsNeighborsCertifyGood.Typename, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyGood) GetTypename() *string { return v.Typename } + +// GetId returns NeighborsNeighborsCertifyGood.Id, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyGood) GetId() string { return v.AllCertifyGood.Id } + +// GetJustification returns NeighborsNeighborsCertifyGood.Justification, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyGood) GetJustification() string { + return v.AllCertifyGood.Justification +} + +// GetSubject returns NeighborsNeighborsCertifyGood.Subject, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyGood) GetSubject() AllCertifyGoodSubjectPackageSourceOrArtifact { + return v.AllCertifyGood.Subject +} + +// GetOrigin returns NeighborsNeighborsCertifyGood.Origin, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyGood) GetOrigin() string { return v.AllCertifyGood.Origin } + +// GetCollector returns NeighborsNeighborsCertifyGood.Collector, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyGood) GetCollector() string { return v.AllCertifyGood.Collector } + +func (v *NeighborsNeighborsCertifyGood) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *NeighborsNeighborsCertifyGood + graphql.NoUnmarshalJSON + } + firstPass.NeighborsNeighborsCertifyGood = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AllCertifyGood) + if err != nil { + return err + } + return nil +} + +type __premarshalNeighborsNeighborsCertifyGood struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Justification string `json:"justification"` + + Subject json.RawMessage `json:"subject"` + + Origin string `json:"origin"` + + Collector string `json:"collector"` +} + +func (v *NeighborsNeighborsCertifyGood) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *NeighborsNeighborsCertifyGood) __premarshalJSON() (*__premarshalNeighborsNeighborsCertifyGood, error) { + var retval __premarshalNeighborsNeighborsCertifyGood + + retval.Typename = v.Typename + retval.Id = v.AllCertifyGood.Id + retval.Justification = v.AllCertifyGood.Justification + { + + dst := &retval.Subject + src := v.AllCertifyGood.Subject + var err error + *dst, err = __marshalAllCertifyGoodSubjectPackageSourceOrArtifact( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal NeighborsNeighborsCertifyGood.AllCertifyGood.Subject: %w", err) + } + } + retval.Origin = v.AllCertifyGood.Origin + retval.Collector = v.AllCertifyGood.Collector + return &retval, nil +} + +// NeighborsNeighborsCertifyLegal includes the requested fields of the GraphQL type CertifyLegal. +// The GraphQL type's documentation follows. +// +// CertifyLegal is an attestation to attach legal information to a package or source. +// +// The certification information is either copied from an attestation found in an +// SBOM or created by a collector/scanner. +// +// Discovered license is also known as Concluded. More information: +// https://docs.clearlydefined.io/curation-guidelines#the-difference-between-declared-and-discovered-licenses +// +// Attribution is also known as Copyright Text. It is what could be displayed to +// comply with notice +// requirements. https://www.nexb.com/oss-attribution-best-practices/ +// +// License expressions follow this format: +// https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/ +type NeighborsNeighborsCertifyLegal struct { + Typename *string `json:"__typename"` + AllCertifyLegalTree `json:"-"` +} + +// GetTypename returns NeighborsNeighborsCertifyLegal.Typename, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyLegal) GetTypename() *string { return v.Typename } -// GetId returns NeighborsNeighborsCertifyGood.Id, and is useful for accessing the field via an interface. -func (v *NeighborsNeighborsCertifyGood) GetId() string { return v.AllCertifyGood.Id } +// GetId returns NeighborsNeighborsCertifyLegal.Id, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyLegal) GetId() string { return v.AllCertifyLegalTree.Id } -// GetJustification returns NeighborsNeighborsCertifyGood.Justification, and is useful for accessing the field via an interface. -func (v *NeighborsNeighborsCertifyGood) GetJustification() string { - return v.AllCertifyGood.Justification +// GetSubject returns NeighborsNeighborsCertifyLegal.Subject, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyLegal) GetSubject() AllCertifyLegalTreeSubjectPackageOrSource { + return v.AllCertifyLegalTree.Subject } -// GetSubject returns NeighborsNeighborsCertifyGood.Subject, and is useful for accessing the field via an interface. -func (v *NeighborsNeighborsCertifyGood) GetSubject() AllCertifyGoodSubjectPackageSourceOrArtifact { - return v.AllCertifyGood.Subject +// GetDeclaredLicense returns NeighborsNeighborsCertifyLegal.DeclaredLicense, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyLegal) GetDeclaredLicense() string { + return v.AllCertifyLegalTree.DeclaredLicense } -// GetOrigin returns NeighborsNeighborsCertifyGood.Origin, and is useful for accessing the field via an interface. -func (v *NeighborsNeighborsCertifyGood) GetOrigin() string { return v.AllCertifyGood.Origin } +// GetDeclaredLicenses returns NeighborsNeighborsCertifyLegal.DeclaredLicenses, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyLegal) GetDeclaredLicenses() []AllCertifyLegalTreeDeclaredLicensesLicense { + return v.AllCertifyLegalTree.DeclaredLicenses +} -// GetCollector returns NeighborsNeighborsCertifyGood.Collector, and is useful for accessing the field via an interface. -func (v *NeighborsNeighborsCertifyGood) GetCollector() string { return v.AllCertifyGood.Collector } +// GetDiscoveredLicense returns NeighborsNeighborsCertifyLegal.DiscoveredLicense, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyLegal) GetDiscoveredLicense() string { + return v.AllCertifyLegalTree.DiscoveredLicense +} -func (v *NeighborsNeighborsCertifyGood) UnmarshalJSON(b []byte) error { +// GetDiscoveredLicenses returns NeighborsNeighborsCertifyLegal.DiscoveredLicenses, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyLegal) GetDiscoveredLicenses() []AllCertifyLegalTreeDiscoveredLicensesLicense { + return v.AllCertifyLegalTree.DiscoveredLicenses +} + +// GetAttribution returns NeighborsNeighborsCertifyLegal.Attribution, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyLegal) GetAttribution() string { + return v.AllCertifyLegalTree.Attribution +} + +// GetJustification returns NeighborsNeighborsCertifyLegal.Justification, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyLegal) GetJustification() string { + return v.AllCertifyLegalTree.Justification +} + +// GetTimeScanned returns NeighborsNeighborsCertifyLegal.TimeScanned, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyLegal) GetTimeScanned() time.Time { + return v.AllCertifyLegalTree.TimeScanned +} + +// GetOrigin returns NeighborsNeighborsCertifyLegal.Origin, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyLegal) GetOrigin() string { return v.AllCertifyLegalTree.Origin } + +// GetCollector returns NeighborsNeighborsCertifyLegal.Collector, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsCertifyLegal) GetCollector() string { + return v.AllCertifyLegalTree.Collector +} + +func (v *NeighborsNeighborsCertifyLegal) UnmarshalJSON(b []byte) error { if string(b) == "null" { return nil } var firstPass struct { - *NeighborsNeighborsCertifyGood + *NeighborsNeighborsCertifyLegal graphql.NoUnmarshalJSON } - firstPass.NeighborsNeighborsCertifyGood = v + firstPass.NeighborsNeighborsCertifyLegal = v err := json.Unmarshal(b, &firstPass) if err != nil { @@ -6951,28 +8228,40 @@ func (v *NeighborsNeighborsCertifyGood) UnmarshalJSON(b []byte) error { } err = json.Unmarshal( - b, &v.AllCertifyGood) + b, &v.AllCertifyLegalTree) if err != nil { return err } return nil } -type __premarshalNeighborsNeighborsCertifyGood struct { +type __premarshalNeighborsNeighborsCertifyLegal struct { Typename *string `json:"__typename"` Id string `json:"id"` + Subject json.RawMessage `json:"subject"` + + DeclaredLicense string `json:"declaredLicense"` + + DeclaredLicenses []AllCertifyLegalTreeDeclaredLicensesLicense `json:"declaredLicenses"` + + DiscoveredLicense string `json:"discoveredLicense"` + + DiscoveredLicenses []AllCertifyLegalTreeDiscoveredLicensesLicense `json:"discoveredLicenses"` + + Attribution string `json:"attribution"` + Justification string `json:"justification"` - Subject json.RawMessage `json:"subject"` + TimeScanned time.Time `json:"timeScanned"` Origin string `json:"origin"` Collector string `json:"collector"` } -func (v *NeighborsNeighborsCertifyGood) MarshalJSON() ([]byte, error) { +func (v *NeighborsNeighborsCertifyLegal) MarshalJSON() ([]byte, error) { premarshaled, err := v.__premarshalJSON() if err != nil { return nil, err @@ -6980,26 +8269,32 @@ func (v *NeighborsNeighborsCertifyGood) MarshalJSON() ([]byte, error) { return json.Marshal(premarshaled) } -func (v *NeighborsNeighborsCertifyGood) __premarshalJSON() (*__premarshalNeighborsNeighborsCertifyGood, error) { - var retval __premarshalNeighborsNeighborsCertifyGood +func (v *NeighborsNeighborsCertifyLegal) __premarshalJSON() (*__premarshalNeighborsNeighborsCertifyLegal, error) { + var retval __premarshalNeighborsNeighborsCertifyLegal retval.Typename = v.Typename - retval.Id = v.AllCertifyGood.Id - retval.Justification = v.AllCertifyGood.Justification + retval.Id = v.AllCertifyLegalTree.Id { dst := &retval.Subject - src := v.AllCertifyGood.Subject + src := v.AllCertifyLegalTree.Subject var err error - *dst, err = __marshalAllCertifyGoodSubjectPackageSourceOrArtifact( + *dst, err = __marshalAllCertifyLegalTreeSubjectPackageOrSource( &src) if err != nil { return nil, fmt.Errorf( - "unable to marshal NeighborsNeighborsCertifyGood.AllCertifyGood.Subject: %w", err) - } - } - retval.Origin = v.AllCertifyGood.Origin - retval.Collector = v.AllCertifyGood.Collector + "unable to marshal NeighborsNeighborsCertifyLegal.AllCertifyLegalTree.Subject: %w", err) + } + } + retval.DeclaredLicense = v.AllCertifyLegalTree.DeclaredLicense + retval.DeclaredLicenses = v.AllCertifyLegalTree.DeclaredLicenses + retval.DiscoveredLicense = v.AllCertifyLegalTree.DiscoveredLicense + retval.DiscoveredLicenses = v.AllCertifyLegalTree.DiscoveredLicenses + retval.Attribution = v.AllCertifyLegalTree.Attribution + retval.Justification = v.AllCertifyLegalTree.Justification + retval.TimeScanned = v.AllCertifyLegalTree.TimeScanned + retval.Origin = v.AllCertifyLegalTree.Origin + retval.Collector = v.AllCertifyLegalTree.Collector return &retval, nil } @@ -8065,6 +9360,110 @@ func (v *NeighborsNeighborsIsOccurrence) __premarshalJSON() (*__premarshalNeighb return &retval, nil } +// NeighborsNeighborsLicense includes the requested fields of the GraphQL type License. +// The GraphQL type's documentation follows. +// +// License represents a particular license. If the license is found on the SPDX +// license list (https://spdx.org/licenses/) then the fields should be: +// +// Name: SPDX license identifier +// Inline: empty +// ListVersion: SPDX license list version +// +// example: +// +// Name: AGPL-3.0-or-later +// Inline: "" +// ListVersion: 3.21 2023-06-18 +// +// If the license is not on the SPDX license list, then a new guid should be +// created and the license text placed inline: +// +// Name: LicenseRef- +// Inline: Full license text +// ListVersion: empty +// +// example: +// +// Name: LicenseRef-1a2b3c +// Inline: Permission to use, copy, modify, and/or distribute ... +// ListVersion: "" +type NeighborsNeighborsLicense struct { + Typename *string `json:"__typename"` + AllLicenseTree `json:"-"` +} + +// GetTypename returns NeighborsNeighborsLicense.Typename, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsLicense) GetTypename() *string { return v.Typename } + +// GetId returns NeighborsNeighborsLicense.Id, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsLicense) GetId() string { return v.AllLicenseTree.Id } + +// GetName returns NeighborsNeighborsLicense.Name, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsLicense) GetName() string { return v.AllLicenseTree.Name } + +// GetInline returns NeighborsNeighborsLicense.Inline, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsLicense) GetInline() *string { return v.AllLicenseTree.Inline } + +// GetListVersion returns NeighborsNeighborsLicense.ListVersion, and is useful for accessing the field via an interface. +func (v *NeighborsNeighborsLicense) GetListVersion() *string { return v.AllLicenseTree.ListVersion } + +func (v *NeighborsNeighborsLicense) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *NeighborsNeighborsLicense + graphql.NoUnmarshalJSON + } + firstPass.NeighborsNeighborsLicense = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AllLicenseTree) + if err != nil { + return err + } + return nil +} + +type __premarshalNeighborsNeighborsLicense struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + Inline *string `json:"inline"` + + ListVersion *string `json:"listVersion"` +} + +func (v *NeighborsNeighborsLicense) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *NeighborsNeighborsLicense) __premarshalJSON() (*__premarshalNeighborsNeighborsLicense, error) { + var retval __premarshalNeighborsNeighborsLicense + + retval.Typename = v.Typename + retval.Id = v.AllLicenseTree.Id + retval.Name = v.AllLicenseTree.Name + retval.Inline = v.AllLicenseTree.Inline + retval.ListVersion = v.AllLicenseTree.ListVersion + return &retval, nil +} + // NeighborsNeighborsNode includes the requested fields of the GraphQL interface Node. // // NeighborsNeighborsNode is implemented by the following types: @@ -8072,6 +9471,7 @@ func (v *NeighborsNeighborsIsOccurrence) __premarshalJSON() (*__premarshalNeighb // NeighborsNeighborsBuilder // NeighborsNeighborsCertifyBad // NeighborsNeighborsCertifyGood +// NeighborsNeighborsCertifyLegal // NeighborsNeighborsCertifyScorecard // NeighborsNeighborsCertifyVEXStatement // NeighborsNeighborsCertifyVuln @@ -8082,6 +9482,7 @@ func (v *NeighborsNeighborsIsOccurrence) __premarshalJSON() (*__premarshalNeighb // NeighborsNeighborsHashEqual // NeighborsNeighborsIsDependency // NeighborsNeighborsIsOccurrence +// NeighborsNeighborsLicense // NeighborsNeighborsPackage // NeighborsNeighborsPkgEqual // NeighborsNeighborsPointOfContact @@ -8106,6 +9507,7 @@ func (v *NeighborsNeighborsArtifact) implementsGraphQLInterfaceNeighborsNeighbor func (v *NeighborsNeighborsBuilder) implementsGraphQLInterfaceNeighborsNeighborsNode() {} func (v *NeighborsNeighborsCertifyBad) implementsGraphQLInterfaceNeighborsNeighborsNode() {} func (v *NeighborsNeighborsCertifyGood) implementsGraphQLInterfaceNeighborsNeighborsNode() {} +func (v *NeighborsNeighborsCertifyLegal) implementsGraphQLInterfaceNeighborsNeighborsNode() {} func (v *NeighborsNeighborsCertifyScorecard) implementsGraphQLInterfaceNeighborsNeighborsNode() {} func (v *NeighborsNeighborsCertifyVEXStatement) implementsGraphQLInterfaceNeighborsNeighborsNode() {} func (v *NeighborsNeighborsCertifyVuln) implementsGraphQLInterfaceNeighborsNeighborsNode() {} @@ -8116,6 +9518,7 @@ func (v *NeighborsNeighborsHasSourceAt) implementsGraphQLInterfaceNeighborsNeigh func (v *NeighborsNeighborsHashEqual) implementsGraphQLInterfaceNeighborsNeighborsNode() {} func (v *NeighborsNeighborsIsDependency) implementsGraphQLInterfaceNeighborsNeighborsNode() {} func (v *NeighborsNeighborsIsOccurrence) implementsGraphQLInterfaceNeighborsNeighborsNode() {} +func (v *NeighborsNeighborsLicense) implementsGraphQLInterfaceNeighborsNeighborsNode() {} func (v *NeighborsNeighborsPackage) implementsGraphQLInterfaceNeighborsNeighborsNode() {} func (v *NeighborsNeighborsPkgEqual) implementsGraphQLInterfaceNeighborsNeighborsNode() {} func (v *NeighborsNeighborsPointOfContact) implementsGraphQLInterfaceNeighborsNeighborsNode() {} @@ -8151,6 +9554,9 @@ func __unmarshalNeighborsNeighborsNode(b []byte, v *NeighborsNeighborsNode) erro case "CertifyGood": *v = new(NeighborsNeighborsCertifyGood) return json.Unmarshal(b, *v) + case "CertifyLegal": + *v = new(NeighborsNeighborsCertifyLegal) + return json.Unmarshal(b, *v) case "CertifyScorecard": *v = new(NeighborsNeighborsCertifyScorecard) return json.Unmarshal(b, *v) @@ -8181,6 +9587,9 @@ func __unmarshalNeighborsNeighborsNode(b []byte, v *NeighborsNeighborsNode) erro case "IsOccurrence": *v = new(NeighborsNeighborsIsOccurrence) return json.Unmarshal(b, *v) + case "License": + *v = new(NeighborsNeighborsLicense) + return json.Unmarshal(b, *v) case "Package": *v = new(NeighborsNeighborsPackage) return json.Unmarshal(b, *v) @@ -8263,6 +9672,18 @@ func __marshalNeighborsNeighborsNode(v *NeighborsNeighborsNode) ([]byte, error) *__premarshalNeighborsNeighborsCertifyGood }{typename, premarshaled} return json.Marshal(result) + case *NeighborsNeighborsCertifyLegal: + typename = "CertifyLegal" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalNeighborsNeighborsCertifyLegal + }{typename, premarshaled} + return json.Marshal(result) case *NeighborsNeighborsCertifyScorecard: typename = "CertifyScorecard" @@ -8383,6 +9804,18 @@ func __marshalNeighborsNeighborsNode(v *NeighborsNeighborsNode) ([]byte, error) *__premarshalNeighborsNeighborsIsOccurrence }{typename, premarshaled} return json.Marshal(result) + case *NeighborsNeighborsLicense: + typename = "License" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalNeighborsNeighborsLicense + }{typename, premarshaled} + return json.Marshal(result) case *NeighborsNeighborsPackage: typename = "Package" @@ -9295,6 +10728,7 @@ func (v *NeighborsResponse) __premarshalJSON() (*__premarshalNeighborsResponse, // NodeNodeBuilder // NodeNodeCertifyBad // NodeNodeCertifyGood +// NodeNodeCertifyLegal // NodeNodeCertifyScorecard // NodeNodeCertifyVEXStatement // NodeNodeCertifyVuln @@ -9305,6 +10739,7 @@ func (v *NeighborsResponse) __premarshalJSON() (*__premarshalNeighborsResponse, // NodeNodeHashEqual // NodeNodeIsDependency // NodeNodeIsOccurrence +// NodeNodeLicense // NodeNodePackage // NodeNodePkgEqual // NodeNodePointOfContact @@ -9329,6 +10764,7 @@ func (v *NodeNodeArtifact) implementsGraphQLInterfaceNodeNode() {} func (v *NodeNodeBuilder) implementsGraphQLInterfaceNodeNode() {} func (v *NodeNodeCertifyBad) implementsGraphQLInterfaceNodeNode() {} func (v *NodeNodeCertifyGood) implementsGraphQLInterfaceNodeNode() {} +func (v *NodeNodeCertifyLegal) implementsGraphQLInterfaceNodeNode() {} func (v *NodeNodeCertifyScorecard) implementsGraphQLInterfaceNodeNode() {} func (v *NodeNodeCertifyVEXStatement) implementsGraphQLInterfaceNodeNode() {} func (v *NodeNodeCertifyVuln) implementsGraphQLInterfaceNodeNode() {} @@ -9339,6 +10775,7 @@ func (v *NodeNodeHasSourceAt) implementsGraphQLInterfaceNodeNode() {} func (v *NodeNodeHashEqual) implementsGraphQLInterfaceNodeNode() {} func (v *NodeNodeIsDependency) implementsGraphQLInterfaceNodeNode() {} func (v *NodeNodeIsOccurrence) implementsGraphQLInterfaceNodeNode() {} +func (v *NodeNodeLicense) implementsGraphQLInterfaceNodeNode() {} func (v *NodeNodePackage) implementsGraphQLInterfaceNodeNode() {} func (v *NodeNodePkgEqual) implementsGraphQLInterfaceNodeNode() {} func (v *NodeNodePointOfContact) implementsGraphQLInterfaceNodeNode() {} @@ -9373,6 +10810,9 @@ func __unmarshalNodeNode(b []byte, v *NodeNode) error { case "CertifyGood": *v = new(NodeNodeCertifyGood) return json.Unmarshal(b, *v) + case "CertifyLegal": + *v = new(NodeNodeCertifyLegal) + return json.Unmarshal(b, *v) case "CertifyScorecard": *v = new(NodeNodeCertifyScorecard) return json.Unmarshal(b, *v) @@ -9403,6 +10843,9 @@ func __unmarshalNodeNode(b []byte, v *NodeNode) error { case "IsOccurrence": *v = new(NodeNodeIsOccurrence) return json.Unmarshal(b, *v) + case "License": + *v = new(NodeNodeLicense) + return json.Unmarshal(b, *v) case "Package": *v = new(NodeNodePackage) return json.Unmarshal(b, *v) @@ -9485,6 +10928,18 @@ func __marshalNodeNode(v *NodeNode) ([]byte, error) { *__premarshalNodeNodeCertifyGood }{typename, premarshaled} return json.Marshal(result) + case *NodeNodeCertifyLegal: + typename = "CertifyLegal" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalNodeNodeCertifyLegal + }{typename, premarshaled} + return json.Marshal(result) case *NodeNodeCertifyScorecard: typename = "CertifyScorecard" @@ -9605,6 +11060,18 @@ func __marshalNodeNode(v *NodeNode) ([]byte, error) { *__premarshalNodeNodeIsOccurrence }{typename, premarshaled} return json.Marshal(result) + case *NodeNodeLicense: + typename = "License" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalNodeNodeLicense + }{typename, premarshaled} + return json.Marshal(result) case *NodeNodePackage: typename = "Package" @@ -10034,7 +11501,157 @@ type __premarshalNodeNodeCertifyGood struct { Collector string `json:"collector"` } -func (v *NodeNodeCertifyGood) MarshalJSON() ([]byte, error) { +func (v *NodeNodeCertifyGood) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *NodeNodeCertifyGood) __premarshalJSON() (*__premarshalNodeNodeCertifyGood, error) { + var retval __premarshalNodeNodeCertifyGood + + retval.Typename = v.Typename + retval.Id = v.AllCertifyGood.Id + retval.Justification = v.AllCertifyGood.Justification + { + + dst := &retval.Subject + src := v.AllCertifyGood.Subject + var err error + *dst, err = __marshalAllCertifyGoodSubjectPackageSourceOrArtifact( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal NodeNodeCertifyGood.AllCertifyGood.Subject: %w", err) + } + } + retval.Origin = v.AllCertifyGood.Origin + retval.Collector = v.AllCertifyGood.Collector + return &retval, nil +} + +// NodeNodeCertifyLegal includes the requested fields of the GraphQL type CertifyLegal. +// The GraphQL type's documentation follows. +// +// CertifyLegal is an attestation to attach legal information to a package or source. +// +// The certification information is either copied from an attestation found in an +// SBOM or created by a collector/scanner. +// +// Discovered license is also known as Concluded. More information: +// https://docs.clearlydefined.io/curation-guidelines#the-difference-between-declared-and-discovered-licenses +// +// Attribution is also known as Copyright Text. It is what could be displayed to +// comply with notice +// requirements. https://www.nexb.com/oss-attribution-best-practices/ +// +// License expressions follow this format: +// https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/ +type NodeNodeCertifyLegal struct { + Typename *string `json:"__typename"` + AllCertifyLegalTree `json:"-"` +} + +// GetTypename returns NodeNodeCertifyLegal.Typename, and is useful for accessing the field via an interface. +func (v *NodeNodeCertifyLegal) GetTypename() *string { return v.Typename } + +// GetId returns NodeNodeCertifyLegal.Id, and is useful for accessing the field via an interface. +func (v *NodeNodeCertifyLegal) GetId() string { return v.AllCertifyLegalTree.Id } + +// GetSubject returns NodeNodeCertifyLegal.Subject, and is useful for accessing the field via an interface. +func (v *NodeNodeCertifyLegal) GetSubject() AllCertifyLegalTreeSubjectPackageOrSource { + return v.AllCertifyLegalTree.Subject +} + +// GetDeclaredLicense returns NodeNodeCertifyLegal.DeclaredLicense, and is useful for accessing the field via an interface. +func (v *NodeNodeCertifyLegal) GetDeclaredLicense() string { + return v.AllCertifyLegalTree.DeclaredLicense +} + +// GetDeclaredLicenses returns NodeNodeCertifyLegal.DeclaredLicenses, and is useful for accessing the field via an interface. +func (v *NodeNodeCertifyLegal) GetDeclaredLicenses() []AllCertifyLegalTreeDeclaredLicensesLicense { + return v.AllCertifyLegalTree.DeclaredLicenses +} + +// GetDiscoveredLicense returns NodeNodeCertifyLegal.DiscoveredLicense, and is useful for accessing the field via an interface. +func (v *NodeNodeCertifyLegal) GetDiscoveredLicense() string { + return v.AllCertifyLegalTree.DiscoveredLicense +} + +// GetDiscoveredLicenses returns NodeNodeCertifyLegal.DiscoveredLicenses, and is useful for accessing the field via an interface. +func (v *NodeNodeCertifyLegal) GetDiscoveredLicenses() []AllCertifyLegalTreeDiscoveredLicensesLicense { + return v.AllCertifyLegalTree.DiscoveredLicenses +} + +// GetAttribution returns NodeNodeCertifyLegal.Attribution, and is useful for accessing the field via an interface. +func (v *NodeNodeCertifyLegal) GetAttribution() string { return v.AllCertifyLegalTree.Attribution } + +// GetJustification returns NodeNodeCertifyLegal.Justification, and is useful for accessing the field via an interface. +func (v *NodeNodeCertifyLegal) GetJustification() string { return v.AllCertifyLegalTree.Justification } + +// GetTimeScanned returns NodeNodeCertifyLegal.TimeScanned, and is useful for accessing the field via an interface. +func (v *NodeNodeCertifyLegal) GetTimeScanned() time.Time { return v.AllCertifyLegalTree.TimeScanned } + +// GetOrigin returns NodeNodeCertifyLegal.Origin, and is useful for accessing the field via an interface. +func (v *NodeNodeCertifyLegal) GetOrigin() string { return v.AllCertifyLegalTree.Origin } + +// GetCollector returns NodeNodeCertifyLegal.Collector, and is useful for accessing the field via an interface. +func (v *NodeNodeCertifyLegal) GetCollector() string { return v.AllCertifyLegalTree.Collector } + +func (v *NodeNodeCertifyLegal) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *NodeNodeCertifyLegal + graphql.NoUnmarshalJSON + } + firstPass.NodeNodeCertifyLegal = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AllCertifyLegalTree) + if err != nil { + return err + } + return nil +} + +type __premarshalNodeNodeCertifyLegal struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Subject json.RawMessage `json:"subject"` + + DeclaredLicense string `json:"declaredLicense"` + + DeclaredLicenses []AllCertifyLegalTreeDeclaredLicensesLicense `json:"declaredLicenses"` + + DiscoveredLicense string `json:"discoveredLicense"` + + DiscoveredLicenses []AllCertifyLegalTreeDiscoveredLicensesLicense `json:"discoveredLicenses"` + + Attribution string `json:"attribution"` + + Justification string `json:"justification"` + + TimeScanned time.Time `json:"timeScanned"` + + Origin string `json:"origin"` + + Collector string `json:"collector"` +} + +func (v *NodeNodeCertifyLegal) MarshalJSON() ([]byte, error) { premarshaled, err := v.__premarshalJSON() if err != nil { return nil, err @@ -10042,26 +11659,32 @@ func (v *NodeNodeCertifyGood) MarshalJSON() ([]byte, error) { return json.Marshal(premarshaled) } -func (v *NodeNodeCertifyGood) __premarshalJSON() (*__premarshalNodeNodeCertifyGood, error) { - var retval __premarshalNodeNodeCertifyGood +func (v *NodeNodeCertifyLegal) __premarshalJSON() (*__premarshalNodeNodeCertifyLegal, error) { + var retval __premarshalNodeNodeCertifyLegal retval.Typename = v.Typename - retval.Id = v.AllCertifyGood.Id - retval.Justification = v.AllCertifyGood.Justification + retval.Id = v.AllCertifyLegalTree.Id { dst := &retval.Subject - src := v.AllCertifyGood.Subject + src := v.AllCertifyLegalTree.Subject var err error - *dst, err = __marshalAllCertifyGoodSubjectPackageSourceOrArtifact( + *dst, err = __marshalAllCertifyLegalTreeSubjectPackageOrSource( &src) if err != nil { return nil, fmt.Errorf( - "unable to marshal NodeNodeCertifyGood.AllCertifyGood.Subject: %w", err) - } - } - retval.Origin = v.AllCertifyGood.Origin - retval.Collector = v.AllCertifyGood.Collector + "unable to marshal NodeNodeCertifyLegal.AllCertifyLegalTree.Subject: %w", err) + } + } + retval.DeclaredLicense = v.AllCertifyLegalTree.DeclaredLicense + retval.DeclaredLicenses = v.AllCertifyLegalTree.DeclaredLicenses + retval.DiscoveredLicense = v.AllCertifyLegalTree.DiscoveredLicense + retval.DiscoveredLicenses = v.AllCertifyLegalTree.DiscoveredLicenses + retval.Attribution = v.AllCertifyLegalTree.Attribution + retval.Justification = v.AllCertifyLegalTree.Justification + retval.TimeScanned = v.AllCertifyLegalTree.TimeScanned + retval.Origin = v.AllCertifyLegalTree.Origin + retval.Collector = v.AllCertifyLegalTree.Collector return &retval, nil } @@ -11097,6 +12720,110 @@ func (v *NodeNodeIsOccurrence) __premarshalJSON() (*__premarshalNodeNodeIsOccurr return &retval, nil } +// NodeNodeLicense includes the requested fields of the GraphQL type License. +// The GraphQL type's documentation follows. +// +// License represents a particular license. If the license is found on the SPDX +// license list (https://spdx.org/licenses/) then the fields should be: +// +// Name: SPDX license identifier +// Inline: empty +// ListVersion: SPDX license list version +// +// example: +// +// Name: AGPL-3.0-or-later +// Inline: "" +// ListVersion: 3.21 2023-06-18 +// +// If the license is not on the SPDX license list, then a new guid should be +// created and the license text placed inline: +// +// Name: LicenseRef- +// Inline: Full license text +// ListVersion: empty +// +// example: +// +// Name: LicenseRef-1a2b3c +// Inline: Permission to use, copy, modify, and/or distribute ... +// ListVersion: "" +type NodeNodeLicense struct { + Typename *string `json:"__typename"` + AllLicenseTree `json:"-"` +} + +// GetTypename returns NodeNodeLicense.Typename, and is useful for accessing the field via an interface. +func (v *NodeNodeLicense) GetTypename() *string { return v.Typename } + +// GetId returns NodeNodeLicense.Id, and is useful for accessing the field via an interface. +func (v *NodeNodeLicense) GetId() string { return v.AllLicenseTree.Id } + +// GetName returns NodeNodeLicense.Name, and is useful for accessing the field via an interface. +func (v *NodeNodeLicense) GetName() string { return v.AllLicenseTree.Name } + +// GetInline returns NodeNodeLicense.Inline, and is useful for accessing the field via an interface. +func (v *NodeNodeLicense) GetInline() *string { return v.AllLicenseTree.Inline } + +// GetListVersion returns NodeNodeLicense.ListVersion, and is useful for accessing the field via an interface. +func (v *NodeNodeLicense) GetListVersion() *string { return v.AllLicenseTree.ListVersion } + +func (v *NodeNodeLicense) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *NodeNodeLicense + graphql.NoUnmarshalJSON + } + firstPass.NodeNodeLicense = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AllLicenseTree) + if err != nil { + return err + } + return nil +} + +type __premarshalNodeNodeLicense struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + Inline *string `json:"inline"` + + ListVersion *string `json:"listVersion"` +} + +func (v *NodeNodeLicense) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *NodeNodeLicense) __premarshalJSON() (*__premarshalNodeNodeLicense, error) { + var retval __premarshalNodeNodeLicense + + retval.Typename = v.Typename + retval.Id = v.AllLicenseTree.Id + retval.Name = v.AllLicenseTree.Name + retval.Inline = v.AllLicenseTree.Inline + retval.ListVersion = v.AllLicenseTree.ListVersion + return &retval, nil +} + // NodeNodePackage includes the requested fields of the GraphQL type Package. // The GraphQL type's documentation follows. // @@ -12253,6 +13980,164 @@ func (v *NodesNodesCertifyGood) __premarshalJSON() (*__premarshalNodesNodesCerti return &retval, nil } +// NodesNodesCertifyLegal includes the requested fields of the GraphQL type CertifyLegal. +// The GraphQL type's documentation follows. +// +// CertifyLegal is an attestation to attach legal information to a package or source. +// +// The certification information is either copied from an attestation found in an +// SBOM or created by a collector/scanner. +// +// Discovered license is also known as Concluded. More information: +// https://docs.clearlydefined.io/curation-guidelines#the-difference-between-declared-and-discovered-licenses +// +// Attribution is also known as Copyright Text. It is what could be displayed to +// comply with notice +// requirements. https://www.nexb.com/oss-attribution-best-practices/ +// +// License expressions follow this format: +// https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/ +type NodesNodesCertifyLegal struct { + Typename *string `json:"__typename"` + AllCertifyLegalTree `json:"-"` +} + +// GetTypename returns NodesNodesCertifyLegal.Typename, and is useful for accessing the field via an interface. +func (v *NodesNodesCertifyLegal) GetTypename() *string { return v.Typename } + +// GetId returns NodesNodesCertifyLegal.Id, and is useful for accessing the field via an interface. +func (v *NodesNodesCertifyLegal) GetId() string { return v.AllCertifyLegalTree.Id } + +// GetSubject returns NodesNodesCertifyLegal.Subject, and is useful for accessing the field via an interface. +func (v *NodesNodesCertifyLegal) GetSubject() AllCertifyLegalTreeSubjectPackageOrSource { + return v.AllCertifyLegalTree.Subject +} + +// GetDeclaredLicense returns NodesNodesCertifyLegal.DeclaredLicense, and is useful for accessing the field via an interface. +func (v *NodesNodesCertifyLegal) GetDeclaredLicense() string { + return v.AllCertifyLegalTree.DeclaredLicense +} + +// GetDeclaredLicenses returns NodesNodesCertifyLegal.DeclaredLicenses, and is useful for accessing the field via an interface. +func (v *NodesNodesCertifyLegal) GetDeclaredLicenses() []AllCertifyLegalTreeDeclaredLicensesLicense { + return v.AllCertifyLegalTree.DeclaredLicenses +} + +// GetDiscoveredLicense returns NodesNodesCertifyLegal.DiscoveredLicense, and is useful for accessing the field via an interface. +func (v *NodesNodesCertifyLegal) GetDiscoveredLicense() string { + return v.AllCertifyLegalTree.DiscoveredLicense +} + +// GetDiscoveredLicenses returns NodesNodesCertifyLegal.DiscoveredLicenses, and is useful for accessing the field via an interface. +func (v *NodesNodesCertifyLegal) GetDiscoveredLicenses() []AllCertifyLegalTreeDiscoveredLicensesLicense { + return v.AllCertifyLegalTree.DiscoveredLicenses +} + +// GetAttribution returns NodesNodesCertifyLegal.Attribution, and is useful for accessing the field via an interface. +func (v *NodesNodesCertifyLegal) GetAttribution() string { return v.AllCertifyLegalTree.Attribution } + +// GetJustification returns NodesNodesCertifyLegal.Justification, and is useful for accessing the field via an interface. +func (v *NodesNodesCertifyLegal) GetJustification() string { + return v.AllCertifyLegalTree.Justification +} + +// GetTimeScanned returns NodesNodesCertifyLegal.TimeScanned, and is useful for accessing the field via an interface. +func (v *NodesNodesCertifyLegal) GetTimeScanned() time.Time { return v.AllCertifyLegalTree.TimeScanned } + +// GetOrigin returns NodesNodesCertifyLegal.Origin, and is useful for accessing the field via an interface. +func (v *NodesNodesCertifyLegal) GetOrigin() string { return v.AllCertifyLegalTree.Origin } + +// GetCollector returns NodesNodesCertifyLegal.Collector, and is useful for accessing the field via an interface. +func (v *NodesNodesCertifyLegal) GetCollector() string { return v.AllCertifyLegalTree.Collector } + +func (v *NodesNodesCertifyLegal) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *NodesNodesCertifyLegal + graphql.NoUnmarshalJSON + } + firstPass.NodesNodesCertifyLegal = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AllCertifyLegalTree) + if err != nil { + return err + } + return nil +} + +type __premarshalNodesNodesCertifyLegal struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Subject json.RawMessage `json:"subject"` + + DeclaredLicense string `json:"declaredLicense"` + + DeclaredLicenses []AllCertifyLegalTreeDeclaredLicensesLicense `json:"declaredLicenses"` + + DiscoveredLicense string `json:"discoveredLicense"` + + DiscoveredLicenses []AllCertifyLegalTreeDiscoveredLicensesLicense `json:"discoveredLicenses"` + + Attribution string `json:"attribution"` + + Justification string `json:"justification"` + + TimeScanned time.Time `json:"timeScanned"` + + Origin string `json:"origin"` + + Collector string `json:"collector"` +} + +func (v *NodesNodesCertifyLegal) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *NodesNodesCertifyLegal) __premarshalJSON() (*__premarshalNodesNodesCertifyLegal, error) { + var retval __premarshalNodesNodesCertifyLegal + + retval.Typename = v.Typename + retval.Id = v.AllCertifyLegalTree.Id + { + + dst := &retval.Subject + src := v.AllCertifyLegalTree.Subject + var err error + *dst, err = __marshalAllCertifyLegalTreeSubjectPackageOrSource( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal NodesNodesCertifyLegal.AllCertifyLegalTree.Subject: %w", err) + } + } + retval.DeclaredLicense = v.AllCertifyLegalTree.DeclaredLicense + retval.DeclaredLicenses = v.AllCertifyLegalTree.DeclaredLicenses + retval.DiscoveredLicense = v.AllCertifyLegalTree.DiscoveredLicense + retval.DiscoveredLicenses = v.AllCertifyLegalTree.DiscoveredLicenses + retval.Attribution = v.AllCertifyLegalTree.Attribution + retval.Justification = v.AllCertifyLegalTree.Justification + retval.TimeScanned = v.AllCertifyLegalTree.TimeScanned + retval.Origin = v.AllCertifyLegalTree.Origin + retval.Collector = v.AllCertifyLegalTree.Collector + return &retval, nil +} + // NodesNodesCertifyScorecard includes the requested fields of the GraphQL type CertifyScorecard. // The GraphQL type's documentation follows. // @@ -13200,33 +15085,154 @@ func (v *NodesNodesIsOccurrence) GetSubject() AllIsOccurrencesTreeSubjectPackage return v.AllIsOccurrencesTree.Subject } -// GetArtifact returns NodesNodesIsOccurrence.Artifact, and is useful for accessing the field via an interface. -func (v *NodesNodesIsOccurrence) GetArtifact() AllIsOccurrencesTreeArtifact { - return v.AllIsOccurrencesTree.Artifact -} +// GetArtifact returns NodesNodesIsOccurrence.Artifact, and is useful for accessing the field via an interface. +func (v *NodesNodesIsOccurrence) GetArtifact() AllIsOccurrencesTreeArtifact { + return v.AllIsOccurrencesTree.Artifact +} + +// GetJustification returns NodesNodesIsOccurrence.Justification, and is useful for accessing the field via an interface. +func (v *NodesNodesIsOccurrence) GetJustification() string { + return v.AllIsOccurrencesTree.Justification +} + +// GetOrigin returns NodesNodesIsOccurrence.Origin, and is useful for accessing the field via an interface. +func (v *NodesNodesIsOccurrence) GetOrigin() string { return v.AllIsOccurrencesTree.Origin } + +// GetCollector returns NodesNodesIsOccurrence.Collector, and is useful for accessing the field via an interface. +func (v *NodesNodesIsOccurrence) GetCollector() string { return v.AllIsOccurrencesTree.Collector } + +func (v *NodesNodesIsOccurrence) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *NodesNodesIsOccurrence + graphql.NoUnmarshalJSON + } + firstPass.NodesNodesIsOccurrence = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AllIsOccurrencesTree) + if err != nil { + return err + } + return nil +} + +type __premarshalNodesNodesIsOccurrence struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Subject json.RawMessage `json:"subject"` + + Artifact AllIsOccurrencesTreeArtifact `json:"artifact"` + + Justification string `json:"justification"` + + Origin string `json:"origin"` + + Collector string `json:"collector"` +} + +func (v *NodesNodesIsOccurrence) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *NodesNodesIsOccurrence) __premarshalJSON() (*__premarshalNodesNodesIsOccurrence, error) { + var retval __premarshalNodesNodesIsOccurrence + + retval.Typename = v.Typename + retval.Id = v.AllIsOccurrencesTree.Id + { + + dst := &retval.Subject + src := v.AllIsOccurrencesTree.Subject + var err error + *dst, err = __marshalAllIsOccurrencesTreeSubjectPackageOrSource( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal NodesNodesIsOccurrence.AllIsOccurrencesTree.Subject: %w", err) + } + } + retval.Artifact = v.AllIsOccurrencesTree.Artifact + retval.Justification = v.AllIsOccurrencesTree.Justification + retval.Origin = v.AllIsOccurrencesTree.Origin + retval.Collector = v.AllIsOccurrencesTree.Collector + return &retval, nil +} + +// NodesNodesLicense includes the requested fields of the GraphQL type License. +// The GraphQL type's documentation follows. +// +// License represents a particular license. If the license is found on the SPDX +// license list (https://spdx.org/licenses/) then the fields should be: +// +// Name: SPDX license identifier +// Inline: empty +// ListVersion: SPDX license list version +// +// example: +// +// Name: AGPL-3.0-or-later +// Inline: "" +// ListVersion: 3.21 2023-06-18 +// +// If the license is not on the SPDX license list, then a new guid should be +// created and the license text placed inline: +// +// Name: LicenseRef- +// Inline: Full license text +// ListVersion: empty +// +// example: +// +// Name: LicenseRef-1a2b3c +// Inline: Permission to use, copy, modify, and/or distribute ... +// ListVersion: "" +type NodesNodesLicense struct { + Typename *string `json:"__typename"` + AllLicenseTree `json:"-"` +} + +// GetTypename returns NodesNodesLicense.Typename, and is useful for accessing the field via an interface. +func (v *NodesNodesLicense) GetTypename() *string { return v.Typename } -// GetJustification returns NodesNodesIsOccurrence.Justification, and is useful for accessing the field via an interface. -func (v *NodesNodesIsOccurrence) GetJustification() string { - return v.AllIsOccurrencesTree.Justification -} +// GetId returns NodesNodesLicense.Id, and is useful for accessing the field via an interface. +func (v *NodesNodesLicense) GetId() string { return v.AllLicenseTree.Id } -// GetOrigin returns NodesNodesIsOccurrence.Origin, and is useful for accessing the field via an interface. -func (v *NodesNodesIsOccurrence) GetOrigin() string { return v.AllIsOccurrencesTree.Origin } +// GetName returns NodesNodesLicense.Name, and is useful for accessing the field via an interface. +func (v *NodesNodesLicense) GetName() string { return v.AllLicenseTree.Name } -// GetCollector returns NodesNodesIsOccurrence.Collector, and is useful for accessing the field via an interface. -func (v *NodesNodesIsOccurrence) GetCollector() string { return v.AllIsOccurrencesTree.Collector } +// GetInline returns NodesNodesLicense.Inline, and is useful for accessing the field via an interface. +func (v *NodesNodesLicense) GetInline() *string { return v.AllLicenseTree.Inline } -func (v *NodesNodesIsOccurrence) UnmarshalJSON(b []byte) error { +// GetListVersion returns NodesNodesLicense.ListVersion, and is useful for accessing the field via an interface. +func (v *NodesNodesLicense) GetListVersion() *string { return v.AllLicenseTree.ListVersion } + +func (v *NodesNodesLicense) UnmarshalJSON(b []byte) error { if string(b) == "null" { return nil } var firstPass struct { - *NodesNodesIsOccurrence + *NodesNodesLicense graphql.NoUnmarshalJSON } - firstPass.NodesNodesIsOccurrence = v + firstPass.NodesNodesLicense = v err := json.Unmarshal(b, &firstPass) if err != nil { @@ -13234,30 +15240,26 @@ func (v *NodesNodesIsOccurrence) UnmarshalJSON(b []byte) error { } err = json.Unmarshal( - b, &v.AllIsOccurrencesTree) + b, &v.AllLicenseTree) if err != nil { return err } return nil } -type __premarshalNodesNodesIsOccurrence struct { +type __premarshalNodesNodesLicense struct { Typename *string `json:"__typename"` Id string `json:"id"` - Subject json.RawMessage `json:"subject"` - - Artifact AllIsOccurrencesTreeArtifact `json:"artifact"` - - Justification string `json:"justification"` + Name string `json:"name"` - Origin string `json:"origin"` + Inline *string `json:"inline"` - Collector string `json:"collector"` + ListVersion *string `json:"listVersion"` } -func (v *NodesNodesIsOccurrence) MarshalJSON() ([]byte, error) { +func (v *NodesNodesLicense) MarshalJSON() ([]byte, error) { premarshaled, err := v.__premarshalJSON() if err != nil { return nil, err @@ -13265,27 +15267,14 @@ func (v *NodesNodesIsOccurrence) MarshalJSON() ([]byte, error) { return json.Marshal(premarshaled) } -func (v *NodesNodesIsOccurrence) __premarshalJSON() (*__premarshalNodesNodesIsOccurrence, error) { - var retval __premarshalNodesNodesIsOccurrence +func (v *NodesNodesLicense) __premarshalJSON() (*__premarshalNodesNodesLicense, error) { + var retval __premarshalNodesNodesLicense retval.Typename = v.Typename - retval.Id = v.AllIsOccurrencesTree.Id - { - - dst := &retval.Subject - src := v.AllIsOccurrencesTree.Subject - var err error - *dst, err = __marshalAllIsOccurrencesTreeSubjectPackageOrSource( - &src) - if err != nil { - return nil, fmt.Errorf( - "unable to marshal NodesNodesIsOccurrence.AllIsOccurrencesTree.Subject: %w", err) - } - } - retval.Artifact = v.AllIsOccurrencesTree.Artifact - retval.Justification = v.AllIsOccurrencesTree.Justification - retval.Origin = v.AllIsOccurrencesTree.Origin - retval.Collector = v.AllIsOccurrencesTree.Collector + retval.Id = v.AllLicenseTree.Id + retval.Name = v.AllLicenseTree.Name + retval.Inline = v.AllLicenseTree.Inline + retval.ListVersion = v.AllLicenseTree.ListVersion return &retval, nil } @@ -13296,6 +15285,7 @@ func (v *NodesNodesIsOccurrence) __premarshalJSON() (*__premarshalNodesNodesIsOc // NodesNodesBuilder // NodesNodesCertifyBad // NodesNodesCertifyGood +// NodesNodesCertifyLegal // NodesNodesCertifyScorecard // NodesNodesCertifyVEXStatement // NodesNodesCertifyVuln @@ -13306,6 +15296,7 @@ func (v *NodesNodesIsOccurrence) __premarshalJSON() (*__premarshalNodesNodesIsOc // NodesNodesHashEqual // NodesNodesIsDependency // NodesNodesIsOccurrence +// NodesNodesLicense // NodesNodesPackage // NodesNodesPkgEqual // NodesNodesPointOfContact @@ -13330,6 +15321,7 @@ func (v *NodesNodesArtifact) implementsGraphQLInterfaceNodesNodesNode() func (v *NodesNodesBuilder) implementsGraphQLInterfaceNodesNodesNode() {} func (v *NodesNodesCertifyBad) implementsGraphQLInterfaceNodesNodesNode() {} func (v *NodesNodesCertifyGood) implementsGraphQLInterfaceNodesNodesNode() {} +func (v *NodesNodesCertifyLegal) implementsGraphQLInterfaceNodesNodesNode() {} func (v *NodesNodesCertifyScorecard) implementsGraphQLInterfaceNodesNodesNode() {} func (v *NodesNodesCertifyVEXStatement) implementsGraphQLInterfaceNodesNodesNode() {} func (v *NodesNodesCertifyVuln) implementsGraphQLInterfaceNodesNodesNode() {} @@ -13340,6 +15332,7 @@ func (v *NodesNodesHasSourceAt) implementsGraphQLInterfaceNodesNodesNode() func (v *NodesNodesHashEqual) implementsGraphQLInterfaceNodesNodesNode() {} func (v *NodesNodesIsDependency) implementsGraphQLInterfaceNodesNodesNode() {} func (v *NodesNodesIsOccurrence) implementsGraphQLInterfaceNodesNodesNode() {} +func (v *NodesNodesLicense) implementsGraphQLInterfaceNodesNodesNode() {} func (v *NodesNodesPackage) implementsGraphQLInterfaceNodesNodesNode() {} func (v *NodesNodesPkgEqual) implementsGraphQLInterfaceNodesNodesNode() {} func (v *NodesNodesPointOfContact) implementsGraphQLInterfaceNodesNodesNode() {} @@ -13374,6 +15367,9 @@ func __unmarshalNodesNodesNode(b []byte, v *NodesNodesNode) error { case "CertifyGood": *v = new(NodesNodesCertifyGood) return json.Unmarshal(b, *v) + case "CertifyLegal": + *v = new(NodesNodesCertifyLegal) + return json.Unmarshal(b, *v) case "CertifyScorecard": *v = new(NodesNodesCertifyScorecard) return json.Unmarshal(b, *v) @@ -13404,6 +15400,9 @@ func __unmarshalNodesNodesNode(b []byte, v *NodesNodesNode) error { case "IsOccurrence": *v = new(NodesNodesIsOccurrence) return json.Unmarshal(b, *v) + case "License": + *v = new(NodesNodesLicense) + return json.Unmarshal(b, *v) case "Package": *v = new(NodesNodesPackage) return json.Unmarshal(b, *v) @@ -13486,6 +15485,18 @@ func __marshalNodesNodesNode(v *NodesNodesNode) ([]byte, error) { *__premarshalNodesNodesCertifyGood }{typename, premarshaled} return json.Marshal(result) + case *NodesNodesCertifyLegal: + typename = "CertifyLegal" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalNodesNodesCertifyLegal + }{typename, premarshaled} + return json.Marshal(result) case *NodesNodesCertifyScorecard: typename = "CertifyScorecard" @@ -13606,6 +15617,18 @@ func __marshalNodesNodesNode(v *NodesNodesNode) ([]byte, error) { *__premarshalNodesNodesIsOccurrence }{typename, premarshaled} return json.Marshal(result) + case *NodesNodesLicense: + typename = "License" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalNodesNodesLicense + }{typename, premarshaled} + return json.Marshal(result) case *NodesNodesPackage: typename = "Package" @@ -14671,6 +16694,20 @@ func (v *PackageNamespacesResponse) GetPackages() []PackageNamespacesPackagesPac return v.Packages } +// PackageOrSourceSpec allows using PackageOrSource union as input for queries. +// +// Exactly one field must be specified. +type PackageOrSourceSpec struct { + Package *PkgSpec `json:"package"` + Source *SourceSpec `json:"source"` +} + +// GetPackage returns PackageOrSourceSpec.Package, and is useful for accessing the field via an interface. +func (v *PackageOrSourceSpec) GetPackage() *PkgSpec { return v.Package } + +// GetSource returns PackageOrSourceSpec.Source, and is useful for accessing the field via an interface. +func (v *PackageOrSourceSpec) GetSource() *SourceSpec { return v.Source } + // PackageQualifierInputSpec allows specifying package qualifiers in mutations. type PackageQualifierInputSpec struct { Key string `json:"key"` @@ -15397,6 +17434,162 @@ func (v *PathPathCertifyGood) __premarshalJSON() (*__premarshalPathPathCertifyGo return &retval, nil } +// PathPathCertifyLegal includes the requested fields of the GraphQL type CertifyLegal. +// The GraphQL type's documentation follows. +// +// CertifyLegal is an attestation to attach legal information to a package or source. +// +// The certification information is either copied from an attestation found in an +// SBOM or created by a collector/scanner. +// +// Discovered license is also known as Concluded. More information: +// https://docs.clearlydefined.io/curation-guidelines#the-difference-between-declared-and-discovered-licenses +// +// Attribution is also known as Copyright Text. It is what could be displayed to +// comply with notice +// requirements. https://www.nexb.com/oss-attribution-best-practices/ +// +// License expressions follow this format: +// https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/ +type PathPathCertifyLegal struct { + Typename *string `json:"__typename"` + AllCertifyLegalTree `json:"-"` +} + +// GetTypename returns PathPathCertifyLegal.Typename, and is useful for accessing the field via an interface. +func (v *PathPathCertifyLegal) GetTypename() *string { return v.Typename } + +// GetId returns PathPathCertifyLegal.Id, and is useful for accessing the field via an interface. +func (v *PathPathCertifyLegal) GetId() string { return v.AllCertifyLegalTree.Id } + +// GetSubject returns PathPathCertifyLegal.Subject, and is useful for accessing the field via an interface. +func (v *PathPathCertifyLegal) GetSubject() AllCertifyLegalTreeSubjectPackageOrSource { + return v.AllCertifyLegalTree.Subject +} + +// GetDeclaredLicense returns PathPathCertifyLegal.DeclaredLicense, and is useful for accessing the field via an interface. +func (v *PathPathCertifyLegal) GetDeclaredLicense() string { + return v.AllCertifyLegalTree.DeclaredLicense +} + +// GetDeclaredLicenses returns PathPathCertifyLegal.DeclaredLicenses, and is useful for accessing the field via an interface. +func (v *PathPathCertifyLegal) GetDeclaredLicenses() []AllCertifyLegalTreeDeclaredLicensesLicense { + return v.AllCertifyLegalTree.DeclaredLicenses +} + +// GetDiscoveredLicense returns PathPathCertifyLegal.DiscoveredLicense, and is useful for accessing the field via an interface. +func (v *PathPathCertifyLegal) GetDiscoveredLicense() string { + return v.AllCertifyLegalTree.DiscoveredLicense +} + +// GetDiscoveredLicenses returns PathPathCertifyLegal.DiscoveredLicenses, and is useful for accessing the field via an interface. +func (v *PathPathCertifyLegal) GetDiscoveredLicenses() []AllCertifyLegalTreeDiscoveredLicensesLicense { + return v.AllCertifyLegalTree.DiscoveredLicenses +} + +// GetAttribution returns PathPathCertifyLegal.Attribution, and is useful for accessing the field via an interface. +func (v *PathPathCertifyLegal) GetAttribution() string { return v.AllCertifyLegalTree.Attribution } + +// GetJustification returns PathPathCertifyLegal.Justification, and is useful for accessing the field via an interface. +func (v *PathPathCertifyLegal) GetJustification() string { return v.AllCertifyLegalTree.Justification } + +// GetTimeScanned returns PathPathCertifyLegal.TimeScanned, and is useful for accessing the field via an interface. +func (v *PathPathCertifyLegal) GetTimeScanned() time.Time { return v.AllCertifyLegalTree.TimeScanned } + +// GetOrigin returns PathPathCertifyLegal.Origin, and is useful for accessing the field via an interface. +func (v *PathPathCertifyLegal) GetOrigin() string { return v.AllCertifyLegalTree.Origin } + +// GetCollector returns PathPathCertifyLegal.Collector, and is useful for accessing the field via an interface. +func (v *PathPathCertifyLegal) GetCollector() string { return v.AllCertifyLegalTree.Collector } + +func (v *PathPathCertifyLegal) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *PathPathCertifyLegal + graphql.NoUnmarshalJSON + } + firstPass.PathPathCertifyLegal = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AllCertifyLegalTree) + if err != nil { + return err + } + return nil +} + +type __premarshalPathPathCertifyLegal struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Subject json.RawMessage `json:"subject"` + + DeclaredLicense string `json:"declaredLicense"` + + DeclaredLicenses []AllCertifyLegalTreeDeclaredLicensesLicense `json:"declaredLicenses"` + + DiscoveredLicense string `json:"discoveredLicense"` + + DiscoveredLicenses []AllCertifyLegalTreeDiscoveredLicensesLicense `json:"discoveredLicenses"` + + Attribution string `json:"attribution"` + + Justification string `json:"justification"` + + TimeScanned time.Time `json:"timeScanned"` + + Origin string `json:"origin"` + + Collector string `json:"collector"` +} + +func (v *PathPathCertifyLegal) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *PathPathCertifyLegal) __premarshalJSON() (*__premarshalPathPathCertifyLegal, error) { + var retval __premarshalPathPathCertifyLegal + + retval.Typename = v.Typename + retval.Id = v.AllCertifyLegalTree.Id + { + + dst := &retval.Subject + src := v.AllCertifyLegalTree.Subject + var err error + *dst, err = __marshalAllCertifyLegalTreeSubjectPackageOrSource( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal PathPathCertifyLegal.AllCertifyLegalTree.Subject: %w", err) + } + } + retval.DeclaredLicense = v.AllCertifyLegalTree.DeclaredLicense + retval.DeclaredLicenses = v.AllCertifyLegalTree.DeclaredLicenses + retval.DiscoveredLicense = v.AllCertifyLegalTree.DiscoveredLicense + retval.DiscoveredLicenses = v.AllCertifyLegalTree.DiscoveredLicenses + retval.Attribution = v.AllCertifyLegalTree.Attribution + retval.Justification = v.AllCertifyLegalTree.Justification + retval.TimeScanned = v.AllCertifyLegalTree.TimeScanned + retval.Origin = v.AllCertifyLegalTree.Origin + retval.Collector = v.AllCertifyLegalTree.Collector + return &retval, nil +} + // PathPathCertifyScorecard includes the requested fields of the GraphQL type CertifyScorecard. // The GraphQL type's documentation follows. // @@ -16347,26 +18540,147 @@ func (v *PathPathIsOccurrence) GetArtifact() AllIsOccurrencesTreeArtifact { return v.AllIsOccurrencesTree.Artifact } -// GetJustification returns PathPathIsOccurrence.Justification, and is useful for accessing the field via an interface. -func (v *PathPathIsOccurrence) GetJustification() string { return v.AllIsOccurrencesTree.Justification } +// GetJustification returns PathPathIsOccurrence.Justification, and is useful for accessing the field via an interface. +func (v *PathPathIsOccurrence) GetJustification() string { return v.AllIsOccurrencesTree.Justification } + +// GetOrigin returns PathPathIsOccurrence.Origin, and is useful for accessing the field via an interface. +func (v *PathPathIsOccurrence) GetOrigin() string { return v.AllIsOccurrencesTree.Origin } + +// GetCollector returns PathPathIsOccurrence.Collector, and is useful for accessing the field via an interface. +func (v *PathPathIsOccurrence) GetCollector() string { return v.AllIsOccurrencesTree.Collector } + +func (v *PathPathIsOccurrence) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *PathPathIsOccurrence + graphql.NoUnmarshalJSON + } + firstPass.PathPathIsOccurrence = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AllIsOccurrencesTree) + if err != nil { + return err + } + return nil +} + +type __premarshalPathPathIsOccurrence struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Subject json.RawMessage `json:"subject"` + + Artifact AllIsOccurrencesTreeArtifact `json:"artifact"` + + Justification string `json:"justification"` + + Origin string `json:"origin"` + + Collector string `json:"collector"` +} + +func (v *PathPathIsOccurrence) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *PathPathIsOccurrence) __premarshalJSON() (*__premarshalPathPathIsOccurrence, error) { + var retval __premarshalPathPathIsOccurrence + + retval.Typename = v.Typename + retval.Id = v.AllIsOccurrencesTree.Id + { + + dst := &retval.Subject + src := v.AllIsOccurrencesTree.Subject + var err error + *dst, err = __marshalAllIsOccurrencesTreeSubjectPackageOrSource( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal PathPathIsOccurrence.AllIsOccurrencesTree.Subject: %w", err) + } + } + retval.Artifact = v.AllIsOccurrencesTree.Artifact + retval.Justification = v.AllIsOccurrencesTree.Justification + retval.Origin = v.AllIsOccurrencesTree.Origin + retval.Collector = v.AllIsOccurrencesTree.Collector + return &retval, nil +} + +// PathPathLicense includes the requested fields of the GraphQL type License. +// The GraphQL type's documentation follows. +// +// License represents a particular license. If the license is found on the SPDX +// license list (https://spdx.org/licenses/) then the fields should be: +// +// Name: SPDX license identifier +// Inline: empty +// ListVersion: SPDX license list version +// +// example: +// +// Name: AGPL-3.0-or-later +// Inline: "" +// ListVersion: 3.21 2023-06-18 +// +// If the license is not on the SPDX license list, then a new guid should be +// created and the license text placed inline: +// +// Name: LicenseRef- +// Inline: Full license text +// ListVersion: empty +// +// example: +// +// Name: LicenseRef-1a2b3c +// Inline: Permission to use, copy, modify, and/or distribute ... +// ListVersion: "" +type PathPathLicense struct { + Typename *string `json:"__typename"` + AllLicenseTree `json:"-"` +} + +// GetTypename returns PathPathLicense.Typename, and is useful for accessing the field via an interface. +func (v *PathPathLicense) GetTypename() *string { return v.Typename } + +// GetId returns PathPathLicense.Id, and is useful for accessing the field via an interface. +func (v *PathPathLicense) GetId() string { return v.AllLicenseTree.Id } + +// GetName returns PathPathLicense.Name, and is useful for accessing the field via an interface. +func (v *PathPathLicense) GetName() string { return v.AllLicenseTree.Name } -// GetOrigin returns PathPathIsOccurrence.Origin, and is useful for accessing the field via an interface. -func (v *PathPathIsOccurrence) GetOrigin() string { return v.AllIsOccurrencesTree.Origin } +// GetInline returns PathPathLicense.Inline, and is useful for accessing the field via an interface. +func (v *PathPathLicense) GetInline() *string { return v.AllLicenseTree.Inline } -// GetCollector returns PathPathIsOccurrence.Collector, and is useful for accessing the field via an interface. -func (v *PathPathIsOccurrence) GetCollector() string { return v.AllIsOccurrencesTree.Collector } +// GetListVersion returns PathPathLicense.ListVersion, and is useful for accessing the field via an interface. +func (v *PathPathLicense) GetListVersion() *string { return v.AllLicenseTree.ListVersion } -func (v *PathPathIsOccurrence) UnmarshalJSON(b []byte) error { +func (v *PathPathLicense) UnmarshalJSON(b []byte) error { if string(b) == "null" { return nil } var firstPass struct { - *PathPathIsOccurrence + *PathPathLicense graphql.NoUnmarshalJSON } - firstPass.PathPathIsOccurrence = v + firstPass.PathPathLicense = v err := json.Unmarshal(b, &firstPass) if err != nil { @@ -16374,30 +18688,26 @@ func (v *PathPathIsOccurrence) UnmarshalJSON(b []byte) error { } err = json.Unmarshal( - b, &v.AllIsOccurrencesTree) + b, &v.AllLicenseTree) if err != nil { return err } return nil } -type __premarshalPathPathIsOccurrence struct { +type __premarshalPathPathLicense struct { Typename *string `json:"__typename"` Id string `json:"id"` - Subject json.RawMessage `json:"subject"` - - Artifact AllIsOccurrencesTreeArtifact `json:"artifact"` - - Justification string `json:"justification"` + Name string `json:"name"` - Origin string `json:"origin"` + Inline *string `json:"inline"` - Collector string `json:"collector"` + ListVersion *string `json:"listVersion"` } -func (v *PathPathIsOccurrence) MarshalJSON() ([]byte, error) { +func (v *PathPathLicense) MarshalJSON() ([]byte, error) { premarshaled, err := v.__premarshalJSON() if err != nil { return nil, err @@ -16405,27 +18715,14 @@ func (v *PathPathIsOccurrence) MarshalJSON() ([]byte, error) { return json.Marshal(premarshaled) } -func (v *PathPathIsOccurrence) __premarshalJSON() (*__premarshalPathPathIsOccurrence, error) { - var retval __premarshalPathPathIsOccurrence +func (v *PathPathLicense) __premarshalJSON() (*__premarshalPathPathLicense, error) { + var retval __premarshalPathPathLicense retval.Typename = v.Typename - retval.Id = v.AllIsOccurrencesTree.Id - { - - dst := &retval.Subject - src := v.AllIsOccurrencesTree.Subject - var err error - *dst, err = __marshalAllIsOccurrencesTreeSubjectPackageOrSource( - &src) - if err != nil { - return nil, fmt.Errorf( - "unable to marshal PathPathIsOccurrence.AllIsOccurrencesTree.Subject: %w", err) - } - } - retval.Artifact = v.AllIsOccurrencesTree.Artifact - retval.Justification = v.AllIsOccurrencesTree.Justification - retval.Origin = v.AllIsOccurrencesTree.Origin - retval.Collector = v.AllIsOccurrencesTree.Collector + retval.Id = v.AllLicenseTree.Id + retval.Name = v.AllLicenseTree.Name + retval.Inline = v.AllLicenseTree.Inline + retval.ListVersion = v.AllLicenseTree.ListVersion return &retval, nil } @@ -16436,6 +18733,7 @@ func (v *PathPathIsOccurrence) __premarshalJSON() (*__premarshalPathPathIsOccurr // PathPathBuilder // PathPathCertifyBad // PathPathCertifyGood +// PathPathCertifyLegal // PathPathCertifyScorecard // PathPathCertifyVEXStatement // PathPathCertifyVuln @@ -16446,6 +18744,7 @@ func (v *PathPathIsOccurrence) __premarshalJSON() (*__premarshalPathPathIsOccurr // PathPathHashEqual // PathPathIsDependency // PathPathIsOccurrence +// PathPathLicense // PathPathPackage // PathPathPkgEqual // PathPathPointOfContact @@ -16470,6 +18769,7 @@ func (v *PathPathArtifact) implementsGraphQLInterfacePathPathNode() func (v *PathPathBuilder) implementsGraphQLInterfacePathPathNode() {} func (v *PathPathCertifyBad) implementsGraphQLInterfacePathPathNode() {} func (v *PathPathCertifyGood) implementsGraphQLInterfacePathPathNode() {} +func (v *PathPathCertifyLegal) implementsGraphQLInterfacePathPathNode() {} func (v *PathPathCertifyScorecard) implementsGraphQLInterfacePathPathNode() {} func (v *PathPathCertifyVEXStatement) implementsGraphQLInterfacePathPathNode() {} func (v *PathPathCertifyVuln) implementsGraphQLInterfacePathPathNode() {} @@ -16480,6 +18780,7 @@ func (v *PathPathHasSourceAt) implementsGraphQLInterfacePathPathNode() func (v *PathPathHashEqual) implementsGraphQLInterfacePathPathNode() {} func (v *PathPathIsDependency) implementsGraphQLInterfacePathPathNode() {} func (v *PathPathIsOccurrence) implementsGraphQLInterfacePathPathNode() {} +func (v *PathPathLicense) implementsGraphQLInterfacePathPathNode() {} func (v *PathPathPackage) implementsGraphQLInterfacePathPathNode() {} func (v *PathPathPkgEqual) implementsGraphQLInterfacePathPathNode() {} func (v *PathPathPointOfContact) implementsGraphQLInterfacePathPathNode() {} @@ -16514,6 +18815,9 @@ func __unmarshalPathPathNode(b []byte, v *PathPathNode) error { case "CertifyGood": *v = new(PathPathCertifyGood) return json.Unmarshal(b, *v) + case "CertifyLegal": + *v = new(PathPathCertifyLegal) + return json.Unmarshal(b, *v) case "CertifyScorecard": *v = new(PathPathCertifyScorecard) return json.Unmarshal(b, *v) @@ -16544,6 +18848,9 @@ func __unmarshalPathPathNode(b []byte, v *PathPathNode) error { case "IsOccurrence": *v = new(PathPathIsOccurrence) return json.Unmarshal(b, *v) + case "License": + *v = new(PathPathLicense) + return json.Unmarshal(b, *v) case "Package": *v = new(PathPathPackage) return json.Unmarshal(b, *v) @@ -16626,6 +18933,18 @@ func __marshalPathPathNode(v *PathPathNode) ([]byte, error) { *__premarshalPathPathCertifyGood }{typename, premarshaled} return json.Marshal(result) + case *PathPathCertifyLegal: + typename = "CertifyLegal" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalPathPathCertifyLegal + }{typename, premarshaled} + return json.Marshal(result) case *PathPathCertifyScorecard: typename = "CertifyScorecard" @@ -16746,6 +19065,18 @@ func __marshalPathPathNode(v *PathPathNode) ([]byte, error) { *__premarshalPathPathIsOccurrence }{typename, premarshaled} return json.Marshal(result) + case *PathPathLicense: + typename = "License" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalPathPathLicense + }{typename, premarshaled} + return json.Marshal(result) case *PathPathPackage: typename = "Package" @@ -18592,6 +20923,106 @@ func (v *__CertifyGoodSrcsInput) GetSources() []SourceInputSpec { return v.Sourc // GetCertifyGoods returns __CertifyGoodSrcsInput.CertifyGoods, and is useful for accessing the field via an interface. func (v *__CertifyGoodSrcsInput) GetCertifyGoods() []CertifyGoodInputSpec { return v.CertifyGoods } +// __CertifyLegalPkgInput is used internally by genqlient +type __CertifyLegalPkgInput struct { + Pkg PkgInputSpec `json:"pkg"` + DeclaredLicenses []LicenseInputSpec `json:"declaredLicenses"` + DiscoveredLicenses []LicenseInputSpec `json:"discoveredLicenses"` + Legal CertifyLegalInputSpec `json:"legal"` +} + +// GetPkg returns __CertifyLegalPkgInput.Pkg, and is useful for accessing the field via an interface. +func (v *__CertifyLegalPkgInput) GetPkg() PkgInputSpec { return v.Pkg } + +// GetDeclaredLicenses returns __CertifyLegalPkgInput.DeclaredLicenses, and is useful for accessing the field via an interface. +func (v *__CertifyLegalPkgInput) GetDeclaredLicenses() []LicenseInputSpec { return v.DeclaredLicenses } + +// GetDiscoveredLicenses returns __CertifyLegalPkgInput.DiscoveredLicenses, and is useful for accessing the field via an interface. +func (v *__CertifyLegalPkgInput) GetDiscoveredLicenses() []LicenseInputSpec { + return v.DiscoveredLicenses +} + +// GetLegal returns __CertifyLegalPkgInput.Legal, and is useful for accessing the field via an interface. +func (v *__CertifyLegalPkgInput) GetLegal() CertifyLegalInputSpec { return v.Legal } + +// __CertifyLegalPkgsInput is used internally by genqlient +type __CertifyLegalPkgsInput struct { + Pkgs []PkgInputSpec `json:"pkgs"` + DeclaredLicensesList [][]LicenseInputSpec `json:"declaredLicensesList"` + DiscoveredLicensesList [][]LicenseInputSpec `json:"discoveredLicensesList"` + Legals []CertifyLegalInputSpec `json:"legals"` +} + +// GetPkgs returns __CertifyLegalPkgsInput.Pkgs, and is useful for accessing the field via an interface. +func (v *__CertifyLegalPkgsInput) GetPkgs() []PkgInputSpec { return v.Pkgs } + +// GetDeclaredLicensesList returns __CertifyLegalPkgsInput.DeclaredLicensesList, and is useful for accessing the field via an interface. +func (v *__CertifyLegalPkgsInput) GetDeclaredLicensesList() [][]LicenseInputSpec { + return v.DeclaredLicensesList +} + +// GetDiscoveredLicensesList returns __CertifyLegalPkgsInput.DiscoveredLicensesList, and is useful for accessing the field via an interface. +func (v *__CertifyLegalPkgsInput) GetDiscoveredLicensesList() [][]LicenseInputSpec { + return v.DiscoveredLicensesList +} + +// GetLegals returns __CertifyLegalPkgsInput.Legals, and is useful for accessing the field via an interface. +func (v *__CertifyLegalPkgsInput) GetLegals() []CertifyLegalInputSpec { return v.Legals } + +// __CertifyLegalSrcInput is used internally by genqlient +type __CertifyLegalSrcInput struct { + Src SourceInputSpec `json:"src"` + DeclaredLicenses []LicenseInputSpec `json:"declaredLicenses"` + DiscoveredLicenses []LicenseInputSpec `json:"discoveredLicenses"` + Legal CertifyLegalInputSpec `json:"legal"` +} + +// GetSrc returns __CertifyLegalSrcInput.Src, and is useful for accessing the field via an interface. +func (v *__CertifyLegalSrcInput) GetSrc() SourceInputSpec { return v.Src } + +// GetDeclaredLicenses returns __CertifyLegalSrcInput.DeclaredLicenses, and is useful for accessing the field via an interface. +func (v *__CertifyLegalSrcInput) GetDeclaredLicenses() []LicenseInputSpec { return v.DeclaredLicenses } + +// GetDiscoveredLicenses returns __CertifyLegalSrcInput.DiscoveredLicenses, and is useful for accessing the field via an interface. +func (v *__CertifyLegalSrcInput) GetDiscoveredLicenses() []LicenseInputSpec { + return v.DiscoveredLicenses +} + +// GetLegal returns __CertifyLegalSrcInput.Legal, and is useful for accessing the field via an interface. +func (v *__CertifyLegalSrcInput) GetLegal() CertifyLegalInputSpec { return v.Legal } + +// __CertifyLegalSrcsInput is used internally by genqlient +type __CertifyLegalSrcsInput struct { + Srcs []SourceInputSpec `json:"srcs"` + DeclaredLicensesList [][]LicenseInputSpec `json:"declaredLicensesList"` + DiscoveredLicensesList [][]LicenseInputSpec `json:"discoveredLicensesList"` + Legals []CertifyLegalInputSpec `json:"legals"` +} + +// GetSrcs returns __CertifyLegalSrcsInput.Srcs, and is useful for accessing the field via an interface. +func (v *__CertifyLegalSrcsInput) GetSrcs() []SourceInputSpec { return v.Srcs } + +// GetDeclaredLicensesList returns __CertifyLegalSrcsInput.DeclaredLicensesList, and is useful for accessing the field via an interface. +func (v *__CertifyLegalSrcsInput) GetDeclaredLicensesList() [][]LicenseInputSpec { + return v.DeclaredLicensesList +} + +// GetDiscoveredLicensesList returns __CertifyLegalSrcsInput.DiscoveredLicensesList, and is useful for accessing the field via an interface. +func (v *__CertifyLegalSrcsInput) GetDiscoveredLicensesList() [][]LicenseInputSpec { + return v.DiscoveredLicensesList +} + +// GetLegals returns __CertifyLegalSrcsInput.Legals, and is useful for accessing the field via an interface. +func (v *__CertifyLegalSrcsInput) GetLegals() []CertifyLegalInputSpec { return v.Legals } + +// __CertifyLegalsInput is used internally by genqlient +type __CertifyLegalsInput struct { + Filter CertifyLegalSpec `json:"filter"` +} + +// GetFilter returns __CertifyLegalsInput.Filter, and is useful for accessing the field via an interface. +func (v *__CertifyLegalsInput) GetFilter() CertifyLegalSpec { return v.Filter } + // __CertifyScorecardInput is used internally by genqlient type __CertifyScorecardInput struct { Source SourceInputSpec `json:"source"` @@ -18900,6 +21331,22 @@ type __IngestBuildersInput struct { // GetBuilders returns __IngestBuildersInput.Builders, and is useful for accessing the field via an interface. func (v *__IngestBuildersInput) GetBuilders() []BuilderInputSpec { return v.Builders } +// __IngestLicenseInput is used internally by genqlient +type __IngestLicenseInput struct { + License LicenseInputSpec `json:"license"` +} + +// GetLicense returns __IngestLicenseInput.License, and is useful for accessing the field via an interface. +func (v *__IngestLicenseInput) GetLicense() LicenseInputSpec { return v.License } + +// __IngestLicensesInput is used internally by genqlient +type __IngestLicensesInput struct { + Licenses []LicenseInputSpec `json:"licenses"` +} + +// GetLicenses returns __IngestLicensesInput.Licenses, and is useful for accessing the field via an interface. +func (v *__IngestLicensesInput) GetLicenses() []LicenseInputSpec { return v.Licenses } + // __IngestPackageInput is used internally by genqlient type __IngestPackageInput struct { Pkg PkgInputSpec `json:"pkg"` @@ -19052,6 +21499,14 @@ func (v *__IsOccurrencesSrcInput) GetArtifacts() []ArtifactInputSpec { return v. // GetOccurrences returns __IsOccurrencesSrcInput.Occurrences, and is useful for accessing the field via an interface. func (v *__IsOccurrencesSrcInput) GetOccurrences() []IsOccurrenceInputSpec { return v.Occurrences } +// __LicensesInput is used internally by genqlient +type __LicensesInput struct { + Filter LicenseSpec `json:"filter"` +} + +// GetFilter returns __LicensesInput.Filter, and is useful for accessing the field via an interface. +func (v *__LicensesInput) GetFilter() LicenseSpec { return v.Filter } + // __NeighborsInput is used internally by genqlient type __NeighborsInput struct { Node string `json:"node"` @@ -19738,17 +22193,202 @@ func CertifyGoodPkg( certifyGood CertifyGoodInputSpec, ) (*CertifyGoodPkgResponse, error) { req := &graphql.Request{ - OpName: "CertifyGoodPkg", - Query: CertifyGoodPkg_Operation, - Variables: &__CertifyGoodPkgInput{ - Pkg: pkg, - PkgMatchType: pkgMatchType, - CertifyGood: certifyGood, + OpName: "CertifyGoodPkg", + Query: CertifyGoodPkg_Operation, + Variables: &__CertifyGoodPkgInput{ + Pkg: pkg, + PkgMatchType: pkgMatchType, + CertifyGood: certifyGood, + }, + } + var err error + + var data CertifyGoodPkgResponse + resp := &graphql.Response{Data: &data} + + err = client.MakeRequest( + ctx, + req, + resp, + ) + + return &data, err +} + +// The query or mutation executed by CertifyGoodPkgs. +const CertifyGoodPkgs_Operation = ` +mutation CertifyGoodPkgs ($pkgs: [PkgInputSpec!]!, $pkgMatchType: MatchFlags!, $certifyGoods: [CertifyGoodInputSpec!]!) { + ingestCertifyGoods(subjects: {packages:$pkgs}, pkgMatchType: $pkgMatchType, certifyGoods: $certifyGoods) +} +` + +func CertifyGoodPkgs( + ctx context.Context, + client graphql.Client, + pkgs []PkgInputSpec, + pkgMatchType MatchFlags, + certifyGoods []CertifyGoodInputSpec, +) (*CertifyGoodPkgsResponse, error) { + req := &graphql.Request{ + OpName: "CertifyGoodPkgs", + Query: CertifyGoodPkgs_Operation, + Variables: &__CertifyGoodPkgsInput{ + Pkgs: pkgs, + PkgMatchType: pkgMatchType, + CertifyGoods: certifyGoods, + }, + } + var err error + + var data CertifyGoodPkgsResponse + resp := &graphql.Response{Data: &data} + + err = client.MakeRequest( + ctx, + req, + resp, + ) + + return &data, err +} + +// The query or mutation executed by CertifyGoodSrc. +const CertifyGoodSrc_Operation = ` +mutation CertifyGoodSrc ($source: SourceInputSpec!, $certifyGood: CertifyGoodInputSpec!) { + ingestCertifyGood(subject: {source:$source}, pkgMatchType: {pkg:ALL_VERSIONS}, certifyGood: $certifyGood) +} +` + +func CertifyGoodSrc( + ctx context.Context, + client graphql.Client, + source SourceInputSpec, + certifyGood CertifyGoodInputSpec, +) (*CertifyGoodSrcResponse, error) { + req := &graphql.Request{ + OpName: "CertifyGoodSrc", + Query: CertifyGoodSrc_Operation, + Variables: &__CertifyGoodSrcInput{ + Source: source, + CertifyGood: certifyGood, + }, + } + var err error + + var data CertifyGoodSrcResponse + resp := &graphql.Response{Data: &data} + + err = client.MakeRequest( + ctx, + req, + resp, + ) + + return &data, err +} + +// The query or mutation executed by CertifyGoodSrcs. +const CertifyGoodSrcs_Operation = ` +mutation CertifyGoodSrcs ($sources: [SourceInputSpec!]!, $certifyGoods: [CertifyGoodInputSpec!]!) { + ingestCertifyGoods(subjects: {sources:$sources}, pkgMatchType: {pkg:ALL_VERSIONS}, certifyGoods: $certifyGoods) +} +` + +func CertifyGoodSrcs( + ctx context.Context, + client graphql.Client, + sources []SourceInputSpec, + certifyGoods []CertifyGoodInputSpec, +) (*CertifyGoodSrcsResponse, error) { + req := &graphql.Request{ + OpName: "CertifyGoodSrcs", + Query: CertifyGoodSrcs_Operation, + Variables: &__CertifyGoodSrcsInput{ + Sources: sources, + CertifyGoods: certifyGoods, + }, + } + var err error + + var data CertifyGoodSrcsResponse + resp := &graphql.Response{Data: &data} + + err = client.MakeRequest( + ctx, + req, + resp, + ) + + return &data, err +} + +// The query or mutation executed by CertifyLegalPkg. +const CertifyLegalPkg_Operation = ` +mutation CertifyLegalPkg ($pkg: PkgInputSpec!, $declaredLicenses: [LicenseInputSpec!]!, $discoveredLicenses: [LicenseInputSpec!]!, $legal: CertifyLegalInputSpec!) { + ingestCertifyLegal(subject: {package:$pkg}, declaredLicenses: $declaredLicenses, discoveredLicenses: $discoveredLicenses, certifyLegal: $legal) +} +` + +func CertifyLegalPkg( + ctx context.Context, + client graphql.Client, + pkg PkgInputSpec, + declaredLicenses []LicenseInputSpec, + discoveredLicenses []LicenseInputSpec, + legal CertifyLegalInputSpec, +) (*CertifyLegalPkgResponse, error) { + req := &graphql.Request{ + OpName: "CertifyLegalPkg", + Query: CertifyLegalPkg_Operation, + Variables: &__CertifyLegalPkgInput{ + Pkg: pkg, + DeclaredLicenses: declaredLicenses, + DiscoveredLicenses: discoveredLicenses, + Legal: legal, + }, + } + var err error + + var data CertifyLegalPkgResponse + resp := &graphql.Response{Data: &data} + + err = client.MakeRequest( + ctx, + req, + resp, + ) + + return &data, err +} + +// The query or mutation executed by CertifyLegalPkgs. +const CertifyLegalPkgs_Operation = ` +mutation CertifyLegalPkgs ($pkgs: [PkgInputSpec!]!, $declaredLicensesList: [[LicenseInputSpec!]!]!, $discoveredLicensesList: [[LicenseInputSpec!]!]!, $legals: [CertifyLegalInputSpec!]!) { + ingestCertifyLegals(subjects: {packages:$pkgs}, declaredLicensesList: $declaredLicensesList, discoveredLicensesList: $discoveredLicensesList, certifyLegals: $legals) +} +` + +func CertifyLegalPkgs( + ctx context.Context, + client graphql.Client, + pkgs []PkgInputSpec, + declaredLicensesList [][]LicenseInputSpec, + discoveredLicensesList [][]LicenseInputSpec, + legals []CertifyLegalInputSpec, +) (*CertifyLegalPkgsResponse, error) { + req := &graphql.Request{ + OpName: "CertifyLegalPkgs", + Query: CertifyLegalPkgs_Operation, + Variables: &__CertifyLegalPkgsInput{ + Pkgs: pkgs, + DeclaredLicensesList: declaredLicensesList, + DiscoveredLicensesList: discoveredLicensesList, + Legals: legals, }, } var err error - var data CertifyGoodPkgResponse + var data CertifyLegalPkgsResponse resp := &graphql.Response{Data: &data} err = client.MakeRequest( @@ -19760,32 +22400,34 @@ func CertifyGoodPkg( return &data, err } -// The query or mutation executed by CertifyGoodPkgs. -const CertifyGoodPkgs_Operation = ` -mutation CertifyGoodPkgs ($pkgs: [PkgInputSpec!]!, $pkgMatchType: MatchFlags!, $certifyGoods: [CertifyGoodInputSpec!]!) { - ingestCertifyGoods(subjects: {packages:$pkgs}, pkgMatchType: $pkgMatchType, certifyGoods: $certifyGoods) +// The query or mutation executed by CertifyLegalSrc. +const CertifyLegalSrc_Operation = ` +mutation CertifyLegalSrc ($src: SourceInputSpec!, $declaredLicenses: [LicenseInputSpec!]!, $discoveredLicenses: [LicenseInputSpec!]!, $legal: CertifyLegalInputSpec!) { + ingestCertifyLegal(subject: {source:$src}, declaredLicenses: $declaredLicenses, discoveredLicenses: $discoveredLicenses, certifyLegal: $legal) } ` -func CertifyGoodPkgs( +func CertifyLegalSrc( ctx context.Context, client graphql.Client, - pkgs []PkgInputSpec, - pkgMatchType MatchFlags, - certifyGoods []CertifyGoodInputSpec, -) (*CertifyGoodPkgsResponse, error) { + src SourceInputSpec, + declaredLicenses []LicenseInputSpec, + discoveredLicenses []LicenseInputSpec, + legal CertifyLegalInputSpec, +) (*CertifyLegalSrcResponse, error) { req := &graphql.Request{ - OpName: "CertifyGoodPkgs", - Query: CertifyGoodPkgs_Operation, - Variables: &__CertifyGoodPkgsInput{ - Pkgs: pkgs, - PkgMatchType: pkgMatchType, - CertifyGoods: certifyGoods, + OpName: "CertifyLegalSrc", + Query: CertifyLegalSrc_Operation, + Variables: &__CertifyLegalSrcInput{ + Src: src, + DeclaredLicenses: declaredLicenses, + DiscoveredLicenses: discoveredLicenses, + Legal: legal, }, } var err error - var data CertifyGoodPkgsResponse + var data CertifyLegalSrcResponse resp := &graphql.Response{Data: &data} err = client.MakeRequest( @@ -19797,30 +22439,34 @@ func CertifyGoodPkgs( return &data, err } -// The query or mutation executed by CertifyGoodSrc. -const CertifyGoodSrc_Operation = ` -mutation CertifyGoodSrc ($source: SourceInputSpec!, $certifyGood: CertifyGoodInputSpec!) { - ingestCertifyGood(subject: {source:$source}, pkgMatchType: {pkg:ALL_VERSIONS}, certifyGood: $certifyGood) +// The query or mutation executed by CertifyLegalSrcs. +const CertifyLegalSrcs_Operation = ` +mutation CertifyLegalSrcs ($srcs: [SourceInputSpec!]!, $declaredLicensesList: [[LicenseInputSpec!]!]!, $discoveredLicensesList: [[LicenseInputSpec!]!]!, $legals: [CertifyLegalInputSpec!]!) { + ingestCertifyLegals(subjects: {sources:$srcs}, declaredLicensesList: $declaredLicensesList, discoveredLicensesList: $discoveredLicensesList, certifyLegals: $legals) } ` -func CertifyGoodSrc( +func CertifyLegalSrcs( ctx context.Context, client graphql.Client, - source SourceInputSpec, - certifyGood CertifyGoodInputSpec, -) (*CertifyGoodSrcResponse, error) { + srcs []SourceInputSpec, + declaredLicensesList [][]LicenseInputSpec, + discoveredLicensesList [][]LicenseInputSpec, + legals []CertifyLegalInputSpec, +) (*CertifyLegalSrcsResponse, error) { req := &graphql.Request{ - OpName: "CertifyGoodSrc", - Query: CertifyGoodSrc_Operation, - Variables: &__CertifyGoodSrcInput{ - Source: source, - CertifyGood: certifyGood, + OpName: "CertifyLegalSrcs", + Query: CertifyLegalSrcs_Operation, + Variables: &__CertifyLegalSrcsInput{ + Srcs: srcs, + DeclaredLicensesList: declaredLicensesList, + DiscoveredLicensesList: discoveredLicensesList, + Legals: legals, }, } var err error - var data CertifyGoodSrcResponse + var data CertifyLegalSrcsResponse resp := &graphql.Response{Data: &data} err = client.MakeRequest( @@ -19832,30 +22478,96 @@ func CertifyGoodSrc( return &data, err } -// The query or mutation executed by CertifyGoodSrcs. -const CertifyGoodSrcs_Operation = ` -mutation CertifyGoodSrcs ($sources: [SourceInputSpec!]!, $certifyGoods: [CertifyGoodInputSpec!]!) { - ingestCertifyGoods(subjects: {sources:$sources}, pkgMatchType: {pkg:ALL_VERSIONS}, certifyGoods: $certifyGoods) +// The query or mutation executed by CertifyLegals. +const CertifyLegals_Operation = ` +query CertifyLegals ($filter: CertifyLegalSpec!) { + CertifyLegal(certifyLegalSpec: $filter) { + ... AllCertifyLegalTree + } +} +fragment AllCertifyLegalTree on CertifyLegal { + id + subject { + __typename + ... on Package { + ... AllPkgTree + } + ... on Source { + ... AllSourceTree + } + } + declaredLicense + declaredLicenses { + ... AllLicenseTree + } + discoveredLicense + discoveredLicenses { + ... AllLicenseTree + } + attribution + justification + timeScanned + origin + collector +} +fragment AllPkgTree on Package { + id + type + namespaces { + id + namespace + names { + id + name + versions { + id + version + qualifiers { + key + value + } + subpath + } + } + } +} +fragment AllSourceTree on Source { + id + type + namespaces { + id + namespace + names { + id + name + tag + commit + } + } +} +fragment AllLicenseTree on License { + id + name + inline + listVersion } ` -func CertifyGoodSrcs( +func CertifyLegals( ctx context.Context, client graphql.Client, - sources []SourceInputSpec, - certifyGoods []CertifyGoodInputSpec, -) (*CertifyGoodSrcsResponse, error) { + filter CertifyLegalSpec, +) (*CertifyLegalsResponse, error) { req := &graphql.Request{ - OpName: "CertifyGoodSrcs", - Query: CertifyGoodSrcs_Operation, - Variables: &__CertifyGoodSrcsInput{ - Sources: sources, - CertifyGoods: certifyGoods, + OpName: "CertifyLegals", + Query: CertifyLegals_Operation, + Variables: &__CertifyLegalsInput{ + Filter: filter, }, } var err error - var data CertifyGoodSrcsResponse + var data CertifyLegalsResponse resp := &graphql.Response{Data: &data} err = client.MakeRequest( @@ -20735,6 +23447,72 @@ func IngestBuilders( return &data, err } +// The query or mutation executed by IngestLicense. +const IngestLicense_Operation = ` +mutation IngestLicense ($license: LicenseInputSpec!) { + ingestLicense(license: $license) +} +` + +func IngestLicense( + ctx context.Context, + client graphql.Client, + license LicenseInputSpec, +) (*IngestLicenseResponse, error) { + req := &graphql.Request{ + OpName: "IngestLicense", + Query: IngestLicense_Operation, + Variables: &__IngestLicenseInput{ + License: license, + }, + } + var err error + + var data IngestLicenseResponse + resp := &graphql.Response{Data: &data} + + err = client.MakeRequest( + ctx, + req, + resp, + ) + + return &data, err +} + +// The query or mutation executed by IngestLicenses. +const IngestLicenses_Operation = ` +mutation IngestLicenses ($licenses: [LicenseInputSpec!]!) { + ingestLicenses(licenses: $licenses) +} +` + +func IngestLicenses( + ctx context.Context, + client graphql.Client, + licenses []LicenseInputSpec, +) (*IngestLicensesResponse, error) { + req := &graphql.Request{ + OpName: "IngestLicenses", + Query: IngestLicenses_Operation, + Variables: &__IngestLicensesInput{ + Licenses: licenses, + }, + } + var err error + + var data IngestLicensesResponse + resp := &graphql.Response{Data: &data} + + err = client.MakeRequest( + ctx, + req, + resp, + ) + + return &data, err +} + // The query or mutation executed by IngestPackage. const IngestPackage_Operation = ` mutation IngestPackage ($pkg: PkgInputSpec!) { @@ -21159,6 +23937,47 @@ func IsOccurrencesSrc( return &data, err } +// The query or mutation executed by Licenses. +const Licenses_Operation = ` +query Licenses ($filter: LicenseSpec!) { + licenses(licenseSpec: $filter) { + ... AllLicenseTree + } +} +fragment AllLicenseTree on License { + id + name + inline + listVersion +} +` + +func Licenses( + ctx context.Context, + client graphql.Client, + filter LicenseSpec, +) (*LicensesResponse, error) { + req := &graphql.Request{ + OpName: "Licenses", + Query: Licenses_Operation, + Variables: &__LicensesInput{ + Filter: filter, + }, + } + var err error + + var data LicensesResponse + resp := &graphql.Response{Data: &data} + + err = client.MakeRequest( + ctx, + req, + resp, + ) + + return &data, err +} + // The query or mutation executed by Neighbors. const Neighbors_Operation = ` query Neighbors ($node: ID!, $usingOnly: [Edge!]!) { @@ -21179,6 +23998,9 @@ query Neighbors ($node: ID!, $usingOnly: [Edge!]!) { ... on Vulnerability { ... AllVulnerabilityTree } + ... on License { + ... AllLicenseTree + } ... on CertifyScorecard { ... AllCertifyScorecard } @@ -21230,6 +24052,9 @@ query Neighbors ($node: ID!, $usingOnly: [Edge!]!) { ... on HasMetadata { ... AllHasMetadata } + ... on CertifyLegal { + ... AllCertifyLegalTree + } } } fragment AllPkgTree on Package { @@ -21284,6 +24109,12 @@ fragment AllVulnerabilityTree on Vulnerability { vulnerabilityID } } +fragment AllLicenseTree on License { + id + name + inline + listVersion +} fragment AllCertifyScorecard on CertifyScorecard { id source { @@ -21551,6 +24382,31 @@ fragment AllHasMetadata on HasMetadata { origin collector } +fragment AllCertifyLegalTree on CertifyLegal { + id + subject { + __typename + ... on Package { + ... AllPkgTree + } + ... on Source { + ... AllSourceTree + } + } + declaredLicense + declaredLicenses { + ... AllLicenseTree + } + discoveredLicense + discoveredLicenses { + ... AllLicenseTree + } + attribution + justification + timeScanned + origin + collector +} ` func Neighbors( @@ -21601,6 +24457,9 @@ query Node ($node: ID!) { ... on Vulnerability { ... AllVulnerabilityTree } + ... on License { + ... AllLicenseTree + } ... on CertifyScorecard { ... AllCertifyScorecard } @@ -21652,6 +24511,9 @@ query Node ($node: ID!) { ... on HasMetadata { ... AllHasMetadata } + ... on CertifyLegal { + ... AllCertifyLegalTree + } } } fragment AllPkgTree on Package { @@ -21706,6 +24568,12 @@ fragment AllVulnerabilityTree on Vulnerability { vulnerabilityID } } +fragment AllLicenseTree on License { + id + name + inline + listVersion +} fragment AllCertifyScorecard on CertifyScorecard { id source { @@ -21973,6 +24841,31 @@ fragment AllHasMetadata on HasMetadata { origin collector } +fragment AllCertifyLegalTree on CertifyLegal { + id + subject { + __typename + ... on Package { + ... AllPkgTree + } + ... on Source { + ... AllSourceTree + } + } + declaredLicense + declaredLicenses { + ... AllLicenseTree + } + discoveredLicense + discoveredLicenses { + ... AllLicenseTree + } + attribution + justification + timeScanned + origin + collector +} ` func Node( @@ -22021,6 +24914,9 @@ query Nodes ($nodes: [ID!]!) { ... on Vulnerability { ... AllVulnerabilityTree } + ... on License { + ... AllLicenseTree + } ... on CertifyScorecard { ... AllCertifyScorecard } @@ -22072,6 +24968,9 @@ query Nodes ($nodes: [ID!]!) { ... on HasMetadata { ... AllHasMetadata } + ... on CertifyLegal { + ... AllCertifyLegalTree + } } } fragment AllPkgTree on Package { @@ -22126,6 +25025,12 @@ fragment AllVulnerabilityTree on Vulnerability { vulnerabilityID } } +fragment AllLicenseTree on License { + id + name + inline + listVersion +} fragment AllCertifyScorecard on CertifyScorecard { id source { @@ -22393,6 +25298,31 @@ fragment AllHasMetadata on HasMetadata { origin collector } +fragment AllCertifyLegalTree on CertifyLegal { + id + subject { + __typename + ... on Package { + ... AllPkgTree + } + ... on Source { + ... AllSourceTree + } + } + declaredLicense + declaredLicenses { + ... AllLicenseTree + } + discoveredLicense + discoveredLicenses { + ... AllLicenseTree + } + attribution + justification + timeScanned + origin + collector +} ` func Nodes( @@ -22670,6 +25600,9 @@ query Path ($subject: ID!, $target: ID!, $maxPathLength: Int!, $usingOnly: [Edge ... on Vulnerability { ... AllVulnerabilityTree } + ... on License { + ... AllLicenseTree + } ... on CertifyScorecard { ... AllCertifyScorecard } @@ -22721,6 +25654,9 @@ query Path ($subject: ID!, $target: ID!, $maxPathLength: Int!, $usingOnly: [Edge ... on HasMetadata { ... AllHasMetadata } + ... on CertifyLegal { + ... AllCertifyLegalTree + } } } fragment AllPkgTree on Package { @@ -22775,6 +25711,12 @@ fragment AllVulnerabilityTree on Vulnerability { vulnerabilityID } } +fragment AllLicenseTree on License { + id + name + inline + listVersion +} fragment AllCertifyScorecard on CertifyScorecard { id source { @@ -23042,6 +25984,31 @@ fragment AllHasMetadata on HasMetadata { origin collector } +fragment AllCertifyLegalTree on CertifyLegal { + id + subject { + __typename + ... on Package { + ... AllPkgTree + } + ... on Source { + ... AllSourceTree + } + } + declaredLicense + declaredLicenses { + ... AllLicenseTree + } + discoveredLicense + discoveredLicenses { + ... AllLicenseTree + } + attribution + justification + timeScanned + origin + collector +} ` func Path( diff --git a/pkg/assembler/clients/operations/certifyLegal.graphql b/pkg/assembler/clients/operations/certifyLegal.graphql new file mode 100644 index 0000000000..f779929537 --- /dev/null +++ b/pkg/assembler/clients/operations/certifyLegal.graphql @@ -0,0 +1,40 @@ +# +# Copyright 2023 The GUAC Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# NOTE: This is experimental and might change in the future! + +# Defines the GraphQL operations to ingest legal attestations into GUAC + +mutation CertifyLegalPkg($pkg: PkgInputSpec!, $declaredLicenses: [LicenseInputSpec!]!, $discoveredLicenses: [LicenseInputSpec!]!, $legal: CertifyLegalInputSpec!) { + ingestCertifyLegal(subject: {package: $pkg}, declaredLicenses: $declaredLicenses, discoveredLicenses: $discoveredLicenses, certifyLegal: $legal) +} + +mutation CertifyLegalPkgs($pkgs: [PkgInputSpec!]!, $declaredLicensesList: [[LicenseInputSpec!]!]!, $discoveredLicensesList: [[LicenseInputSpec!]!]!, $legals: [CertifyLegalInputSpec!]!) { + ingestCertifyLegals(subjects: {packages: $pkgs}, declaredLicensesList: $declaredLicensesList, discoveredLicensesList: $discoveredLicensesList, certifyLegals: $legals) +} + +mutation CertifyLegalSrc($src: SourceInputSpec!, $declaredLicenses: [LicenseInputSpec!]!, $discoveredLicenses: [LicenseInputSpec!]!, $legal: CertifyLegalInputSpec!) { + ingestCertifyLegal(subject: {source: $src}, declaredLicenses: $declaredLicenses, discoveredLicenses: $discoveredLicenses, certifyLegal: $legal) +} + +mutation CertifyLegalSrcs($srcs: [SourceInputSpec!]!, $declaredLicensesList: [[LicenseInputSpec!]!]!, $discoveredLicensesList: [[LicenseInputSpec!]!]!, $legals: [CertifyLegalInputSpec!]!) { + ingestCertifyLegals(subjects: {sources: $srcs}, declaredLicensesList: $declaredLicensesList, discoveredLicensesList: $discoveredLicensesList, certifyLegals: $legals) +} + +query CertifyLegals($filter: CertifyLegalSpec!) { + CertifyLegal(certifyLegalSpec: $filter) { + ...AllCertifyLegalTree + } +} diff --git a/pkg/assembler/clients/operations/license.graphql b/pkg/assembler/clients/operations/license.graphql new file mode 100644 index 0000000000..1a16ff3078 --- /dev/null +++ b/pkg/assembler/clients/operations/license.graphql @@ -0,0 +1,36 @@ +# +# Copyright 2023 The GUAC Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# NOTE: This is experimental and might change in the future! + +# Ingest License + +mutation IngestLicense($license: LicenseInputSpec!) { + ingestLicense(license: $license) +} + +# Bulk Ingest Licenses + +mutation IngestLicenses($licenses: [LicenseInputSpec!]!) { + ingestLicenses(licenses: $licenses) +} + +# Exposes GraphQL queries to retrieve GUAC licenses + +query Licenses($filter: LicenseSpec!) { + licenses(licenseSpec: $filter) { + ...AllLicenseTree + } +} diff --git a/pkg/assembler/clients/operations/path.graphql b/pkg/assembler/clients/operations/path.graphql index 7cd84999c1..c8176ae59d 100644 --- a/pkg/assembler/clients/operations/path.graphql +++ b/pkg/assembler/clients/operations/path.graphql @@ -45,6 +45,9 @@ query Path( ... on Vulnerability { ...AllVulnerabilityTree } + ... on License { + ...AllLicenseTree + } ... on CertifyScorecard { ...AllCertifyScorecard } @@ -96,6 +99,9 @@ query Path( ... on HasMetadata { ...AllHasMetadata } + ... on CertifyLegal { + ...AllCertifyLegalTree + } } } @@ -117,6 +123,9 @@ query Neighbors($node: ID!, $usingOnly: [Edge!]!) { ... on Vulnerability { ...AllVulnerabilityTree } + ... on License { + ...AllLicenseTree + } ... on CertifyScorecard { ...AllCertifyScorecard } @@ -168,6 +177,9 @@ query Neighbors($node: ID!, $usingOnly: [Edge!]!) { ... on HasMetadata { ...AllHasMetadata } + ... on CertifyLegal { + ...AllCertifyLegalTree + } } } @@ -189,6 +201,9 @@ query Node($node: ID!) { ... on Vulnerability { ...AllVulnerabilityTree } + ... on License { + ...AllLicenseTree + } ... on CertifyScorecard { ...AllCertifyScorecard } @@ -240,6 +255,9 @@ query Node($node: ID!) { ... on HasMetadata { ...AllHasMetadata } + ... on CertifyLegal { + ...AllCertifyLegalTree + } } } @@ -261,6 +279,9 @@ query Nodes($nodes: [ID!]!) { ... on Vulnerability { ...AllVulnerabilityTree } + ... on License { + ...AllLicenseTree + } ... on CertifyScorecard { ...AllCertifyScorecard } @@ -312,5 +333,8 @@ query Nodes($nodes: [ID!]!) { ... on HasMetadata { ...AllHasMetadata } + ... on CertifyLegal { + ...AllCertifyLegalTree + } } } diff --git a/pkg/assembler/clients/operations/trees.graphql b/pkg/assembler/clients/operations/trees.graphql index 112d4c351d..aba7d89e48 100644 --- a/pkg/assembler/clients/operations/trees.graphql +++ b/pkg/assembler/clients/operations/trees.graphql @@ -67,6 +67,13 @@ fragment AllBuilderTree on Builder { uri } +fragment AllLicenseTree on License { + id + name + inline + listVersion +} + fragment AllVulnerabilityTree on Vulnerability { id type @@ -172,6 +179,32 @@ fragment AllSLSATree on HasSLSA { } } +fragment AllCertifyLegalTree on CertifyLegal { + id + subject { + __typename + ... on Package { + ...AllPkgTree + } + ... on Source { + ...AllSourceTree + } + } + declaredLicense + declaredLicenses { + ...AllLicenseTree + } + discoveredLicense + discoveredLicenses { + ...AllLicenseTree + } + attribution + justification + timeScanned + origin + collector +} + fragment AllCertifyBad on CertifyBad { id justification diff --git a/pkg/assembler/graphql/generated/artifact.generated.go b/pkg/assembler/graphql/generated/artifact.generated.go index fc804757f9..fe1f331753 100644 --- a/pkg/assembler/graphql/generated/artifact.generated.go +++ b/pkg/assembler/graphql/generated/artifact.generated.go @@ -27,6 +27,8 @@ type MutationResolver interface { IngestCertifyBads(ctx context.Context, subjects model.PackageSourceOrArtifactInputs, pkgMatchType model.MatchFlags, certifyBads []*model.CertifyBadInputSpec) ([]string, error) IngestCertifyGood(ctx context.Context, subject model.PackageSourceOrArtifactInput, pkgMatchType model.MatchFlags, certifyGood model.CertifyGoodInputSpec) (string, error) IngestCertifyGoods(ctx context.Context, subjects model.PackageSourceOrArtifactInputs, pkgMatchType model.MatchFlags, certifyGoods []*model.CertifyGoodInputSpec) ([]string, error) + IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, certifyLegal model.CertifyLegalInputSpec) (string, error) + IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.LicenseInputSpec, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) IngestScorecard(ctx context.Context, source model.SourceInputSpec, scorecard model.ScorecardInputSpec) (string, error) IngestScorecards(ctx context.Context, sources []*model.SourceInputSpec, scorecards []*model.ScorecardInputSpec) ([]string, error) IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.VulnerabilityInputSpec, vexStatement model.VexStatementInputSpec) (string, error) @@ -45,6 +47,8 @@ type MutationResolver interface { IngestDependencies(ctx context.Context, pkgs []*model.PkgInputSpec, depPkgs []*model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.ArtifactInputSpec, occurrence model.IsOccurrenceInputSpec) (string, error) IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.ArtifactInputSpec, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) + IngestLicense(ctx context.Context, license *model.LicenseInputSpec) (string, error) + IngestLicenses(ctx context.Context, licenses []*model.LicenseInputSpec) ([]string, error) IngestHasMetadata(ctx context.Context, subject model.PackageSourceOrArtifactInput, pkgMatchType model.MatchFlags, hasMetadata model.HasMetadataInputSpec) (string, error) IngestPackage(ctx context.Context, pkg model.PkgInputSpec) (string, error) IngestPackages(ctx context.Context, pkgs []*model.PkgInputSpec) ([]string, error) @@ -62,6 +66,7 @@ type QueryResolver interface { Builders(ctx context.Context, builderSpec model.BuilderSpec) ([]*model.Builder, error) CertifyBad(ctx context.Context, certifyBadSpec model.CertifyBadSpec) ([]*model.CertifyBad, error) CertifyGood(ctx context.Context, certifyGoodSpec model.CertifyGoodSpec) ([]*model.CertifyGood, error) + CertifyLegal(ctx context.Context, certifyLegalSpec model.CertifyLegalSpec) ([]*model.CertifyLegal, error) Scorecards(ctx context.Context, scorecardSpec model.CertifyScorecardSpec) ([]*model.CertifyScorecard, error) CertifyVEXStatement(ctx context.Context, certifyVEXStatementSpec model.CertifyVEXStatementSpec) ([]*model.CertifyVEXStatement, error) CertifyVuln(ctx context.Context, certifyVulnSpec model.CertifyVulnSpec) ([]*model.CertifyVuln, error) @@ -72,6 +77,7 @@ type QueryResolver interface { HashEqual(ctx context.Context, hashEqualSpec model.HashEqualSpec) ([]*model.HashEqual, error) IsDependency(ctx context.Context, isDependencySpec model.IsDependencySpec) ([]*model.IsDependency, error) IsOccurrence(ctx context.Context, isOccurrenceSpec model.IsOccurrenceSpec) ([]*model.IsOccurrence, error) + Licenses(ctx context.Context, licenseSpec model.LicenseSpec) ([]*model.License, error) HasMetadata(ctx context.Context, hasMetadataSpec model.HasMetadataSpec) ([]*model.HasMetadata, error) Packages(ctx context.Context, pkgSpec model.PkgSpec) ([]*model.Package, error) Path(ctx context.Context, subject string, target string, maxPathLength int, usingOnly []model.Edge) ([]model.Node, error) @@ -282,6 +288,90 @@ func (ec *executionContext) field_Mutation_ingestCertifyGoods_args(ctx context.C return args, nil } +func (ec *executionContext) field_Mutation_ingestCertifyLegal_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 model.PackageOrSourceInput + if tmp, ok := rawArgs["subject"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("subject")) + arg0, err = ec.unmarshalNPackageOrSourceInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPackageOrSourceInput(ctx, tmp) + if err != nil { + return nil, err + } + } + args["subject"] = arg0 + var arg1 []*model.LicenseInputSpec + if tmp, ok := rawArgs["declaredLicenses"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("declaredLicenses")) + arg1, err = ec.unmarshalNLicenseInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpecᚄ(ctx, tmp) + if err != nil { + return nil, err + } + } + args["declaredLicenses"] = arg1 + var arg2 []*model.LicenseInputSpec + if tmp, ok := rawArgs["discoveredLicenses"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("discoveredLicenses")) + arg2, err = ec.unmarshalNLicenseInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpecᚄ(ctx, tmp) + if err != nil { + return nil, err + } + } + args["discoveredLicenses"] = arg2 + var arg3 model.CertifyLegalInputSpec + if tmp, ok := rawArgs["certifyLegal"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("certifyLegal")) + arg3, err = ec.unmarshalNCertifyLegalInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐCertifyLegalInputSpec(ctx, tmp) + if err != nil { + return nil, err + } + } + args["certifyLegal"] = arg3 + return args, nil +} + +func (ec *executionContext) field_Mutation_ingestCertifyLegals_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 model.PackageOrSourceInputs + if tmp, ok := rawArgs["subjects"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("subjects")) + arg0, err = ec.unmarshalNPackageOrSourceInputs2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPackageOrSourceInputs(ctx, tmp) + if err != nil { + return nil, err + } + } + args["subjects"] = arg0 + var arg1 [][]*model.LicenseInputSpec + if tmp, ok := rawArgs["declaredLicensesList"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("declaredLicensesList")) + arg1, err = ec.unmarshalNLicenseInputSpec2ᚕᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpecᚄ(ctx, tmp) + if err != nil { + return nil, err + } + } + args["declaredLicensesList"] = arg1 + var arg2 [][]*model.LicenseInputSpec + if tmp, ok := rawArgs["discoveredLicensesList"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("discoveredLicensesList")) + arg2, err = ec.unmarshalNLicenseInputSpec2ᚕᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpecᚄ(ctx, tmp) + if err != nil { + return nil, err + } + } + args["discoveredLicensesList"] = arg2 + var arg3 []*model.CertifyLegalInputSpec + if tmp, ok := rawArgs["certifyLegals"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("certifyLegals")) + arg3, err = ec.unmarshalNCertifyLegalInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐCertifyLegalInputSpecᚄ(ctx, tmp) + if err != nil { + return nil, err + } + } + args["certifyLegals"] = arg3 + return args, nil +} + func (ec *executionContext) field_Mutation_ingestCertifyVuln_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -621,6 +711,36 @@ func (ec *executionContext) field_Mutation_ingestHashEquals_args(ctx context.Con return args, nil } +func (ec *executionContext) field_Mutation_ingestLicense_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *model.LicenseInputSpec + if tmp, ok := rawArgs["license"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("license")) + arg0, err = ec.unmarshalOLicenseInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpec(ctx, tmp) + if err != nil { + return nil, err + } + } + args["license"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Mutation_ingestLicenses_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 []*model.LicenseInputSpec + if tmp, ok := rawArgs["licenses"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("licenses")) + arg0, err = ec.unmarshalNLicenseInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpecᚄ(ctx, tmp) + if err != nil { + return nil, err + } + } + args["licenses"] = arg0 + return args, nil +} + func (ec *executionContext) field_Mutation_ingestOccurrence_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -1152,6 +1272,21 @@ func (ec *executionContext) field_Query_CertifyGood_args(ctx context.Context, ra return args, nil } +func (ec *executionContext) field_Query_CertifyLegal_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 model.CertifyLegalSpec + if tmp, ok := rawArgs["certifyLegalSpec"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("certifyLegalSpec")) + arg0, err = ec.unmarshalNCertifyLegalSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐCertifyLegalSpec(ctx, tmp) + if err != nil { + return nil, err + } + } + args["certifyLegalSpec"] = arg0 + return args, nil +} + func (ec *executionContext) field_Query_CertifyVEXStatement_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -1377,6 +1512,21 @@ func (ec *executionContext) field_Query_findSoftware_args(ctx context.Context, r return args, nil } +func (ec *executionContext) field_Query_licenses_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 model.LicenseSpec + if tmp, ok := rawArgs["licenseSpec"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("licenseSpec")) + arg0, err = ec.unmarshalNLicenseSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseSpec(ctx, tmp) + if err != nil { + return nil, err + } + } + args["licenseSpec"] = arg0 + return args, nil +} + func (ec *executionContext) field_Query_neighbors_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -2143,6 +2293,116 @@ func (ec *executionContext) fieldContext_Mutation_ingestCertifyGoods(ctx context return fc, nil } +func (ec *executionContext) _Mutation_ingestCertifyLegal(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_ingestCertifyLegal(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().IngestCertifyLegal(rctx, fc.Args["subject"].(model.PackageOrSourceInput), fc.Args["declaredLicenses"].([]*model.LicenseInputSpec), fc.Args["discoveredLicenses"].([]*model.LicenseInputSpec), fc.Args["certifyLegal"].(model.CertifyLegalInputSpec)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_ingestCertifyLegal(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Mutation_ingestCertifyLegal_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_ingestCertifyLegals(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_ingestCertifyLegals(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().IngestCertifyLegals(rctx, fc.Args["subjects"].(model.PackageOrSourceInputs), fc.Args["declaredLicensesList"].([][]*model.LicenseInputSpec), fc.Args["discoveredLicensesList"].([][]*model.LicenseInputSpec), fc.Args["certifyLegals"].([]*model.CertifyLegalInputSpec)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalNID2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_ingestCertifyLegals(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Mutation_ingestCertifyLegals_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Mutation_ingestScorecard(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Mutation_ingestScorecard(ctx, field) if err != nil { @@ -3133,6 +3393,116 @@ func (ec *executionContext) fieldContext_Mutation_ingestOccurrences(ctx context. return fc, nil } +func (ec *executionContext) _Mutation_ingestLicense(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_ingestLicense(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().IngestLicense(rctx, fc.Args["license"].(*model.LicenseInputSpec)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_ingestLicense(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Mutation_ingestLicense_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_ingestLicenses(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_ingestLicenses(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().IngestLicenses(rctx, fc.Args["licenses"].([]*model.LicenseInputSpec)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalNID2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_ingestLicenses(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Mutation_ingestLicenses_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Mutation_ingestHasMetadata(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Mutation_ingestHasMetadata(ctx, field) if err != nil { @@ -3996,6 +4366,85 @@ func (ec *executionContext) fieldContext_Query_CertifyGood(ctx context.Context, return fc, nil } +func (ec *executionContext) _Query_CertifyLegal(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_CertifyLegal(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().CertifyLegal(rctx, fc.Args["certifyLegalSpec"].(model.CertifyLegalSpec)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.CertifyLegal) + fc.Result = res + return ec.marshalNCertifyLegal2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐCertifyLegalᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_CertifyLegal(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_CertifyLegal_id(ctx, field) + case "subject": + return ec.fieldContext_CertifyLegal_subject(ctx, field) + case "declaredLicense": + return ec.fieldContext_CertifyLegal_declaredLicense(ctx, field) + case "declaredLicenses": + return ec.fieldContext_CertifyLegal_declaredLicenses(ctx, field) + case "discoveredLicense": + return ec.fieldContext_CertifyLegal_discoveredLicense(ctx, field) + case "discoveredLicenses": + return ec.fieldContext_CertifyLegal_discoveredLicenses(ctx, field) + case "attribution": + return ec.fieldContext_CertifyLegal_attribution(ctx, field) + case "justification": + return ec.fieldContext_CertifyLegal_justification(ctx, field) + case "timeScanned": + return ec.fieldContext_CertifyLegal_timeScanned(ctx, field) + case "origin": + return ec.fieldContext_CertifyLegal_origin(ctx, field) + case "collector": + return ec.fieldContext_CertifyLegal_collector(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type CertifyLegal", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_CertifyLegal_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Query_scorecards(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Query_scorecards(ctx, field) if err != nil { @@ -4690,6 +5139,71 @@ func (ec *executionContext) fieldContext_Query_IsOccurrence(ctx context.Context, return fc, nil } +func (ec *executionContext) _Query_licenses(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_licenses(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Licenses(rctx, fc.Args["licenseSpec"].(model.LicenseSpec)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.License) + fc.Result = res + return ec.marshalNLicense2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_licenses(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_License_id(ctx, field) + case "name": + return ec.fieldContext_License_name(ctx, field) + case "inline": + return ec.fieldContext_License_inline(ctx, field) + case "listVersion": + return ec.fieldContext_License_listVersion(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type License", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_licenses_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Query_HasMetadata(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Query_HasMetadata(ctx, field) if err != nil { @@ -5782,6 +6296,20 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { out.Invalids++ } + case "ingestCertifyLegal": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_ingestCertifyLegal(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "ingestCertifyLegals": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_ingestCertifyLegals(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } case "ingestScorecard": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Mutation_ingestScorecard(ctx, field) @@ -5908,6 +6436,20 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { out.Invalids++ } + case "ingestLicense": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_ingestLicense(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "ingestLicenses": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_ingestLicenses(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } case "ingestHasMetadata": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Mutation_ingestHasMetadata(ctx, field) @@ -6114,6 +6656,28 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "CertifyLegal": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_CertifyLegal(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "scorecards": field := field @@ -6334,6 +6898,28 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "licenses": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_licenses(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "HasMetadata": field := field diff --git a/pkg/assembler/graphql/generated/certifyLegal.generated.go b/pkg/assembler/graphql/generated/certifyLegal.generated.go new file mode 100644 index 0000000000..419cdc38b3 --- /dev/null +++ b/pkg/assembler/graphql/generated/certifyLegal.generated.go @@ -0,0 +1,930 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "context" + "errors" + "fmt" + "strconv" + "sync" + "sync/atomic" + "time" + + "github.com/99designs/gqlgen/graphql" + "github.com/guacsec/guac/pkg/assembler/graphql/model" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _CertifyLegal_id(ctx context.Context, field graphql.CollectedField, obj *model.CertifyLegal) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CertifyLegal_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CertifyLegal_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CertifyLegal", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CertifyLegal_subject(ctx context.Context, field graphql.CollectedField, obj *model.CertifyLegal) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CertifyLegal_subject(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Subject, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(model.PackageOrSource) + fc.Result = res + return ec.marshalNPackageOrSource2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPackageOrSource(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CertifyLegal_subject(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CertifyLegal", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type PackageOrSource does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CertifyLegal_declaredLicense(ctx context.Context, field graphql.CollectedField, obj *model.CertifyLegal) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CertifyLegal_declaredLicense(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeclaredLicense, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CertifyLegal_declaredLicense(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CertifyLegal", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CertifyLegal_declaredLicenses(ctx context.Context, field graphql.CollectedField, obj *model.CertifyLegal) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CertifyLegal_declaredLicenses(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeclaredLicenses, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.License) + fc.Result = res + return ec.marshalNLicense2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CertifyLegal_declaredLicenses(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CertifyLegal", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_License_id(ctx, field) + case "name": + return ec.fieldContext_License_name(ctx, field) + case "inline": + return ec.fieldContext_License_inline(ctx, field) + case "listVersion": + return ec.fieldContext_License_listVersion(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type License", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _CertifyLegal_discoveredLicense(ctx context.Context, field graphql.CollectedField, obj *model.CertifyLegal) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CertifyLegal_discoveredLicense(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DiscoveredLicense, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CertifyLegal_discoveredLicense(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CertifyLegal", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CertifyLegal_discoveredLicenses(ctx context.Context, field graphql.CollectedField, obj *model.CertifyLegal) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CertifyLegal_discoveredLicenses(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DiscoveredLicenses, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.License) + fc.Result = res + return ec.marshalNLicense2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CertifyLegal_discoveredLicenses(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CertifyLegal", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_License_id(ctx, field) + case "name": + return ec.fieldContext_License_name(ctx, field) + case "inline": + return ec.fieldContext_License_inline(ctx, field) + case "listVersion": + return ec.fieldContext_License_listVersion(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type License", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _CertifyLegal_attribution(ctx context.Context, field graphql.CollectedField, obj *model.CertifyLegal) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CertifyLegal_attribution(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Attribution, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CertifyLegal_attribution(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CertifyLegal", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CertifyLegal_justification(ctx context.Context, field graphql.CollectedField, obj *model.CertifyLegal) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CertifyLegal_justification(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Justification, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CertifyLegal_justification(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CertifyLegal", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CertifyLegal_timeScanned(ctx context.Context, field graphql.CollectedField, obj *model.CertifyLegal) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CertifyLegal_timeScanned(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TimeScanned, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(time.Time) + fc.Result = res + return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CertifyLegal_timeScanned(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CertifyLegal", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Time does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CertifyLegal_origin(ctx context.Context, field graphql.CollectedField, obj *model.CertifyLegal) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CertifyLegal_origin(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Origin, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CertifyLegal_origin(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CertifyLegal", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CertifyLegal_collector(ctx context.Context, field graphql.CollectedField, obj *model.CertifyLegal) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CertifyLegal_collector(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Collector, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CertifyLegal_collector(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CertifyLegal", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputCertifyLegalInputSpec(ctx context.Context, obj interface{}) (model.CertifyLegalInputSpec, error) { + var it model.CertifyLegalInputSpec + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"declaredLicense", "discoveredLicense", "attribution", "justification", "timeScanned", "origin", "collector"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "declaredLicense": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("declaredLicense")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.DeclaredLicense = data + case "discoveredLicense": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("discoveredLicense")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.DiscoveredLicense = data + case "attribution": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("attribution")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.Attribution = data + case "justification": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("justification")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.Justification = data + case "timeScanned": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("timeScanned")) + data, err := ec.unmarshalNTime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + it.TimeScanned = data + case "origin": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("origin")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.Origin = data + case "collector": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("collector")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.Collector = data + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputCertifyLegalSpec(ctx context.Context, obj interface{}) (model.CertifyLegalSpec, error) { + var it model.CertifyLegalSpec + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"id", "subject", "declaredLicense", "declaredLicenses", "discoveredLicense", "discoveredLicenses", "attribution", "justification", "timeScanned", "origin", "collector"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "id": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + data, err := ec.unmarshalOID2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.ID = data + case "subject": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("subject")) + data, err := ec.unmarshalOPackageOrSourceSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPackageOrSourceSpec(ctx, v) + if err != nil { + return it, err + } + it.Subject = data + case "declaredLicense": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("declaredLicense")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.DeclaredLicense = data + case "declaredLicenses": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("declaredLicenses")) + data, err := ec.unmarshalOLicenseSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseSpecᚄ(ctx, v) + if err != nil { + return it, err + } + it.DeclaredLicenses = data + case "discoveredLicense": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("discoveredLicense")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.DiscoveredLicense = data + case "discoveredLicenses": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("discoveredLicenses")) + data, err := ec.unmarshalOLicenseSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseSpecᚄ(ctx, v) + if err != nil { + return it, err + } + it.DiscoveredLicenses = data + case "attribution": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("attribution")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Attribution = data + case "justification": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("justification")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Justification = data + case "timeScanned": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("timeScanned")) + data, err := ec.unmarshalOTime2ᚖtimeᚐTime(ctx, v) + if err != nil { + return it, err + } + it.TimeScanned = data + case "origin": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("origin")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Origin = data + case "collector": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("collector")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Collector = data + } + } + + return it, nil +} + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var certifyLegalImplementors = []string{"CertifyLegal", "Node"} + +func (ec *executionContext) _CertifyLegal(ctx context.Context, sel ast.SelectionSet, obj *model.CertifyLegal) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, certifyLegalImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("CertifyLegal") + case "id": + out.Values[i] = ec._CertifyLegal_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "subject": + out.Values[i] = ec._CertifyLegal_subject(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "declaredLicense": + out.Values[i] = ec._CertifyLegal_declaredLicense(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "declaredLicenses": + out.Values[i] = ec._CertifyLegal_declaredLicenses(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "discoveredLicense": + out.Values[i] = ec._CertifyLegal_discoveredLicense(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "discoveredLicenses": + out.Values[i] = ec._CertifyLegal_discoveredLicenses(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "attribution": + out.Values[i] = ec._CertifyLegal_attribution(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "justification": + out.Values[i] = ec._CertifyLegal_justification(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "timeScanned": + out.Values[i] = ec._CertifyLegal_timeScanned(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "origin": + out.Values[i] = ec._CertifyLegal_origin(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "collector": + out.Values[i] = ec._CertifyLegal_collector(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalNCertifyLegal2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐCertifyLegalᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.CertifyLegal) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNCertifyLegal2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐCertifyLegal(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNCertifyLegal2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐCertifyLegal(ctx context.Context, sel ast.SelectionSet, v *model.CertifyLegal) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._CertifyLegal(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNCertifyLegalInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐCertifyLegalInputSpec(ctx context.Context, v interface{}) (model.CertifyLegalInputSpec, error) { + res, err := ec.unmarshalInputCertifyLegalInputSpec(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNCertifyLegalInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐCertifyLegalInputSpecᚄ(ctx context.Context, v interface{}) ([]*model.CertifyLegalInputSpec, error) { + var vSlice []interface{} + if v != nil { + vSlice = graphql.CoerceList(v) + } + var err error + res := make([]*model.CertifyLegalInputSpec, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNCertifyLegalInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐCertifyLegalInputSpec(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) unmarshalNCertifyLegalInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐCertifyLegalInputSpec(ctx context.Context, v interface{}) (*model.CertifyLegalInputSpec, error) { + res, err := ec.unmarshalInputCertifyLegalInputSpec(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNCertifyLegalSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐCertifyLegalSpec(ctx context.Context, v interface{}) (model.CertifyLegalSpec, error) { + res, err := ec.unmarshalInputCertifyLegalSpec(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/pkg/assembler/graphql/generated/license.generated.go b/pkg/assembler/graphql/generated/license.generated.go new file mode 100644 index 0000000000..ab84b8a56b --- /dev/null +++ b/pkg/assembler/graphql/generated/license.generated.go @@ -0,0 +1,499 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "context" + "errors" + "strconv" + "sync" + "sync/atomic" + + "github.com/99designs/gqlgen/graphql" + "github.com/guacsec/guac/pkg/assembler/graphql/model" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _License_id(ctx context.Context, field graphql.CollectedField, obj *model.License) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_License_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_License_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "License", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _License_name(ctx context.Context, field graphql.CollectedField, obj *model.License) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_License_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_License_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "License", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _License_inline(ctx context.Context, field graphql.CollectedField, obj *model.License) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_License_inline(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Inline, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_License_inline(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "License", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _License_listVersion(ctx context.Context, field graphql.CollectedField, obj *model.License) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_License_listVersion(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ListVersion, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_License_listVersion(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "License", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputLicenseInputSpec(ctx context.Context, obj interface{}) (model.LicenseInputSpec, error) { + var it model.LicenseInputSpec + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"name", "inline", "listVersion"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "name": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.Name = data + case "inline": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inline")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Inline = data + case "listVersion": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("listVersion")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.ListVersion = data + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputLicenseSpec(ctx context.Context, obj interface{}) (model.LicenseSpec, error) { + var it model.LicenseSpec + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"id", "name", "inline", "listVersion"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "id": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + data, err := ec.unmarshalOID2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.ID = data + case "name": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Name = data + case "inline": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inline")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Inline = data + case "listVersion": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("listVersion")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.ListVersion = data + } + } + + return it, nil +} + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var licenseImplementors = []string{"License", "Node"} + +func (ec *executionContext) _License(ctx context.Context, sel ast.SelectionSet, obj *model.License) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, licenseImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("License") + case "id": + out.Values[i] = ec._License_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec._License_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "inline": + out.Values[i] = ec._License_inline(ctx, field, obj) + case "listVersion": + out.Values[i] = ec._License_listVersion(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalNLicense2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.License) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNLicense2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicense(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNLicense2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicense(ctx context.Context, sel ast.SelectionSet, v *model.License) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._License(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNLicenseInputSpec2ᚕᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpecᚄ(ctx context.Context, v interface{}) ([][]*model.LicenseInputSpec, error) { + var vSlice []interface{} + if v != nil { + vSlice = graphql.CoerceList(v) + } + var err error + res := make([][]*model.LicenseInputSpec, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNLicenseInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpecᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) unmarshalNLicenseInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpecᚄ(ctx context.Context, v interface{}) ([]*model.LicenseInputSpec, error) { + var vSlice []interface{} + if v != nil { + vSlice = graphql.CoerceList(v) + } + var err error + res := make([]*model.LicenseInputSpec, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNLicenseInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpec(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) unmarshalNLicenseInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpec(ctx context.Context, v interface{}) (*model.LicenseInputSpec, error) { + res, err := ec.unmarshalInputLicenseInputSpec(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNLicenseSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseSpec(ctx context.Context, v interface{}) (model.LicenseSpec, error) { + res, err := ec.unmarshalInputLicenseSpec(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNLicenseSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseSpec(ctx context.Context, v interface{}) (*model.LicenseSpec, error) { + res, err := ec.unmarshalInputLicenseSpec(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalOLicenseInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpec(ctx context.Context, v interface{}) (*model.LicenseInputSpec, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputLicenseInputSpec(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalOLicenseSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseSpecᚄ(ctx context.Context, v interface{}) ([]*model.LicenseSpec, error) { + if v == nil { + return nil, nil + } + var vSlice []interface{} + if v != nil { + vSlice = graphql.CoerceList(v) + } + var err error + res := make([]*model.LicenseSpec, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNLicenseSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseSpec(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/pkg/assembler/graphql/generated/path.generated.go b/pkg/assembler/graphql/generated/path.generated.go index 45159cc283..d060616467 100644 --- a/pkg/assembler/graphql/generated/path.generated.go +++ b/pkg/assembler/graphql/generated/path.generated.go @@ -185,6 +185,20 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj return graphql.Null } return ec._VulnerabilityMetadata(ctx, sel, obj) + case model.License: + return ec._License(ctx, sel, &obj) + case *model.License: + if obj == nil { + return graphql.Null + } + return ec._License(ctx, sel, obj) + case model.CertifyLegal: + return ec._CertifyLegal(ctx, sel, &obj) + case *model.CertifyLegal: + if obj == nil { + return graphql.Null + } + return ec._CertifyLegal(ctx, sel, obj) default: panic(fmt.Errorf("unexpected type %T", obj)) } diff --git a/pkg/assembler/graphql/generated/root_.generated.go b/pkg/assembler/graphql/generated/root_.generated.go index b3938847f9..5a73078e08 100644 --- a/pkg/assembler/graphql/generated/root_.generated.go +++ b/pkg/assembler/graphql/generated/root_.generated.go @@ -66,6 +66,20 @@ type ComplexityRoot struct { Subject func(childComplexity int) int } + CertifyLegal struct { + Attribution func(childComplexity int) int + Collector func(childComplexity int) int + DeclaredLicense func(childComplexity int) int + DeclaredLicenses func(childComplexity int) int + DiscoveredLicense func(childComplexity int) int + DiscoveredLicenses func(childComplexity int) int + ID func(childComplexity int) int + Justification func(childComplexity int) int + Origin func(childComplexity int) int + Subject func(childComplexity int) int + TimeScanned func(childComplexity int) int + } + CertifyScorecard struct { ID func(childComplexity int) int Scorecard func(childComplexity int) int @@ -158,6 +172,13 @@ type ComplexityRoot struct { Subject func(childComplexity int) int } + License struct { + ID func(childComplexity int) int + Inline func(childComplexity int) int + ListVersion func(childComplexity int) int + Name func(childComplexity int) int + } + Mutation struct { IngestArtifact func(childComplexity int, artifact *model.ArtifactInputSpec) int IngestArtifacts func(childComplexity int, artifacts []*model.ArtifactInputSpec) int @@ -167,6 +188,8 @@ type ComplexityRoot struct { IngestCertifyBads func(childComplexity int, subjects model.PackageSourceOrArtifactInputs, pkgMatchType model.MatchFlags, certifyBads []*model.CertifyBadInputSpec) int IngestCertifyGood func(childComplexity int, subject model.PackageSourceOrArtifactInput, pkgMatchType model.MatchFlags, certifyGood model.CertifyGoodInputSpec) int IngestCertifyGoods func(childComplexity int, subjects model.PackageSourceOrArtifactInputs, pkgMatchType model.MatchFlags, certifyGoods []*model.CertifyGoodInputSpec) int + IngestCertifyLegal func(childComplexity int, subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, certifyLegal model.CertifyLegalInputSpec) int + IngestCertifyLegals func(childComplexity int, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.LicenseInputSpec, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) int IngestCertifyVuln func(childComplexity int, pkg model.PkgInputSpec, vulnerability model.VulnerabilityInputSpec, certifyVuln model.ScanMetadataInput) int IngestCertifyVulns func(childComplexity int, pkgs []*model.PkgInputSpec, vulnerabilities []*model.VulnerabilityInputSpec, certifyVulns []*model.ScanMetadataInput) int IngestDependencies func(childComplexity int, pkgs []*model.PkgInputSpec, depPkgs []*model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) int @@ -177,6 +200,8 @@ type ComplexityRoot struct { IngestHasSourceAt func(childComplexity int, pkg model.PkgInputSpec, pkgMatchType model.MatchFlags, source model.SourceInputSpec, hasSourceAt model.HasSourceAtInputSpec) int IngestHashEqual func(childComplexity int, artifact model.ArtifactInputSpec, otherArtifact model.ArtifactInputSpec, hashEqual model.HashEqualInputSpec) int IngestHashEquals func(childComplexity int, artifacts []*model.ArtifactInputSpec, otherArtifacts []*model.ArtifactInputSpec, hashEquals []*model.HashEqualInputSpec) int + IngestLicense func(childComplexity int, license *model.LicenseInputSpec) int + IngestLicenses func(childComplexity int, licenses []*model.LicenseInputSpec) int IngestOccurrence func(childComplexity int, subject model.PackageOrSourceInput, artifact model.ArtifactInputSpec, occurrence model.IsOccurrenceInputSpec) int IngestOccurrences func(childComplexity int, subjects model.PackageOrSourceInputs, artifacts []*model.ArtifactInputSpec, occurrences []*model.IsOccurrenceInputSpec) int IngestPackage func(childComplexity int, pkg model.PkgInputSpec) int @@ -252,6 +277,7 @@ type ComplexityRoot struct { Builders func(childComplexity int, builderSpec model.BuilderSpec) int CertifyBad func(childComplexity int, certifyBadSpec model.CertifyBadSpec) int CertifyGood func(childComplexity int, certifyGoodSpec model.CertifyGoodSpec) int + CertifyLegal func(childComplexity int, certifyLegalSpec model.CertifyLegalSpec) int CertifyVEXStatement func(childComplexity int, certifyVEXStatementSpec model.CertifyVEXStatementSpec) int CertifyVuln func(childComplexity int, certifyVulnSpec model.CertifyVulnSpec) int FindSoftware func(childComplexity int, searchText string) int @@ -262,6 +288,7 @@ type ComplexityRoot struct { HashEqual func(childComplexity int, hashEqualSpec model.HashEqualSpec) int IsDependency func(childComplexity int, isDependencySpec model.IsDependencySpec) int IsOccurrence func(childComplexity int, isOccurrenceSpec model.IsOccurrenceSpec) int + Licenses func(childComplexity int, licenseSpec model.LicenseSpec) int Neighbors func(childComplexity int, node string, usingOnly []model.Edge) int Node func(childComplexity int, node string) int Nodes func(childComplexity int, nodes []string) int @@ -487,6 +514,83 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.CertifyGood.Subject(childComplexity), true + case "CertifyLegal.attribution": + if e.complexity.CertifyLegal.Attribution == nil { + break + } + + return e.complexity.CertifyLegal.Attribution(childComplexity), true + + case "CertifyLegal.collector": + if e.complexity.CertifyLegal.Collector == nil { + break + } + + return e.complexity.CertifyLegal.Collector(childComplexity), true + + case "CertifyLegal.declaredLicense": + if e.complexity.CertifyLegal.DeclaredLicense == nil { + break + } + + return e.complexity.CertifyLegal.DeclaredLicense(childComplexity), true + + case "CertifyLegal.declaredLicenses": + if e.complexity.CertifyLegal.DeclaredLicenses == nil { + break + } + + return e.complexity.CertifyLegal.DeclaredLicenses(childComplexity), true + + case "CertifyLegal.discoveredLicense": + if e.complexity.CertifyLegal.DiscoveredLicense == nil { + break + } + + return e.complexity.CertifyLegal.DiscoveredLicense(childComplexity), true + + case "CertifyLegal.discoveredLicenses": + if e.complexity.CertifyLegal.DiscoveredLicenses == nil { + break + } + + return e.complexity.CertifyLegal.DiscoveredLicenses(childComplexity), true + + case "CertifyLegal.id": + if e.complexity.CertifyLegal.ID == nil { + break + } + + return e.complexity.CertifyLegal.ID(childComplexity), true + + case "CertifyLegal.justification": + if e.complexity.CertifyLegal.Justification == nil { + break + } + + return e.complexity.CertifyLegal.Justification(childComplexity), true + + case "CertifyLegal.origin": + if e.complexity.CertifyLegal.Origin == nil { + break + } + + return e.complexity.CertifyLegal.Origin(childComplexity), true + + case "CertifyLegal.subject": + if e.complexity.CertifyLegal.Subject == nil { + break + } + + return e.complexity.CertifyLegal.Subject(childComplexity), true + + case "CertifyLegal.timeScanned": + if e.complexity.CertifyLegal.TimeScanned == nil { + break + } + + return e.complexity.CertifyLegal.TimeScanned(childComplexity), true + case "CertifyScorecard.id": if e.complexity.CertifyScorecard.ID == nil { break @@ -921,6 +1025,34 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.IsOccurrence.Subject(childComplexity), true + case "License.id": + if e.complexity.License.ID == nil { + break + } + + return e.complexity.License.ID(childComplexity), true + + case "License.inline": + if e.complexity.License.Inline == nil { + break + } + + return e.complexity.License.Inline(childComplexity), true + + case "License.listVersion": + if e.complexity.License.ListVersion == nil { + break + } + + return e.complexity.License.ListVersion(childComplexity), true + + case "License.name": + if e.complexity.License.Name == nil { + break + } + + return e.complexity.License.Name(childComplexity), true + case "Mutation.ingestArtifact": if e.complexity.Mutation.IngestArtifact == nil { break @@ -1017,6 +1149,30 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.IngestCertifyGoods(childComplexity, args["subjects"].(model.PackageSourceOrArtifactInputs), args["pkgMatchType"].(model.MatchFlags), args["certifyGoods"].([]*model.CertifyGoodInputSpec)), true + case "Mutation.ingestCertifyLegal": + if e.complexity.Mutation.IngestCertifyLegal == nil { + break + } + + args, err := ec.field_Mutation_ingestCertifyLegal_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.IngestCertifyLegal(childComplexity, args["subject"].(model.PackageOrSourceInput), args["declaredLicenses"].([]*model.LicenseInputSpec), args["discoveredLicenses"].([]*model.LicenseInputSpec), args["certifyLegal"].(model.CertifyLegalInputSpec)), true + + case "Mutation.ingestCertifyLegals": + if e.complexity.Mutation.IngestCertifyLegals == nil { + break + } + + args, err := ec.field_Mutation_ingestCertifyLegals_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.IngestCertifyLegals(childComplexity, args["subjects"].(model.PackageOrSourceInputs), args["declaredLicensesList"].([][]*model.LicenseInputSpec), args["discoveredLicensesList"].([][]*model.LicenseInputSpec), args["certifyLegals"].([]*model.CertifyLegalInputSpec)), true + case "Mutation.ingestCertifyVuln": if e.complexity.Mutation.IngestCertifyVuln == nil { break @@ -1137,6 +1293,30 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.IngestHashEquals(childComplexity, args["artifacts"].([]*model.ArtifactInputSpec), args["otherArtifacts"].([]*model.ArtifactInputSpec), args["hashEquals"].([]*model.HashEqualInputSpec)), true + case "Mutation.ingestLicense": + if e.complexity.Mutation.IngestLicense == nil { + break + } + + args, err := ec.field_Mutation_ingestLicense_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.IngestLicense(childComplexity, args["license"].(*model.LicenseInputSpec)), true + + case "Mutation.ingestLicenses": + if e.complexity.Mutation.IngestLicenses == nil { + break + } + + args, err := ec.field_Mutation_ingestLicenses_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.IngestLicenses(childComplexity, args["licenses"].([]*model.LicenseInputSpec)), true + case "Mutation.ingestOccurrence": if e.complexity.Mutation.IngestOccurrence == nil { break @@ -1609,6 +1789,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.CertifyGood(childComplexity, args["certifyGoodSpec"].(model.CertifyGoodSpec)), true + case "Query.CertifyLegal": + if e.complexity.Query.CertifyLegal == nil { + break + } + + args, err := ec.field_Query_CertifyLegal_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.CertifyLegal(childComplexity, args["certifyLegalSpec"].(model.CertifyLegalSpec)), true + case "Query.CertifyVEXStatement": if e.complexity.Query.CertifyVEXStatement == nil { break @@ -1729,6 +1921,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.IsOccurrence(childComplexity, args["isOccurrenceSpec"].(model.IsOccurrenceSpec)), true + case "Query.licenses": + if e.complexity.Query.Licenses == nil { + break + } + + args, err := ec.field_Query_licenses_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Licenses(childComplexity, args["licenseSpec"].(model.LicenseSpec)), true + case "Query.neighbors": if e.complexity.Query.Neighbors == nil { break @@ -2267,6 +2471,8 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputCertifyBadSpec, ec.unmarshalInputCertifyGoodInputSpec, ec.unmarshalInputCertifyGoodSpec, + ec.unmarshalInputCertifyLegalInputSpec, + ec.unmarshalInputCertifyLegalSpec, ec.unmarshalInputCertifyScorecardSpec, ec.unmarshalInputCertifyVEXStatementSpec, ec.unmarshalInputCertifyVulnSpec, @@ -2283,6 +2489,8 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputIsDependencySpec, ec.unmarshalInputIsOccurrenceInputSpec, ec.unmarshalInputIsOccurrenceSpec, + ec.unmarshalInputLicenseInputSpec, + ec.unmarshalInputLicenseSpec, ec.unmarshalInputMatchFlags, ec.unmarshalInputPackageOrArtifactInput, ec.unmarshalInputPackageOrArtifactInputs, @@ -2762,6 +2970,112 @@ extend type Mutation { certifyGoods: [CertifyGoodInputSpec!]! ): [ID!]! } +`, BuiltIn: false}, + {Name: "../schema/certifyLegal.graphql", Input: `# +# Copyright 2023 The GUAC Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# NOTE: This is experimental and might change in the future! + +# Defines a GraphQL schema for the legal certifications + +""" +CertifyLegal is an attestation to attach legal information to a package or source. + +The certification information is either copied from an attestation found in an +SBOM or created by a collector/scanner. + +Discovered license is also known as Concluded. More information: +https://docs.clearlydefined.io/curation-guidelines#the-difference-between-declared-and-discovered-licenses + +Attribution is also known as Copyright Text. It is what could be displayed to +comply with notice +requirements. https://www.nexb.com/oss-attribution-best-practices/ + +License expressions follow this format: +https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/ +""" +type CertifyLegal { + id: ID! + "The package version or source that is attested" + subject: PackageOrSource! + "The license expression as delcared" + declaredLicense: String! + "A list of license objects found in the declared license expression" + declaredLicenses: [License!]! + "The license expression as discovered by scan" + discoveredLicense: String! + "A list of license objects found in the discovered license expression" + discoveredLicenses: [License!]! + "Attribution text of the subject" + attribution: String! + "Extra justification for the certification" + justification: String! + "Time of scan (in RFC 3339 format)" + timeScanned: Time! + "Document from which this attestation is generated from" + origin: String! + "GUAC collector for the document" + collector: String! +} + +""" +CertifyLegalSpec allows filtering the list of legal certifications to +return in a query. + +Specifying just the package allows to query for all certifications associated +with the package. +""" +input CertifyLegalSpec { + id: ID + subject: PackageOrSourceSpec + declaredLicense: String + declaredLicenses: [LicenseSpec!] + discoveredLicense: String + discoveredLicenses: [LicenseSpec!] + attribution: String + justification: String + timeScanned: Time + origin: String + collector: String +} + +""" +CertifyLegalInputSpec represents the input for certifying legal information in +mutations. +""" +input CertifyLegalInputSpec { + declaredLicense: String! + discoveredLicense: String! + attribution: String! + justification: String! + timeScanned: Time! + origin: String! + collector: String! +} + +extend type Query { + "Returns all legal certifications matching the input filter." + CertifyLegal(certifyLegalSpec: CertifyLegalSpec!): [CertifyLegal!]! +} + +extend type Mutation { + "Adds a legal certification to a package or source." + ingestCertifyLegal(subject: PackageOrSourceInput!, declaredLicenses: [LicenseInputSpec!]!, discoveredLicenses: [LicenseInputSpec!]!, certifyLegal: CertifyLegalInputSpec!): ID! + "Bulk add legal certifications to packages or sources, not both at same time." + ingestCertifyLegals(subjects: PackageOrSourceInputs!, declaredLicensesList: [[LicenseInputSpec!]!]!, discoveredLicensesList: [[LicenseInputSpec!]!]!, certifyLegals: [CertifyLegalInputSpec!]!): [ID!]! +} `, BuiltIn: false}, {Name: "../schema/certifyScorecard.graphql", Input: `# # Copyright 2023 The GUAC Authors. @@ -3850,6 +4164,91 @@ extend type Mutation { occurrences: [IsOccurrenceInputSpec!]! ): [ID!]! } +`, BuiltIn: false}, + {Name: "../schema/license.graphql", Input: `# +# Copyright 2023 The GUAC Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# NOTE: This is experimental and might change in the future! + +# Defines a GraphQL schema for the license + +""" +License represents a particular license. If the license is found on the SPDX +license list (https://spdx.org/licenses/) then the fields should be: + +Name: SPDX license identifier +Inline: empty +ListVersion: SPDX license list version + +example: + +Name: AGPL-3.0-or-later +Inline: "" +ListVersion: 3.21 2023-06-18 + +If the license is not on the SPDX license list, then a new guid should be +created and the license text placed inline: + +Name: LicenseRef- +Inline: Full license text +ListVersion: empty + +example: + +Name: LicenseRef-1a2b3c +Inline: Permission to use, copy, modify, and/or distribute ... +ListVersion: "" +""" +type License { + id: ID! + name: String! + inline: String + listVersion: String +} + +""" +LicenseSpec allows filtering the list of licenses to return in a query. +""" +input LicenseSpec { + id: ID + name: String + inline: String + listVersion: String +} + +""" +LicenseInputSpec specifies an license for mutations. One of inline or +listVersion should be empty or missing. +""" +input LicenseInputSpec { + name: String! + inline: String + listVersion: String +} + +extend type Query { + "Returns all licenses matching a filter." + licenses(licenseSpec: LicenseSpec!): [License!]! +} + +extend type Mutation { + "Ingests a new license and returns it." + ingestLicense(license: LicenseInputSpec): ID! + "Bulk ingests new licenses and returns a list of them." + ingestLicenses(licenses: [LicenseInputSpec!]!): [ID!]! +} `, BuiltIn: false}, {Name: "../schema/metadata.graphql", Input: `# # Copyright 2023 The GUAC Authors. @@ -4184,6 +4583,8 @@ union Node = | HasMetadata | PointOfContact | VulnerabilityMetadata + | License + | CertifyLegal """ Edge allows filtering path/neighbors output to only contain a subset of all @@ -4202,34 +4603,37 @@ enum Edge { ARTIFACT_CERTIFY_GOOD ARTIFACT_CERTIFY_VEX_STATEMENT ARTIFACT_HASH_EQUAL + ARTIFACT_HAS_METADATA ARTIFACT_HAS_SBOM ARTIFACT_HAS_SLSA ARTIFACT_IS_OCCURRENCE - ARTIFACT_HAS_METADATA ARTIFACT_POINT_OF_CONTACT BUILDER_HAS_SLSA - VULNERABILITY_CERTIFY_VEX_STATEMENT - VULNERABILITY_CERTIFY_VULN - VULNERABILITY_VULN_EQUAL - VULNERABILITY_VULN_METADATA + LICENSE_CERTIFY_LEGAL PACKAGE_CERTIFY_BAD PACKAGE_CERTIFY_GOOD + PACKAGE_CERTIFY_LEGAL PACKAGE_CERTIFY_VEX_STATEMENT PACKAGE_CERTIFY_VULN + PACKAGE_HAS_METADATA PACKAGE_HAS_SBOM PACKAGE_HAS_SOURCE_AT PACKAGE_IS_DEPENDENCY PACKAGE_IS_OCCURRENCE PACKAGE_PKG_EQUAL - PACKAGE_HAS_METADATA PACKAGE_POINT_OF_CONTACT SOURCE_CERTIFY_BAD SOURCE_CERTIFY_GOOD + SOURCE_CERTIFY_LEGAL SOURCE_CERTIFY_SCORECARD + SOURCE_HAS_METADATA SOURCE_HAS_SOURCE_AT SOURCE_IS_OCCURRENCE - SOURCE_HAS_METADATA SOURCE_POINT_OF_CONTACT + VULNERABILITY_CERTIFY_VEX_STATEMENT + VULNERABILITY_CERTIFY_VULN + VULNERABILITY_VULN_EQUAL + VULNERABILITY_VULN_METADATA CERTIFY_BAD_ARTIFACT CERTIFY_BAD_PACKAGE @@ -4237,13 +4641,19 @@ enum Edge { CERTIFY_GOOD_ARTIFACT CERTIFY_GOOD_PACKAGE CERTIFY_GOOD_SOURCE + CERTIFY_LEGAL_LICENSE + CERTIFY_LEGAL_PACKAGE + CERTIFY_LEGAL_SOURCE CERTIFY_SCORECARD_SOURCE CERTIFY_VEX_STATEMENT_ARTIFACT - CERTIFY_VEX_STATEMENT_VULNERABILITY CERTIFY_VEX_STATEMENT_PACKAGE - CERTIFY_VULN_VULNERABILITY + CERTIFY_VEX_STATEMENT_VULNERABILITY CERTIFY_VULN_PACKAGE + CERTIFY_VULN_VULNERABILITY HASH_EQUAL_ARTIFACT + HAS_METADATA_ARTIFACT + HAS_METADATA_PACKAGE + HAS_METADATA_SOURCE HAS_SBOM_ARTIFACT HAS_SBOM_PACKAGE HAS_SLSA_BUILT_BY @@ -4255,14 +4665,11 @@ enum Edge { IS_OCCURRENCE_ARTIFACT IS_OCCURRENCE_PACKAGE IS_OCCURRENCE_SOURCE - VULN_EQUAL_VULNERABILITY PKG_EQUAL_PACKAGE - HAS_METADATA_PACKAGE - HAS_METADATA_ARTIFACT - HAS_METADATA_SOURCE - POINT_OF_CONTACT_PACKAGE POINT_OF_CONTACT_ARTIFACT + POINT_OF_CONTACT_PACKAGE POINT_OF_CONTACT_SOURCE + VULN_EQUAL_VULNERABILITY VULN_METADATA_VULNERABILITY } diff --git a/pkg/assembler/graphql/model/nodes.go b/pkg/assembler/graphql/model/nodes.go index 6ca6dfc737..b5ed7aba57 100644 --- a/pkg/assembler/graphql/model/nodes.go +++ b/pkg/assembler/graphql/model/nodes.go @@ -181,6 +181,77 @@ type CertifyGoodSpec struct { Collector *string `json:"collector,omitempty"` } +// CertifyLegal is an attestation to attach legal information to a package or source. +// +// The certification information is either copied from an attestation found in an +// SBOM or created by a collector/scanner. +// +// Discovered license is also known as Concluded. More information: +// https://docs.clearlydefined.io/curation-guidelines#the-difference-between-declared-and-discovered-licenses +// +// Attribution is also known as Copyright Text. It is what could be displayed to +// comply with notice +// requirements. https://www.nexb.com/oss-attribution-best-practices/ +// +// License expressions follow this format: +// https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/ +type CertifyLegal struct { + ID string `json:"id"` + // The package version or source that is attested + Subject PackageOrSource `json:"subject"` + // The license expression as delcared + DeclaredLicense string `json:"declaredLicense"` + // A list of license objects found in the declared license expression + DeclaredLicenses []*License `json:"declaredLicenses"` + // The license expression as discovered by scan + DiscoveredLicense string `json:"discoveredLicense"` + // A list of license objects found in the discovered license expression + DiscoveredLicenses []*License `json:"discoveredLicenses"` + // Attribution text of the subject + Attribution string `json:"attribution"` + // Extra justification for the certification + Justification string `json:"justification"` + // Time of scan (in RFC 3339 format) + TimeScanned time.Time `json:"timeScanned"` + // Document from which this attestation is generated from + Origin string `json:"origin"` + // GUAC collector for the document + Collector string `json:"collector"` +} + +func (CertifyLegal) IsNode() {} + +// CertifyLegalInputSpec represents the input for certifying legal information in +// mutations. +type CertifyLegalInputSpec struct { + DeclaredLicense string `json:"declaredLicense"` + DiscoveredLicense string `json:"discoveredLicense"` + Attribution string `json:"attribution"` + Justification string `json:"justification"` + TimeScanned time.Time `json:"timeScanned"` + Origin string `json:"origin"` + Collector string `json:"collector"` +} + +// CertifyLegalSpec allows filtering the list of legal certifications to +// return in a query. +// +// Specifying just the package allows to query for all certifications associated +// with the package. +type CertifyLegalSpec struct { + ID *string `json:"id,omitempty"` + Subject *PackageOrSourceSpec `json:"subject,omitempty"` + DeclaredLicense *string `json:"declaredLicense,omitempty"` + DeclaredLicenses []*LicenseSpec `json:"declaredLicenses,omitempty"` + DiscoveredLicense *string `json:"discoveredLicense,omitempty"` + DiscoveredLicenses []*LicenseSpec `json:"discoveredLicenses,omitempty"` + Attribution *string `json:"attribution,omitempty"` + Justification *string `json:"justification,omitempty"` + TimeScanned *time.Time `json:"timeScanned,omitempty"` + Origin *string `json:"origin,omitempty"` + Collector *string `json:"collector,omitempty"` +} + // CertifyScorecard is an attestation to attach a Scorecard analysis to a // particular source repository. type CertifyScorecard struct { @@ -576,6 +647,56 @@ type IsOccurrenceSpec struct { Collector *string `json:"collector,omitempty"` } +// License represents a particular license. If the license is found on the SPDX +// license list (https://spdx.org/licenses/) then the fields should be: +// +// Name: SPDX license identifier +// Inline: empty +// ListVersion: SPDX license list version +// +// example: +// +// Name: AGPL-3.0-or-later +// Inline: "" +// ListVersion: 3.21 2023-06-18 +// +// If the license is not on the SPDX license list, then a new guid should be +// created and the license text placed inline: +// +// Name: LicenseRef- +// Inline: Full license text +// ListVersion: empty +// +// example: +// +// Name: LicenseRef-1a2b3c +// Inline: Permission to use, copy, modify, and/or distribute ... +// ListVersion: "" +type License struct { + ID string `json:"id"` + Name string `json:"name"` + Inline *string `json:"inline,omitempty"` + ListVersion *string `json:"listVersion,omitempty"` +} + +func (License) IsNode() {} + +// LicenseInputSpec specifies an license for mutations. One of inline or +// listVersion should be empty or missing. +type LicenseInputSpec struct { + Name string `json:"name"` + Inline *string `json:"inline,omitempty"` + ListVersion *string `json:"listVersion,omitempty"` +} + +// LicenseSpec allows filtering the list of licenses to return in a query. +type LicenseSpec struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Inline *string `json:"inline,omitempty"` + ListVersion *string `json:"listVersion,omitempty"` +} + // MatchFlags is used to input the PkgMatchType enum. type MatchFlags struct { Pkg PkgMatchType `json:"pkg"` @@ -1459,47 +1580,56 @@ const ( EdgeArtifactCertifyGood Edge = "ARTIFACT_CERTIFY_GOOD" EdgeArtifactCertifyVexStatement Edge = "ARTIFACT_CERTIFY_VEX_STATEMENT" EdgeArtifactHashEqual Edge = "ARTIFACT_HASH_EQUAL" + EdgeArtifactHasMetadata Edge = "ARTIFACT_HAS_METADATA" EdgeArtifactHasSbom Edge = "ARTIFACT_HAS_SBOM" EdgeArtifactHasSlsa Edge = "ARTIFACT_HAS_SLSA" EdgeArtifactIsOccurrence Edge = "ARTIFACT_IS_OCCURRENCE" - EdgeArtifactHasMetadata Edge = "ARTIFACT_HAS_METADATA" EdgeArtifactPointOfContact Edge = "ARTIFACT_POINT_OF_CONTACT" EdgeBuilderHasSlsa Edge = "BUILDER_HAS_SLSA" - EdgeVulnerabilityCertifyVexStatement Edge = "VULNERABILITY_CERTIFY_VEX_STATEMENT" - EdgeVulnerabilityCertifyVuln Edge = "VULNERABILITY_CERTIFY_VULN" - EdgeVulnerabilityVulnEqual Edge = "VULNERABILITY_VULN_EQUAL" - EdgeVulnerabilityVulnMetadata Edge = "VULNERABILITY_VULN_METADATA" + EdgeLicenseCertifyLegal Edge = "LICENSE_CERTIFY_LEGAL" EdgePackageCertifyBad Edge = "PACKAGE_CERTIFY_BAD" EdgePackageCertifyGood Edge = "PACKAGE_CERTIFY_GOOD" + EdgePackageCertifyLegal Edge = "PACKAGE_CERTIFY_LEGAL" EdgePackageCertifyVexStatement Edge = "PACKAGE_CERTIFY_VEX_STATEMENT" EdgePackageCertifyVuln Edge = "PACKAGE_CERTIFY_VULN" + EdgePackageHasMetadata Edge = "PACKAGE_HAS_METADATA" EdgePackageHasSbom Edge = "PACKAGE_HAS_SBOM" EdgePackageHasSourceAt Edge = "PACKAGE_HAS_SOURCE_AT" EdgePackageIsDependency Edge = "PACKAGE_IS_DEPENDENCY" EdgePackageIsOccurrence Edge = "PACKAGE_IS_OCCURRENCE" EdgePackagePkgEqual Edge = "PACKAGE_PKG_EQUAL" - EdgePackageHasMetadata Edge = "PACKAGE_HAS_METADATA" EdgePackagePointOfContact Edge = "PACKAGE_POINT_OF_CONTACT" EdgeSourceCertifyBad Edge = "SOURCE_CERTIFY_BAD" EdgeSourceCertifyGood Edge = "SOURCE_CERTIFY_GOOD" + EdgeSourceCertifyLegal Edge = "SOURCE_CERTIFY_LEGAL" EdgeSourceCertifyScorecard Edge = "SOURCE_CERTIFY_SCORECARD" + EdgeSourceHasMetadata Edge = "SOURCE_HAS_METADATA" EdgeSourceHasSourceAt Edge = "SOURCE_HAS_SOURCE_AT" EdgeSourceIsOccurrence Edge = "SOURCE_IS_OCCURRENCE" - EdgeSourceHasMetadata Edge = "SOURCE_HAS_METADATA" EdgeSourcePointOfContact Edge = "SOURCE_POINT_OF_CONTACT" + EdgeVulnerabilityCertifyVexStatement Edge = "VULNERABILITY_CERTIFY_VEX_STATEMENT" + EdgeVulnerabilityCertifyVuln Edge = "VULNERABILITY_CERTIFY_VULN" + EdgeVulnerabilityVulnEqual Edge = "VULNERABILITY_VULN_EQUAL" + EdgeVulnerabilityVulnMetadata Edge = "VULNERABILITY_VULN_METADATA" EdgeCertifyBadArtifact Edge = "CERTIFY_BAD_ARTIFACT" EdgeCertifyBadPackage Edge = "CERTIFY_BAD_PACKAGE" EdgeCertifyBadSource Edge = "CERTIFY_BAD_SOURCE" EdgeCertifyGoodArtifact Edge = "CERTIFY_GOOD_ARTIFACT" EdgeCertifyGoodPackage Edge = "CERTIFY_GOOD_PACKAGE" EdgeCertifyGoodSource Edge = "CERTIFY_GOOD_SOURCE" + EdgeCertifyLegalLicense Edge = "CERTIFY_LEGAL_LICENSE" + EdgeCertifyLegalPackage Edge = "CERTIFY_LEGAL_PACKAGE" + EdgeCertifyLegalSource Edge = "CERTIFY_LEGAL_SOURCE" EdgeCertifyScorecardSource Edge = "CERTIFY_SCORECARD_SOURCE" EdgeCertifyVexStatementArtifact Edge = "CERTIFY_VEX_STATEMENT_ARTIFACT" - EdgeCertifyVexStatementVulnerability Edge = "CERTIFY_VEX_STATEMENT_VULNERABILITY" EdgeCertifyVexStatementPackage Edge = "CERTIFY_VEX_STATEMENT_PACKAGE" - EdgeCertifyVulnVulnerability Edge = "CERTIFY_VULN_VULNERABILITY" + EdgeCertifyVexStatementVulnerability Edge = "CERTIFY_VEX_STATEMENT_VULNERABILITY" EdgeCertifyVulnPackage Edge = "CERTIFY_VULN_PACKAGE" + EdgeCertifyVulnVulnerability Edge = "CERTIFY_VULN_VULNERABILITY" EdgeHashEqualArtifact Edge = "HASH_EQUAL_ARTIFACT" + EdgeHasMetadataArtifact Edge = "HAS_METADATA_ARTIFACT" + EdgeHasMetadataPackage Edge = "HAS_METADATA_PACKAGE" + EdgeHasMetadataSource Edge = "HAS_METADATA_SOURCE" EdgeHasSbomArtifact Edge = "HAS_SBOM_ARTIFACT" EdgeHasSbomPackage Edge = "HAS_SBOM_PACKAGE" EdgeHasSlsaBuiltBy Edge = "HAS_SLSA_BUILT_BY" @@ -1511,14 +1641,11 @@ const ( EdgeIsOccurrenceArtifact Edge = "IS_OCCURRENCE_ARTIFACT" EdgeIsOccurrencePackage Edge = "IS_OCCURRENCE_PACKAGE" EdgeIsOccurrenceSource Edge = "IS_OCCURRENCE_SOURCE" - EdgeVulnEqualVulnerability Edge = "VULN_EQUAL_VULNERABILITY" EdgePkgEqualPackage Edge = "PKG_EQUAL_PACKAGE" - EdgeHasMetadataPackage Edge = "HAS_METADATA_PACKAGE" - EdgeHasMetadataArtifact Edge = "HAS_METADATA_ARTIFACT" - EdgeHasMetadataSource Edge = "HAS_METADATA_SOURCE" - EdgePointOfContactPackage Edge = "POINT_OF_CONTACT_PACKAGE" EdgePointOfContactArtifact Edge = "POINT_OF_CONTACT_ARTIFACT" + EdgePointOfContactPackage Edge = "POINT_OF_CONTACT_PACKAGE" EdgePointOfContactSource Edge = "POINT_OF_CONTACT_SOURCE" + EdgeVulnEqualVulnerability Edge = "VULN_EQUAL_VULNERABILITY" EdgeVulnMetadataVulnerability Edge = "VULN_METADATA_VULNERABILITY" ) @@ -1527,47 +1654,56 @@ var AllEdge = []Edge{ EdgeArtifactCertifyGood, EdgeArtifactCertifyVexStatement, EdgeArtifactHashEqual, + EdgeArtifactHasMetadata, EdgeArtifactHasSbom, EdgeArtifactHasSlsa, EdgeArtifactIsOccurrence, - EdgeArtifactHasMetadata, EdgeArtifactPointOfContact, EdgeBuilderHasSlsa, - EdgeVulnerabilityCertifyVexStatement, - EdgeVulnerabilityCertifyVuln, - EdgeVulnerabilityVulnEqual, - EdgeVulnerabilityVulnMetadata, + EdgeLicenseCertifyLegal, EdgePackageCertifyBad, EdgePackageCertifyGood, + EdgePackageCertifyLegal, EdgePackageCertifyVexStatement, EdgePackageCertifyVuln, + EdgePackageHasMetadata, EdgePackageHasSbom, EdgePackageHasSourceAt, EdgePackageIsDependency, EdgePackageIsOccurrence, EdgePackagePkgEqual, - EdgePackageHasMetadata, EdgePackagePointOfContact, EdgeSourceCertifyBad, EdgeSourceCertifyGood, + EdgeSourceCertifyLegal, EdgeSourceCertifyScorecard, + EdgeSourceHasMetadata, EdgeSourceHasSourceAt, EdgeSourceIsOccurrence, - EdgeSourceHasMetadata, EdgeSourcePointOfContact, + EdgeVulnerabilityCertifyVexStatement, + EdgeVulnerabilityCertifyVuln, + EdgeVulnerabilityVulnEqual, + EdgeVulnerabilityVulnMetadata, EdgeCertifyBadArtifact, EdgeCertifyBadPackage, EdgeCertifyBadSource, EdgeCertifyGoodArtifact, EdgeCertifyGoodPackage, EdgeCertifyGoodSource, + EdgeCertifyLegalLicense, + EdgeCertifyLegalPackage, + EdgeCertifyLegalSource, EdgeCertifyScorecardSource, EdgeCertifyVexStatementArtifact, - EdgeCertifyVexStatementVulnerability, EdgeCertifyVexStatementPackage, - EdgeCertifyVulnVulnerability, + EdgeCertifyVexStatementVulnerability, EdgeCertifyVulnPackage, + EdgeCertifyVulnVulnerability, EdgeHashEqualArtifact, + EdgeHasMetadataArtifact, + EdgeHasMetadataPackage, + EdgeHasMetadataSource, EdgeHasSbomArtifact, EdgeHasSbomPackage, EdgeHasSlsaBuiltBy, @@ -1579,20 +1715,17 @@ var AllEdge = []Edge{ EdgeIsOccurrenceArtifact, EdgeIsOccurrencePackage, EdgeIsOccurrenceSource, - EdgeVulnEqualVulnerability, EdgePkgEqualPackage, - EdgeHasMetadataPackage, - EdgeHasMetadataArtifact, - EdgeHasMetadataSource, - EdgePointOfContactPackage, EdgePointOfContactArtifact, + EdgePointOfContactPackage, EdgePointOfContactSource, + EdgeVulnEqualVulnerability, EdgeVulnMetadataVulnerability, } func (e Edge) IsValid() bool { switch e { - case EdgeArtifactCertifyBad, EdgeArtifactCertifyGood, EdgeArtifactCertifyVexStatement, EdgeArtifactHashEqual, EdgeArtifactHasSbom, EdgeArtifactHasSlsa, EdgeArtifactIsOccurrence, EdgeArtifactHasMetadata, EdgeArtifactPointOfContact, EdgeBuilderHasSlsa, EdgeVulnerabilityCertifyVexStatement, EdgeVulnerabilityCertifyVuln, EdgeVulnerabilityVulnEqual, EdgeVulnerabilityVulnMetadata, EdgePackageCertifyBad, EdgePackageCertifyGood, EdgePackageCertifyVexStatement, EdgePackageCertifyVuln, EdgePackageHasSbom, EdgePackageHasSourceAt, EdgePackageIsDependency, EdgePackageIsOccurrence, EdgePackagePkgEqual, EdgePackageHasMetadata, EdgePackagePointOfContact, EdgeSourceCertifyBad, EdgeSourceCertifyGood, EdgeSourceCertifyScorecard, EdgeSourceHasSourceAt, EdgeSourceIsOccurrence, EdgeSourceHasMetadata, EdgeSourcePointOfContact, EdgeCertifyBadArtifact, EdgeCertifyBadPackage, EdgeCertifyBadSource, EdgeCertifyGoodArtifact, EdgeCertifyGoodPackage, EdgeCertifyGoodSource, EdgeCertifyScorecardSource, EdgeCertifyVexStatementArtifact, EdgeCertifyVexStatementVulnerability, EdgeCertifyVexStatementPackage, EdgeCertifyVulnVulnerability, EdgeCertifyVulnPackage, EdgeHashEqualArtifact, EdgeHasSbomArtifact, EdgeHasSbomPackage, EdgeHasSlsaBuiltBy, EdgeHasSlsaMaterials, EdgeHasSlsaSubject, EdgeHasSourceAtPackage, EdgeHasSourceAtSource, EdgeIsDependencyPackage, EdgeIsOccurrenceArtifact, EdgeIsOccurrencePackage, EdgeIsOccurrenceSource, EdgeVulnEqualVulnerability, EdgePkgEqualPackage, EdgeHasMetadataPackage, EdgeHasMetadataArtifact, EdgeHasMetadataSource, EdgePointOfContactPackage, EdgePointOfContactArtifact, EdgePointOfContactSource, EdgeVulnMetadataVulnerability: + case EdgeArtifactCertifyBad, EdgeArtifactCertifyGood, EdgeArtifactCertifyVexStatement, EdgeArtifactHashEqual, EdgeArtifactHasMetadata, EdgeArtifactHasSbom, EdgeArtifactHasSlsa, EdgeArtifactIsOccurrence, EdgeArtifactPointOfContact, EdgeBuilderHasSlsa, EdgeLicenseCertifyLegal, EdgePackageCertifyBad, EdgePackageCertifyGood, EdgePackageCertifyLegal, EdgePackageCertifyVexStatement, EdgePackageCertifyVuln, EdgePackageHasMetadata, EdgePackageHasSbom, EdgePackageHasSourceAt, EdgePackageIsDependency, EdgePackageIsOccurrence, EdgePackagePkgEqual, EdgePackagePointOfContact, EdgeSourceCertifyBad, EdgeSourceCertifyGood, EdgeSourceCertifyLegal, EdgeSourceCertifyScorecard, EdgeSourceHasMetadata, EdgeSourceHasSourceAt, EdgeSourceIsOccurrence, EdgeSourcePointOfContact, EdgeVulnerabilityCertifyVexStatement, EdgeVulnerabilityCertifyVuln, EdgeVulnerabilityVulnEqual, EdgeVulnerabilityVulnMetadata, EdgeCertifyBadArtifact, EdgeCertifyBadPackage, EdgeCertifyBadSource, EdgeCertifyGoodArtifact, EdgeCertifyGoodPackage, EdgeCertifyGoodSource, EdgeCertifyLegalLicense, EdgeCertifyLegalPackage, EdgeCertifyLegalSource, EdgeCertifyScorecardSource, EdgeCertifyVexStatementArtifact, EdgeCertifyVexStatementPackage, EdgeCertifyVexStatementVulnerability, EdgeCertifyVulnPackage, EdgeCertifyVulnVulnerability, EdgeHashEqualArtifact, EdgeHasMetadataArtifact, EdgeHasMetadataPackage, EdgeHasMetadataSource, EdgeHasSbomArtifact, EdgeHasSbomPackage, EdgeHasSlsaBuiltBy, EdgeHasSlsaMaterials, EdgeHasSlsaSubject, EdgeHasSourceAtPackage, EdgeHasSourceAtSource, EdgeIsDependencyPackage, EdgeIsOccurrenceArtifact, EdgeIsOccurrencePackage, EdgeIsOccurrenceSource, EdgePkgEqualPackage, EdgePointOfContactArtifact, EdgePointOfContactPackage, EdgePointOfContactSource, EdgeVulnEqualVulnerability, EdgeVulnMetadataVulnerability: return true } return false diff --git a/pkg/assembler/graphql/resolvers/certifyLegal.resolvers.go b/pkg/assembler/graphql/resolvers/certifyLegal.resolvers.go new file mode 100644 index 0000000000..4e117ce048 --- /dev/null +++ b/pkg/assembler/graphql/resolvers/certifyLegal.resolvers.go @@ -0,0 +1,40 @@ +package resolvers + +// This file will be automatically regenerated based on the schema, any resolver implementations +// will be copied through when generating and any unknown code will be moved to the end. +// Code generated by github.com/99designs/gqlgen version v0.17.36 + +import ( + "context" + + "github.com/guacsec/guac/pkg/assembler/graphql/model" +) + +// IngestCertifyLegal is the resolver for the ingestCertifyLegal field. +func (r *mutationResolver) IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, certifyLegal model.CertifyLegalInputSpec) (string, error) { + // TODO validate subjects are pkg or source + cl, err := r.Backend.IngestCertifyLegal(ctx, subject, declaredLicenses, discoveredLicenses, &certifyLegal) + if err != nil { + return "", err + } + return cl.ID, nil +} + +// IngestCertifyLegals is the resolver for the ingestCertifyLegals field. +func (r *mutationResolver) IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.LicenseInputSpec, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) { + // TODO validate subjects are pkg or source + cls, err := r.Backend.IngestCertifyLegals(ctx, subjects, declaredLicensesList, discoveredLicensesList, certifyLegals) + if err != nil { + return nil, err + } + var ids []string + for _, cl := range cls { + ids = append(ids, cl.ID) + } + return ids, nil +} + +// CertifyLegal is the resolver for the CertifyLegal field. +func (r *queryResolver) CertifyLegal(ctx context.Context, certifyLegalSpec model.CertifyLegalSpec) ([]*model.CertifyLegal, error) { + return r.Backend.CertifyLegal(ctx, &certifyLegalSpec) +} diff --git a/pkg/assembler/graphql/resolvers/license.resolvers.go b/pkg/assembler/graphql/resolvers/license.resolvers.go new file mode 100644 index 0000000000..b41e123d6f --- /dev/null +++ b/pkg/assembler/graphql/resolvers/license.resolvers.go @@ -0,0 +1,47 @@ +package resolvers + +// This file will be automatically regenerated based on the schema, any resolver implementations +// will be copied through when generating and any unknown code will be moved to the end. +// Code generated by github.com/99designs/gqlgen version v0.17.36 + +import ( + "context" + + "github.com/guacsec/guac/pkg/assembler/backends/helper" + "github.com/guacsec/guac/pkg/assembler/graphql/model" +) + +// IngestLicense is the resolver for the ingestLicense field. +func (r *mutationResolver) IngestLicense(ctx context.Context, license *model.LicenseInputSpec) (string, error) { + if err := helper.ValidateLicenseInput(license); err != nil { + return "", err + } + il, err := r.Backend.IngestLicense(ctx, license) + if err != nil { + return "", err + } + return il.ID, nil +} + +// IngestLicenses is the resolver for the ingestLicenses field. +func (r *mutationResolver) IngestLicenses(ctx context.Context, licenses []*model.LicenseInputSpec) ([]string, error) { + for _, l := range licenses { + if err := helper.ValidateLicenseInput(l); err != nil { + return nil, err + } + } + ils, err := r.Backend.IngestLicenses(ctx, licenses) + if err != nil { + return nil, err + } + var ids []string + for _, il := range ils { + ids = append(ids, il.ID) + } + return ids, nil +} + +// Licenses is the resolver for the licenses field. +func (r *queryResolver) Licenses(ctx context.Context, licenseSpec model.LicenseSpec) ([]*model.License, error) { + return r.Backend.Licenses(ctx, &licenseSpec) +} diff --git a/pkg/assembler/graphql/schema/certifyLegal.graphql b/pkg/assembler/graphql/schema/certifyLegal.graphql new file mode 100644 index 0000000000..a4c3d6221b --- /dev/null +++ b/pkg/assembler/graphql/schema/certifyLegal.graphql @@ -0,0 +1,105 @@ +# +# Copyright 2023 The GUAC Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# NOTE: This is experimental and might change in the future! + +# Defines a GraphQL schema for the legal certifications + +""" +CertifyLegal is an attestation to attach legal information to a package or source. + +The certification information is either copied from an attestation found in an +SBOM or created by a collector/scanner. + +Discovered license is also known as Concluded. More information: +https://docs.clearlydefined.io/curation-guidelines#the-difference-between-declared-and-discovered-licenses + +Attribution is also known as Copyright Text. It is what could be displayed to +comply with notice +requirements. https://www.nexb.com/oss-attribution-best-practices/ + +License expressions follow this format: +https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/ +""" +type CertifyLegal { + id: ID! + "The package version or source that is attested" + subject: PackageOrSource! + "The license expression as delcared" + declaredLicense: String! + "A list of license objects found in the declared license expression" + declaredLicenses: [License!]! + "The license expression as discovered by scan" + discoveredLicense: String! + "A list of license objects found in the discovered license expression" + discoveredLicenses: [License!]! + "Attribution text of the subject" + attribution: String! + "Extra justification for the certification" + justification: String! + "Time of scan (in RFC 3339 format)" + timeScanned: Time! + "Document from which this attestation is generated from" + origin: String! + "GUAC collector for the document" + collector: String! +} + +""" +CertifyLegalSpec allows filtering the list of legal certifications to +return in a query. + +Specifying just the package allows to query for all certifications associated +with the package. +""" +input CertifyLegalSpec { + id: ID + subject: PackageOrSourceSpec + declaredLicense: String + declaredLicenses: [LicenseSpec!] + discoveredLicense: String + discoveredLicenses: [LicenseSpec!] + attribution: String + justification: String + timeScanned: Time + origin: String + collector: String +} + +""" +CertifyLegalInputSpec represents the input for certifying legal information in +mutations. +""" +input CertifyLegalInputSpec { + declaredLicense: String! + discoveredLicense: String! + attribution: String! + justification: String! + timeScanned: Time! + origin: String! + collector: String! +} + +extend type Query { + "Returns all legal certifications matching the input filter." + CertifyLegal(certifyLegalSpec: CertifyLegalSpec!): [CertifyLegal!]! +} + +extend type Mutation { + "Adds a legal certification to a package or source." + ingestCertifyLegal(subject: PackageOrSourceInput!, declaredLicenses: [LicenseInputSpec!]!, discoveredLicenses: [LicenseInputSpec!]!, certifyLegal: CertifyLegalInputSpec!): ID! + "Bulk add legal certifications to packages or sources, not both at same time." + ingestCertifyLegals(subjects: PackageOrSourceInputs!, declaredLicensesList: [[LicenseInputSpec!]!]!, discoveredLicensesList: [[LicenseInputSpec!]!]!, certifyLegals: [CertifyLegalInputSpec!]!): [ID!]! +} diff --git a/pkg/assembler/graphql/schema/license.graphql b/pkg/assembler/graphql/schema/license.graphql new file mode 100644 index 0000000000..c8f65f5ede --- /dev/null +++ b/pkg/assembler/graphql/schema/license.graphql @@ -0,0 +1,84 @@ +# +# Copyright 2023 The GUAC Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# NOTE: This is experimental and might change in the future! + +# Defines a GraphQL schema for the license + +""" +License represents a particular license. If the license is found on the SPDX +license list (https://spdx.org/licenses/) then the fields should be: + +Name: SPDX license identifier +Inline: empty +ListVersion: SPDX license list version + +example: + +Name: AGPL-3.0-or-later +Inline: "" +ListVersion: 3.21 2023-06-18 + +If the license is not on the SPDX license list, then a new guid should be +created and the license text placed inline: + +Name: LicenseRef- +Inline: Full license text +ListVersion: empty + +example: + +Name: LicenseRef-1a2b3c +Inline: Permission to use, copy, modify, and/or distribute ... +ListVersion: "" +""" +type License { + id: ID! + name: String! + inline: String + listVersion: String +} + +""" +LicenseSpec allows filtering the list of licenses to return in a query. +""" +input LicenseSpec { + id: ID + name: String + inline: String + listVersion: String +} + +""" +LicenseInputSpec specifies an license for mutations. One of inline or +listVersion should be empty or missing. +""" +input LicenseInputSpec { + name: String! + inline: String + listVersion: String +} + +extend type Query { + "Returns all licenses matching a filter." + licenses(licenseSpec: LicenseSpec!): [License!]! +} + +extend type Mutation { + "Ingests a new license and returns it." + ingestLicense(license: LicenseInputSpec): ID! + "Bulk ingests new licenses and returns a list of them." + ingestLicenses(licenses: [LicenseInputSpec!]!): [ID!]! +} diff --git a/pkg/assembler/graphql/schema/path.graphql b/pkg/assembler/graphql/schema/path.graphql index 69dba2179b..e779d2d781 100644 --- a/pkg/assembler/graphql/schema/path.graphql +++ b/pkg/assembler/graphql/schema/path.graphql @@ -46,6 +46,8 @@ union Node = | HasMetadata | PointOfContact | VulnerabilityMetadata + | License + | CertifyLegal """ Edge allows filtering path/neighbors output to only contain a subset of all @@ -64,34 +66,37 @@ enum Edge { ARTIFACT_CERTIFY_GOOD ARTIFACT_CERTIFY_VEX_STATEMENT ARTIFACT_HASH_EQUAL + ARTIFACT_HAS_METADATA ARTIFACT_HAS_SBOM ARTIFACT_HAS_SLSA ARTIFACT_IS_OCCURRENCE - ARTIFACT_HAS_METADATA ARTIFACT_POINT_OF_CONTACT BUILDER_HAS_SLSA - VULNERABILITY_CERTIFY_VEX_STATEMENT - VULNERABILITY_CERTIFY_VULN - VULNERABILITY_VULN_EQUAL - VULNERABILITY_VULN_METADATA + LICENSE_CERTIFY_LEGAL PACKAGE_CERTIFY_BAD PACKAGE_CERTIFY_GOOD + PACKAGE_CERTIFY_LEGAL PACKAGE_CERTIFY_VEX_STATEMENT PACKAGE_CERTIFY_VULN + PACKAGE_HAS_METADATA PACKAGE_HAS_SBOM PACKAGE_HAS_SOURCE_AT PACKAGE_IS_DEPENDENCY PACKAGE_IS_OCCURRENCE PACKAGE_PKG_EQUAL - PACKAGE_HAS_METADATA PACKAGE_POINT_OF_CONTACT SOURCE_CERTIFY_BAD SOURCE_CERTIFY_GOOD + SOURCE_CERTIFY_LEGAL SOURCE_CERTIFY_SCORECARD + SOURCE_HAS_METADATA SOURCE_HAS_SOURCE_AT SOURCE_IS_OCCURRENCE - SOURCE_HAS_METADATA SOURCE_POINT_OF_CONTACT + VULNERABILITY_CERTIFY_VEX_STATEMENT + VULNERABILITY_CERTIFY_VULN + VULNERABILITY_VULN_EQUAL + VULNERABILITY_VULN_METADATA CERTIFY_BAD_ARTIFACT CERTIFY_BAD_PACKAGE @@ -99,13 +104,19 @@ enum Edge { CERTIFY_GOOD_ARTIFACT CERTIFY_GOOD_PACKAGE CERTIFY_GOOD_SOURCE + CERTIFY_LEGAL_LICENSE + CERTIFY_LEGAL_PACKAGE + CERTIFY_LEGAL_SOURCE CERTIFY_SCORECARD_SOURCE CERTIFY_VEX_STATEMENT_ARTIFACT - CERTIFY_VEX_STATEMENT_VULNERABILITY CERTIFY_VEX_STATEMENT_PACKAGE - CERTIFY_VULN_VULNERABILITY + CERTIFY_VEX_STATEMENT_VULNERABILITY CERTIFY_VULN_PACKAGE + CERTIFY_VULN_VULNERABILITY HASH_EQUAL_ARTIFACT + HAS_METADATA_ARTIFACT + HAS_METADATA_PACKAGE + HAS_METADATA_SOURCE HAS_SBOM_ARTIFACT HAS_SBOM_PACKAGE HAS_SLSA_BUILT_BY @@ -117,14 +128,11 @@ enum Edge { IS_OCCURRENCE_ARTIFACT IS_OCCURRENCE_PACKAGE IS_OCCURRENCE_SOURCE - VULN_EQUAL_VULNERABILITY PKG_EQUAL_PACKAGE - HAS_METADATA_PACKAGE - HAS_METADATA_ARTIFACT - HAS_METADATA_SOURCE - POINT_OF_CONTACT_PACKAGE POINT_OF_CONTACT_ARTIFACT + POINT_OF_CONTACT_PACKAGE POINT_OF_CONTACT_SOURCE + VULN_EQUAL_VULNERABILITY VULN_METADATA_VULNERABILITY }