Skip to content

Commit

Permalink
Add Username and Description to Access token commands
Browse files Browse the repository at this point in the history
  • Loading branch information
Smirl committed Jun 13, 2023
1 parent bc2be24 commit 9071933
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 21 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1477,6 +1477,41 @@ err = accessManager.UpdateGroupInProject("tstprj", "tstgroup", projectGroup)
err = accessManager.DeleteExistingProjectGroup("tstprj", "tstgroup")
```

#### Create an access token for the JFrog Platform

```go
import "github.com/jfrog/jfrog-client-go/access/services"

False := false // required to be passed by reference below
True := true // required to be passed by reference below
createParams := services.CreateTokenParams{
CommonTokenParams: auth.CommonTokenParams{
Scope: "applied-permissions/groups:grp",
ExpiresIn: 3600,
Refreshable: &True,
Audience: "jfrt@*",
},
Description: "my best token",
IncludeReferenceToken: &False,
Username: "username",
}

accessToken, err := accessManager.CreateAccessToken(createParams)
```

#### Refresh an existing access token

```go
import "github.com/jfrog/jfrog-client-go/access/services"

refreshParams := services.CreateTokenParams{
CommonTokenParams: auth.CommonTokenParams{
RefreshToken: accessToken.RefreshToken,
},
}
refreshedToken, err := accessManager.RefreshAccessToken(refreshParams)
```

## Distribution APIs

### Creating Distribution Service Manager
Expand Down
54 changes: 33 additions & 21 deletions access/services/accesstoken.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package services
import (
"encoding/json"
"fmt"
"net/http"

"github.com/jfrog/jfrog-client-go/artifactory/services/utils"
"github.com/jfrog/jfrog-client-go/auth"
"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/jfrog/jfrog-client-go/utils/io/httputils"
"net/http"
)

// #nosec G101 -- False positive - no hardcoded credentials.
Expand All @@ -21,39 +22,59 @@ type TokenService struct {

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

func NewCreateTokenParams(params CreateTokenParams) CreateTokenParams {
return CreateTokenParams{CommonTokenParams: params.CommonTokenParams, IncludeReferenceToken: params.IncludeReferenceToken}
return CreateTokenParams{
CommonTokenParams: params.CommonTokenParams,
Description: params.Description,
IncludeReferenceToken: params.IncludeReferenceToken,
Username: params.Username,
}
}

func NewTokenService(client *jfroghttpclient.JfrogHttpClient) *TokenService {
return &TokenService{client: client}
}

// Create an access token for the JFrog Platform
func (ps *TokenService) CreateAccessToken(params CreateTokenParams) (auth.CreateTokenResponseData, error) {
return ps.createAccessToken(params)
}

// Refresh an existing access token without having to provide the old token.
// The Refresh Token is the same API endpoint as Create Token, with a specific grant type: refresh_token
func (ps *TokenService) RefreshAccessToken(token CreateTokenParams) (auth.CreateTokenResponseData, error) {
param, err := createRefreshTokenRequestParams(token)
if err != nil {
return auth.CreateTokenResponseData{}, err
// Validate provided parameters
if token.RefreshToken == "" {
return auth.CreateTokenResponseData{}, errorutils.CheckErrorf("error: trying to refresh token, but 'refresh_token' field wasn't provided. ")
}
return ps.createAccessToken(*param)
// Set refresh required parameters
var trueValue = true
params := NewCreateTokenParams(token)
params.GrantType = "refresh_token"
params.Refreshable = &trueValue

return ps.createAccessToken(params)
}

// createAccessToken is used to create & refresh access tokens.
func (ps *TokenService) createAccessToken(params CreateTokenParams) (auth.CreateTokenResponseData, error) {
// Set the request headers
// Create output response variable
tokenInfo := auth.CreateTokenResponseData{}

// Set the request headers
httpDetails := ps.ServiceDetails.CreateHttpClientDetails()
utils.SetContentType("application/json", &httpDetails.Headers)
err := ps.addAccessTokenAuthorizationHeader(params, &httpDetails)
if err != nil {
return tokenInfo, err
}

// Marshall the request body
requestContent, err := json.Marshal(params)
if errorutils.CheckError(err) != nil {
return tokenInfo, err
Expand All @@ -66,10 +87,14 @@ func (ps *TokenService) createAccessToken(params CreateTokenParams) (auth.Create
if err = errorutils.CheckResponseStatusWithBody(resp, body, http.StatusOK); err != nil {
return tokenInfo, err
}

// Unmarshall the response body and return
err = json.Unmarshal(body, &tokenInfo)
return tokenInfo, errorutils.CheckError(err)
}

// Use AccessToken from ServiceDetails (which is the default behaviour)
// If that is not present then we can use the token we are refreshing as the token
func (ps *TokenService) addAccessTokenAuthorizationHeader(params CreateTokenParams, httpDetails *httputils.HttpClientDetails) error {
access := ps.ServiceDetails.GetAccessToken()
if access == "" {
Expand All @@ -81,16 +106,3 @@ func (ps *TokenService) addAccessTokenAuthorizationHeader(params CreateTokenPara
utils.AddHeader("Authorization", fmt.Sprintf("Bearer %s", access), &httpDetails.Headers)
return nil
}

func createRefreshTokenRequestParams(p CreateTokenParams) (*CreateTokenParams, error) {
var trueValue = true
// Validate provided parameters
if p.RefreshToken == "" {
return nil, errorutils.CheckErrorf("error: trying to refresh token, but 'refresh_token' field wasn't provided. ")
}
params := NewCreateTokenParams(p)
// Set refresh required parameters
params.GrantType = "refresh_token"
params.Refreshable = &trueValue
return &params, nil
}

0 comments on commit 9071933

Please sign in to comment.