Skip to content

Commit

Permalink
login: improve text on already authenticated and on OAuth login
Browse files Browse the repository at this point in the history
Users have trouble understanding the different login paths on the CLI.
The default login is performed through an OAuth flow with the option
to fallback to a username and PAT login using the `docker login -u
<username>` option.

This patch improves the text around `docker login`, indicating:
1. The username is shown when already authenticated
2. When not authenticated, the OAuth login flow explains the fallback
clearly to the user and indicates a PAT can be used instead of a
password.
3. The password prompt now explicitly states that it accepts a PAT.

Signed-off-by: Alano Terblanche <[email protected]>
  • Loading branch information
Benehiko committed Jan 28, 2025
1 parent 41c2786 commit 02f89d5
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 7 deletions.
2 changes: 1 addition & 1 deletion cli/command/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func PromptUserForCredentials(ctx context.Context, cli Cli, argUser, argPassword
}
}()

argPassword, err = PromptForInput(ctx, cli.In(), cli.Out(), "Password: ")
argPassword, err = PromptForInput(ctx, cli.In(), cli.Out(), "Password/PAT: ")
if err != nil {
return registrytypes.AuthConfig{}, err
}
Expand Down
11 changes: 8 additions & 3 deletions cli/command/registry/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ func NewLoginCommand(dockerCli command.Cli) *cobra.Command {
flags := cmd.Flags()

flags.StringVarP(&opts.user, "username", "u", "", "Username")
flags.StringVarP(&opts.password, "password", "p", "", "Password")
flags.BoolVar(&opts.passwordStdin, "password-stdin", false, "Take the password from stdin")
flags.StringVarP(&opts.password, "password", "p", "", "Password/PAT")
flags.BoolVar(&opts.passwordStdin, "password-stdin", false, "Take the password/PAT from stdin")

return cmd
}
Expand Down Expand Up @@ -120,7 +120,12 @@ func runLogin(ctx context.Context, dockerCli command.Cli, opts loginOptions) err
}

func loginWithStoredCredentials(ctx context.Context, dockerCli command.Cli, authConfig registrytypes.AuthConfig) (msg string, _ error) {
_, _ = fmt.Fprintf(dockerCli.Out(), "Authenticating with existing credentials...\n")
_, _ = fmt.Fprintf(dockerCli.Out(), "Authenticating with existing credentials...")
if authConfig.Username != "" {
_, _ = fmt.Fprintf(dockerCli.Out(), " [Username: %s]", authConfig.Username)
}

_, _ = fmt.Fprintf(dockerCli.Out(), "\nTo login with a different account, run 'docker logout' followed by 'docker login'\n\n")
response, err := dockerCli.Client().RegistryLogin(ctx, authConfig)
if err != nil {
if errdefs.IsUnauthorized(err) {
Expand Down
4 changes: 2 additions & 2 deletions cli/command/registry/login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ func TestLoginWithCredStoreCreds(t *testing.T) {
}{
{
inputAuthConfig: registrytypes.AuthConfig{},
expectedMsg: "Authenticating with existing credentials...\n",
expectedMsg: "Authenticating with existing credentials...\nTo login with a different account, run 'docker logout' followed by 'docker login'\n\n",
},
{
inputAuthConfig: registrytypes.AuthConfig{
Username: unknownUser,
},
expectedErr: errUnknownUser,
expectedMsg: "Authenticating with existing credentials...\n",
expectedMsg: "Authenticating with existing credentials... [Username: userunknownError]\nTo login with a different account, run 'docker logout' followed by 'docker login'\n\n",
expectedErrMsg: fmt.Sprintf("Login did not succeed, error: %s\n", errUnknownUser),
},
}
Expand Down
3 changes: 2 additions & 1 deletion cli/internal/oauth/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ func (m *OAuthManager) LoginDevice(ctx context.Context, w io.Writer) (*types.Aut
}

_, _ = fmt.Fprintln(w, aec.Bold.Apply("\nUSING WEB-BASED LOGIN"))
_, _ = fmt.Fprintln(w, "To sign in with credentials on the command line, use 'docker login -u <username>'")
_, _ = fmt.Fprintln(w, "> To sign in with username and PAT credentials on the command line, use 'docker login -u <username>'")
_, _ = fmt.Fprintln(w, "> When prompted to enter a password, enter the PAT retrieved from: "+aec.Underline.Apply("https://app.docker.com/settings"))
_, _ = fmt.Fprintf(w, "\nYour one-time device confirmation code is: "+aec.Bold.Apply("%s\n"), state.UserCode)
_, _ = fmt.Fprintf(w, aec.Bold.Apply("Press ENTER")+" to open your browser or submit your device code here: "+aec.Underline.Apply("%s\n"), strings.Split(state.VerificationURI, "?")[0])

Expand Down

0 comments on commit 02f89d5

Please sign in to comment.