-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
login: improve text on already authenticated and on OAuth login #5774
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #5774 +/- ##
==========================================
- Coverage 59.42% 59.41% -0.02%
==========================================
Files 347 347
Lines 29402 29414 +12
==========================================
+ Hits 17472 17476 +4
- Misses 10958 10966 +8
Partials 972 972 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I'll update the tests quick so we can get this in. I think we might also want to adjust the prompt slightly when using |
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]>
6594119
to
02f89d5
Compare
Signed-off-by: Alano Terblanche <[email protected]>
@vvoland please take another look, added some additional changes and regenerated the documents |
cli/command/registry.go
Outdated
@@ -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: ") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PAT feels a bit awkward as a prompt. @thaJeztah @laurazard any opinions on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I'm a bit unsure. I think it's nice to be explicit (we could even say secret
!) but I think in general, password is what's expected by users, and other CLIs that also accept other types of secrets usually default to password
.
cli/command/registry/login.go
Outdated
flags.StringVarP(&opts.password, "password", "p", "", "Password/PAT") | ||
flags.BoolVar(&opts.passwordStdin, "password-stdin", false, "Take the password/PAT from stdin") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WDYT about expanding the acronym in the description?
flags.StringVarP(&opts.password, "password", "p", "", "Password/PAT") | |
flags.BoolVar(&opts.passwordStdin, "password-stdin", false, "Take the password/PAT from stdin") | |
flags.StringVarP(&opts.password, "password", "p", "", "Password or Personal Access Token (PAT)") | |
flags.BoolVar(&opts.passwordStdin, "password-stdin", false, "Take the password/PAT from stdin") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I can expand it
cli/command/registry.go
Outdated
@@ -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: ") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I'm a bit unsure. I think it's nice to be explicit (we could even say secret
!) but I think in general, password is what's expected by users, and other CLIs that also accept other types of secrets usually default to password
.
_, _ = 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") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is clearer for sure! I wish we could improve this eventually. Maybe in the future we can do something like prompt the user, if TTY – something like Found credentials for index.docker.io. Reuse credentials (Y/n)?
WDYT @thaJeztah @vvoland ?
@@ -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>'") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...username and PAT credentials
sounds weird (weirder than it already does).
Either keep it as is, which isn't great but works for password/PAT/whatever, or we should reword this.
@@ -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")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
??? This feels like the CLI going around the CLIs back and telling users to do something else 😅
Users can use PATs, but telling users explicitly to use PATs from the Web login prompt feels weird when they can also use passwords. And it turns an already long prompt that most users don't read all the way through even longer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thoughts @dvdksn ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, making this prompt even longer will have the opposite effect I think. The longer it is, the less likely a user is to read it at all. That's why we were trying to keep it as terse as possible in the first iteration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about Organizational Access Tokens (OAT)?
I think in general I would prefer if we used terminology like "Credential login" vs "Device login", where credential login encompasses username+pw/pat/oat. I don't like the idea of listing all the possible options in the CLI.
Signed-off-by: Alano Terblanche <[email protected]>
@@ -178,7 +179,15 @@ func PromptUserForCredentials(ctx context.Context, cli Cli, argUser, argPassword | |||
} | |||
}() | |||
|
|||
argPassword, err = PromptForInput(ctx, cli.In(), cli.Out(), "Password: ") | |||
var credentialPrompt strings.Builder | |||
credentialPrompt.WriteString( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could reuse the Info ->
printing from image push, it also handles the non-tty vs tty output:
Lines 187 to 207 in bdd70c1
func printNote(dockerCli command.Cli, format string, args ...any) { | |
if dockerCli.Err().IsTerminal() { | |
format = strings.ReplaceAll(format, "--platform", aec.Bold.Apply("--platform")) | |
} | |
header := " Info -> " | |
padding := len(header) | |
if dockerCli.Err().IsTerminal() { | |
padding = len("i Info > ") | |
header = aec.Bold.Apply(aec.LightCyanB.Apply(aec.BlackF.Apply("i")) + " " + aec.LightCyanF.Apply("Info → ")) | |
} | |
_, _ = fmt.Fprint(dockerCli.Err(), header) | |
s := fmt.Sprintf(format, args...) | |
for idx, line := range strings.Split(s, "\n") { | |
if idx > 0 { | |
_, _ = fmt.Fprint(dockerCli.Err(), strings.Repeat(" ", padding)) | |
} | |
_, _ = fmt.Fprintln(dockerCli.Err(), aec.Italic.Apply(line)) | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, maybe we could merge your PR https://github.com/docker/cli/pull/5744/files#diff-b4864574dd8732ca90419836bdba5372ed10f8107dc49bf811adbfc0a1506592R15-R36
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:- What I did
- How I did it
- How to verify it
- Description for the changelog
- A picture of a cute animal (not mandatory but encouraged)