Skip to content

Commit 8504708

Browse files
committed
Merge remote-tracking branch 'upstream/dev'
2 parents a06223f + 6fb27bd commit 8504708

17 files changed

Lines changed: 382 additions & 130 deletions

File tree

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@
124124
- [Get Web Login Authentication Token](#get-web-login-authentication-token)
125125
- [Creating an Access Token](#creating-an-access-token)
126126
- [Refreshing an Access Token](#refreshing-an-access-token)
127+
- [Exchanging an OIDC Access Token](#exchanging-an-oidc-access-token)
127128
- [Distribution APIs](#distribution-apis)
128129
- [Creating Distribution Service Manager](#creating-distribution-service-manager)
129130
- [Creating Distribution Details](#creating-distribution-details)
@@ -1657,6 +1658,25 @@ params.RefreshToken = "<refresh token>"
16571658
results, err := accessManager.RefreshToken(params)
16581659
```
16591660

1661+
### exchanging-an-oidc-access-token
1662+
1663+
```go
1664+
params := services.CreateOidcTokenParams{
1665+
GrantType: "urn:ietf:params:oauth:grant-type:token-exchange", // The type of grant being requested
1666+
SubjectTokenType: "urn:ietf:params:oauth:token-type:id_token", // The type of token being exchanged
1667+
OidcTokenID: "<oidc token id aka subject_token>", // The ID of the OIDC token to be exchanged
1668+
ProjectKey: "<JFrog project key>", // Optional: Key to link the token to a specific project
1669+
ApplicationKey: "<application key>", // Optional: Key to link the token to a specific application
1670+
RunId: "<ci run id>", // Optional: ID to link the token to a specific run
1671+
JobId: "<ci job id>", // Optional: ID to link the token to a specific job
1672+
Repo: "<source code repository>", // Optional: Repository associated with the token
1673+
Audience: "<audience>", // The intended audience of the token
1674+
ProviderName: "<provider name>", // The name of the OIDC provider
1675+
}
1676+
1677+
response, err = servicesManager.ExchangeOidcToken(params)
1678+
```
1679+
16601680
## Distribution APIs
16611681

16621682
### Creating Distribution Service Manager

access/manager.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,9 @@ func (sm *AccessServicesManager) GetLoginAuthenticationToken(uuid string) (auth.
137137
loginService.ServiceDetails = sm.config.GetServiceDetails()
138138
return loginService.GetLoginAuthenticationToken(uuid)
139139
}
140+
141+
func (sm *AccessServicesManager) ExchangeOidcToken(params services.CreateOidcTokenParams) (auth.OidcTokenResponseData, error) {
142+
tokenService := services.NewTokenService(sm.client)
143+
tokenService.ServiceDetails = sm.config.GetServiceDetails()
144+
return tokenService.ExchangeOidcToken(params)
145+
}

access/services/accesstoken.go

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ import (
1212
)
1313

1414
// #nosec G101 -- False positive - no hardcoded credentials.
15-
const tokensApi = "api/v1/tokens"
15+
const (
16+
// jfrog-ignore - not a real token
17+
tokensApi = "api/v1/tokens"
18+
// jfrog-ignore - not a real token
19+
oidcTokensApi = "api/v1/oidc/token"
20+
)
1621

1722
type TokenService struct {
1823
client *jfroghttpclient.JfrogHttpClient
@@ -27,6 +32,21 @@ type CreateTokenParams struct {
2732
Description string `json:"description,omitempty"`
2833
}
2934

35+
type CreateOidcTokenParams struct {
36+
GrantType string `json:"grant_type,omitempty"`
37+
SubjectTokenType string `json:"subject_token_type,omitempty"`
38+
OidcTokenID string `json:"subject_token,omitempty"`
39+
ProviderName string `json:"provider_name,omitempty"`
40+
ProjectKey string `json:"project_key,omitempty"`
41+
JobId string `json:"job_id,omitempty"`
42+
RunId string `json:"run_id,omitempty"`
43+
Repo string `json:"repo,omitempty"`
44+
ApplicationKey string `json:"application_key,omitempty"`
45+
Audience string `json:"audience,omitempty"`
46+
IdentityMappingName string `json:"identity_mapping_name,omitempty"`
47+
IncludeReferenceToken *bool `json:"include_reference_token,omitempty"`
48+
}
49+
3050
func NewCreateTokenParams(params CreateTokenParams) CreateTokenParams {
3151
return CreateTokenParams{CommonTokenParams: params.CommonTokenParams, IncludeReferenceToken: params.IncludeReferenceToken}
3252
}
@@ -84,6 +104,26 @@ func (ps *TokenService) handleUnauthenticated(params CreateTokenParams, httpDeta
84104
return errorutils.CheckErrorf("cannot create access token without credentials")
85105
}
86106

107+
func (ps *TokenService) ExchangeOidcToken(params CreateOidcTokenParams) (auth.OidcTokenResponseData, error) {
108+
var tokenInfo auth.OidcTokenResponseData
109+
httpDetails := ps.ServiceDetails.CreateHttpClientDetails()
110+
httpDetails.SetContentTypeApplicationJson()
111+
requestContent, err := json.Marshal(params)
112+
if errorutils.CheckError(err) != nil {
113+
return tokenInfo, err
114+
}
115+
url := fmt.Sprintf("%s%s", ps.ServiceDetails.GetUrl(), oidcTokensApi)
116+
resp, body, err := ps.client.SendPost(url, requestContent, &httpDetails)
117+
if err != nil {
118+
return tokenInfo, err
119+
}
120+
if err = errorutils.CheckResponseStatusWithBody(resp, body, http.StatusOK); err != nil {
121+
return tokenInfo, fmt.Errorf("failed to exchange OIDC token: %w", err)
122+
}
123+
err = json.Unmarshal(body, &tokenInfo)
124+
return tokenInfo, errorutils.CheckError(err)
125+
}
126+
87127
func prepareForRefresh(p CreateTokenParams) (*CreateTokenParams, error) {
88128
// Validate provided parameters
89129
if p.RefreshToken == "" {

artifactory/services/utils/multipartupload_test.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package utils
22

33
import (
4+
"crypto/rand"
45
"encoding/json"
56
"fmt"
67
"net/http"
@@ -16,21 +17,20 @@ import (
1617
"github.com/jfrog/jfrog-client-go/utils/log"
1718
"github.com/jfrog/jfrog-client-go/utils/tests"
1819
"github.com/stretchr/testify/assert"
19-
"golang.org/x/exp/rand"
2020
)
2121

2222
const (
23-
localPath = "localPath"
24-
repoKey = "repoKey"
25-
repoPath = "repoPath"
26-
partSize = SizeGiB
27-
partSizeMB = 1024
28-
partNumber = 2
29-
splitCount = 3
30-
token = "token"
23+
localPath = "localPath"
24+
repoKey = "repoKey"
25+
repoPath = "repoPath"
26+
partSize = SizeGiB
27+
partSizeMB = 1024
28+
partNumber = 2
29+
splitCount = 3
30+
token = "token"
31+
// jfrog-ignore - test url
3132
partUrl = "http://dummy-url-part"
3233
sha1 = "sha1"
33-
nodeId = "nodeId"
3434
checksumToken = "checksumToken"
3535
)
3636

auth/authutils.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ type CreateTokenResponseData struct {
1717
TokenId string `json:"token_id,omitempty"`
1818
}
1919

20+
type OidcTokenResponseData struct {
21+
CommonTokenParams
22+
IssuedTokenType string `json:"issued_token_type,omitempty"`
23+
Username string `json:"username,omitempty"`
24+
}
25+
2026
type CommonTokenParams struct {
2127
Scope string `json:"scope,omitempty"`
2228
AccessToken string `json:"access_token,omitempty"`

auth/authutils_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ import (
99
)
1010

1111
var (
12-
// #nosec G101 -- Dummy tokens for tests
12+
// #nosec G101 -- Dummy tokens for tests jfrog-ignore
1313
token1 = "eyJ2ZXIiOiIyIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYiLCJraWQiOiJIcnU2VHctZk1yOTV3dy12TDNjV3ZBVjJ3Qm9FSHpHdGlwUEFwOE1JdDljIn0.eyJzdWIiOiJqZnJ0QDAxYzNnZmZoZzJlOHc2MTQ5ZTNhMnEwdzk3XC91c2Vyc1wvYWRtaW4iLCJzY3AiOiJtZW1iZXItb2YtZ3JvdXBzOnJlYWRlcnMgYXBpOioiLCJhdWQiOiJqZnJ0QDAxYzNnZmZoZzJlOHc2MTQ5ZTNhMnEwdzk3IiwiaXNzIjoiamZydEAwMWMzZ2ZmaGcyZTh3NjE0OWUzYTJxMHc5NyIsImV4cCI6MTU1NjAzNzc2NSwiaWF0IjoxNTU2MDM0MTY1LCJqdGkiOiI1M2FlMzgyMy05NGM3LTQ0OGItOGExOC1iZGVhNDBiZjFlMjAifQ.Bp3sdvppvRxysMlLgqT48nRIHXISj9sJUCXrm7pp8evJGZW1S9hFuK1olPmcSybk2HNzdzoMcwhUmdUzAssiQkQvqd_HanRcfFbrHeg5l1fUQ397ECES-r5xK18SYtG1VR7LNTVzhJqkmRd3jzqfmIK2hKWpEgPfm8DRz3j4GGtDRxhb3oaVsT2tSSi_VfT3Ry74tzmO0GcCvmBE2oh58kUZ4QfEsalgZ8IpYHTxovsgDx_M7ujOSZx_hzpz-iy268-OkrU22PQPCfBmlbEKeEUStUO9n0pj4l1ODL31AGARyJRy46w4yzhw7Fk5P336WmDMXYs5LAX2XxPFNLvNzA"
14-
// #nosec G101
14+
// #nosec G101 jfrog-ignore
1515
token2 = "eyJ2ZXIiOiIyIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYiLCJraWQiOiJIcnU2VHctZk1yOTV3dy12TDNjV3ZBVjJ3Qm9FSHpHdGlwUEFwOE1JdDljIn0.eyJzdWIiOiJqZnJ0QDAwMWMzZ2ZmaGcyZTh3NjE0OWUzYTJxMHc5NyIsImV4cCI6MTU1NjAzNzc2NSwiaWF0IjoxNTU2MDM0MTY1LCJqdGkiOiI1M2FlMzgyMy05NGM3LTQ0OGItOGExOC1iZGVhNDBiZjFlMjAifQ.Bp3sdvppvRxysMlLgqT48nRIHXISj9sJUCXrm7pp8evJGZW1S9hFuK1olPmcSybk2HNzdzoMcwhUmdUzAssiQkQvqd_HanRcfFbrHeg5l1fUQ397ECES-r5xK18SYtG1VR7LNTVzhJqkmRd3jzqfmIK2hKWpEgPfm8DRz3j4GGtDRxhb3oaVsT2tSSi_VfT3Ry74tzmO0GcCvmBE2oh58kUZ4QfEsalgZ8IpYHTxovsgDx_M7ujOSZx_hzpz-iy268-OkrU22PQPCfBmlbEKeEUStUO9n0pj4l1ODL31AGARyJRy46w4yzhw7Fk5P336WmDMXYs5LAX2XxPFNLvNzA"
16-
// #nosec G101
16+
// #nosec G101 jfrog-ignore
1717
token3 = "eyJ2ZXIiOiIyIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYiLCJraWQiOiJIcnU2VHctZk1yOTV3dy12TDNjV3ZBVjJ3Qm9FSHpHdGlwUEFwOE1JdDljIn0"
18-
// #nosec G101
18+
// #nosec G101 jfrog-ignore
1919
token4 = "eyJ2ZXIiOiIyIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYiLCJraWQiOiJsS0NYXzFvaTBQbTZGdF9XRklkejZLZ1g4U0FULUdOY0lJWXRjTC1KM084In0.eyJzdWIiOiJqZmZlQDAwMFwvdXNlcnNcL3RlbXB1c2VyIiwic2NwIjoiYXBwbGllZC1wZXJtaXNzaW9uc1wvYWRtaW4gYXBpOioiLCJhdWQiOlsiamZydEAqIiwiamZtZEAqIiwiamZldnRAKiIsImpmYWNAKiJdLCJpc3MiOiJqZmZlQDAwMCIsImV4cCI6MTYxNjQ4OTU4NSwiaWF0IjoxNjE2NDg1OTg1LCJqdGkiOiI0OTBlYWEzOS1mMzYxLTQxYjAtOTA5Ni1kNjg5NmQ0ZWQ3YjEifQ.J5P8Pu5tqEjgnLFLEoCdh1LJHWiMmEHht95v0EFuixwO-osq7sfXua_UCGBkKbmqVSGKew9kl_LTcbq_uMe281_5q2yYxT74iqc2wQ1K0uovEUeIU6E65oi70JwUWUwcF3sNJ2gFatnvgSu-2Kv6m-DtSIW36WS3Mh8uMZQ19ob4fmueVmMFyQsp0EEG6xFYeOK6SB8OUd0gAd_XvXiSRuF0eLabhKmXM2pVBLYfd2KIMlkFckEOGGOzeglvA62xmP4Ik7UsF487NAo0LeS_Pd79owr0jtgTYkCTrLlFhUzUMDVmD_LsCMyf_S4CJxhwkCRhhy9SYSs1WPgknL3--w"
20-
// #nosec G101
20+
// #nosec G101 jfrog-ignore
2121
token5 = "eyJ2ZXIiOiIyIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYiLCJraWQiOiJDRlVIRER4UXZaM1VNWEZxS0ZWUlFiOEFROEd6VWxSZkZJMEt4TmIzdk1jIn0.eyJzdWIiOiJ5YWhhdi90ZXN0LXJlcG8iLCJzY3AiOiJhcHBsaWVkLXBlcm1pc3Npb25zL2dyb3VwczpcImFkbWluLWdyb3VwXCIsIiwiYXVkIjoiKkAqIiwiaXNzIjoiamZhY0AwMWdnbXFxcDc0MzZuOTB3d3I4Ym5nMXp5OSIsImV4cCI6MTcxNTE4MzA3MiwiaWF0IjoxNzE1MTgzMDEyLCJqdGkiOiJmN2IxMmIzMi0xMmNkLTQ1Y2ItYWZjYS1iNTYyMjc2YjY0YmQifQ.I6df8E0_1t7uYzSQkiQBNh9GIGyr541rIRQ8BDD401N4DV98dWsqACmdlYTOAaxn_el4Lz7_OaK0GnVNGf9hiZz9QKaXbe-HnL9jG-TobpOlyhkc6iBpnizuZ9T9YiveCG_NgDMWn5syiZ912t6PuZqNN2JmwswqfE9QDm6xCH8fu7h0Rs1qDNkahtgQvO99e5d7LnuOS9VfkXBxLDZ5AeUbd89zmujgDB4hMXB3J-dQ3QxGHRPS_KUo7sf7lRvn4PydYkhbhrhg6GP6ss6rMmEJM5v8azMTrkLwksoCWtK9YpD5S70f7AoE5U5j5BttZ0S5dPGagKWZJiA1egna-w"
2222
)
2323

auth/cert/loader.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ func GetTransportWithLoadedCert(certificatesDirPath string, insecureTls bool, tr
5757
transport.TLSClientConfig = &tls.Config{
5858
RootCAs: caCertPool,
5959
ClientSessionCache: tls.NewLRUClientSessionCache(1),
60-
//#nosec G402 -- Skipping insecure tls verification was requested by the user.
60+
//#nosec G402 jfrog-ignore -- Skipping insecure tls verification was requested by the user.
6161
InsecureSkipVerify: insecureTls,
62+
MinVersion: tls.VersionTLS12,
6263
}
6364

6465
return transport, nil

go.mod

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
module github.com/jfrog/jfrog-client-go
22

3-
go 1.22.9
3+
go 1.23.7
44

55
require (
6-
github.com/ProtonMail/go-crypto v1.1.5
6+
github.com/ProtonMail/go-crypto v1.1.6
77
github.com/buger/jsonparser v1.1.1
8-
github.com/forPelevin/gomoji v1.2.0
9-
github.com/go-git/go-git/v5 v5.13.2
10-
github.com/golang-jwt/jwt/v4 v4.5.1
8+
github.com/forPelevin/gomoji v1.3.0
9+
github.com/go-git/go-git/v5 v5.14.0
10+
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
1313
github.com/jfrog/build-info-go v1.10.10
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
1717
github.com/xanzy/ssh-agent v0.3.3
18-
golang.org/x/crypto v0.32.0
19-
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c
20-
golang.org/x/term v0.29.0
18+
golang.org/x/crypto v0.36.0
19+
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394
20+
golang.org/x/term v0.30.0
2121
)
2222

2323
require (
@@ -49,9 +49,9 @@ require (
4949
github.com/ulikunitz/xz v0.5.12 // indirect
5050
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
5151
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
52-
golang.org/x/net v0.34.0 // indirect
53-
golang.org/x/sync v0.11.0 // indirect
54-
golang.org/x/sys v0.30.0 // indirect
52+
golang.org/x/net v0.38.0 // indirect
53+
golang.org/x/sync v0.12.0 // indirect
54+
golang.org/x/sys v0.31.0 // indirect
5555
gopkg.in/warnings.v0 v0.1.2 // indirect
5656
gopkg.in/yaml.v3 v3.0.1 // indirect
5757
)

0 commit comments

Comments
 (0)