From b2208380fb2684d3f724618da0d21518da2dd953 Mon Sep 17 00:00:00 2001 From: nscuro Date: Sun, 27 Oct 2024 18:49:45 +0100 Subject: [PATCH] feat: support `projectTags` and `isLatest` flags for bom uploads Signed-off-by: nscuro --- about_test.go | 25 +++++++++-------- bom_test.go | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++ permission.go | 17 +++++++++++ project.go | 1 + 4 files changed, 109 insertions(+), 12 deletions(-) create mode 100644 bom_test.go diff --git a/about_test.go b/about_test.go index 0fa695f..27d4252 100644 --- a/about_test.go +++ b/about_test.go @@ -12,7 +12,7 @@ import ( ) func TestAboutService_Get(t *testing.T) { - _, client := setUpContainer(t) + client := setUpContainer(t, testContainerOptions{}) about, err := client.About.Get(context.TODO()) require.NoError(t, err) @@ -30,7 +30,11 @@ func TestAboutService_Get(t *testing.T) { require.Equal(t, "Alpine", about.Framework.Name) } -func setUpContainer(t *testing.T) (testcontainers.Container, *Client) { +type testContainerOptions struct { + APIPermissions []string +} + +func setUpContainer(t *testing.T, options testContainerOptions) *Client { ctx := context.Background() container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ @@ -69,22 +73,19 @@ func setUpContainer(t *testing.T) (testcontainers.Container, *Client) { client, err = NewClient(apiURL, WithBearerToken(bearerToken)) require.NoError(t, err) - // TODO: Pass desired permissions as parameter to setUpContainer - team, err := client.Team.Create(ctx, Team{ - Name: "test", - Permissions: []Permission{ - { - Name: "VIEW_PORTFOLIO", - }, - }, - }) + team, err := client.Team.Create(ctx, Team{Name: "test"}) require.NoError(t, err) + for _, permissionName := range options.APIPermissions { + _, err = client.Permission.AddPermissionToTeam(ctx, Permission{Name: permissionName}, team.UUID) + require.NoError(t, err) + } + apiKey, err := client.Team.GenerateAPIKey(ctx, team.UUID) require.NoError(t, err) client, err = NewClient(apiURL, WithAPIKey(apiKey)) require.NoError(t, err) - return container, client + return client } diff --git a/bom_test.go b/bom_test.go new file mode 100644 index 0000000..bf6e83d --- /dev/null +++ b/bom_test.go @@ -0,0 +1,78 @@ +package dtrack + +import ( + "context" + "encoding/base64" + "github.com/stretchr/testify/require" + "testing" +) + +func TestBOMService_Upload(t *testing.T) { + client := setUpContainer(t, testContainerOptions{ + APIPermissions: []string{ + PermissionBOMUpload, + PermissionProjectCreationUpload, + PermissionViewPortfolio, + }, + }) + + _, err := client.BOM.Upload(context.Background(), BOMUploadRequest{ + ProjectName: "acme-app", + ProjectVersion: "1.2.3", + ProjectTags: []Tag{ + {Name: "foo"}, + {Name: "bar"}, + }, + IsLatest: true, + AutoCreate: true, + BOM: base64.StdEncoding.EncodeToString([]byte(` +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "components": [] +}`)), + }) + require.NoError(t, err) + + project, err := client.Project.Lookup(context.Background(), "acme-app", "1.2.3") + require.NoError(t, err) + require.Contains(t, project.Tags, Tag{Name: "foo"}) + require.Contains(t, project.Tags, Tag{Name: "bar"}) + require.True(t, project.IsLatest) +} + +func TestBOMService_PostBom(t *testing.T) { + client := setUpContainer(t, testContainerOptions{ + APIPermissions: []string{ + PermissionBOMUpload, + PermissionProjectCreationUpload, + PermissionViewPortfolio, + }, + }) + + _, err := client.BOM.PostBom(context.Background(), BOMUploadRequest{ + ProjectName: "acme-app", + ProjectVersion: "1.2.3", + ProjectTags: []Tag{ + {Name: "foo"}, + {Name: "bar"}, + }, + IsLatest: true, + AutoCreate: true, + BOM: ` +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "components": [] +}`, + }) + require.NoError(t, err) + + project, err := client.Project.Lookup(context.Background(), "acme-app", "1.2.3") + require.NoError(t, err) + require.Contains(t, project.Tags, Tag{Name: "foo"}) + require.Contains(t, project.Tags, Tag{Name: "bar"}) + require.True(t, project.IsLatest) +} diff --git a/permission.go b/permission.go index 53b76e7..d25ce79 100644 --- a/permission.go +++ b/permission.go @@ -8,6 +8,23 @@ import ( "github.com/google/uuid" ) +const ( + PermissionAccessManagement = "ACCESS_MANAGEMENT" + PermissionBOMUpload = "BOM_UPLOAD" + PermissionPolicyManagement = "POLICY_MANAGEMENT" + PermissionPolicyViolationAnalysis = "POLICY_VIOLATION_ANALYSIS" + PermissionPortfolioManagement = "PORTFOLIO_MANAGEMENT" + PermissionProjectCreationUpload = "PROJECT_CREATION_UPLOAD" + PermissionSystemConfiguration = "SYSTEM_CONFIGURATION" + PermissionTagManagement = "TAG_MANAGEMENT" + PermissionViewBadges = "VIEW_BADGES" + PermissionViewPolicyViolation = "VIEW_POLICY_VIOLATION" + PermissionViewPortfolio = "VIEW_PORTFOLIO" + PermissionViewVulnerability = "VIEW_VULNERABILITY" + PermissionVulnerabilityAnalysis = "VULNERABILITY_ANALYSIS" + PermissionVulnerabilityManagement = "VULNERABILITY_MANAGEMENT" +) + type PermissionService struct { client *Client } diff --git a/project.go b/project.go index 44c5fee..8781f61 100644 --- a/project.go +++ b/project.go @@ -25,6 +25,7 @@ type Project struct { Properties []ProjectProperty `json:"properties,omitempty"` Tags []Tag `json:"tags,omitempty"` Active bool `json:"active"` + IsLatest bool `json:"isLatest"` // Since v4.12.0 Metrics ProjectMetrics `json:"metrics"` ParentRef *ParentRef `json:"parent,omitempty"` LastBOMImport int `json:"lastBomImport"`