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

Audit Maven - use maven-dep-tree plugin #1023

Merged
merged 37 commits into from
Nov 19, 2023
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
fdeb9ae
init commit
omerzi Nov 9, 2023
f8ca081
Merge remote-tracking branch 'upstream/dev' into mvn-dep-tree
omerzi Nov 9, 2023
faf177c
Merge branch 'dev' into mvn-dep-tree
omerzi Nov 9, 2023
b2a782d
fix static analysis
omerzi Nov 9, 2023
9ba6866
Merge remote-tracking branch 'origin/mvn-dep-tree' into mvn-dep-tree
omerzi Nov 9, 2023
80c03df
fix static analysis
omerzi Nov 9, 2023
b6d73a0
fix gradle test
omerzi Nov 9, 2023
485ebdc
fix gradle test
omerzi Nov 9, 2023
63d1f76
Update jars
omerzi Nov 13, 2023
1511903
Merge remote-tracking branch 'origin/mvn-dep-tree' into mvn-dep-tree
omerzi Nov 13, 2023
7fbe7d0
Merge remote-tracking branch 'upstream/dev' into mvn-dep-tree
omerzi Nov 13, 2023
b60d643
Merge remote-tracking branch 'upstream/dev' into mvn-dep-tree
omerzi Nov 13, 2023
fd84b8e
Merge remote-tracking branch 'origin/mvn-dep-tree' into mvn-dep-tree
omerzi Nov 13, 2023
3e56246
Merge remote-tracking branch 'upstream/dev' into mvn-dep-tree
omerzi Nov 14, 2023
be4c85f
Merge remote-tracking branch 'upstream/dev' into mvn-dep-tree
omerzi Nov 14, 2023
7267cb6
Merge remote-tracking branch 'origin/mvn-dep-tree' into mvn-dep-tree
omerzi Nov 14, 2023
e246bac
Merge branch 'dev' into mvn-dep-tree
omerzi Nov 14, 2023
14a6c86
update
omerzi Nov 14, 2023
bb193b3
Merge remote-tracking branch 'origin/mvn-dep-tree' into mvn-dep-tree
omerzi Nov 14, 2023
9a5913d
update
omerzi Nov 14, 2023
fbe63dc
update
omerzi Nov 14, 2023
33ef16c
added test
omerzi Nov 14, 2023
79fed67
added test
omerzi Nov 14, 2023
3be15cf
added test
omerzi Nov 14, 2023
49562d5
added test
omerzi Nov 14, 2023
9218f07
added test
omerzi Nov 14, 2023
451f53d
CR + improvements
omerzi Nov 15, 2023
9c7f366
fix test
omerzi Nov 15, 2023
48aaccd
fix test
omerzi Nov 15, 2023
5edcb17
fix test
omerzi Nov 15, 2023
0c8020b
Merge branch 'dev' into mvn-dep-tree
omerzi Nov 15, 2023
53390b0
Merge remote-tracking branch 'upstream/dev' into mvn-dep-tree
omerzi Nov 16, 2023
5fdbb8f
CR
omerzi Nov 19, 2023
198ed60
CR
omerzi Nov 19, 2023
2409fe7
CR
omerzi Nov 19, 2023
44bca20
CR
omerzi Nov 19, 2023
f701fad
CR
omerzi Nov 19, 2023
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
2 changes: 2 additions & 0 deletions artifactory/utils/projectconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ func SetResolutionRepoIfExists(params xrayutils.AuditParams, tech coreutils.Tech
if params.DepsRepo() != "" || params.IgnoreConfigFile() {
return
}

configFilePath, exists, err := GetProjectConfFilePath(techType[tech])
if err != nil {
err = fmt.Errorf("failed while searching for %s.yaml config file: %s", tech.String(), err.Error())
Expand All @@ -211,6 +212,7 @@ func SetResolutionRepoIfExists(params xrayutils.AuditParams, tech coreutils.Tech
return
}

log.Debug("Using resolver config from", configFilePath)
repoConfig, err := ReadResolutionOnlyConfiguration(configFilePath)
if err != nil {
err = fmt.Errorf("failed while reading %s.yaml config file: %s", tech.String(), err.Error())
Expand Down
6 changes: 3 additions & 3 deletions buildscripts/download-jars.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
# https://github.com/jfrog/maven-dep-tree

# Once you have updated the versions mentioned below, please execute this script from the root directory of the jfrog-cli-core to ensure the JAR files are updated.
GRADLE_DEP_TREE_VERSION="3.0.0"
MAVEN_DEP_TREE_VERSION="1.0.0"
GRADLE_DEP_TREE_VERSION="3.0.1"
MAVEN_DEP_TREE_VERSION="1.0.2"
omerzi marked this conversation as resolved.
Show resolved Hide resolved

curl -fL https://releases.jfrog.io/artifactory/oss-release-local/com/jfrog/gradle-dep-tree/${GRADLE_DEP_TREE_VERSION}/gradle-dep-tree-${GRADLE_DEP_TREE_VERSION}.jar -o xray/commands/audit/sca/java/gradle-dep-tree.jar
# curl -fL https://releases.jfrog.io/artifactory/oss-release-local/com/jfrog/maven-dep-tree/${MAVEN_DEP_TREE_VERSION}/maven-dep-tree-${MAVEN_DEP_TREE_VERSION}.jar -o xray/commands/audit/sca/java/maven-dep-tree.jar
curl -fL https://releases.jfrog.io/artifactory/oss-release-local/com/jfrog/maven-dep-tree/${MAVEN_DEP_TREE_VERSION}/maven-dep-tree-${MAVEN_DEP_TREE_VERSION}.jar -o xray/commands/audit/sca/java/maven-dep-tree.jar
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,6 @@ require (
gopkg.in/warnings.v0 v0.1.2 // indirect
)

// replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20231109105822-00d80f604090
// replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go dev

// replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go dev
33 changes: 33 additions & 0 deletions utils/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,39 @@ func (serverDetails *ServerDetails) createAuthConfig(details auth.ServiceDetails
return details, nil
}

// GetAuthenticationCredentials retrieves authentication credentials for the serverDetails instance.
// If both a username and password are provided, they are returned.
// If only an access token is provided, the function extracts the username from the access token,
// and both the username and access token are returned.
//
// Returns:
// - Username and password if both are provided.
// - Username extracted from the access token, along with the access token, if the access token is provided.
// - An error if neither username/password nor access token is provided, with details about the missing credentials.
func (serverDetails *ServerDetails) GetAuthenticationCredentials() (string, string, error) {
// Username and password are set
if serverDetails.Password != "" && serverDetails.User != "" {
return serverDetails.User, serverDetails.Password, nil
}

// Access token is set, extract the username from the access token if needed
if serverDetails.AccessToken != "" {
if serverDetails.User == "" {
serverDetails.User = auth.ExtractUsernameFromAccessToken(serverDetails.AccessToken)
omerzi marked this conversation as resolved.
Show resolved Hide resolved
}
return serverDetails.User, serverDetails.AccessToken, nil
}

// Username/Password or Access token isn't set
errMissingCredsMsg := "either username/password or access token must be set for "
if serverDetails.Url != "" {
errMissingCredsMsg += serverDetails.Url
} else if serverDetails.ArtifactoryUrl != "" {
errMissingCredsMsg += serverDetails.ArtifactoryUrl
}
return "", "", errors.New(errMissingCredsMsg)
omerzi marked this conversation as resolved.
Show resolved Hide resolved
}

func (missionControlDetails *MissionControlDetails) GetAccessToken() string {
return missionControlDetails.AccessToken
}
Expand Down
103 changes: 103 additions & 0 deletions xray/commands/audit/sca/java/deptreemanager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package java

import (
"encoding/json"
"github.com/jfrog/gofrog/datastructures"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
xrayUtils "github.com/jfrog/jfrog-client-go/xray/services/utils"
"os"
"strings"
)

type DepTreeParams struct {
Tool coreutils.Technology
UseWrapper bool
IsMvnDepTreeInstalled bool
Server *config.ServerDetails
DepsRepo string
}

type DepTreeManager struct {
server *config.ServerDetails
releasesRepo string
depsRepo string
useWrapper bool
}

func NewDepTreeManager(params *DepTreeParams) *DepTreeManager {
return &DepTreeManager{useWrapper: params.UseWrapper, depsRepo: params.DepsRepo, server: params.Server}
}

// The structure of a dependency tree of a module in a Gradle/Maven project, as created by the gradle-dep-tree and maven-dep-tree plugins.
type moduleDepTree struct {
Root string `json:"root"`
Nodes map[string]depTreeNode `json:"nodes"`
}

type depTreeNode struct {
Children []string `json:"children"`
}

// getGraphFromDepTree reads the output files of the gradle-dep-tree and maven-dep-tree plugins and returns them as a slice of GraphNodes.
// It takes the output of the plugin's run (which is a byte representation of a list of paths of the output files, separated by newlines) as input.
func getGraphFromDepTree(depTreeOutput []byte) (depsGraph []*xrayUtils.GraphNode, uniqueDeps []string, err error) {
modules, err := parseDepTreeFiles(depTreeOutput)
if err != nil {
return
}
uniqueDepsSet := datastructures.MakeSet[string]()
for _, moduleTree := range modules {
directDepId := GavPackageTypeIdentifier + moduleTree.Root
directDependency := &xrayUtils.GraphNode{
Id: directDepId,
Nodes: []*xrayUtils.GraphNode{},
}
uniqueDepsSet.Add(directDepId)
populateDependencyTree(directDependency, moduleTree.Root, moduleTree, uniqueDepsSet)
depsGraph = append(depsGraph, directDependency)
}
uniqueDeps = uniqueDepsSet.ToSlice()
return
}

func populateDependencyTree(currNode *xrayUtils.GraphNode, currNodeId string, moduleTree *moduleDepTree, uniqueDepsSet *datastructures.Set[string]) {
if currNode.NodeHasLoop() {
return
}
for _, childId := range moduleTree.Nodes[currNodeId].Children {
childGav := GavPackageTypeIdentifier + childId
childNode := &xrayUtils.GraphNode{
Id: childGav,
Nodes: []*xrayUtils.GraphNode{},
Parent: currNode,
}
uniqueDepsSet.Add(childGav)
populateDependencyTree(childNode, childId, moduleTree, uniqueDepsSet)
currNode.Nodes = append(currNode.Nodes, childNode)
}
}

func parseDepTreeFiles(jsonFilePaths []byte) ([]*moduleDepTree, error) {
outputFilePaths := strings.Split(strings.TrimSpace(string(jsonFilePaths)), "\n")
var modules []*moduleDepTree
for _, path := range outputFilePaths {
results, err := parseDepTreeFile(path)
if err != nil {
return nil, err
}
modules = append(modules, results)
}
return modules, nil
}

func parseDepTreeFile(path string) (results *moduleDepTree, err error) {
depTreeJson, err := os.ReadFile(strings.TrimSpace(path))
if errorutils.CheckError(err) != nil {
return
}
results = &moduleDepTree{}
err = errorutils.CheckError(json.Unmarshal(depTreeJson, &results))
return
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import (
"github.com/stretchr/testify/assert"
"os"
"path/filepath"
"reflect"
"testing"
)

func TestGetGraphFromDepTree(t *testing.T) {
func TestGetGradleGraphFromDepTree(t *testing.T) {
// Create and change directory to test workspace
tempDirPath, cleanUp := sca.CreateTestWorkspace(t, "gradle-example-ci-server")
defer func() {
Expand Down Expand Up @@ -42,6 +43,9 @@ func TestGetGraphFromDepTree(t *testing.T) {
},
expectedUniqueDeps: []string{
GavPackageTypeIdentifier + "junit:junit:4.11",
GavPackageTypeIdentifier + "org.jfrog.example.gradle:webservice:1.0",
GavPackageTypeIdentifier + "org.jfrog.example.gradle:api:1.0",
GavPackageTypeIdentifier + "org.jfrog.example.gradle:" + filepath.Base(tempDirPath) + ":1.0",
GavPackageTypeIdentifier + "commons-io:commons-io:1.2",
GavPackageTypeIdentifier + "org.apache.wicket:wicket:1.3.7",
GavPackageTypeIdentifier + "org.jfrog.example.gradle:shared:1.0",
Expand All @@ -53,12 +57,12 @@ func TestGetGraphFromDepTree(t *testing.T) {
},
}

manager := &depTreeManager{}
manager := &gradleDepTreeManager{&DepTreeManager{}}
outputFileContent, err := manager.runGradleDepTree()
assert.NoError(t, err)
depTree, uniqueDeps, err := getGraphFromDepTree(outputFileContent)
assert.NoError(t, err)
assert.ElementsMatch(t, uniqueDeps, testCase.expectedUniqueDeps, "First is actual, Second is Expected")
reflect.DeepEqual(uniqueDeps, testCase.expectedUniqueDeps)

for _, dependency := range depTree {
depChild, exists := testCase.expectedTree[dependency.Id]
omerzi marked this conversation as resolved.
Show resolved Hide resolved
omerzi marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
Binary file modified xray/commands/audit/sca/java/gradle-dep-tree.jar
Binary file not shown.
Loading
Loading