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

Add Git Repository Url as Xray Scan Graph param #1039

Open
wants to merge 35 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
ad691bd
Add Git Repository Url as Xray Scan Graph param
attiasas Nov 7, 2024
39bfb72
Merge remote-tracking branch 'upstream/dev' into add_repo_context_sca…
attiasas Nov 10, 2024
2a9fae2
add the new query param
attiasas Nov 10, 2024
5676279
add comment
attiasas Nov 10, 2024
91b62c2
add tests
attiasas Nov 10, 2024
d770235
update GitContextValues
attiasas Nov 10, 2024
49f91b6
change to IsDirty for backward compatibility
attiasas Nov 11, 2024
99a8fa8
Merge remote-tracking branch 'upstream/dev' into add_repo_context_sca…
attiasas Nov 24, 2024
d8a3c65
Use XscGitInfoContext.GitRepoUrl instead of new field
attiasas Nov 24, 2024
ee866b4
Use new attribute
attiasas Nov 24, 2024
3e824ce
with tests, remove redundent
attiasas Nov 24, 2024
8c59138
fix tests
attiasas Nov 24, 2024
7a1efc4
remove is dirty
attiasas Nov 24, 2024
874db13
Merge remote-tracking branch 'upstream/dev' into add_repo_context_sca…
attiasas Nov 24, 2024
ce7936c
merge fix
attiasas Nov 24, 2024
a8b7f3d
fix tests
attiasas Nov 24, 2024
d384d38
CR changes
attiasas Nov 25, 2024
a7f4654
CR changes
attiasas Nov 25, 2024
c243bb1
change version
attiasas Nov 25, 2024
a53eeb4
Merge remote-tracking branch 'upstream/dev' into add_repo_context_sca…
attiasas Nov 28, 2024
4f2b45e
remove ssh test cases
attiasas Dec 1, 2024
e64699e
Merge remote-tracking branch 'upstream/dev' into add_repo_context_sca…
attiasas Dec 1, 2024
ef70745
Add Ignore rule git attribute, fix categories
attiasas Dec 2, 2024
23f6250
Merge remote-tracking branch 'upstream/dev' into add_repo_context_sca…
attiasas Dec 2, 2024
ba0c6c7
Parse policy Field from scan response
attiasas Dec 2, 2024
2a7081e
remove old input to the right place, simplify git url input
attiasas Dec 13, 2024
a1c11b2
use diff min version for git repo url
attiasas Dec 13, 2024
04afcbf
Merge remote-tracking branch 'upstream/dev' into add_repo_context_sca…
attiasas Dec 15, 2024
c2d37b1
fix tests
attiasas Dec 15, 2024
26f6d53
add sast ignore params
attiasas Dec 15, 2024
3a7eca3
add policy criteria for expo and sast
attiasas Dec 15, 2024
efd7feb
tidy
attiasas Dec 15, 2024
e1f513b
improve xcreate policy rule
attiasas Dec 15, 2024
1cce319
create sast criteria
attiasas Dec 15, 2024
edc3f6f
fix ignore rule api
attiasas Dec 16, 2024
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
18 changes: 10 additions & 8 deletions artifactory/services/utils/tests/xray/consts.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package xray

import xrayServices "github.com/jfrog/jfrog-client-go/xray/services"
import (
xscServices "github.com/jfrog/jfrog-client-go/xsc/services"
)

const ScanResponse = `
{
Expand Down Expand Up @@ -1437,15 +1439,15 @@ const XscGitInfoResponse = `{"multi_scan_id": "3472b4e2-bddc-11ee-a9c9-acde48001

const XscGitInfoBadResponse = `"failed create git info request: git_repo_url field must contain value"`

var GitInfoContextWithMinimalRequiredFields = xrayServices.XscGitInfoContext{
GitRepoUrl: "https://git.jfrog.info/projects/XSC/repos/xsc-service",
BranchName: "feature/XRAY-123-cool-feature",
CommitHash: "acc5e24e69a-d3c1-4022-62eb-69e4a1e5",
var GitInfoContextWithMinimalRequiredFields = xscServices.XscGitInfoContext{
GitRepoHttpsCloneUrl: "https://git.jfrog.info/projects/XSC/repos/xsc-service",
BranchName: "feature/XRAY-123-cool-feature",
LastCommitHash: "acc5e24e69a-d3c1-4022-62eb-69e4a1e5",
}

var GitInfoContextWithMissingFields = xrayServices.XscGitInfoContext{
GitRepoUrl: "https://git.jfrog.info/projects/XSC/repos/xsc-service",
BranchName: "feature/XRAY-123-cool-feature",
var GitInfoContextWithMissingFields = xscServices.XscGitInfoContext{
GitRepoHttpsCloneUrl: "https://git.jfrog.info/projects/XSC/repos/xsc-service",
BranchName: "feature/XRAY-123-cool-feature",
}

const TestMultiScanId = "3472b4e2-bddc-11ee-a9c9-acde48001122"
Expand Down
9 changes: 1 addition & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMx
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo=
Expand All @@ -144,19 +142,14 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o=
golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q=
Expand Down
7 changes: 3 additions & 4 deletions xray/services/enrich.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ func (es *EnrichService) GetImportGraphResults(scanId string) (*ScanResponse, er
type XrayGraphImportParams struct {
// A path in Artifactory that this Artifact is intended to be deployed to.
// This will provide a way to extract the watches that should be applied on this graph
ScanType ScanType
SBOMInput []byte
XscGitInfoContext *XscGitInfoContext
XscVersion string
ScanType ScanType
SBOMInput []byte
XscVersion string
}
2 changes: 1 addition & 1 deletion xray/services/ignorerule.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (xirs *IgnoreRuleService) Delete(ignoreRuleId string) error {
}

// Create will create a new Xray ignore rule
// The function creates the ignore rule and returns its id which is recieved after post
// The function creates the ignore rule and returns its id which is received after post
func (xirs *IgnoreRuleService) Create(params utils.IgnoreRuleParams) (ignoreRuleId string, err error) {
ignoreRuleBody := utils.CreateIgnoreRuleBody(params)
content, err := json.Marshal(ignoreRuleBody)
Expand Down
59 changes: 28 additions & 31 deletions xray/services/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import (
"strings"
"time"

clientUtils "github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/log"
xrayUtils "github.com/jfrog/jfrog-client-go/xray/services/utils"
"github.com/jfrog/jfrog-client-go/xsc/services/utils"
xscUtils "github.com/jfrog/jfrog-client-go/xsc/services/utils"

"github.com/jfrog/jfrog-client-go/auth"
"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"
Expand Down Expand Up @@ -46,6 +47,9 @@ const (

scanTechQueryParam = "tech="

gitRepoKeyQueryParam = "git_repo="
MinXrayVersionGitRepoKey = "3.108.0"

XscVersionAPI = "system/version"
)

Expand Down Expand Up @@ -75,28 +79,33 @@ func createScanGraphQueryParams(scanParams XrayGraphScanParams) string {
}
}
}

// Xsc params are used only when XSC is enabled and MultiScanId is provided
if scanParams.XscVersion != "" && scanParams.MultiScanId != "" {
params = append(params, multiScanIdParam+scanParams.MultiScanId)
gitInfoContext := scanParams.XscGitInfoContext
if gitInfoContext != nil {
if len(gitInfoContext.Technologies) > 0 {
// Append the tech type, each graph can contain only one tech type
params = append(params, scanTechQueryParam+gitInfoContext.Technologies[0])
}
if scanParams.Technology != "" {
params = append(params, scanTechQueryParam+scanParams.Technology)
}
}

if scanParams.ScanType != "" {
params = append(params, scanTypeQueryParam+string(scanParams.ScanType))
}

if isGitRepoUrlSupported(scanParams.XrayVersion) && scanParams.GitRepoHttpsCloneUrl != "" {
// Add git repo key to the query params to produce violations defined in the git repo policy
params = append(params, gitRepoKeyQueryParam+xscUtils.GetGitRepoUrlKey(scanParams.GitRepoHttpsCloneUrl))
}

if len(params) == 0 {
return ""
}
return "?" + strings.Join(params, "&")
}

func isGitRepoUrlSupported(xrayVersion string) bool {
return clientUtils.ValidateMinimumVersion(clientUtils.Xray, xrayVersion, MinXrayVersionGitRepoKey) == nil
}

func (ss *ScanService) ScanGraph(scanParams XrayGraphScanParams) (string, error) {
httpClientsDetails := ss.XrayDetails.CreateHttpClientDetails()
httpClientsDetails.SetContentTypeApplicationJson()
Expand All @@ -114,7 +123,7 @@ func (ss *ScanService) ScanGraph(scanParams XrayGraphScanParams) (string, error)

// When XSC is enabled and MultiScanId is provided, modify the URL to use XSC scan graph (analytics enabled)
if scanParams.XrayVersion != "" && scanParams.XscVersion != "" && scanParams.MultiScanId != "" {
url = utils.XrayUrlToXscUrl(ss.XrayDetails.GetUrl(), scanParams.XrayVersion) + XscGraphAPI
url = xscUtils.XrayUrlToXscUrl(ss.XrayDetails.GetUrl(), scanParams.XrayVersion) + XscGraphAPI
}
url += createScanGraphQueryParams(scanParams)
resp, body, err := ss.client.SendPost(url, requestBody, &httpClientsDetails)
Expand Down Expand Up @@ -144,7 +153,7 @@ func (ss *ScanService) GetScanGraphResults(scanId, xrayVersion string, includeVu
endPoint := ss.XrayDetails.GetUrl() + scanGraphAPI
// Modify endpoint if XSC is enabled
if xscEnabled {
endPoint = utils.XrayUrlToXscUrl(ss.XrayDetails.GetUrl(), xrayVersion) + XscGraphAPI
endPoint = xscUtils.XrayUrlToXscUrl(ss.XrayDetails.GetUrl(), xrayVersion) + XscGraphAPI
}
endPoint += "/" + scanId

Expand Down Expand Up @@ -183,7 +192,10 @@ func (ss *ScanService) GetScanGraphResults(scanId, xrayVersion string, includeVu
type XrayGraphScanParams struct {
// A path in Artifactory that this Artifact is intended to be deployed to.
// This will provide a way to extract the watches that should be applied on this graph
RepoPath string
RepoPath string
// This will provide a way to extract the watches that should be applied on this graph
GitRepoHttpsCloneUrl string
// This will provide a way to extract the watches that should be applied on this graph
ProjectKey string
Watches []string
ScanType ScanType
Expand All @@ -193,9 +205,9 @@ type XrayGraphScanParams struct {
BinaryGraph *xrayUtils.BinaryGraphNode
IncludeVulnerabilities bool
IncludeLicenses bool
XscGitInfoContext *XscGitInfoContext
XscVersion string
XrayVersion string
Technology string
MultiScanId string
}

Expand Down Expand Up @@ -231,6 +243,7 @@ type Violation struct {
LicenseKey string `json:"license_key,omitempty"`
LicenseName string `json:"license_name,omitempty"`
IgnoreUrl string `json:"ignore_url,omitempty"`
Policies []Policy `json:"policies,omitempty"`
RiskReason string `json:"risk_reason,omitempty"`
IsEol *bool `json:"is_eol,omitempty"`
EolMessage string `json:"eol_message,omitempty"`
Expand Down Expand Up @@ -308,25 +321,9 @@ type JfrogResearchSeverityReason struct {
IsPositive bool `json:"is_positive,omitempty"`
}

type XscPostContextResponse struct {
MultiScanId string `json:"multi_scan_id,omitempty"`
}

type XscVersionResponse struct {
Version string `json:"xsc_version"`
}

type XscGitInfoContext struct {
GitRepoUrl string `json:"git_repo_url"`
GitRepoName string `json:"git_repo_name,omitempty"`
GitProject string `json:"git_project,omitempty"`
GitProvider string `json:"git_provider,omitempty"`
Technologies []string `json:"technologies,omitempty"`
BranchName string `json:"branch_name"`
LastCommit string `json:"last_commit,omitempty"`
CommitHash string `json:"commit_hash"`
CommitMessage string `json:"commit_message,omitempty"`
CommitAuthor string `json:"commit_author,omitempty"`
type Policy struct {
Policy string `json:"policy,omitempty"`
Rule string `json:"rule,omitempty"`
}

func (gp *XrayGraphScanParams) GetProjectKey() string {
Expand Down
65 changes: 37 additions & 28 deletions xray/services/scan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,48 @@ import (
func TestCreateScanGraphQueryParams(t *testing.T) {
tests := []struct {
testName string
projectKey string
repoPath string
watches []string
scanType ScanType
params XrayGraphScanParams
expectedQuery string
}{
{"with_project_key", "p1", "", nil, Binary,
fmt.Sprintf("?%s%s&%s%s", projectQueryParam, "p1", scanTypeQueryParam, Binary)},

{"with_repo_path", "", "r1", nil, Binary,
fmt.Sprintf("?%s%s&%s%s", repoPathQueryParam, "r1", scanTypeQueryParam, Binary)},

{"with_watches", "", "", []string{"w1", "w2"}, Binary,
fmt.Sprintf("?%s%s&%s%s&%s%s", watchesQueryParam, "w1", watchesQueryParam, "w2", scanTypeQueryParam, Binary)},

{"with_empty_watch_string", "", "", []string{""}, "",
""},

{"without_context", "", "", nil, Dependency,
fmt.Sprintf("?%s%s", scanTypeQueryParam, Dependency)},

{"without_scan_type", "", "", []string{"w1", "w2"}, "",
fmt.Sprintf("?%s%s&%s%s", watchesQueryParam, "w1", watchesQueryParam, "w2")},
{
testName: "with_project_key",
params: XrayGraphScanParams{ProjectKey: "p1", ScanType: Binary},
expectedQuery: fmt.Sprintf("?%s%s&%s%s", projectQueryParam, "p1", scanTypeQueryParam, Binary),
},
{
testName: "with_repo_path",
params: XrayGraphScanParams{RepoPath: "r1", ScanType: Binary},
expectedQuery: fmt.Sprintf("?%s%s&%s%s", repoPathQueryParam, "r1", scanTypeQueryParam, Binary),
},
{
testName: "with_watches",
params: XrayGraphScanParams{Watches: []string{"w1", "w2"}, ScanType: Binary},
expectedQuery: fmt.Sprintf("?%s%s&%s%s&%s%s", watchesQueryParam, "w1", watchesQueryParam, "w2", scanTypeQueryParam, Binary),
},
{
testName: "with_empty_watch_string",
params: XrayGraphScanParams{Watches: []string{""}},
expectedQuery: "",
},
{
testName: "without_context",
params: XrayGraphScanParams{ScanType: Dependency, XrayVersion: MinXrayVersionGitRepoKey},
expectedQuery: fmt.Sprintf("?%s%s", scanTypeQueryParam, Dependency),
},
{
testName: "without_scan_type",
params: XrayGraphScanParams{Watches: []string{"w1", "w2"}},
expectedQuery: fmt.Sprintf("?%s%s&%s%s", watchesQueryParam, "w1", watchesQueryParam, "w2"),
},
{
testName: "with_git_repo_url",
params: XrayGraphScanParams{GitRepoHttpsCloneUrl: "http://some-url", ScanType: Dependency, XrayVersion: MinXrayVersionGitRepoKey},
expectedQuery: fmt.Sprintf("?%s%s&%s%s", scanTypeQueryParam, Dependency, gitRepoKeyQueryParam, "some-url.git"),
},
}
for _, test := range tests {
t.Run(test.testName, func(t *testing.T) {
params := XrayGraphScanParams{
RepoPath: test.repoPath,
Watches: test.watches,
ProjectKey: test.projectKey,
ScanType: test.scanType,
}
actualQuery := createScanGraphQueryParams(params)
actualQuery := createScanGraphQueryParams(test.params)
if actualQuery != test.expectedQuery {
t.Error(test.testName, "Expecting:", test.expectedQuery, "Got:", actualQuery)
}
Expand Down
23 changes: 19 additions & 4 deletions xray/services/utils/ignorerulebody.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ package utils

import "time"

const (
SecretExposureType ExposureType = "secret"
IacExposureType ExposureType = "iac"
)

type ExposureType string

type IgnoreRuleParams struct {
Notes string `json:"notes"`
ExpiresAt time.Time `json:"expires_at,omitempty"`
Expand All @@ -20,17 +27,25 @@ type IgnoreFilters struct {
Vulnerabilities []string `json:"vulnerabilities,omitempty"`
Licenses []string `json:"licenses,omitempty"`
CVEs []string `json:"cves,omitempty"`
GitRepositories []string `json:"git_repositories,omitempty"`
Policies []string `json:"policies,omitempty"`
Watches []string `json:"watches,omitempty"`
DockerLayers []string `json:"docker-layers,omitempty"`
OperationalRisks []string `json:"operational_risk,omitempty"`
Exposures []ExposuresFilterName `json:"exposures,omitempty"`
Sast []SastFilterName `json:"sast,omitempty"`
ReleaseBundles []IgnoreFilterNameVersion `json:"release-bundles,omitempty"`
Builds []IgnoreFilterNameVersion `json:"builds,omitempty"`
Components []IgnoreFilterNameVersion `json:"components,omitempty"`
Artifacts []IgnoreFilterNameVersionPath `json:"artifacts,omitempty"`
}

type SastFilterName struct {
Fingerprint []string `json:"fingerprint,omitempty"`
Rule []string `json:"rule,omitempty"`
FilePath []string `json:"file_path,omitempty"`
}

type IgnoreFilterNameVersion struct {
Name string `json:"name"`
Version string `json:"version,omitempty"`
Expand All @@ -42,12 +57,12 @@ type IgnoreFilterNameVersionPath struct {
}

type ExposuresFilterName struct {
Catagories []ExposuresCatagories `json:"catagories,omitempty"`
Scanners []string `json:"scanners,omitempty"`
FilePath []string `json:"file_path,omitempty"`
Categories []ExposureType `json:"categories,omitempty"`
Scanners []string `json:"scanners,omitempty"`
FilePath []string `json:"file_path,omitempty"`
}

type ExposuresCatagories struct {
type ExposuresCategories struct {
Secrets bool `json:"secrets,omitempty"`
Services bool `json:"services,omitempty"`
Applications bool `json:"applications,omitempty"`
Expand Down
Loading
Loading