From 379466b91a95046647b99cf43ab3f1b89fe55db7 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Thu, 23 Mar 2023 22:39:39 +0100 Subject: [PATCH] chore: download SBOMs using CAS Signed-off-by: Miguel Martinez Trivino --- app/controlplane/cmd/wire_gen.go | 2 +- .../dependencytrack/dependencytrack.go | 19 +++++++++---------- .../dependencytrack/dependencytrack_test.go | 2 +- .../dependencytrack/testdata/test-key.ec.pem | 7 +++++++ .../internal/biz/testdata/test-key.ec.pem | 7 +++++++ .../internal/biz/testhelpers/database.go | 9 ++++++++- .../internal/biz/testhelpers/suite.go | 4 +++- .../internal/biz/testhelpers/wire.go | 2 ++ .../internal/biz/testhelpers/wire_gen.go | 9 ++++++++- 9 files changed, 46 insertions(+), 15 deletions(-) create mode 100644 app/controlplane/internal/biz/integration/dependencytrack/testdata/test-key.ec.pem create mode 100644 app/controlplane/internal/biz/testdata/test-key.ec.pem diff --git a/app/controlplane/cmd/wire_gen.go b/app/controlplane/cmd/wire_gen.go index 6c61918db..86bc6962f 100644 --- a/app/controlplane/cmd/wire_gen.go +++ b/app/controlplane/cmd/wire_gen.go @@ -90,7 +90,7 @@ func wireApp(bootstrap *conf.Bootstrap, readerWriter credentials.ReaderWriter, l Opts: v, } workflowRunService := service.NewWorkflowRunService(newWorkflowRunServiceOpts) - integration := dependencytrack.New(integrationUseCase, ociRepositoryUseCase, readerWriter, logger) + integration := dependencytrack.New(integrationUseCase, ociRepositoryUseCase, readerWriter, casClientUseCase, logger) newAttestationServiceOpts := &service.NewAttestationServiceOpts{ WorkflowRunUC: workflowRunUseCase, WorkflowUC: workflowUseCase, diff --git a/app/controlplane/internal/biz/integration/dependencytrack/dependencytrack.go b/app/controlplane/internal/biz/integration/dependencytrack/dependencytrack.go index e6662a8a3..c3c5f3ebb 100644 --- a/app/controlplane/internal/biz/integration/dependencytrack/dependencytrack.go +++ b/app/controlplane/internal/biz/integration/dependencytrack/dependencytrack.go @@ -29,7 +29,6 @@ import ( "github.com/chainloop-dev/chainloop/app/controlplane/internal/biz" "github.com/chainloop-dev/chainloop/app/controlplane/internal/integrations/dependencytrack" "github.com/chainloop-dev/chainloop/internal/attestation/renderer" - "github.com/chainloop-dev/chainloop/internal/blobmanager/oci" "github.com/chainloop-dev/chainloop/internal/credentials" "github.com/chainloop-dev/chainloop/internal/servicelogger" "github.com/go-kratos/kratos/v2/log" @@ -41,13 +40,14 @@ type Integration struct { integrationUC *biz.IntegrationUseCase ociUC *biz.OCIRepositoryUseCase credentialsProvider credentials.ReaderWriter + casClient biz.CASClient log *log.Helper } const Kind = "Dependency-Track" -func New(integrationUC *biz.IntegrationUseCase, ociUC *biz.OCIRepositoryUseCase, creds credentials.ReaderWriter, l log.Logger) *Integration { - return &Integration{integrationUC, ociUC, creds, servicelogger.ScopedHelper(l, "biz/integration/deptrack")} +func New(integrationUC *biz.IntegrationUseCase, ociUC *biz.OCIRepositoryUseCase, creds credentials.ReaderWriter, c biz.CASClient, l log.Logger) *Integration { + return &Integration{integrationUC, ociUC, creds, c, servicelogger.ScopedHelper(l, "biz/integration/deptrack")} } func (uc *Integration) Add(ctx context.Context, orgID, host, apiKey string, enableProjectCreation bool) (*biz.Integration, error) { @@ -105,6 +105,7 @@ func (uc *Integration) UploadSBOMs(envelope *dsse.Envelope, orgID, workflowID st return nil } + // There is at least one enabled integration, extract the SBOMs predicate, err := renderer.ExtractPredicate(envelope) if err != nil { return err @@ -117,11 +118,6 @@ func (uc *Integration) UploadSBOMs(envelope *dsse.Envelope, orgID, workflowID st return errors.NotFound("not found", "main repository not found") } - backend, err := oci.NewBackendProvider(uc.credentialsProvider).FromCredentials(ctx, repo.SecretName) - if err != nil { - return err - } - for _, m := range predicate.Materials { if m.Type != contractAPI.CraftingSchema_Material_SBOM_CYCLONEDX_JSON.String() { continue @@ -133,11 +129,14 @@ func (uc *Integration) UploadSBOMs(envelope *dsse.Envelope, orgID, workflowID st continue } + digest = "sha256:" + digest + uc.log.Infow("msg", "SBOM present, downloading", "workflowID", workflowID, "integration", Kind, "name", m.Name) // Download SBOM - if err := backend.Download(ctx, buf, digest); err != nil { - return err + if err := uc.casClient.Download(ctx, repo.SecretName, buf, digest); err != nil { + return fmt.Errorf("downloading from CAS: %w", err) } + uc.log.Infow("msg", "SBOM downloaded", "digest", digest, "workflowID", workflowID, "integration", Kind, "name", m.Name) // Run integrations with that sbom diff --git a/app/controlplane/internal/biz/integration/dependencytrack/dependencytrack_test.go b/app/controlplane/internal/biz/integration/dependencytrack/dependencytrack_test.go index 6b413b678..4aa7226ae 100644 --- a/app/controlplane/internal/biz/integration/dependencytrack/dependencytrack_test.go +++ b/app/controlplane/internal/biz/integration/dependencytrack/dependencytrack_test.go @@ -34,7 +34,7 @@ func (s *testSuite) TestAdd() { org, err := s.Organization.Create(ctx, "testing org") assert.NoError(err) - i := dependencytrack.New(s.Integration, s.OCIRepo, credsReader, nil) + i := dependencytrack.New(s.Integration, s.OCIRepo, credsReader, nil, nil) credsReader.On("SaveCredentials", ctx, org.ID, mock.Anything).Return("secret-key", nil) diff --git a/app/controlplane/internal/biz/integration/dependencytrack/testdata/test-key.ec.pem b/app/controlplane/internal/biz/integration/dependencytrack/testdata/test-key.ec.pem new file mode 100644 index 000000000..87607aaaf --- /dev/null +++ b/app/controlplane/internal/biz/integration/dependencytrack/testdata/test-key.ec.pem @@ -0,0 +1,7 @@ +-----BEGIN EC PRIVATE KEY----- +MIHcAgEBBEIAH5EPbqm6m8XzqQOao85bpZR+X+mjJNEdeC46PuW9hvJVzXxQl7hK +O4QNGanrmKIItYklBrX7YOLqzaFYXNL/zQKgBwYFK4EEACOhgYkDgYYABAB4jcRn +lZuECX6QvUAOCGiMVCbxYv+mOXgn2X0EDx+MEhHcSN2jjf0IinRpVMtufrFjG+A0 +dhF2wK0O9HxPvcVP9gAnjlu5gak7H4SjM9JkCTdWIMpcXrW3lzRAVbb0niYv0Wbc +sAQhsfOVcKEo88Zaqlisw0edRb+BtZsFMWIniyzb0Q== +-----END EC PRIVATE KEY----- diff --git a/app/controlplane/internal/biz/testdata/test-key.ec.pem b/app/controlplane/internal/biz/testdata/test-key.ec.pem new file mode 100644 index 000000000..87607aaaf --- /dev/null +++ b/app/controlplane/internal/biz/testdata/test-key.ec.pem @@ -0,0 +1,7 @@ +-----BEGIN EC PRIVATE KEY----- +MIHcAgEBBEIAH5EPbqm6m8XzqQOao85bpZR+X+mjJNEdeC46PuW9hvJVzXxQl7hK +O4QNGanrmKIItYklBrX7YOLqzaFYXNL/zQKgBwYFK4EEACOhgYkDgYYABAB4jcRn +lZuECX6QvUAOCGiMVCbxYv+mOXgn2X0EDx+MEhHcSN2jjf0IinRpVMtufrFjG+A0 +dhF2wK0O9HxPvcVP9gAnjlu5gak7H4SjM9JkCTdWIMpcXrW3lzRAVbb0niYv0Wbc +sAQhsfOVcKEo88Zaqlisw0edRb+BtZsFMWIniyzb0Q== +-----END EC PRIVATE KEY----- diff --git a/app/controlplane/internal/biz/testhelpers/database.go b/app/controlplane/internal/biz/testhelpers/database.go index 85bcac7f8..3939e70a8 100644 --- a/app/controlplane/internal/biz/testhelpers/database.go +++ b/app/controlplane/internal/biz/testhelpers/database.go @@ -84,7 +84,10 @@ func NewTestingUseCases(t *testing.T, opts ...NewTestingUCOpt) *TestingUseCases db := NewTestDatabase(t) log := log.NewStdLogger(io.Discard) - testData, _, err := WireTestData(db, t, log, newArgs.credsReaderWriter, &robotaccount.Builder{}, &conf.Auth{GeneratedJwsHmacSecret: "test"}) + testData, _, err := WireTestData(db, t, log, newArgs.credsReaderWriter, &robotaccount.Builder{}, &conf.Auth{ + GeneratedJwsHmacSecret: "test", + CasRobotAccountPrivateKeyPath: "./testdata/test-key.ec.pem", + }) assert.NoError(t, err) return testData } @@ -140,6 +143,10 @@ func newConfData(db *TestDatabase, t *testing.T) *conf.Data { return &conf.Data{Database: &conf.Data_Database{Driver: "pgx", Source: db.ConnectionString(t)}} } +func newConfCAS() *conf.Bootstrap_CASServer { + return &conf.Bootstrap_CASServer{Grpc: &conf.Server_GRPC{}} +} + func (db *TestDatabase) Close(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() diff --git a/app/controlplane/internal/biz/testhelpers/suite.go b/app/controlplane/internal/biz/testhelpers/suite.go index 35ee46934..3dae42199 100644 --- a/app/controlplane/internal/biz/testhelpers/suite.go +++ b/app/controlplane/internal/biz/testhelpers/suite.go @@ -15,7 +15,9 @@ package testhelpers -import "github.com/stretchr/testify/suite" +import ( + "github.com/stretchr/testify/suite" +) // Suite that creates a database and sets the schema before each test type UseCasesEachTestSuite struct { diff --git a/app/controlplane/internal/biz/testhelpers/wire.go b/app/controlplane/internal/biz/testhelpers/wire.go index e83b63588..ef3451de8 100644 --- a/app/controlplane/internal/biz/testhelpers/wire.go +++ b/app/controlplane/internal/biz/testhelpers/wire.go @@ -43,9 +43,11 @@ func WireTestData(*TestDatabase, *testing.T, log.Logger, credentials.ReaderWrite integration.ProviderSet, wire.Bind(new(backend.Provider), new(*oci.BackendProvider)), wire.Bind(new(credentials.Reader), new(credentials.ReaderWriter)), + wire.Bind(new(biz.CASClient), new(*biz.CASClientUseCase)), oci.NewBackendProvider, wire.Struct(new(TestingUseCases), "*"), newConfData, + newConfCAS, ), ) } diff --git a/app/controlplane/internal/biz/testhelpers/wire_gen.go b/app/controlplane/internal/biz/testhelpers/wire_gen.go index 3b82b2173..0d13cae48 100644 --- a/app/controlplane/internal/biz/testhelpers/wire_gen.go +++ b/app/controlplane/internal/biz/testhelpers/wire_gen.go @@ -68,7 +68,14 @@ func WireTestData(testDatabase *TestDatabase, t *testing.T, logger log.Logger, r userUseCase := biz.NewUserUseCase(newUserUseCaseParams) robotAccountRepo := data.NewRobotAccountRepo(dataData, logger) robotAccountUseCase := biz.NewRootAccountUseCase(robotAccountRepo, workflowRepo, auth, logger) - integration := dependencytrack.New(integrationUseCase, ociRepositoryUseCase, readerWriter, logger) + casCredentialsUseCase, err := biz.NewCASCredentialsUseCase(auth) + if err != nil { + cleanup() + return nil, nil, err + } + bootstrap_CASServer := newConfCAS() + casClientUseCase := biz.NewCASClientUseCase(casCredentialsUseCase, bootstrap_CASServer, logger) + integration := dependencytrack.New(integrationUseCase, ociRepositoryUseCase, readerWriter, casClientUseCase, logger) testingUseCases := &TestingUseCases{ DB: testDatabase, L: logger,