fallback to regular login if oauth login fails to start

Signed-off-by: Laura Brehm <laurabrehm@hey.com>
This commit is contained in:
Laura Brehm 2024-08-13 13:54:16 +01:00
parent 5eb3275c28
commit c3fe7bc336
No known key found for this signature in database
GPG Key ID: 08EC1B0491948487
2 changed files with 16 additions and 5 deletions

View File

@ -144,10 +144,16 @@ func loginWithStoredCredentials(ctx context.Context, dockerCli command.Cli, auth
func loginUser(ctx context.Context, dockerCli command.Cli, opts loginOptions, defaultUsername, serverAddress string) (*registrytypes.AuthenticateOKBody, error) { func loginUser(ctx context.Context, dockerCli command.Cli, opts loginOptions, defaultUsername, serverAddress string) (*registrytypes.AuthenticateOKBody, error) {
// If we're logging into the index server and the user didn't provide a username or password, use the device flow // If we're logging into the index server and the user didn't provide a username or password, use the device flow
if serverAddress == registry.IndexServer && opts.user == "" && opts.password == "" { if serverAddress == registry.IndexServer && opts.user == "" && opts.password == "" {
return loginWithDeviceCodeFlow(ctx, dockerCli) response, err := loginWithDeviceCodeFlow(ctx, dockerCli)
} else { // if the error represents a failure to initiate the device-code flow,
return loginWithUsernameAndPassword(ctx, dockerCli, opts, defaultUsername, serverAddress) // then we fallback to regular cli credentials login
if !errors.Is(err, manager.ErrDeviceLoginStartFail) {
return response, err
}
fmt.Fprint(dockerCli.Err(), "Failed to start web-based login - falling back to command line login...\n\n")
} }
return loginWithUsernameAndPassword(ctx, dockerCli, opts, defaultUsername, serverAddress)
} }
func loginWithUsernameAndPassword(ctx context.Context, dockerCli command.Cli, opts loginOptions, defaultUsername, serverAddress string) (*registrytypes.AuthenticateOKBody, error) { func loginWithUsernameAndPassword(ctx context.Context, dockerCli command.Cli, opts loginOptions, defaultUsername, serverAddress string) (*registrytypes.AuthenticateOKBody, error) {

View File

@ -15,6 +15,7 @@ import (
"github.com/docker/cli/cli/internal/oauth/api" "github.com/docker/cli/cli/internal/oauth/api"
"github.com/docker/docker/registry" "github.com/docker/docker/registry"
"github.com/morikuni/aec" "github.com/morikuni/aec"
"github.com/sirupsen/logrus"
"github.com/pkg/browser" "github.com/pkg/browser"
) )
@ -70,6 +71,8 @@ func New(options OAuthManagerOptions) *OAuthManager {
} }
} }
var ErrDeviceLoginStartFail = errors.New("failed to start device code flow login")
// LoginDevice launches the device authentication flow with the tenant, // LoginDevice launches the device authentication flow with the tenant,
// printing instructions to the provided writer and attempting to open the // printing instructions to the provided writer and attempting to open the
// browser for the user to authenticate. // browser for the user to authenticate.
@ -80,11 +83,13 @@ func New(options OAuthManagerOptions) *OAuthManager {
func (m *OAuthManager) LoginDevice(ctx context.Context, w io.Writer) (*types.AuthConfig, error) { func (m *OAuthManager) LoginDevice(ctx context.Context, w io.Writer) (*types.AuthConfig, error) {
state, err := m.api.GetDeviceCode(ctx, m.audience) state, err := m.api.GetDeviceCode(ctx, m.audience)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get device code: %w", err) logrus.Debugf("failed to start device code login: %v", err)
return nil, ErrDeviceLoginStartFail
} }
if state.UserCode == "" { if state.UserCode == "" {
return nil, errors.New("no user code returned") logrus.Debugf("failed to start device code login: missing user code")
return nil, ErrDeviceLoginStartFail
} }
_, _ = fmt.Fprintln(w, aec.Bold.Apply("\nUSING WEB BASED LOGIN")) _, _ = fmt.Fprintln(w, aec.Bold.Apply("\nUSING WEB BASED LOGIN"))