Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 22 additions & 0 deletions docs/common/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ const (
JfrogCliServerID = ` JFROG_CLI_SERVER_ID
Server ID configured using the config command.`

JfrogCliUrl = ` JFROG_CLI_URL
[Default: None]
JFrog platform URL, used unless the --url command option is sent.`

//#nosec G101
JfrogCliAccessToken = ` JFROG_CLI_ACCESS_TOKEN
[Default: None]
JFrog access token, used unless the --access-token command option is sent.`

JfrogCliUser = ` JFROG_CLI_USER
[Default: None]
JFrog username, used unless the --user command option is sent.`

//#nosec G101
JfrogCliPassword = ` JFROG_CLI_PASSWORD
[Default: None]
JFrog password, used unless the --password command option is sent.`

Ci = ` CI
[Default: false]
If true, disables interactive prompts and progress bar.`
Expand Down Expand Up @@ -137,6 +155,10 @@ func GetGlobalEnvVars() string {
JfrogCliBuildNumber,
JfrogCliBuildProject,
JfrogCliServerID,
JfrogCliUrl,
JfrogCliAccessToken,
JfrogCliUser,
JfrogCliPassword,
Ci,
JfrogCliPluginsServer,
JfrogCliPluginsRepo,
Expand Down
6 changes: 6 additions & 0 deletions utils/cliutils/cli_consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ const (
//#nosec G101
JfrogCliGithubToken = "JFROG_CLI_GITHUB_TOKEN"
JfrogCliHideSurvey = "JFROG_CLI_HIDE_SURVEY"
JfrogCliUrl = "JFROG_CLI_URL"
//#nosec G101
JfrogCliAccessToken = "JFROG_CLI_ACCESS_TOKEN"
JfrogCliUser = "JFROG_CLI_USER"
//#nosec G101
JfrogCliPassword = "JFROG_CLI_PASSWORD"
// JfrogCliErrorOutputFormat controls how HTTP response errors are surfaced.
// Set to "json" to emit the structured response (status code + body) as JSON
// on stderr instead of the default human-readable text. Unset or "text" keeps
Expand Down
10 changes: 8 additions & 2 deletions utils/cliutils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,21 +318,27 @@ func getOrDefaultEnv(arg, envKey string) string {

func CreateServerDetailsFromFlags(c *cli.Context) (details *coreConfig.ServerDetails, err error) {
details = new(coreConfig.ServerDetails)
details.Url = clientutils.AddTrailingSlashIfNeeded(c.String(url))
details.Url = clientutils.AddTrailingSlashIfNeeded(getOrDefaultEnv(c.String(url), JfrogCliUrl))
details.ArtifactoryUrl = clientutils.AddTrailingSlashIfNeeded(c.String(configRtUrl))
details.DistributionUrl = clientutils.AddTrailingSlashIfNeeded(c.String(configDistUrl))
details.XrayUrl = clientutils.AddTrailingSlashIfNeeded(c.String(configXrUrl))
details.MissionControlUrl = clientutils.AddTrailingSlashIfNeeded(c.String(configMcUrl))
details.PipelinesUrl = clientutils.AddTrailingSlashIfNeeded(c.String(configPlUrl))
details.User = c.String(user)
details.User = getOrDefaultEnv(c.String(user), JfrogCliUser)
details.Password, err = handleSecretInput(c, password, passwordStdin)
if err != nil {
return
}
if details.Password == "" {
details.Password = os.Getenv(JfrogCliPassword)
}
details.AccessToken, err = handleSecretInput(c, accessToken, accessTokenStdin)
if err != nil {
return
}
if details.AccessToken == "" {
details.AccessToken = os.Getenv(JfrogCliAccessToken)
}
details.SshKeyPath = c.String(sshKeyPath)
details.SshPassphrase = c.String(sshPassphrase)
details.ClientCertPath = c.String(ClientCertPath)
Expand Down
94 changes: 94 additions & 0 deletions utils/cliutils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,100 @@ func TestGetFlagOrEnvValue(t *testing.T) {
}
}

func TestCreateServerDetailsFromFlagsEnvFallback(t *testing.T) {
testCases := []struct {
name string
flags map[string]string
env map[string]string
expectedUrl string
expectedUser string
expectedPassword string
expectedAccessToken string
}{
{
name: "url falls back to env",
env: map[string]string{JfrogCliUrl: "https://acme.jfrog.io"},
expectedUrl: "https://acme.jfrog.io/",
},
{
name: "url flag wins over env",
flags: map[string]string{url: "https://flag.jfrog.io"},
env: map[string]string{JfrogCliUrl: "https://env.jfrog.io"},
expectedUrl: "https://flag.jfrog.io/",
},
{
name: "access token falls back to env",
env: map[string]string{JfrogCliAccessToken: "env-token"},
expectedAccessToken: "env-token",
},
{
name: "access token flag wins over env",
flags: map[string]string{accessToken: "flag-token"},
env: map[string]string{JfrogCliAccessToken: "env-token"},
expectedAccessToken: "flag-token",
},
{
name: "user and password fall back to env",
env: map[string]string{JfrogCliUser: "env-user", JfrogCliPassword: "env-password"},
expectedUser: "env-user",
expectedPassword: "env-password",
},
{
name: "user and password flags win over env",
flags: map[string]string{user: "flag-user", password: "flag-password"},
env: map[string]string{JfrogCliUser: "env-user", JfrogCliPassword: "env-password"},
expectedUser: "flag-user",
expectedPassword: "flag-password",
},
{
name: "neither flags nor env keeps connection fields empty",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
for _, envVarName := range []string{JfrogCliUrl, JfrogCliAccessToken, JfrogCliUser, JfrogCliPassword} {
t.Setenv(envVarName, "")
}
for envVarName, envVarValue := range tc.env {
t.Setenv(envVarName, envVarValue)
}

flagValue := func(flagName string) string {
return tc.flags[flagName]
}
set := flag.NewFlagSet("test", 0)
set.String(url, flagValue(url), "")
set.String(configRtUrl, "", "")
set.String(configDistUrl, "", "")
set.String(configXrUrl, "", "")
set.String(configMcUrl, "", "")
set.String(configPlUrl, "", "")
set.String(user, flagValue(user), "")
set.String(password, flagValue(password), "")
set.Bool(passwordStdin, false, "")
set.String(accessToken, flagValue(accessToken), "")
set.Bool(accessTokenStdin, false, "")
set.String(sshKeyPath, "", "")
set.String(sshPassphrase, "", "")
set.String(ClientCertPath, "", "")
set.String(ClientCertKeyPath, "", "")
set.String(serverId, "", "")
set.Bool(InsecureTls, false, "")
set.Bool(disableTokenRefresh, false, "")
c := cli.NewContext(nil, set, nil)

details, err := CreateServerDetailsFromFlags(c)

assert.NoError(t, err)
assert.Equal(t, tc.expectedUrl, details.Url)
assert.Equal(t, tc.expectedUser, details.User)
assert.Equal(t, tc.expectedPassword, details.Password)
assert.Equal(t, tc.expectedAccessToken, details.AccessToken)
})
}
}

// TestAuthorizationHeaderInCliVersionCheck tests that the HTTP request for checking new CLI versions
// includes an authorization header when a GitHub token is provided.
func TestAuthorizationHeaderInCliVersionCheck(t *testing.T) {
Expand Down
Loading