From 533b489083b339fbb5bdb88c3c9dc9ea569a1f73 Mon Sep 17 00:00:00 2001 From: AlvoBen <144705560+AlvoBen@users.noreply.github.com> Date: Tue, 2 Apr 2024 11:59:30 +0300 Subject: [PATCH] CLI | Add Missing PackageManager Types (AST-38138) (#691) * add package manager types * add unit test * Change createDependencyMapFromDependencyResolution signature to fix linter errors * fix lint errors * Resolve pr review conversation --------- Co-authored-by: AlvoBen --- .../scarealtime/sca-realtime-utils.go | 3 + internal/commands/scarealtime/sca-realtime.go | 60 ++++++++++--------- .../commands/scarealtime/sca-realtime_test.go | 35 +++++++++++ 3 files changed, 71 insertions(+), 27 deletions(-) diff --git a/internal/commands/scarealtime/sca-realtime-utils.go b/internal/commands/scarealtime/sca-realtime-utils.go index 02d119c66..dd0d8336f 100644 --- a/internal/commands/scarealtime/sca-realtime-utils.go +++ b/internal/commands/scarealtime/sca-realtime-utils.go @@ -22,6 +22,7 @@ var GetPackageManagerFromResolvingModuleType = map[string]string{ "composer": "Php", "gomodules": "Go", "pip": "Python", + "poetry": "Python", "rubygems": "Ruby", "npm": "Npm", "yarn": "Npm", @@ -34,6 +35,8 @@ var GetPackageManagerFromResolvingModuleType = map[string]string{ "swiftpm": "Ios", "carthage": "Ios", "cocoapods": "Ios", + "nuget": "Nuget", + "cpp": "Cpp", } // downloadSCAResolverAndHashFileIfNeeded Downloads SCA Realtime if it is not downloaded yet diff --git a/internal/commands/scarealtime/sca-realtime.go b/internal/commands/scarealtime/sca-realtime.go index 72b589185..feed5b429 100644 --- a/internal/commands/scarealtime/sca-realtime.go +++ b/internal/commands/scarealtime/sca-realtime.go @@ -129,34 +129,9 @@ func GetSCAVulnerabilities(scaRealTimeWrapper wrappers.ScaRealTimeWrapper) error var modelResults []wrappers.ScaVulnerabilitiesResponseModel var scaRealtimeScanErrors []wrappers.ScaRealtimeScanError - for _, dependencyResolutionResult := range scaResolverResults.DependencyResolutionResults { + for i, dependencyResolutionResult := range scaResolverResults.DependencyResolutionResults { // We're using a map to avoid adding repeated packages in request body - dependencyMap := make(map[string]wrappers.ScaDependencyBodyRequest) - - for i := range dependencyResolutionResult.Dependencies { - var dependency = dependencyResolutionResult.Dependencies[i] - var packageManager = GetPackageManagerFromResolvingModuleType[strings.ToLower(dependency.ResolvingModuleType)] - - // if no package manager is found uses the resolving module type - if packageManager == "" { - packageManager = strings.ToLower(dependency.ResolvingModuleType) - } - - dependencyMap[dependency.ID.NodeID] = wrappers.ScaDependencyBodyRequest{ - PackageName: dependency.ID.Name, - Version: dependency.ID.Version, - PackageManager: packageManager, - } - if len(dependency.Children) > 0 { - for _, dependencyChildren := range dependency.Children { - dependencyMap[dependencyChildren.NodeID] = wrappers.ScaDependencyBodyRequest{ - PackageName: dependencyChildren.Name, - Version: dependencyChildren.Version, - PackageManager: packageManager, - } - } - } - } + dependencyMap := createDependencyMapFromDependencyResolution(&scaResolverResults.DependencyResolutionResults[i]) // Get all ScaDependencyBodyRequest from the map to call SCA API var bodyRequest []wrappers.ScaDependencyBodyRequest @@ -211,6 +186,37 @@ func GetSCAVulnerabilities(scaRealTimeWrapper wrappers.ScaRealTimeWrapper) error return nil } +func createDependencyMapFromDependencyResolution(dependencyResolutionResult *DependencyResolution) map[string]wrappers.ScaDependencyBodyRequest { + // We're using a map to avoid adding repeated packages in request body + dependencyMap := make(map[string]wrappers.ScaDependencyBodyRequest) + + for i := range dependencyResolutionResult.Dependencies { + var dependency = dependencyResolutionResult.Dependencies[i] + var packageManager = GetPackageManagerFromResolvingModuleType[strings.ToLower(dependency.ResolvingModuleType)] + + // if no package manager is found uses the resolving module type + if packageManager == "" { + packageManager = strings.ToLower(dependency.ResolvingModuleType) + } + + dependencyMap[dependency.ID.NodeID] = wrappers.ScaDependencyBodyRequest{ + PackageName: dependency.ID.Name, + Version: dependency.ID.Version, + PackageManager: packageManager, + } + if len(dependency.Children) > 0 { + for _, dependencyChildren := range dependency.Children { + dependencyMap[dependencyChildren.NodeID] = wrappers.ScaDependencyBodyRequest{ + PackageName: dependencyChildren.Name, + Version: dependencyChildren.Version, + PackageManager: packageManager, + } + } + } + } + return dependencyMap +} + func GetScaVulnerabilitiesPackages(scaRealTimeWrapper wrappers.ScaRealTimeWrapper, bodyRequest []wrappers.ScaDependencyBodyRequest) (vulnerabilities []wrappers.ScaVulnerabilitiesResponseModel, err, err1 error) { //nolint:lll // We need to call the SCA API for each DependencyResolution so that we can save the file name vulnerabilitiesResponseModel, errorModel, errVulnerabilities := scaRealTimeWrapper.GetScaVulnerabilitiesPackages(bodyRequest) diff --git a/internal/commands/scarealtime/sca-realtime_test.go b/internal/commands/scarealtime/sca-realtime_test.go index 90d8f9c98..891b5fd8b 100644 --- a/internal/commands/scarealtime/sca-realtime_test.go +++ b/internal/commands/scarealtime/sca-realtime_test.go @@ -57,3 +57,38 @@ func TestRequiredProjectDir(t *testing.T) { err := cmd.Execute() assert.Error(t, err, "Provided path does not exist: "+invalidProjectPath, err.Error()) } + +func TestCreateDependencyMapFromDependencyResolution_NugetDependencies_Success(t *testing.T) { + dependecyResolutionResult := DependencyResolution{ + Dependencies: []Dependency{ + NewDependency("8ce2d33f-5783-4fe1-b9a7-3ce2c9a3aae9", "Microsoft. NETCore. Platforms", + "1.1.0", "Nuget", []interface{}{"NetStandard20"}), + NewDependency("60b40261-18b2-4cf6-bdf5-e23ad408de3b", "NETStandard.Library", + "2.0.3", "Nuget", []interface{}{"NetStandard20"}), + }, + } + dependencyMap := createDependencyMapFromDependencyResolution(&dependecyResolutionResult) + assert.Equal(t, len(dependencyMap), 2) + assert.Equal(t, dependencyMap["60b40261-18b2-4cf6-bdf5-e23ad408de3b"].PackageManager, "Nuget") + assert.Equal(t, dependencyMap["60b40261-18b2-4cf6-bdf5-e23ad408de3b"].Version, "2.0.3") + assert.Equal(t, dependencyMap["60b40261-18b2-4cf6-bdf5-e23ad408de3b"].PackageName, "NETStandard.Library") + assert.Equal(t, dependencyMap["8ce2d33f-5783-4fe1-b9a7-3ce2c9a3aae9"].PackageManager, "Nuget") + assert.Equal(t, dependencyMap["8ce2d33f-5783-4fe1-b9a7-3ce2c9a3aae9"].Version, "1.1.0") + assert.Equal(t, dependencyMap["8ce2d33f-5783-4fe1-b9a7-3ce2c9a3aae9"].PackageName, "Microsoft. NETCore. Platforms") +} + +func NewDependency(nodeID, name, version, resolvingModuleType string, targetFrameworks []interface{}) Dependency { + return Dependency{ + ID: NewID(nodeID, name, version), + ResolvingModuleType: resolvingModuleType, + TargetFrameworks: targetFrameworks, + } +} + +func NewID(nodeID, name, version string) ID { + return ID{ + NodeID: nodeID, + Name: name, + Version: version, + } +}