Skip to content

Commit

Permalink
Merge remote-tracking branch 'jfrog-prod/dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
eranturgeman committed Oct 3, 2023
2 parents 7b2943f + 3537ae8 commit 15552e7
Show file tree
Hide file tree
Showing 21 changed files with 379 additions and 113 deletions.
71 changes: 51 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</div>

| Branch | Status |
|:------:|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
| :----: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| master | [![Build status](https://github.com/jfrog/jfrog-client-go/actions/workflows/tests.yml/badge.svg?branch=master)](https://github.com/jfrog/jfrog-client-go/actions) [![Static Analysis](https://github.com/jfrog/jfrog-client-go/actions/workflows/analysis.yml/badge.svg?branch=master)](https://github.com/jfrog/jfrog-client-go/actions/workflows/analysis.yml) |
| dev | [![Build status](https://github.com/jfrog/jfrog-client-go/actions/workflows/tests.yml/badge.svg?branch=dev)](https://github.com/jfrog/jfrog-client-go/actions) [![Static Analysis](https://github.com/jfrog/jfrog-client-go/actions/workflows/analysis.yml/badge.svg?branch=dev)](https://github.com/jfrog/jfrog-client-go/actions/workflows/analysis.yml) |

Expand Down Expand Up @@ -54,11 +54,11 @@
- [Cleaning Unreferenced Git LFS Files from Artifactory](#cleaning-unreferenced-git-lfs-files-from-artifactory)
- [Executing AQLs](#executing-aqls)
- [Reading Files in Artifactory](#reading-files-in-artifactory)
- [Creating an Access Token](#creating-an-access-token)
- [Fetching Access Tokens](#fetching-access-tokens)
- [Fetching Access Tokens of a User](#fetching-access-tokens-of-a-user)
- [Refreshing an Access Token](#refreshing-an-access-token)
- [Revoking an Access Token](#revoking-an-access-token)
- [Creating an Artifactory Access Token](#creating-an-artifactory-access-token)
- [Fetching Artifactory Access Tokens](#fetching-artifactory-access-tokens)
- [Fetching Artifactory Access Tokens of a User](#fetching-artifactory-access-tokens-of-a-user)
- [Refreshing an Artifactory Access Token](#refreshing-an-artifactory-access-token)
- [Revoking an Artifactory Access Token](#revoking-an-artifactory-access-token)
- [Create API Key](#create-api-key)
- [Regenerate API Key](#regenerate-api-key)
- [Get API Key](#get-api-key)
Expand Down Expand Up @@ -111,13 +111,15 @@
- [Getting a Project](#getting-a-project)
- [Getting all Projects](#getting-all-projects)
- [Assigning Repository to Project](#assigning-repository-to-project)
- [Unassigning Repository from Project](#unassigning-repository-from-project)
- [Un-assigning Repository from Project](#un-assigning-repository-from-project)
- [Get all groups assigned to a project](#get-all-groups-assigned-to-a-project)
- [Get a specific group assigned to a project](#get-a-specific-group-assigned-to-a-project)
- [Add or update a group assigned to a project](#add-or-update-a-group-assigned-to-a-project)
- [Remove a group from a project](#remove-a-group-from-a-project)
- [Send Web Login Authentication Request](#send-web-login-authentication-request)
- [Get Web Login Authentication Token](#get-web-login-authentication-token)
- [Creating an Access Token](#creating-an-access-token)
- [Refreshing an Access Token](#refreshing-an-access-token)
- [Distribution APIs](#distribution-apis)
- [Creating Distribution Service Manager](#creating-distribution-service-manager)
- [Creating Distribution Details](#creating-distribution-details)
Expand Down Expand Up @@ -249,7 +251,7 @@ content of this repository is deleted.
#### Test Types

| Type | Description | Prerequisites |
|----------------------|--------------------|-------------------------------|
| -------------------- | ------------------ | ----------------------------- |
| `-test.artifactory` | Artifactory tests | Artifactory Pro |
| `-test.distribution` | Distribution tests | Artifactory with Distribution |
| `-test.xray` | Xray tests | Artifactory with Xray |
Expand All @@ -260,7 +262,7 @@ content of this repository is deleted.
#### Connection Details

| Flag | Description |
|---------------------|--------------------------------------------------------------------------------------------------------|
| ------------------- | ------------------------------------------------------------------------------------------------------ |
| `-rt.url` | [Default: http://localhost:8081/artifactory] Artifactory URL. |
| `-ds.url` | [Optional] JFrog Distribution URL. |
| `-xr.url` | [Optional] JFrog Xray URL. |
Expand Down Expand Up @@ -355,8 +357,10 @@ serviceConfig, err := config.NewConfigBuilder().
SetDryRun(false).
// Add [Context](https://golang.org/pkg/context/)
SetContext(ctx).
// Optionally overwrite the default HTTP timeout, which is set to 30 seconds.
SetHttpTimeout(180 * time.Second).
// Optionally overwrite the default dial timeout, which is set to 30 seconds.
SetDialTimeout(180 * time.Second).
// Optionally set the total HTTP request timeout.
SetOverallRequestTimeout(10 * time.Minute).
// Optionally overwrite the default HTTP retries, which is set to 3.
SetHttpRetries(8).
Build()
Expand Down Expand Up @@ -725,7 +729,7 @@ rtManager.Aql(aql string)
rtManager.ReadRemoteFile(FilePath string)
```

#### Creating an Access Token
#### Creating an Artifactory Access Token

```go
params := services.NewCreateTokenParams()
Expand All @@ -739,19 +743,19 @@ params.Audience = "jfrt@<serviceID1> jfrt@<serviceID2>"
results, err := rtManager.CreateToken(params)
```

#### Fetching Access Tokens
#### Fetching Artifactory Access Tokens

```go
results, err := rtManager.GetTokens()
```

#### Fetching Access Tokens of a User
#### Fetching Artifactory Access Tokens of a User

```g
results, err := rtManager.GetUserTokens(username)
```

#### Refreshing an Access Token
#### Refreshing an Artifactory Access Token

```go
params := services.NewRefreshTokenParams()
Expand All @@ -762,7 +766,7 @@ params.Token.ExpiresIn = 3600
results, err := rtManager.RefreshToken(params)
```

#### Revoking an Access Token
#### Revoking an Artifactory Access Token

```go
params := services.NewRevokeTokenParams()
Expand Down Expand Up @@ -1467,7 +1471,7 @@ err = accessManager.GetAllProjects()
err = accessManager.AssignRepoToProject("repoName", "tstprj", true)
```

#### Unassigning Repository from Project
#### Un-assigning Repository from Project

```go
err = accessManager.AssignRepoToProject("repoName")
Expand Down Expand Up @@ -1515,6 +1519,32 @@ uuid := "09b34617-b48a-455d-8b05-25a6989fb76a"
err = accessManager.GetLoginAuthenticationToken(uuid)
```

#### Creating an Access Token

```go
params := CreateTokenParams{}
params.Scope = "applied-permissions/user"
params.Username = "my-user"
params.ExpiresIn = 12345 // nil = system default, 0 = no expiry.
params.Refreshable = true
params.Audience = "jfrt@<serviceID1>"
reference := true
params.IncludeReferenceToken = &reference
params.ProjectKey = "my-project"
params.Description = "my-token"

results, err := accessManager.CreateToken(params)
```

#### Refreshing an Access Token

```go
params := accessServices.CreateTokenParams{}
params.RefreshToken = "<refresh token>"

results, err := accessManager.RefreshToken(params)
```

## Distribution APIs

### Creating Distribution Service Manager
Expand Down Expand Up @@ -1937,7 +1967,7 @@ vulnerabilitiesReportRequest := services.VulnerabilitiesReportRequestParams{
Severity: []string{
"High",
"Medium"
},
},
CvssScore: services.CvssScore {
MinScore: float64(6.3),
MaxScore: float64(9)
Expand Down Expand Up @@ -1992,6 +2022,7 @@ reportContent, err := xrayManager.ReportContent(reportContentRequest)
// The reportId argument value is returned as part of the xrayManager.GenerateVulnerabilitiesReport API response.
err := xrayManager.DeleteReport(reportId)
```
#### Generate Licences Report
```go
Expand Down Expand Up @@ -2091,7 +2122,7 @@ violationsReportRequest := services.ViolationsReportRequestParams{
Severity: []string{
"High",
"Medium"
},
},
CvssScore: services.CvssScore {
MinScore: float64(6.3),
MaxScore: float64(9)
Expand All @@ -2104,7 +2135,7 @@ violationsReportRequest := services.ViolationsReportRequestParams{
Start: "2020-06-29T12:22:16Z",
End: "2020-06-29T12:22:16Z"
},
SummaryContains: "kernel",
SummaryContains: "kernel",
HasRemediation: &falseValue,
},
LicenseFilters: services.LicensesFilter {
Expand Down
2 changes: 2 additions & 0 deletions access/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ func New(config config.Config) (*AccessServicesManager, error) {
SetClientCertKeyPath(details.GetClientCertKeyPath()).
AppendPreRequestInterceptor(details.RunPreRequestFunctions).
SetContext(config.GetContext()).
SetDialTimeout(config.GetDialTimeout()).
SetOverallRequestTimeout(config.GetOverallRequestTimeout()).
SetRetries(config.GetHttpRetries()).
SetRetryWaitMilliSecs(config.GetHttpRetryWaitMilliSecs()).
Build()
Expand Down
41 changes: 22 additions & 19 deletions access/services/accesstoken.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ type TokenService struct {

type CreateTokenParams struct {
auth.CommonTokenParams
IncludeReferenceToken *bool `json:"include_reference_token,omitempty"`
IncludeReferenceToken *bool `json:"include_reference_token,omitempty"`
Username string `json:"username,omitempty"`
ProjectKey string `json:"project_key,omitempty"`
Description string `json:"description,omitempty"`
}

func NewCreateTokenParams(params CreateTokenParams) CreateTokenParams {
Expand All @@ -37,22 +40,19 @@ func (ps *TokenService) CreateAccessToken(params CreateTokenParams) (auth.Create
return ps.createAccessToken(params)
}

func (ps *TokenService) RefreshAccessToken(token CreateTokenParams) (auth.CreateTokenResponseData, error) {
param, err := createRefreshTokenRequestParams(token)
func (ps *TokenService) RefreshAccessToken(params CreateTokenParams) (auth.CreateTokenResponseData, error) {
refreshParams, err := prepareForRefresh(params)
if err != nil {
return auth.CreateTokenResponseData{}, err
}
return ps.createAccessToken(*param)
return ps.createAccessToken(*refreshParams)
}

// createAccessToken is used to create & refresh access tokens.
func (ps *TokenService) createAccessToken(params CreateTokenParams) (auth.CreateTokenResponseData, error) {
// Set the request headers
tokenInfo := auth.CreateTokenResponseData{}
func (ps *TokenService) createAccessToken(params CreateTokenParams) (tokenInfo auth.CreateTokenResponseData, err error) {
httpDetails := ps.ServiceDetails.CreateHttpClientDetails()
utils.SetContentType("application/json", &httpDetails.Headers)
err := ps.addAccessTokenAuthorizationHeader(params, &httpDetails)
if err != nil {
if err = ps.handleUnauthenticated(params, &httpDetails); err != nil {
return tokenInfo, err
}
requestContent, err := json.Marshal(params)
Expand All @@ -71,23 +71,26 @@ func (ps *TokenService) createAccessToken(params CreateTokenParams) (auth.Create
return tokenInfo, errorutils.CheckError(err)
}

func (ps *TokenService) addAccessTokenAuthorizationHeader(params CreateTokenParams, httpDetails *httputils.HttpClientDetails) error {
access := ps.ServiceDetails.GetAccessToken()
if access == "" {
access = params.AccessToken
func (ps *TokenService) handleUnauthenticated(params CreateTokenParams, httpDetails *httputils.HttpClientDetails) error {
// Creating access tokens using username and password is available since Artifactory 7.63.2,
// by enabling "Enable Token Generation via API" in the UI.
if httpDetails.AccessToken != "" || (httpDetails.User != "" && httpDetails.Password != "") {
return nil
}
if access == "" {
return errorutils.CheckErrorf("failed: adding accessToken authorization, but No accessToken was provided. ")
// Use token from params if provided.
if params.AccessToken != "" {
httpDetails.AccessToken = params.AccessToken
return nil
}
utils.AddHeader("Authorization", fmt.Sprintf("Bearer %s", access), &httpDetails.Headers)
return nil
return errorutils.CheckErrorf("cannot create access token without credentials")
}

func createRefreshTokenRequestParams(p CreateTokenParams) (*CreateTokenParams, error) {
func prepareForRefresh(p CreateTokenParams) (*CreateTokenParams, error) {
// Validate provided parameters
if p.RefreshToken == "" {
return nil, errorutils.CheckErrorf("error: trying to refresh token, but 'refresh_token' field wasn't provided. ")
return nil, errorutils.CheckErrorf("trying to refresh token, but 'refresh_token' field wasn't provided")
}

params := NewCreateTokenParams(p)
// Set refresh required parameters
params.GrantType = "refresh_token"
Expand Down
3 changes: 2 additions & 1 deletion artifactory/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ func NewWithProgress(config config.Config, progress ioutils.ProgressMgr) (Artifa
SetCertificatesPath(config.GetCertificatesPath()).
SetInsecureTls(config.IsInsecureTls()).
SetContext(config.GetContext()).
SetTimeout(config.GetHttpTimeout()).
SetDialTimeout(config.GetDialTimeout()).
SetOverallRequestTimeout(config.GetOverallRequestTimeout()).
SetClientCertPath(artDetails.GetClientCertPath()).
SetClientCertKeyPath(artDetails.GetClientCertKeyPath()).
AppendPreRequestInterceptor(artDetails.RunPreRequestFunctions).
Expand Down
3 changes: 2 additions & 1 deletion auth/authutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ import (
type CreateTokenResponseData struct {
CommonTokenParams
ReferenceToken string `json:"reference_token,omitempty"`
TokenId string `json:"token_id,omitempty"`
}

type CommonTokenParams struct {
Scope string `json:"scope,omitempty"`
AccessToken string `json:"access_token,omitempty"`
ExpiresIn int `json:"expires_in,omitempty"`
ExpiresIn *uint `json:"expires_in,omitempty"`
TokenType string `json:"token_type,omitempty"`
Refreshable *bool `json:"refreshable,omitempty"`
RefreshToken string `json:"refresh_token,omitempty"`
Expand Down
30 changes: 20 additions & 10 deletions auth/servicedetails.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package auth

import (
"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"
"sync"
"time"

"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"

"github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
"github.com/jfrog/jfrog-client-go/utils/io/httputils"
Expand Down Expand Up @@ -44,7 +45,8 @@ type ServiceDetails interface {
SetSshPassphrase(sshPassphrase string)
SetSshAuthHeaders(sshAuthHeaders map[string]string)
SetClient(client *jfroghttpclient.JfrogHttpClient)
SetHttpTimeout(httpTimeout time.Duration)
SetDialTimeout(dialTimeout time.Duration)
SetOverallRequestTimeout(overallRequestTimeout time.Duration)

IsSshAuthHeaderSet() bool
IsSshAuthentication() bool
Expand All @@ -71,7 +73,8 @@ type CommonConfigFields struct {
SshAuthHeaders map[string]string `json:"-"`
TokenMutex sync.Mutex
client *jfroghttpclient.JfrogHttpClient
httpTimeout time.Duration
dialTimeout time.Duration
overallRequestTimeout time.Duration
}

func (ccf *CommonConfigFields) GetUrl() string {
Expand Down Expand Up @@ -178,8 +181,12 @@ func (ccf *CommonConfigFields) SetClient(client *jfroghttpclient.JfrogHttpClient
ccf.client = client
}

func (ccf *CommonConfigFields) SetHttpTimeout(httpTimeout time.Duration) {
ccf.httpTimeout = httpTimeout
func (ccf *CommonConfigFields) SetDialTimeout(dialTimeout time.Duration) {
ccf.dialTimeout = dialTimeout
}

func (ccf *CommonConfigFields) SetOverallRequestTimeout(overallRequestTimeout time.Duration) {
ccf.overallRequestTimeout = overallRequestTimeout
}

func (ccf *CommonConfigFields) IsSshAuthHeaderSet() bool {
Expand Down Expand Up @@ -267,9 +274,12 @@ func SshTokenRefreshPreRequestInterceptor(fields *CommonConfigFields, httpClient

func (ccf *CommonConfigFields) CreateHttpClientDetails() httputils.HttpClientDetails {
return httputils.HttpClientDetails{
User: ccf.User,
Password: ccf.Password,
ApiKey: ccf.ApiKey,
AccessToken: ccf.AccessToken,
Headers: utils.CopyMap(ccf.GetSshAuthHeaders())}
User: ccf.User,
Password: ccf.Password,
ApiKey: ccf.ApiKey,
AccessToken: ccf.AccessToken,
Headers: utils.CopyMap(ccf.GetSshAuthHeaders()),
DialTimeout: ccf.dialTimeout,
OverallRequestTimeout: ccf.overallRequestTimeout,
}
}
Loading

0 comments on commit 15552e7

Please sign in to comment.