@@ -3,6 +3,7 @@ package commands
33import (
44 "errors"
55 "fmt"
6+ generic "github.com/jfrog/jfrog-cli-core/v2/general/token"
67 "net/url"
78 "os"
89 "reflect"
@@ -39,11 +40,11 @@ const (
3940 BasicAuth AuthenticationMethod = "Username and Password / Reference token"
4041 MTLS AuthenticationMethod = "Mutual TLS"
4142 WebLogin AuthenticationMethod = "Web Login"
43+ // Currently supported only non-interactively.
44+ OIDC AuthenticationMethod = "OIDC"
4245)
4346
4447const (
45- // Indicates that the config command uses OIDC authentication.
46- configOidcCommandName = "config_oidc"
4748 // Default config command name.
4849 configCommandName = "config"
4950)
@@ -63,8 +64,9 @@ type ConfigCommand struct {
6364 // Forcibly make the configured server default.
6465 makeDefault bool
6566 // For unit tests
66- disablePrompts bool
67- cmdType ConfigAction
67+ disablePrompts bool
68+ cmdType ConfigAction
69+ oidcSetupParams * generic.OidcParams
6870}
6971
7072func NewConfigCommand (cmdType ConfigAction , serverId string ) * ConfigCommand {
@@ -150,27 +152,9 @@ func (cc *ConfigCommand) ServerDetails() (*config.ServerDetails, error) {
150152}
151153
152154func (cc * ConfigCommand ) CommandName () string {
153- oidcConfigured , err := clientUtils .GetBoolEnvValue (coreutils .UsageOidcConfigured , false )
154- if err != nil {
155- log .Warn ("Failed to get the value of the environment variable: " + coreutils .UsageAutoPublishedBuild + ". " + err .Error ())
156- }
157- if oidcConfigured {
158- return configOidcCommandName
159- }
160155 return configCommandName
161156}
162157
163- // ExecAndReportUsage runs the ConfigCommand and then triggers a usage report if needed,
164- // Report usage only if OIDC integration was used
165- // Usage must be sent after command execution as we need the server details to be set.
166- func (cc * ConfigCommand ) ExecAndReportUsage () (err error ) {
167- if err = cc .Run (); err != nil {
168- return
169- }
170- reportUsage (cc , nil )
171- return
172- }
173-
174158func (cc * ConfigCommand ) config () error {
175159 configurations , err := cc .prepareConfigurationData ()
176160 if err != nil {
@@ -215,6 +199,12 @@ func (cc *ConfigCommand) getConfigurationNonInteractively() error {
215199 }
216200 }
217201
202+ if cc .OidcAuthMethodUsed () {
203+ if err := exchangeOidcTokenAndSetAccessToken (cc ); err != nil {
204+ return err
205+ }
206+ }
207+
218208 if cc .details .AccessToken != "" && cc .details .User == "" {
219209 if err := cc .validateTokenIsNotApiKey (); err != nil {
220210 return err
@@ -224,6 +214,35 @@ func (cc *ConfigCommand) getConfigurationNonInteractively() error {
224214 return nil
225215}
226216
217+ // When a user is configuration a new server with OIDC, we will exchange the token and set the access token.
218+ func exchangeOidcTokenAndSetAccessToken (cc * ConfigCommand ) error {
219+ if err := validateOidcParams (cc .details .Url , cc .oidcSetupParams ); err != nil {
220+ return err
221+ }
222+ log .Debug ("Exchanging OIDC token..." )
223+ exchangeOidcTokenCmd := generic .NewOidcTokenExchangeCommand ()
224+ exchangeOidcTokenCmd .
225+ SetServerDetails (cc .details ).
226+ SetProviderName (cc .oidcSetupParams .ProviderName ).
227+ SetOidcTokenID (cc .oidcSetupParams .TokenId ).
228+ SetProviderType (cc .oidcSetupParams .ProviderType ).
229+ SetAudience (cc .oidcSetupParams .Audience ).
230+ SetApplicationKey (cc .oidcSetupParams .ApplicationKey ).
231+ SetProjectKey (cc .oidcSetupParams .ProjectKey ).
232+ SetRepository (cc .oidcSetupParams .Repository ).
233+ SetJobId (cc .oidcSetupParams .JobId ).
234+ SetRunId (cc .oidcSetupParams .RunId )
235+
236+ // Usage report will be sent only after execution in order to have valid token
237+ err := ExecAndThenReportUsage (exchangeOidcTokenCmd )
238+ if err != nil {
239+ return err
240+ }
241+ // Update the config server details with the exchanged token
242+ cc .details .AccessToken = exchangeOidcTokenCmd .GetExchangedToken ()
243+ return nil
244+ }
245+
227246func (cc * ConfigCommand ) addTrailingSlashes () {
228247 cc .details .ArtifactoryUrl = clientUtils .AddTrailingSlashIfNeeded (cc .details .ArtifactoryUrl )
229248 cc .details .DistributionUrl = clientUtils .AddTrailingSlashIfNeeded (cc .details .DistributionUrl )
@@ -281,6 +300,7 @@ func (cc *ConfigCommand) prepareConfigurationData() ([]*config.ServerDetails, er
281300 if cc .defaultDetails != nil {
282301 cc .details .InsecureTls = cc .defaultDetails .InsecureTls
283302 }
303+ cc .oidcSetupParams = new (generic.OidcParams )
284304 }
285305
286306 // Get configurations list
@@ -404,6 +424,7 @@ func (cc *ConfigCommand) promptAuthMethods() (selectedMethod AuthenticationMetho
404424 WebLogin ,
405425 BasicAuth ,
406426 MTLS ,
427+ OIDC ,
407428 }
408429 var selectableItems []ioutils.PromptItem
409430 for _ , curMethod := range authMethods {
@@ -483,6 +504,15 @@ func (cc *ConfigCommand) readClientCertInfoFromConsole() {
483504 }
484505}
485506
507+ func (cc * ConfigCommand ) SetOidcExchangeTokenId (id string ) {
508+ cc .oidcSetupParams .TokenId = id
509+ }
510+
511+ // If OIDC params were provided it indicates that we should use OIDC authentication method.
512+ func (cc * ConfigCommand ) OidcAuthMethodUsed () bool {
513+ return cc .oidcSetupParams != nil && cc .oidcSetupParams .ProviderName != ""
514+ }
515+
486516func readAccessTokenFromConsole (details * config.ServerDetails ) error {
487517 token , err := ioutils .ScanPasswordFromConsole ("JFrog access token:" )
488518 if err == nil {
@@ -817,6 +847,11 @@ func (cc *ConfigCommand) handleWebLogin() error {
817847 return nil
818848}
819849
850+ func (cc * ConfigCommand ) SetOIDCParams (oidcDetails * generic.OidcParams ) * ConfigCommand {
851+ cc .oidcSetupParams = oidcDetails
852+ return cc
853+ }
854+
820855// Return true if a URL is safe. URL is considered not safe if the following conditions are met:
821856// 1. The URL uses an http:// scheme
822857// 2. The URL leads to a URL outside the local machine
@@ -852,6 +887,7 @@ func assertSingleAuthMethod(details *config.ServerDetails) error {
852887
853888type ConfigCommandConfiguration struct {
854889 ServerDetails * config.ServerDetails
890+ OidcParams * generic.OidcParams
855891 Interactive bool
856892 EncPassword bool
857893 BasicAuthOnly bool
@@ -868,3 +904,16 @@ func GetAllServerIds() []string {
868904 }
869905 return serverIds
870906}
907+
908+ func validateOidcParams (platformUrl string , oidcParams * generic.OidcParams ) error {
909+ if platformUrl == "" {
910+ return errorutils .CheckErrorf ("the --url flag must be provided when --oidc-provider is used" )
911+ }
912+ if oidcParams .TokenId == "" {
913+ return errorutils .CheckErrorf ("the --oidc-token-id flag must be provided when --oidc-provider is used. Ensure the flag is set or the environment variable is exported. If running on a CI server, verify the token is correctly injected." )
914+ }
915+ if oidcParams .ProviderName == "" {
916+ return errorutils .CheckErrorf ("the --oidc-provider flag must be provided when using OIDC authentication" )
917+ }
918+ return nil
919+ }
0 commit comments