Skip to content

Commit

Permalink
feat: support projectTags and isLatest flags for bom uploads (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
nscuro authored Oct 27, 2024
1 parent 096b70c commit 782de96
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 15 deletions.
25 changes: 13 additions & 12 deletions about_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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{
Expand Down Expand Up @@ -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
}
19 changes: 16 additions & 3 deletions bom.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/google/uuid"
"net/http"
"net/url"
"strings"
)

type BOMService struct {
Expand All @@ -16,9 +17,11 @@ type BOMUploadRequest struct {
ProjectUUID *uuid.UUID `json:"project,omitempty"`
ProjectName string `json:"projectName,omitempty"`
ProjectVersion string `json:"projectVersion,omitempty"`
ParentUUID *uuid.UUID `json:"parentUUID,omitempty"` // Since v4.8.0
ParentName string `json:"parentName,omitempty"` // Since v4.8.0
ParentVersion string `json:"parentVersion,omitempty"` // Since v4.8.0
ProjectTags []Tag `json:"projectTags,omitempty"` // Since v4.12.0
ParentUUID *uuid.UUID `json:"parentUUID,omitempty"` // Since v4.8.0
ParentName string `json:"parentName,omitempty"` // Since v4.8.0
ParentVersion string `json:"parentVersion,omitempty"` // Since v4.8.0
IsLatest bool `json:"isLatestProjectVersion,omitempty"` // Since v4.12.0
AutoCreate bool `json:"autoCreate"`
BOM string `json:"bom"`
}
Expand Down Expand Up @@ -111,6 +114,16 @@ func (bs BOMService) PostBom(ctx context.Context, uploadReq BOMUploadRequest) (t
if uploadReq.ProjectVersion != "" {
params["projectVersion"] = append(params["projectVersion"], uploadReq.ProjectVersion)
}
if len(uploadReq.ProjectTags) > 0 {
tagNames := make([]string, len(uploadReq.ProjectTags))
for i := range uploadReq.ProjectTags {
tagNames[i] = uploadReq.ProjectTags[i].Name
}
params["projectTags"] = append(params["projectTags"], strings.Join(tagNames, ","))
}
if uploadReq.IsLatest {
params["isLatest"] = append(params["isLatest"], "true")
}
if uploadReq.ParentUUID != nil {
params["parentUUID"] = append(params["parentUUID"], uploadReq.ParentUUID.String())
}
Expand Down
78 changes: 78 additions & 0 deletions bom_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
17 changes: 17 additions & 0 deletions permission.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
1 change: 1 addition & 0 deletions project.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down

0 comments on commit 782de96

Please sign in to comment.