Skip to content
Open
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
2 changes: 1 addition & 1 deletion buildscripts/download-jars.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# 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.1.0"
GRADLE_DEP_TREE_VERSION="3.2.0"
# Changing this version also requires a change in mavenDepTreeVersion within utils/java/mvn.go.
MAVEN_DEP_TREE_VERSION="1.1.5"

Expand Down
29 changes: 18 additions & 11 deletions cli/docs/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/jfrog/jfrog-cli-core/v2/common/cliutils"
pluginsCommon "github.com/jfrog/jfrog-cli-core/v2/plugins/common"
"github.com/jfrog/jfrog-cli-core/v2/plugins/components"

"github.com/jfrog/jfrog-cli-security/commands/git/contributors"
"github.com/jfrog/jfrog-cli-security/commands/xray/offlineupdate"
"github.com/jfrog/jfrog-cli-security/utils"
Expand Down Expand Up @@ -84,15 +85,16 @@ const (
InsecureTls = "insecure-tls"

// Generic command flags
SpecFlag = "spec"
Threads = "threads"
Recursive = "recursive"
RegexpFlag = "regexp"
AntFlag = "ant"
Project = "project"
Exclusions = "exclusions"
IncludeDirs = "include-dirs"
UseWrapper = "use-wrapper"
SpecFlag = "spec"
Threads = "threads"
Recursive = "recursive"
RegexpFlag = "regexp"
AntFlag = "ant"
Project = "project"
Exclusions = "exclusions"
IncludeDirs = "include-dirs"
UseWrapper = "use-wrapper"
UseIncludedBuilds = "use-included-builds"
)

const (
Expand Down Expand Up @@ -193,7 +195,7 @@ var commandFlags = map[string][]string{
useWrapperAudit, DepType, RequirementsFile, Fail, ExtendedTable, WorkingDirs, ExclusionsAudit, Mvn, Gradle, Npm,
Pnpm, Yarn, Go, Swift, Cocoapods, Nuget, Pip, Pipenv, Poetry, MinSeverity, FixableOnly, ThirdPartyContextualAnalysis, Threads,
auditSca, auditIac, auditSast, auditSecrets, auditWithoutCA, SecretValidation, ScanVuln, OutputDir, SkipAutoInstall, AllowPartialResults, MaxTreeDepth,
StaticSca, XrayLibPluginBinaryCustomPath, AnalyzerManagerCustomPath, UploadRtRepoPath,
StaticSca, XrayLibPluginBinaryCustomPath, AnalyzerManagerCustomPath, UploadRtRepoPath, UseIncludedBuilds,
},
UploadCdx: {
UploadRepoPath, uploadProjectKey,
Expand All @@ -212,7 +214,7 @@ var commandFlags = map[string][]string{
StaticSca, XrayLibPluginBinaryCustomPath, AnalyzerManagerCustomPath, AddSastRules,
},
CurationAudit: {
CurationOutput, WorkingDirs, Threads, RequirementsFile, InsecureTls, useWrapperAudit, SolutionPath, DockerImageName,
CurationOutput, WorkingDirs, Threads, RequirementsFile, InsecureTls, useWrapperAudit, UseIncludedBuilds, SolutionPath, DockerImageName,
},
GitCountContributors: {
InputFile, ScmType, ScmApiUrl, Token, Owner, RepoName, Months, DetailedSummary, InsecureTls,
Expand Down Expand Up @@ -289,6 +291,11 @@ var flagsMap = map[string]components.Flag{
"[Gradle, Maven] Set to true if you'd like to use the Gradle or Maven wrapper.",
components.WithBoolDefaultValue(true),
),
UseIncludedBuilds: components.NewBoolFlag(
UseIncludedBuilds,
"[Gradle] Set to true if you'd like to take into account included builds (composite builds) of gradle projects, in addition to including subprojects",
components.WithBoolDefaultValue(false),
),
WorkingDirs: components.NewStringFlag(WorkingDirs, "A comma-separated(,) list of relative working directories, to determine the audit targets locations. If flag isn't provided, a recursive scan is triggered from the root directory of the project."),
OutputDir: components.NewStringFlag(OutputDir, "Target directory to save partial results to.", components.SetHiddenStrFlag()),
UploadRepoPath: components.NewStringFlag(UploadRepoPath, "Artifactory repository name or path to upload the cyclonedx file to. If no name or path are provided, a local generic repository will be created which will automatically be indexed by Xray.", components.WithStrDefaultValue("import-cdx-scan-results")),
Expand Down
12 changes: 8 additions & 4 deletions cli/scancommands.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/jfrog/jfrog-cli-core/v2/plugins/components"
coreConfig "github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"

flags "github.com/jfrog/jfrog-cli-security/cli/docs"
auditSpecificDocs "github.com/jfrog/jfrog-cli-security/cli/docs/auditspecific"
enrichDocs "github.com/jfrog/jfrog-cli-security/cli/docs/enrich"
Expand All @@ -31,13 +32,14 @@ import (
uploadCdxDocs "github.com/jfrog/jfrog-cli-security/cli/docs/upload"
"github.com/jfrog/jfrog-cli-security/utils"

"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
"github.com/jfrog/jfrog-client-go/utils/log"
"github.com/urfave/cli"

"github.com/jfrog/jfrog-cli-security/commands/enrich"
"github.com/jfrog/jfrog-cli-security/commands/source_mcp"
"github.com/jfrog/jfrog-cli-security/sca/bom/indexer"
"github.com/jfrog/jfrog-cli-security/utils/xray"
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
"github.com/jfrog/jfrog-client-go/utils/log"
"github.com/urfave/cli"

"github.com/jfrog/jfrog-cli-security/commands/audit"
"github.com/jfrog/jfrog-cli-security/commands/curation"
Expand Down Expand Up @@ -554,7 +556,8 @@ func CreateAuditCmd(c *components.Context) (string, string, *coreConfig.ServerDe
SetNpmScope(c.GetStringFlagValue(flags.DepType)).
SetPipRequirementsFile(c.GetStringFlagValue(flags.RequirementsFile)).
SetMaxTreeDepth(c.GetStringFlagValue(flags.MaxTreeDepth)).
SetExclusions(pluginsCommon.GetStringsArrFlagValue(c, flags.Exclusions))
SetExclusions(pluginsCommon.GetStringsArrFlagValue(c, flags.Exclusions)).
SetUseIncludedBuilds(c.GetBoolFlagValue(flags.UseIncludedBuilds))
return xrayVersion, xscVersion, serverDetails, auditCmd, err
}

Expand Down Expand Up @@ -692,6 +695,7 @@ func getCurationCommand(c *components.Context) (*curation.CurationAuditCommand,
SetExcludeTestDependencies(c.GetBoolFlagValue(flags.ExcludeTestDeps)).
SetOutputFormat(format).
SetUseWrapper(c.GetBoolFlagValue(flags.UseWrapper)).
SetUseIncludedBuilds(c.GetBoolFlagValue(flags.UseIncludedBuilds)).
SetInsecureTls(c.GetBoolFlagValue(flags.InsecureTls)).
SetNpmScope(c.GetStringFlagValue(flags.DepType)).
SetPipRequirementsFile(c.GetStringFlagValue(flags.RequirementsFile)).
Expand Down
8 changes: 8 additions & 0 deletions commands/audit/auditbasicparams.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ type AuditBasicParams struct {
xscVersion string
configProfile *xscservices.ConfigProfile
solutionFilePath string
useIncludedBuilds bool
}

func (abp *AuditBasicParams) DirectDependencies() *[]string {
Expand Down Expand Up @@ -342,3 +343,10 @@ func (abp *AuditBasicParams) SetSolutionFilePath(solutionFilePath string) *Audit
abp.solutionFilePath = solutionFilePath
return abp
}

func (abp *AuditBasicParams) UseIncludedBuilds() bool { return abp.useIncludedBuilds }

func (abp *AuditBasicParams) SetUseIncludedBuilds(useIncludedBuilds bool) *AuditBasicParams {
abp.useIncludedBuilds = useIncludedBuilds
return abp
}
3 changes: 2 additions & 1 deletion commands/audit/auditparams.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ func (params *AuditParams) ToBuildInfoBomGenParams() (bomParams technologies.Bui
// Python params
PipRequirementsFile: params.PipRequirementsFile(),
// Pnpm params
MaxTreeDepth: params.MaxTreeDepth(),
MaxTreeDepth: params.MaxTreeDepth(),
UseIncludedBuilds: params.UseIncludedBuilds(),
}
return
}
Expand Down
1 change: 1 addition & 0 deletions sca/bom/buildinfo/buildinfobom.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ func GetTechDependencyTree(params technologies.BuildInfoBomGeneratorParams, arti
UseWrapper: params.UseWrapper,
IsCurationCmd: params.IsCurationCmd,
CurationCacheFolder: curationCacheFolder,
UseIncludedBuilds: params.UseIncludedBuilds,
}, tech)
case techutils.Npm:
depTreeResult.FullDepTrees, uniqueDepsIds, err = npm.BuildDependencyTree(params)
Expand Down
10 changes: 6 additions & 4 deletions sca/bom/buildinfo/technologies/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@ import (
buildInfoUtils "github.com/jfrog/build-info-go/utils"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/utils/tests"
"github.com/jfrog/jfrog-cli-security/utils"
"github.com/jfrog/jfrog-cli-security/utils/techutils"
"github.com/jfrog/jfrog-cli-security/utils/xray"
"github.com/jfrog/jfrog-cli-security/utils/xray/scangraph"
"github.com/jfrog/jfrog-client-go/artifactory/services/fspatterns"
clientutils "github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
ioUtils "github.com/jfrog/jfrog-client-go/utils/io"
"github.com/jfrog/jfrog-client-go/utils/log"
"github.com/jfrog/jfrog-client-go/xray/services"
xscservices "github.com/jfrog/jfrog-client-go/xsc/services"

"github.com/jfrog/jfrog-cli-security/utils"
"github.com/jfrog/jfrog-cli-security/utils/techutils"
"github.com/jfrog/jfrog-cli-security/utils/xray"
"github.com/jfrog/jfrog-cli-security/utils/xray/scangraph"
)

const (
Expand Down Expand Up @@ -51,6 +52,7 @@ type BuildInfoBomGeneratorParams struct {
// Java params
IsMavenDepTreeInstalled bool
UseWrapper bool
UseIncludedBuilds bool
// Python params
PipRequirementsFile string
// Npm params
Expand Down
19 changes: 12 additions & 7 deletions sca/bom/buildinfo/technologies/java/deptreemanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,18 @@ type DepTreeParams struct {
IsMavenDepTreeInstalled bool
IsCurationCmd bool
CurationCacheFolder string
UseIncludedBuilds bool
}

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

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

// 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.
Expand Down Expand Up @@ -78,10 +80,13 @@ func GetModuleTreeAndDependencies(module *moduleDepTree) (*xrayUtils.GraphNode,
childId := GavPackageTypeIdentifier + childName
childrenList = append(childrenList, childId)
}

moduleTreeMap[dependencyId] = xray.DepTreeNode{
Classifier: dependency.Classifier,
Types: dependency.Types,
Children: childrenList,
Classifier: dependency.Classifier,
Types: dependency.Types,
Children: childrenList,
Unresolved: dependency.Unresolved,
Configurations: dependency.Configurations,
}
}
return xray.BuildXrayDependencyTree(moduleTreeMap, GavPackageTypeIdentifier+module.Root)
Expand Down
3 changes: 2 additions & 1 deletion sca/bom/buildinfo/technologies/java/gradle.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ func (gdt *gradleDepTreeManager) execGradleDepTree(depTreeDir string) (outputFil
"-q",
gradleNoCacheFlag,
fmt.Sprintf("-Dcom.jfrog.depsTreeOutputFile=%s", outputFilePath),
"-Dcom.jfrog.includeAllBuildFiles=true"}
"-Dcom.jfrog.includeAllBuildFiles=true",
fmt.Sprintf("-Dcom.jfrog.includeIncludedBuilds=%t", gdt.useIncludedBuilds)}
Comment on lines +166 to +167
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no issue using both flags, right?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean 'includeAllBuildFiles' and 'includeIncludedBuilds' ? They're not exactly related, 'includeAllBuildFiles' was already present before my change. It's used for for the gradle subprojects not for gradle included builds


// Add curation audit mode for pass-through functionality if this is a curation command
if gdt.isCurationCmd {
Expand Down
25 changes: 25 additions & 0 deletions sca/bom/buildinfo/technologies/java/gradle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
"github.com/jfrog/jfrog-cli-core/v2/utils/ioutils"
"github.com/jfrog/jfrog-cli-core/v2/utils/tests"

"github.com/jfrog/jfrog-cli-security/sca/bom/buildinfo/technologies"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -91,6 +92,30 @@ func TestGradleTreesWithConfig(t *testing.T) {
}
}

func TestGradleTreesWithConfig_UsingIncludedBuilds(t *testing.T) {
// Create and change directory to test workspace
tempDirPath, cleanUp := technologies.CreateTestWorkspace(t, filepath.Join("projects", "package-managers", "gradle", "gradle-example-included-builds"))
defer cleanUp()
assert.NoError(t, os.Chmod(filepath.Join(tempDirPath, "gradlew"), 0700))

// Run getModulesDependencyTrees
modulesDependencyTrees, uniqueDeps, err := buildGradleDependencyTree(&DepTreeParams{UseWrapper: true, UseIncludedBuilds: true})
if assert.NoError(t, err) && assert.NotNil(t, modulesDependencyTrees) {
assert.Len(t, modulesDependencyTrees, 4)
assert.Len(t, uniqueDeps, 10)
// Check module
module := tests.GetAndAssertNode(t, modulesDependencyTrees, "org.jfrog.test.gradle.publish:api:1.0-SNAPSHOT")
assert.Len(t, module.Nodes, 4)

// Check direct dependency
directDependency := tests.GetAndAssertNode(t, module.Nodes, "commons-lang:commons-lang:2.4")
assert.Len(t, directDependency.Nodes, 1)

// Check transitive dependency
tests.GetAndAssertNode(t, directDependency.Nodes, "commons-io:commons-io:1.2")
}
}

func TestIsGradleWrapperExist(t *testing.T) {
// Check Gradle wrapper doesn't exist
isWrapperExist, err := isGradleWrapperExist()
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version: 1
type: gradle
usePlugin: true
useWrapper: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
configurations {
spi
}

buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath(group: 'org.jfrog.buildinfo', name: 'build-info-extractor-gradle', version: '4+')
}
configurations.classpath {
resolutionStrategy {
cacheDynamicVersionsFor 0, 'seconds'
cacheChangingModulesFor 0, 'seconds'
}
}
}

apply plugin: 'com.jfrog.artifactory'
group = 'org.jfrog.test.gradle.publish'
version = currentVersion
status = 'Integration'
repositories {
mavenCentral()
}

apply plugin: 'java'
apply plugin: 'maven-publish'

dependencies {
testImplementation 'junit:junit:4.7'
}

publishing {
publications {
mavenJava(MavenPublication) {
from components.java
artifact(file("$rootDir/gradle.properties"))
}
}
}

apply plugin: 'ivy-publish'

publishing {
publications {
ivyJava(IvyPublication) {
from components.java
artifact(file("$rootDir/settings.gradle")) {
name "gradle-settings"
extension "txt"
type "text"
}
// The config below will add a extra attribute to the ivy.xml
// See http://ant.apache.org/ivy/history/latest-milestone/concept.html#extra
descriptor.withXml {
asNode().info[0].attributes().put('e:architecture', 'amd64')
}
}
}
}

artifactoryPublish {
publications(publishing.publications.ivyJava)
properties {
simpleFile '**:**:**:*@*', simpleFile: 'only on settings file'
}
}

dependencies {
implementation project(':shared')
implementation module("commons-lang:commons-lang:2.4") {
dependency("commons-io:commons-io:1.2")
}
implementation group: 'org.apache.wicket', name: 'wicket', version: '1.3.7'

}

// Just a smoke test that using this option does not lead to any exception
compileJava.options.compilerArgs = ['-Xlint:unchecked']
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
currentVersion=1.0-SNAPSHOT
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
rootProject.name = 'api'
//include 'proj'

include ':shared'
project(':shared').projectDir=file("$rootDir/../shared")
Loading