fallback to regular login if oauth login fails to start

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

View File

@ -165,10 +165,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) {

View File

@ -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"
)
@ -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,
// printing instructions to the provided writer and attempting to open the
// 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) {
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"))