Skip to content
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
16 changes: 8 additions & 8 deletions accesscontrol/casbin_rbac_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ import (
// in-memory by casbin's model layer; this adapter only satisfies the interface.
type noopAdapter struct{}

func (noopAdapter) LoadPolicy(_ casbinModel.Model) error { return nil }
func (noopAdapter) SavePolicy(_ casbinModel.Model) error { return nil }
func (noopAdapter) AddPolicy(_, _ string, _ []string) error { return nil }
func (noopAdapter) RemovePolicy(_, _ string, _ []string) error { return nil }
func (noopAdapter) RemoveFilteredPolicy(_, _ string, _ int, _ ...string) error { return nil }
func (noopAdapter) LoadPolicyCtx(_ context.Context, _ casbinModel.Model) error { return nil }
func (noopAdapter) SavePolicyCtx(_ context.Context, _ casbinModel.Model) error { return nil }
func (noopAdapter) AddPolicyCtx(_ context.Context, _, _ string, _ []string) error { return nil }
func (noopAdapter) LoadPolicy(_ casbinModel.Model) error { return nil }
func (noopAdapter) SavePolicy(_ casbinModel.Model) error { return nil }
func (noopAdapter) AddPolicy(_, _ string, _ []string) error { return nil }
func (noopAdapter) RemovePolicy(_, _ string, _ []string) error { return nil }
func (noopAdapter) RemoveFilteredPolicy(_, _ string, _ int, _ ...string) error { return nil }
func (noopAdapter) LoadPolicyCtx(_ context.Context, _ casbinModel.Model) error { return nil }
func (noopAdapter) SavePolicyCtx(_ context.Context, _ casbinModel.Model) error { return nil }
func (noopAdapter) AddPolicyCtx(_ context.Context, _, _ string, _ []string) error { return nil }
func (noopAdapter) RemovePolicyCtx(_ context.Context, _, _ string, _ []string) error { return nil }
func (noopAdapter) RemoveFilteredPolicyCtx(_ context.Context, _, _ string, _ int, _ ...string) error {
return nil
Expand Down
69 changes: 0 additions & 69 deletions accesscontrol/members.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,72 +14,3 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

package accesscontrol

import (
"maps"

"github.com/l3montree-dev/devguard/dtos"
"github.com/l3montree-dev/devguard/shared"
"github.com/l3montree-dev/devguard/utils"
"github.com/ory/client-go"
)

// FetchMembersOfOrganization retrieves all members of an organization including their roles
// from both the RBAC system and third-party integrations
func FetchMembersOfOrganization(ctx shared.Context) ([]dtos.UserDTO, error) {
// get all members from the organization
organization := shared.GetOrg(ctx)
accessControl := shared.GetRBAC(ctx)

members, err := accessControl.GetAllMembersOfOrganization()

if err != nil {
return nil, err
}

users := make([]dtos.UserDTO, 0, len(members))
if len(members) > 0 {
// get the auth admin client from the context
authAdminClient := shared.GetAuthAdminClient(ctx)
// fetch the users from the auth service
m, err := authAdminClient.ListUser(client.IdentityAPIListIdentitiesRequest{}.Ids(members))
if err != nil {
return nil, err
}

// get the roles for the members
errGroup := utils.ErrGroup[map[string]shared.Role](10)
for _, member := range m {
errGroup.Go(func() (map[string]shared.Role, error) {
role, err := accessControl.GetDomainRole(member.Id)
if err != nil {
return map[string]shared.Role{member.Id: shared.RoleUnknown}, nil
}
return map[string]shared.Role{member.Id: role}, nil
})
}

roles, err := errGroup.WaitAndCollect()
if err != nil {
return nil, err
}

roleMap := utils.Reduce(roles, func(acc map[string]shared.Role, r map[string]shared.Role) map[string]shared.Role {
maps.Copy(acc, r)
return acc
}, make(map[string]shared.Role))

for _, member := range m {
users = append(users, dtos.UserDTO{
ID: member.Id,
Name: shared.IdentityName(member.Traits),
Role: string(roleMap[member.Id]),
})
}
}

// fetch all members from third party integrations
thirdPartyIntegrations := shared.GetThirdPartyIntegration(ctx)
users = append(users, thirdPartyIntegrations.GetUsers(organization)...)
return users, nil
}
5 changes: 0 additions & 5 deletions cmd/devguard-scanner/commands/clean.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package commands

import (
"context"
"log/slog"

"github.com/google/go-containerregistry/pkg/authn"
Expand All @@ -12,10 +11,6 @@ import (
"github.com/spf13/cobra"
)

func cleanImage(ctx context.Context, regOpts cosignoptions.RegistryOptions, cleanType cosignoptions.CleanType, imageRef string) error {
return cosignclean.CleanCmd(ctx, regOpts, cleanType, imageRef, true)
}

// NewCleanCommand returns a command that removes attestations/signatures from an OCI image.
func NewCleanCommand() *cobra.Command {
cmd := &cobra.Command{
Expand Down
9 changes: 5 additions & 4 deletions cmd/devguard-scanner/commands/clean_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/google/go-containerregistry/pkg/registry"
"github.com/google/go-containerregistry/pkg/v1/random"
"github.com/google/go-containerregistry/pkg/v1/remote"
cosignclean "github.com/sigstore/cosign/v2/cmd/cosign/cli"
cosignoptions "github.com/sigstore/cosign/v2/cmd/cosign/cli/options"
ociremote "github.com/sigstore/cosign/v2/pkg/oci/remote"
)
Expand Down Expand Up @@ -100,7 +101,7 @@ func TestCleanImageCleanTypeAllRemovesAllTags(t *testing.T) {
t.Fatal("signature tag should exist before clean")
}

if err := cleanImage(context.Background(), regOpts, cosignoptions.CleanTypeAll, imageRef); err != nil {
if err := cosignclean.CleanCmd(context.Background(), regOpts, cosignoptions.CleanTypeAll, imageRef, true); err != nil {
t.Fatalf("cleanImage: %v", err)
}

Expand Down Expand Up @@ -130,7 +131,7 @@ func TestCleanImageCleanTypeAttestationLeavesSignatureTag(t *testing.T) {
pushDummyImage(t, attTag, remoteOpts)
pushDummyImage(t, sigTag, remoteOpts)

if err := cleanImage(context.Background(), regOpts, cosignoptions.CleanTypeAttestation, imageRef); err != nil {
if err := cosignclean.CleanCmd(context.Background(), regOpts, cosignoptions.CleanTypeAttestation, imageRef, true); err != nil {
t.Fatalf("cleanImage: %v", err)
}

Expand Down Expand Up @@ -160,7 +161,7 @@ func TestCleanImageCleanTypeSignatureLeavesAttestationTag(t *testing.T) {
pushDummyImage(t, attTag, remoteOpts)
pushDummyImage(t, sigTag, remoteOpts)

if err := cleanImage(context.Background(), regOpts, cosignoptions.CleanTypeSignature, imageRef); err != nil {
if err := cosignclean.CleanCmd(context.Background(), regOpts, cosignoptions.CleanTypeSignature, imageRef, true); err != nil {
t.Fatalf("cleanImage: %v", err)
}

Expand All @@ -179,7 +180,7 @@ func TestCleanImageNoTagsDoesNotError(t *testing.T) {
pushBaseImage(t, imageRef, remoteOpts)

// no attestation/signature tags present — clean should still succeed
if err := cleanImage(context.Background(), regOpts, cosignoptions.CleanTypeAll, imageRef); err != nil {
if err := cosignclean.CleanCmd(context.Background(), regOpts, cosignoptions.CleanTypeAll, imageRef, true); err != nil {
t.Fatalf("cleanImage on image with no sig/att tags failed: %v", err)
}
}
27 changes: 0 additions & 27 deletions cmd/devguard-scanner/commands/intoto/intoto_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,41 +20,14 @@ import (
"fmt"
"log/slog"
"os"
"strings"

toto "github.com/in-toto/in-toto-golang/in_toto"
"github.com/l3montree-dev/devguard/cmd/devguard-scanner/config"
"github.com/l3montree-dev/devguard/cmd/devguard-scanner/scanner"
"github.com/l3montree-dev/devguard/utils"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)

func parseGitIgnore(path string) ([]string, error) {
// read .gitignore if exists
content, err := os.ReadFile(path)
if err == nil {
ignorePaths := strings.Split(string(content), "\n")

// make sure to remove new lines and empty strings
ignorePaths = utils.Filter(
utils.Map(utils.Map(ignorePaths, strings.TrimSpace), func(e string) string {
// nextjs products a gitignore which contains /node_modules but we need to ignore /node_modules/
if e == "/node_modules" {
return e + "/"
}
return e
}),
func(e string) bool {
return e != "" && e != "\n" && !strings.HasPrefix(strings.TrimSpace(e), "#")
})

return ignorePaths, nil
}

return nil, err
}

func stopInTotoRecording(cmd *cobra.Command, args []string) error {
if config.RuntimeInTotoConfig.Disabled {
return nil
Expand Down
31 changes: 0 additions & 31 deletions cmd/devguard-scanner/commands/intoto/intoto_record_test.go
Original file line number Diff line number Diff line change
@@ -1,32 +1 @@
package intotocmd

import (
"os"
"path"
"testing"

"github.com/stretchr/testify/assert"
)

func TestParseGitIgnore(t *testing.T) {
t.Run("parseGitIgnore with empty strings", func(t *testing.T) {
// create temp dir for testing
dir, err := os.MkdirTemp("", "test")
assert.NoError(t, err, "failed to create temporary directory")

defer os.RemoveAll(dir)

// Create a temporary .gitignore file for testing
gitignoreContent := "\n.DS_Store\n\t\t\t\n"

filepath := path.Join(dir, ".gitignore")

err = os.WriteFile(filepath, []byte(gitignoreContent), 0600)
assert.NoError(t, err, "failed to create temporary .gitignore file")

ignorePaths, err := parseGitIgnore(filepath)
assert.NoError(t, err, "expected no error when reading .gitignore")
assert.Equal(t, []string{".DS_Store"}, ignorePaths, "unexpected ignore paths")

})
}
2 changes: 1 addition & 1 deletion cmd/devguard-scanner/commands/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func signCmd(cmd *cobra.Command, args []string) error {
&cosignoptions.RootOptions{},
ko,
fileOrImageName,
false, // b64
false, // b64
"", "", // outputSignature, outputCertificate
false, // tlogUpload
)
Expand Down
14 changes: 7 additions & 7 deletions controllers/asset_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ import (
)

type AssetController struct {
assetRepository shared.AssetRepository
assetVersionRepository shared.AssetVersionRepository
assetRepository shared.AssetRepository
assetVersionRepository shared.AssetVersionRepository
artifactRiskHistoryRepository shared.ArtifactRiskHistoryRepository
assetService shared.AssetService
dependencyVulnService shared.DependencyVulnService
statisticsService shared.StatisticsService
thirdPartyIntegration shared.IntegrationAggregate
daemonRunner shared.DaemonRunner
assetService shared.AssetService
dependencyVulnService shared.DependencyVulnService
statisticsService shared.StatisticsService
thirdPartyIntegration shared.IntegrationAggregate
daemonRunner shared.DaemonRunner

utils.FireAndForgetSynchronizer
}
Expand Down
4 changes: 0 additions & 4 deletions database/models/comment_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,3 @@ type Comment struct {
UserID uuid.UUID `json:"userId"`
Comment string `json:"comment"`
}

func (m Comment) TableName() string {
return "comments"
}
15 changes: 1 addition & 14 deletions database/models/component_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (c ComponentDependencyNode) GetID() string {
func (c ComponentDependency) ToNodes() []ComponentDependencyNode {
// a component dependency represents an edge in the dependency tree
// thus we can represent it as two nodes
return []ComponentDependencyNode{ComponentDependencyNode{ID: utils.SafeDereference(c.ComponentID)}, ComponentDependencyNode{ID: c.DependencyID}}
return []ComponentDependencyNode{{ID: utils.SafeDereference(c.ComponentID)}, {ID: c.DependencyID}}
}

func resolveLicense(component ComponentDependency, componentLicenseOverwrites map[string]string) cyclonedx.Licenses {
Expand Down Expand Up @@ -246,19 +246,6 @@ func (c ComponentDependency) GetDependentID() *string {
return c.ComponentID
}

func BuildDepMap(deps []ComponentDependency) map[string][]string {
depMap := make(map[string][]string)
for _, dep := range deps {
if _, ok := depMap[utils.SafeDereference(dep.ComponentID)]; !ok {
depMap[utils.SafeDereference(dep.ComponentID)] = []string{}
}
depMap[utils.SafeDereference(dep.ComponentID)] = append(depMap[utils.SafeDereference(dep.ComponentID)], dep.DependencyID)
}
return depMap
}

const NoVersion = "0.0.0"

func (c Component) TableName() string {
return "components"
}
Expand Down
21 changes: 0 additions & 21 deletions database/models/vulnevent_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,27 +76,6 @@ type VulnEventDetail struct {
URI string `json:"uri"`
}

func EventTypeToVulnState(eventType dtos.VulnEventType) (dtos.VulnState, error) {
switch eventType {
case dtos.EventTypeComment:
return dtos.VulnStateOpen, nil
case dtos.EventTypeFixed:
return dtos.VulnStateFixed, nil
case dtos.EventTypeDetected:
fallthrough
case dtos.EventTypeReopened:
return dtos.VulnStateOpen, nil
case dtos.EventTypeAccepted:
return dtos.VulnStateAccepted, nil
case dtos.EventTypeFalsePositive:
return dtos.VulnStateFalsePositive, nil
case dtos.EventTypeMarkedForTransfer:
return dtos.VulnStateMarkedForTransfer, nil
default:
return "", fmt.Errorf("event type %s does not map to a vuln state", eventType)
}
}

func (event *VulnEvent) GetArbitraryJSONData() map[string]any {
// parse the additional data
if event.ArbitraryJSONData == "" {
Expand Down
6 changes: 0 additions & 6 deletions database/repositories/external_reference_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@ func NewExternalReferenceRepository(db *gorm.DB) shared.ExternalReferenceReposit
}
}

func (r *externalReferenceRepository) FindByAssetID(ctx context.Context, tx *gorm.DB, assetID uuid.UUID) ([]models.ExternalReference, error) {
var refs []models.ExternalReference
err := r.GetDB(ctx, tx).Where("asset_id = ?", assetID).Find(&refs).Error
return refs, err
}

func (r *externalReferenceRepository) FindByAssetVersion(ctx context.Context, tx *gorm.DB, assetID uuid.UUID, assetVersionName string) ([]models.ExternalReference, error) {
var refs []models.ExternalReference
err := r.GetDB(ctx, tx).Where("asset_id = ? AND asset_version_name = ?", assetID, assetVersionName).Find(&refs).Error
Expand Down
4 changes: 2 additions & 2 deletions database/repositories/gitlab_integration_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ func (r *gitlabOauth2TokenRepository) CreateIfNotExists(ctx context.Context, tx
return r.GetDB(ctx, tx).Clauses(clause.OnConflict{
DoNothing: true,
Columns: []clause.Column{
clause.Column{
{
Name: "provider_id",
},
clause.Column{
{
Name: "user_id",
},
},
Expand Down
Loading
Loading