mirror of
https://github.com/safedep/vet.git
synced 2025-12-10 12:07:30 -06:00
Merge branch 'main' into fix/policy-violation-suspicious-#483
This commit is contained in:
commit
b4976630da
15
pkg/readers/fixtures/vsix/.cursor/extensions/extensions.json
Normal file
15
pkg/readers/fixtures/vsix/.cursor/extensions/extensions.json
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
[
|
||||
{
|
||||
"identifier": {
|
||||
"id": "golang.go",
|
||||
"uuid": "36c8e36e-4981-4810-b4db-2fba5441957c"
|
||||
},
|
||||
"version": "0.39.1",
|
||||
"location": {
|
||||
"path": "/home/user/.cursor/extensions/golang.go-0.39.1",
|
||||
"scheme": "file"
|
||||
},
|
||||
"relativeLocation": "golang.go-0.39.1"
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,15 @@
|
||||
|
||||
[
|
||||
{
|
||||
"identifier": {
|
||||
"id": "redhat.java",
|
||||
"uuid": "198a707e-28af-4e84-8610-6e2f628dd12d"
|
||||
},
|
||||
"version": "1.20.0",
|
||||
"location": {
|
||||
"path": "/home/user/.vscode-oss/extensions/redhat.java-1.20.0",
|
||||
"scheme": "file"
|
||||
},
|
||||
"relativeLocation": "redhat.java-1.20.0"
|
||||
}
|
||||
]
|
||||
14
pkg/readers/fixtures/vsix/.vscode/extensions/extensions.json
vendored
Normal file
14
pkg/readers/fixtures/vsix/.vscode/extensions/extensions.json
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"identifier": {
|
||||
"id": "ms-python.python",
|
||||
"uuid": "f1f59ae4-9318-4f3c-a9b5-81b2eaa5f8a3"
|
||||
},
|
||||
"version": "2023.20.0",
|
||||
"location": {
|
||||
"path": "/home/user/.vscode/extensions/ms-python.python-2023.20.0",
|
||||
"scheme": "file"
|
||||
},
|
||||
"relativeLocation": "ms-python.python-2023.20.0"
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,15 @@
|
||||
|
||||
[
|
||||
{
|
||||
"identifier": {
|
||||
"id": "rust-lang.rust",
|
||||
"uuid": "3f899f2a-4d01-4718-ac18-4e5832cf5e6b"
|
||||
},
|
||||
"version": "0.7.9",
|
||||
"location": {
|
||||
"path": "/home/user/.windsurf/extensions/rust-lang.rust-0.7.9",
|
||||
"scheme": "file"
|
||||
},
|
||||
"relativeLocation": "rust-lang.rust-0.7.9"
|
||||
}
|
||||
]
|
||||
@ -1,26 +0,0 @@
|
||||
[
|
||||
{
|
||||
"identifier": {
|
||||
"id": "castwide.solargraph",
|
||||
"uuid": "349e83e2-207c-4309-a8d2-dfa43f7ee0c9"
|
||||
},
|
||||
"version": "0.24.1",
|
||||
"location": {
|
||||
"$mid": 1,
|
||||
"path": "/Users/dev/.vscode/extensions/castwide.solargraph-0.24.1",
|
||||
"scheme": "file"
|
||||
},
|
||||
"relativeLocation": "castwide.solargraph-0.24.1",
|
||||
"metadata": {
|
||||
"id": "349e83e2-207c-4309-a8d2-dfa43f7ee0c9",
|
||||
"publisherId": "8244762e-597b-434d-b303-f780ff47b36c",
|
||||
"publisherDisplayName": "Castwide",
|
||||
"targetPlatform": "undefined",
|
||||
"updated": false,
|
||||
"isPreReleaseVersion": false,
|
||||
"installedTimestamp": 1703166823676,
|
||||
"pinned": false,
|
||||
"preRelease": false
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -68,15 +68,24 @@ var _ PackageManifestReader = (*vsixExtReader)(nil)
|
||||
|
||||
func NewVSIXExtReader(distributions []string) (*vsixExtReader, error) {
|
||||
customDistributions := make(map[string]distributionInfo)
|
||||
ecosystem := models.EcosystemVSCodeExtensions
|
||||
|
||||
for i, distribution := range distributions {
|
||||
// Check if the path matches any supported editor
|
||||
foundMatch := false
|
||||
ecosystem := models.EcosystemVSCodeExtensions
|
||||
|
||||
for _, eco := range editors {
|
||||
if strings.Contains(distribution, eco.FilePath) {
|
||||
ecosystem = eco.Ecosystem
|
||||
foundMatch = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !foundMatch {
|
||||
return nil, fmt.Errorf("unsupported editor path: %s", distribution)
|
||||
}
|
||||
|
||||
customDistributions[fmt.Sprintf("custom-%d", i)] = distributionInfo{
|
||||
FilePath: distribution,
|
||||
Ecosystem: ecosystem,
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
package readers
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
packagev1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/package/v1"
|
||||
"github.com/safedep/vet/pkg/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
@ -13,8 +15,49 @@ func TestVSCodeExtReaderInit(t *testing.T) {
|
||||
assert.NotNil(t, reader)
|
||||
}
|
||||
|
||||
func TestVSCodeExtReaderEnumManifests(t *testing.T) {
|
||||
reader, err := NewVSIXExtReader([]string{"./fixtures/vsx"})
|
||||
// TestVSCodeExtReaderForAllEditors tests each editor individually
|
||||
func TestVSCodeExtReaderForAllEditors(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
expectedPkg string
|
||||
expectedVersion string
|
||||
expectedEco packagev1.Ecosystem
|
||||
}{
|
||||
{
|
||||
name: "VSCode Editor",
|
||||
path: ".vscode/extensions/",
|
||||
expectedPkg: "ms-python.python",
|
||||
expectedVersion: "2023.20.0",
|
||||
expectedEco: packagev1.Ecosystem_ECOSYSTEM_VSCODE,
|
||||
},
|
||||
{
|
||||
name: "VSCodium Editor",
|
||||
path: ".vscode-oss/extensions/",
|
||||
expectedPkg: "redhat.java",
|
||||
expectedVersion: "1.20.0",
|
||||
expectedEco: packagev1.Ecosystem_ECOSYSTEM_OPENVSX,
|
||||
},
|
||||
{
|
||||
name: "Cursor Editor",
|
||||
path: ".cursor/extensions/",
|
||||
expectedPkg: "golang.go",
|
||||
expectedVersion: "0.39.1",
|
||||
expectedEco: packagev1.Ecosystem_ECOSYSTEM_OPENVSX,
|
||||
},
|
||||
{
|
||||
name: "Windsurf Editor",
|
||||
path: ".windsurf/extensions/",
|
||||
expectedPkg: "rust-lang.rust",
|
||||
expectedVersion: "0.7.9",
|
||||
expectedEco: packagev1.Ecosystem_ECOSYSTEM_OPENVSX,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
path := filepath.Join("./fixtures/vsix", tt.path)
|
||||
reader, err := NewVSIXExtReader([]string{path})
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, reader)
|
||||
|
||||
@ -22,12 +65,66 @@ func TestVSCodeExtReaderEnumManifests(t *testing.T) {
|
||||
assert.NotNil(t, manifest)
|
||||
assert.NotNil(t, reader)
|
||||
|
||||
assert.Equal(t, 1, manifest.GetPackagesCount())
|
||||
assert.Equal(t, "castwide.solargraph", manifest.GetPackages()[0].GetName())
|
||||
assert.Equal(t, "0.24.1", manifest.GetPackages()[0].GetVersion())
|
||||
packages := manifest.GetPackages()
|
||||
assert.Equal(t, 1, len(packages))
|
||||
assert.Equal(t, tt.expectedPkg, packages[0].GetName())
|
||||
assert.Equal(t, tt.expectedVersion, packages[0].GetVersion())
|
||||
assert.Equal(t, tt.expectedEco, packages[0].GetControlTowerSpecEcosystem())
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestVSCodeExtReaderWithMultipleEditors tests reading from multiple editors simultaneously
|
||||
func TestVSCodeExtReaderWithMultipleEditors(t *testing.T) {
|
||||
paths := []string{
|
||||
"./fixtures/vsix/.vscode/extensions",
|
||||
"./fixtures/vsix/.vscode-oss/extensions",
|
||||
"./fixtures/vsix/.cursor/extensions",
|
||||
"./fixtures/vsix/.windsurf/extensions",
|
||||
}
|
||||
|
||||
reader, err := NewVSIXExtReader(paths)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, reader)
|
||||
|
||||
foundPackages := make(map[string]bool)
|
||||
packageCount := 0
|
||||
|
||||
err = reader.EnumManifests(func(manifest *models.PackageManifest, reader PackageReader) error {
|
||||
assert.NotNil(t, manifest)
|
||||
packages := manifest.GetPackages()
|
||||
packageCount += len(packages)
|
||||
|
||||
for _, pkg := range packages {
|
||||
foundPackages[pkg.GetName()] = true
|
||||
|
||||
// Verify ecosystem based on package source
|
||||
switch pkg.GetName() {
|
||||
case "ms-python.python":
|
||||
assert.Equal(t, packagev1.Ecosystem_ECOSYSTEM_VSCODE, pkg.GetControlTowerSpecEcosystem())
|
||||
case "redhat.java", "golang.go", "rust-lang.rust":
|
||||
assert.Equal(t, packagev1.Ecosystem_ECOSYSTEM_OPENVSX, pkg.GetControlTowerSpecEcosystem())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 4, packageCount) // Should find all four extensions
|
||||
assert.True(t, foundPackages["ms-python.python"])
|
||||
assert.True(t, foundPackages["redhat.java"])
|
||||
assert.True(t, foundPackages["golang.go"])
|
||||
assert.True(t, foundPackages["rust-lang.rust"])
|
||||
}
|
||||
|
||||
func TestVSCodeExtReaderWithInvalidPath(t *testing.T) {
|
||||
reader, err := NewVSIXExtReader([]string{"./fixtures/vsix/nonexistent"})
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, reader)
|
||||
}
|
||||
|
||||
53
pkg/reporter/github_sync_resolver.go
Normal file
53
pkg/reporter/github_sync_resolver.go
Normal file
@ -0,0 +1,53 @@
|
||||
package reporter
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
controltowerv1pb "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/controltower/v1"
|
||||
controltowerv1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/services/controltower/v1"
|
||||
)
|
||||
|
||||
type githubActionResolver struct{}
|
||||
|
||||
func GithubActionsSyncReporterResolver() SyncReporterEnvResolver {
|
||||
return &githubActionResolver{}
|
||||
}
|
||||
|
||||
var _ SyncReporterEnvResolver = &githubActionResolver{}
|
||||
|
||||
func (g *githubActionResolver) GetProjectSource() controltowerv1pb.Project_Source {
|
||||
return controltowerv1pb.Project_SOURCE_GITHUB
|
||||
}
|
||||
|
||||
func (g *githubActionResolver) GetProjectURL() string {
|
||||
return os.Getenv("GITHUB_SERVER_URL") + "/" + os.Getenv("GITHUB_REPOSITORY")
|
||||
}
|
||||
|
||||
func (g *githubActionResolver) GitRef() string {
|
||||
return os.Getenv("GITHUB_REF")
|
||||
}
|
||||
|
||||
func (g *githubActionResolver) GitSha() string {
|
||||
return os.Getenv("GITHUB_SHA")
|
||||
}
|
||||
|
||||
func (g *githubActionResolver) Trigger() controltowerv1.ToolTrigger {
|
||||
switch eventName := os.Getenv("GITHUB_EVENT_NAME"); eventName {
|
||||
case "push":
|
||||
return controltowerv1.ToolTrigger_TOOL_TRIGGER_PUSH
|
||||
case "pull_request", "pull_request_target":
|
||||
return controltowerv1.ToolTrigger_TOOL_TRIGGER_PULL_REQUEST
|
||||
case "create":
|
||||
// In GitHub Actions, 'create' event with ref_type=tag indicates a tag was created
|
||||
if os.Getenv("GITHUB_REF_TYPE") == "tag" {
|
||||
return controltowerv1.ToolTrigger_TOOL_TRIGGER_TAG
|
||||
}
|
||||
return controltowerv1.ToolTrigger_TOOL_TRIGGER_UNSPECIFIED
|
||||
case "schedule":
|
||||
return controltowerv1.ToolTrigger_TOOL_TRIGGER_SCHEDULED
|
||||
case "workflow_dispatch", "repository_dispatch":
|
||||
return controltowerv1.ToolTrigger_TOOL_TRIGGER_MANUAL
|
||||
default:
|
||||
return controltowerv1.ToolTrigger_TOOL_TRIGGER_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ package reporter
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@ -187,6 +188,15 @@ type syncReporter struct {
|
||||
// Verify syncReporter implements the Reporter interface
|
||||
var _ Reporter = (*syncReporter)(nil)
|
||||
|
||||
func NewSyncReporterEnvironmentResolver() SyncReporterEnvResolver {
|
||||
// The `GITHUB_ACTIONS` environment variable is always set to true when GitHub Actions is running the workflow
|
||||
if _, exists := os.LookupEnv("GITHUB_ACTIONS"); exists {
|
||||
return GithubActionsSyncReporterResolver()
|
||||
}
|
||||
|
||||
return DefaultSyncReporterEnvResolver()
|
||||
}
|
||||
|
||||
// NewSyncReporter creates a new sync reporter.
|
||||
func NewSyncReporter(config SyncReporterConfig, envResolver SyncReporterEnvResolver, callbacks SyncReporterCallbacks) (*syncReporter, error) {
|
||||
if config.ClientConnection == nil {
|
||||
|
||||
@ -3,6 +3,7 @@ package reporter
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
controltowerv1pb "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/controltower/v1"
|
||||
@ -111,6 +112,77 @@ func mockDependencyGraph(pkg *models.Package) {
|
||||
pkg.Manifest.DependencyGraph = dg
|
||||
}
|
||||
|
||||
func TestNewSyncReporterEnvironmentResolver(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
setupEnv func(t *testing.T)
|
||||
expectedProjectSource controltowerv1pb.Project_Source
|
||||
expectedProjectUrl string
|
||||
expectedTrigger controltowerv1.ToolTrigger
|
||||
expectedGitRef string
|
||||
expectedGitSha string
|
||||
}{
|
||||
{
|
||||
name: "should return GitHub Actions values when GITHUB_ACTIONS is set",
|
||||
setupEnv: func(t *testing.T) {
|
||||
t.Setenv("GITHUB_ACTIONS", "true")
|
||||
t.Setenv("GITHUB_SERVER_URL", "https://github.com")
|
||||
t.Setenv("GITHUB_REPOSITORY", "safedep/vet")
|
||||
t.Setenv("GITHUB_EVENT_NAME", "push")
|
||||
t.Setenv("GITHUB_REF", "refs/heads/main")
|
||||
t.Setenv("GITHUB_SHA", "abc123")
|
||||
},
|
||||
expectedProjectSource: controltowerv1pb.Project_SOURCE_GITHUB,
|
||||
expectedTrigger: controltowerv1.ToolTrigger_TOOL_TRIGGER_PUSH,
|
||||
expectedProjectUrl: "https://github.com/safedep/vet",
|
||||
expectedGitRef: "refs/heads/main",
|
||||
expectedGitSha: "abc123",
|
||||
},
|
||||
{
|
||||
name: "should return default values when GITHUB_ACTIONS is not set",
|
||||
setupEnv: func(t *testing.T) {
|
||||
// No environment setup needed
|
||||
os.Unsetenv("GITHUB_ACTIONS")
|
||||
os.Unsetenv("GITHUB_REPOSITORY")
|
||||
os.Unsetenv("GITHUB_SERVER_URL")
|
||||
os.Unsetenv("GITHUB_REF")
|
||||
os.Unsetenv("GITHUB_SHA")
|
||||
os.Unsetenv("GITHUB_EVENT_NAME")
|
||||
},
|
||||
expectedProjectSource: controltowerv1pb.Project_SOURCE_UNSPECIFIED,
|
||||
expectedTrigger: controltowerv1.ToolTrigger_TOOL_TRIGGER_MANUAL,
|
||||
expectedProjectUrl: "",
|
||||
expectedGitRef: "",
|
||||
expectedGitSha: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Setup test environment
|
||||
tt.setupEnv(t)
|
||||
|
||||
// Get the resolver
|
||||
resolver := NewSyncReporterEnvironmentResolver()
|
||||
|
||||
source := resolver.GetProjectSource()
|
||||
assert.Equal(t, tt.expectedProjectSource, source, "unexpected project source")
|
||||
|
||||
url := resolver.GetProjectURL()
|
||||
assert.Equal(t, tt.expectedProjectUrl, url, "unexpected project URL")
|
||||
|
||||
trigger := resolver.Trigger()
|
||||
assert.Equal(t, tt.expectedTrigger, trigger, "unexpected trigger")
|
||||
|
||||
gitRef := resolver.GitRef()
|
||||
assert.Equal(t, tt.expectedGitRef, gitRef, "unexpected git ref")
|
||||
|
||||
gitSha := resolver.GitSha()
|
||||
assert.Equal(t, tt.expectedGitSha, gitSha, "unexpected git sha")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncPackage(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
2
scan.go
2
scan.go
@ -679,7 +679,7 @@ func internalStartScan() error {
|
||||
ProjectVersion: syncReportStream,
|
||||
EnableMultiProjectSync: syncEnableMultiProject,
|
||||
ClientConnection: clientConn,
|
||||
}, reporter.DefaultSyncReporterEnvResolver(), reporter.SyncReporterCallbacks{
|
||||
}, reporter.NewSyncReporterEnvironmentResolver(), reporter.SyncReporterCallbacks{
|
||||
OnSyncStart: func() {
|
||||
ui.PrintMsg("🌐 Syncing data to SafeDep Cloud...")
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user