Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support projectTags and isLatest flags for bom uploads #30

Merged
merged 2 commits into from
Oct 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading