Skip to content

Commit

Permalink
fallback to regular login if oauth login fails to start
Browse files Browse the repository at this point in the history
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
  • Loading branch information
laurazard committed Aug 13, 2024
1 parent 58bf2cc commit 69f8157
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 5 deletions.
12 changes: 9 additions & 3 deletions cli/command/registry/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,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) {
// 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 == "" {
return loginWithDeviceCodeFlow(ctx, dockerCli)
} else {
return loginWithUsernameAndPassword(ctx, dockerCli, opts, defaultUsername, serverAddress)
response, err := loginWithDeviceCodeFlow(ctx, dockerCli)
// if the error represents a failure to initiate the device-code flow,
// 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) {
Expand Down
9 changes: 7 additions & 2 deletions cli/internal/oauth/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/docker/cli/cli/internal/oauth/api"
"github.com/docker/docker/registry"
"github.com/morikuni/aec"
"github.com/sirupsen/logrus"

"github.com/pkg/browser"
)
Expand Down Expand Up @@ -66,6 +67,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,
// printing instructions to the provided writer and attempting to open the
// browser for the user to authenticate.
Expand All @@ -76,11 +79,13 @@ func New(options OAuthManagerOptions) *OAuthManager {
func (m *OAuthManager) LoginDevice(ctx context.Context, w io.Writer) (*types.AuthConfig, error) {
state, err := m.api.GetDeviceCode(ctx, m.audience)
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 == "" {
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"))
Expand Down

0 comments on commit 69f8157

Please sign in to comment.