Skip to content

Commit b4a5421

Browse files
committed
Merge remote-tracking branch 'upstream/dev'
2 parents 8eb9b69 + 3d062a1 commit b4a5421

File tree

13 files changed

+132
-56
lines changed

13 files changed

+132
-56
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,6 +1918,11 @@ serviceConfig, err := config.NewConfigBuilder().
19181918
xrayManager, err := xray.New(serviceConfig)
19191919
```
19201920

1921+
If the provided token is scoped for a `project` you need to set its value in the manager for authentications in relevant API's
1922+
```go
1923+
xrayManager, err := xray.New(serviceConfig).SetProjectKey("project")
1924+
```
1925+
19211926
### Using Xray Services
19221927

19231928
#### Fetching Xray's Version

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ require (
1010
github.com/golang-jwt/jwt/v4 v4.5.2
1111
github.com/gookit/color v1.5.4
1212
github.com/jfrog/archiver/v3 v3.6.1
13-
github.com/jfrog/build-info-go v1.10.11
13+
github.com/jfrog/build-info-go v1.10.12
1414
github.com/jfrog/gofrog v1.7.6
1515
github.com/minio/sha256-simd v1.0.1
1616
github.com/stretchr/testify v1.10.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl
5757
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
5858
github.com/jfrog/archiver/v3 v3.6.1 h1:LOxnkw9pOn45DzCbZNFV6K0+6dCsQ0L8mR3ZcujO5eI=
5959
github.com/jfrog/archiver/v3 v3.6.1/go.mod h1:VgR+3WZS4N+i9FaDwLZbq+jeU4B4zctXL+gL4EMzfLw=
60-
github.com/jfrog/build-info-go v1.10.11 h1:wAMGCAHa49+ec01HqzSidLAHNIub+glh4ksFp3pYy7o=
61-
github.com/jfrog/build-info-go v1.10.11/go.mod h1:JcISnovFXKx3wWf3p1fcMmlPdt6adxScXvoJN4WXqIE=
60+
github.com/jfrog/build-info-go v1.10.12 h1:KO/YUeKYtDrnpcmsXmwqr6akjzrwA0hSTUB+Op/HF88=
61+
github.com/jfrog/build-info-go v1.10.12/go.mod h1:JcISnovFXKx3wWf3p1fcMmlPdt6adxScXvoJN4WXqIE=
6262
github.com/jfrog/gofrog v1.7.6 h1:QmfAiRzVyaI7JYGsB7cxfAJePAZTzFz0gRWZSE27c6s=
6363
github.com/jfrog/gofrog v1.7.6/go.mod h1:ntr1txqNOZtHplmaNd7rS4f8jpA5Apx8em70oYEe7+4=
6464
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=

utils/utils.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828
const (
2929
Development = "development"
3030
Agent = "jfrog-client-go"
31-
Version = "1.53.0"
31+
Version = "1.53.1"
3232
)
3333

3434
const xrayDevVersion = "3.x-dev"
@@ -622,3 +622,29 @@ func SetEnvWithResetCallback(key, value string) (func() error, error) {
622622
return errorutils.CheckError(os.Unsetenv(key))
623623
}, nil
624624
}
625+
626+
const (
627+
// If the access token used for the client is project-scoped, the API call needs to contain the project key as query param to pass to the Server.
628+
ProjectKeyQueryParam = "projectKey="
629+
)
630+
631+
// To access some of the API calls in Xray, we need to add the project key as a query parameter (used for validations if the token is project-scoped).
632+
func AppendScopedProjectKeyParam(url, projectKey string) string {
633+
// make sure the project key is not empty and not already in the URL
634+
if projectKey == "" || urlContainsProjectKeyParam(url) {
635+
return url
636+
}
637+
if strings.Contains(url, "?") {
638+
// the URL already contains query parameters, append the project key with an '&'
639+
url += "&" + ProjectKeyQueryParam + projectKey
640+
} else {
641+
// the URL does not contain any query parameters, add the project key with a '?'
642+
url += "?" + ProjectKeyQueryParam + projectKey
643+
}
644+
return url
645+
}
646+
647+
func urlContainsProjectKeyParam(url string) bool {
648+
// check if the URL already contains the project key query parameter
649+
return len(url) > 0 && strings.Contains(url, ProjectKeyQueryParam)
650+
}

xray/manager.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
type XrayServicesManager struct {
1313
client *jfroghttpclient.JfrogHttpClient
1414
config config.Config
15+
// Global reference to the provided project key, used for API endpoints that require it for authentication
16+
scopeProjectKey string
1517
}
1618

1719
// New creates a service manager to interact with Xray
@@ -34,6 +36,11 @@ func New(config config.Config) (*XrayServicesManager, error) {
3436
return manager, err
3537
}
3638

39+
func (sm *XrayServicesManager) SetProjectKey(projectKey string) *XrayServicesManager {
40+
sm.scopeProjectKey = projectKey
41+
return sm
42+
}
43+
3744
// Client will return the http client
3845
func (sm *XrayServicesManager) Client() *jfroghttpclient.JfrogHttpClient {
3946
return sm.client
@@ -154,6 +161,7 @@ func (sm *XrayServicesManager) IsTokenValidationEnabled() (isEnabled bool, err e
154161
func (sm *XrayServicesManager) ScanGraph(params services.XrayGraphScanParams) (scanId string, err error) {
155162
scanService := services.NewScanService(sm.client)
156163
scanService.XrayDetails = sm.config.GetServiceDetails()
164+
scanService.ScopeProjectKey = sm.scopeProjectKey
157165
return scanService.ScanGraph(params)
158166
}
159167

@@ -162,6 +170,7 @@ func (sm *XrayServicesManager) ScanGraph(params services.XrayGraphScanParams) (s
162170
func (sm *XrayServicesManager) GetScanGraphResults(scanID, xrayVersion string, includeVulnerabilities, includeLicenses, xscEnabled bool) (*services.ScanResponse, error) {
163171
scanService := services.NewScanService(sm.client)
164172
scanService.XrayDetails = sm.config.GetServiceDetails()
173+
scanService.ScopeProjectKey = sm.scopeProjectKey
165174
return scanService.GetScanGraphResults(scanID, xrayVersion, includeVulnerabilities, includeLicenses, xscEnabled)
166175
}
167176

@@ -185,6 +194,7 @@ func (sm *XrayServicesManager) GetImportGraphResults(scanID string) (*services.S
185194
func (sm *XrayServicesManager) BuildScan(params services.XrayBuildParams, includeVulnerabilities bool) (scanResponse *services.BuildScanResponse, noFailBuildPolicy bool, err error) {
186195
buildScanService := services.NewBuildScanService(sm.client)
187196
buildScanService.XrayDetails = sm.config.GetServiceDetails()
197+
buildScanService.ScopeProjectKey = sm.scopeProjectKey
188198
return buildScanService.ScanBuild(params, includeVulnerabilities)
189199
}
190200

@@ -241,12 +251,14 @@ func (sm *XrayServicesManager) ArtifactSummary(params services.ArtifactSummaryPa
241251
func (sm *XrayServicesManager) IsEntitled(featureId string) (bool, error) {
242252
entitlementsService := services.NewEntitlementsService(sm.client)
243253
entitlementsService.XrayDetails = sm.config.GetServiceDetails()
254+
entitlementsService.ScopeProjectKey = sm.scopeProjectKey
244255
return entitlementsService.IsEntitled(featureId)
245256
}
246257

247258
// Xsc returns the Xsc service inside Xray
248259
func (sm *XrayServicesManager) Xsc() *xsc.XscInnerService {
249260
xscService := xsc.NewXscService(sm.client)
250261
xscService.XrayDetails = sm.config.GetServiceDetails()
262+
xscService.ScopeProjectKey = sm.scopeProjectKey
251263
return xscService
252264
}

xray/services/buildscan.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ import (
44
"encoding/json"
55
"errors"
66
"fmt"
7+
"net/http"
8+
"strings"
9+
710
"github.com/jfrog/gofrog/version"
811
"github.com/jfrog/jfrog-client-go/auth"
912
"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"
13+
"github.com/jfrog/jfrog-client-go/utils"
1014
"github.com/jfrog/jfrog-client-go/utils/errorutils"
1115
"github.com/jfrog/jfrog-client-go/utils/io/httputils"
1216
"github.com/jfrog/jfrog-client-go/utils/log"
13-
"net/http"
14-
"strings"
1517
)
1618

1719
const (
@@ -25,8 +27,9 @@ const (
2527
)
2628

2729
type BuildScanService struct {
28-
client *jfroghttpclient.JfrogHttpClient
29-
XrayDetails auth.ServiceDetails
30+
client *jfroghttpclient.JfrogHttpClient
31+
XrayDetails auth.ServiceDetails
32+
ScopeProjectKey string
3033
}
3134

3235
// NewBuildScanService creates a new service to scan build dependencies.
@@ -61,7 +64,7 @@ func (bs *BuildScanService) triggerScan(paramsBytes []byte) error {
6164
httpClientsDetails.SetContentTypeApplicationJson()
6265
url := bs.XrayDetails.GetUrl() + BuildScanAPI
6366

64-
resp, body, err := bs.client.SendPost(url, paramsBytes, &httpClientsDetails)
67+
resp, body, err := bs.client.SendPost(utils.AppendScopedProjectKeyParam(url, bs.ScopeProjectKey), paramsBytes, &httpClientsDetails)
6568
if err != nil {
6669
return err
6770
}
@@ -149,7 +152,7 @@ func (bs *BuildScanService) getResultsGetRequestFunc(params XrayBuildParams, htt
149152
endPoint += "?" + strings.Join(queryParams, "&")
150153
}
151154
return func() (*http.Response, []byte, error) {
152-
resp, body, _, err := bs.client.SendGet(endPoint, true, httpClientsDetails)
155+
resp, body, _, err := bs.client.SendGet(utils.AppendScopedProjectKeyParam(endPoint, bs.ScopeProjectKey), true, httpClientsDetails)
153156
return resp, body, err
154157
}
155158
}
@@ -163,7 +166,7 @@ func (bs *BuildScanService) getResultsPostRequestFunc(params XrayBuildParams, pa
163166
endPoint += "?" + strings.Join(queryParams, "&")
164167
}
165168
return func() (*http.Response, []byte, error) {
166-
resp, body, err := bs.client.SendPost(endPoint, paramsBytes, httpClientsDetails)
169+
resp, body, err := bs.client.SendPost(utils.AppendScopedProjectKeyParam(endPoint, bs.ScopeProjectKey), paramsBytes, httpClientsDetails)
167170
return resp, body, err
168171
}
169172
}

xray/services/entitlements.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ import (
88

99
"github.com/jfrog/jfrog-client-go/auth"
1010
"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"
11+
clientutils "github.com/jfrog/jfrog-client-go/utils"
1112
"github.com/jfrog/jfrog-client-go/utils/errorutils"
1213
)
1314

1415
type EntitlementsService struct {
15-
client *jfroghttpclient.JfrogHttpClient
16-
XrayDetails auth.ServiceDetails
16+
client *jfroghttpclient.JfrogHttpClient
17+
XrayDetails auth.ServiceDetails
18+
ScopeProjectKey string
1719
}
1820

1921
// NewEntitlementsService creates a new service to retrieve the entitlement data from Xray
@@ -26,10 +28,14 @@ func (es *EntitlementsService) GetXrayDetails() auth.ServiceDetails {
2628
return es.XrayDetails
2729
}
2830

31+
func (es *EntitlementsService) getUrlForEntitlementApi(featureId string) string {
32+
return clientutils.AppendScopedProjectKeyParam(es.XrayDetails.GetUrl()+"api/v1/entitlements/feature/"+featureId, es.ScopeProjectKey)
33+
}
34+
2935
// IsEntitled returns true if the user is entitled for the requested feature ID
3036
func (es *EntitlementsService) IsEntitled(featureId string) (entitled bool, err error) {
3137
httpDetails := es.XrayDetails.CreateHttpClientDetails()
32-
resp, body, _, err := es.client.SendGet(es.XrayDetails.GetUrl()+"api/v1/entitlements/feature/"+featureId, true, &httpDetails)
38+
resp, body, _, err := es.client.SendGet(es.getUrlForEntitlementApi(featureId), true, &httpDetails)
3339
if err != nil {
3440
err = errors.New("failed while attempting to get JFrog Xray entitlements response: " + err.Error())
3541
return
@@ -40,7 +46,7 @@ func (es *EntitlementsService) IsEntitled(featureId string) (entitled bool, err
4046
}
4147
var userEntitlements entitlements
4248
if err = json.Unmarshal(body, &userEntitlements); err != nil {
43-
err = errorutils.CheckErrorf("couldn't parse JFrog Xray server entitlements response: " + err.Error())
49+
err = errorutils.CheckErrorf("couldn't parse JFrog Xray server entitlements response: %s", err.Error())
4450
return
4551
}
4652
entitled = userEntitlements.Entitled

xray/services/scan.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"time"
88

99
clientUtils "github.com/jfrog/jfrog-client-go/utils"
10+
clientutils "github.com/jfrog/jfrog-client-go/utils"
1011
"github.com/jfrog/jfrog-client-go/utils/log"
1112
xrayUtils "github.com/jfrog/jfrog-client-go/xray/services/utils"
1213
xscUtils "github.com/jfrog/jfrog-client-go/xsc/services/utils"
@@ -54,8 +55,9 @@ const (
5455
type ScanType string
5556

5657
type ScanService struct {
57-
client *jfroghttpclient.JfrogHttpClient
58-
XrayDetails auth.ServiceDetails
58+
client *jfroghttpclient.JfrogHttpClient
59+
XrayDetails auth.ServiceDetails
60+
ScopeProjectKey string
5961
}
6062

6163
// NewScanService creates a new service to scan binaries and audit code projects' dependencies.
@@ -124,7 +126,7 @@ func (ss *ScanService) ScanGraph(scanParams XrayGraphScanParams) (string, error)
124126
url = xscUtils.XrayUrlToXscUrl(ss.XrayDetails.GetUrl(), scanParams.XrayVersion) + XscGraphAPI
125127
}
126128
url += createScanGraphQueryParams(scanParams)
127-
resp, body, err := ss.client.SendPost(url, requestBody, &httpClientsDetails)
129+
resp, body, err := ss.client.SendPost(clientutils.AppendScopedProjectKeyParam(url, ss.ScopeProjectKey), requestBody, &httpClientsDetails)
128130
if err != nil {
129131
return "", err
130132
}
@@ -168,7 +170,7 @@ func (ss *ScanService) GetScanGraphResults(scanId, xrayVersion string, includeVu
168170
pollingExecutor := &httputils.PollingExecutor{
169171
Timeout: defaultMaxWaitMinutes,
170172
PollingInterval: defaultSyncSleepInterval,
171-
PollingAction: xrayUtils.PollingAction(ss.client, endPoint, httpClientsDetails),
173+
PollingAction: xrayUtils.PollingAction(ss.client, clientutils.AppendScopedProjectKeyParam(endPoint, ss.ScopeProjectKey), httpClientsDetails),
172174
MsgPrefix: "Get Dependencies Scan results... ",
173175
}
174176

xray/services/xsc/xsc.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ import (
1010
// XscService is the Xray Source Control service in the Xray service, available from v3.107.13.
1111
// This service replaces the Xray Source Control service, which was available as a standalone service.
1212
type XscInnerService struct {
13-
client *jfroghttpclient.JfrogHttpClient
14-
XrayDetails auth.ServiceDetails
13+
client *jfroghttpclient.JfrogHttpClient
14+
XrayDetails auth.ServiceDetails
15+
ScopeProjectKey string
1516
}
1617

1718
func NewXscService(client *jfroghttpclient.JfrogHttpClient) *XscInnerService {
@@ -27,41 +28,48 @@ func (xs *XscInnerService) GetVersion() (string, error) {
2728
func (xs *XscInnerService) AddAnalyticsGeneralEvent(event services.XscAnalyticsGeneralEvent, xrayVersion string) (string, error) {
2829
eventService := services.NewAnalyticsEventService(xs.client)
2930
eventService.XrayDetails = xs.XrayDetails
31+
eventService.ScopeProjectKey = xs.ScopeProjectKey
3032
return eventService.AddGeneralEvent(event, xrayVersion)
3133
}
3234

3335
func (xs *XscInnerService) SendXscLogErrorRequest(errorLog *services.ExternalErrorLog) error {
3436
logErrorService := services.NewLogErrorEventService(xs.client)
3537
logErrorService.XrayDetails = xs.XrayDetails
38+
logErrorService.ScopeProjectKey = xs.ScopeProjectKey
3639
return logErrorService.SendLogErrorEvent(errorLog)
3740
}
3841

3942
func (xs *XscInnerService) UpdateAnalyticsGeneralEvent(event services.XscAnalyticsGeneralEventFinalize) error {
4043
eventService := services.NewAnalyticsEventService(xs.client)
4144
eventService.XrayDetails = xs.XrayDetails
45+
eventService.ScopeProjectKey = xs.ScopeProjectKey
4246
return eventService.UpdateGeneralEvent(event)
4347
}
4448

4549
func (xs *XscInnerService) GetAnalyticsGeneralEvent(msi string) (*services.XscAnalyticsGeneralEvent, error) {
4650
eventService := services.NewAnalyticsEventService(xs.client)
4751
eventService.XrayDetails = xs.XrayDetails
52+
eventService.ScopeProjectKey = xs.ScopeProjectKey
4853
return eventService.GetGeneralEvent(msi)
4954
}
5055

5156
func (xs *XscInnerService) GetConfigProfileByName(profileName string) (*services.ConfigProfile, error) {
5257
configProfileService := services.NewConfigurationProfileService(xs.client)
5358
configProfileService.XrayDetails = xs.XrayDetails
59+
configProfileService.ScopeProjectKey = xs.ScopeProjectKey
5460
return configProfileService.GetConfigurationProfileByName(profileName)
5561
}
5662

5763
func (xs *XscInnerService) GetConfigProfileByUrl(repoUrl string) (*services.ConfigProfile, error) {
5864
configProfileService := services.NewConfigurationProfileService(xs.client)
5965
configProfileService.XrayDetails = xs.XrayDetails
66+
configProfileService.ScopeProjectKey = xs.ScopeProjectKey
6067
return configProfileService.GetConfigurationProfileByUrl(repoUrl)
6168
}
6269

6370
func (xs *XscInnerService) GetResourceWatches(gitRepo, project string) (watches *utils.ResourcesWatchesBody, err error) {
6471
watchService := services.NewWatchService(xs.client)
6572
watchService.XrayDetails = xs.XrayDetails
73+
watchService.ScopeProjectKey = xs.ScopeProjectKey
6674
return watchService.GetResourceWatches(gitRepo, project)
6775
}

0 commit comments

Comments
 (0)