fix(login): Deprecate CLI token (#15057)

### What does this PR try to resolve?

This came up in #13623 to avoid putting tokens into shell history.

### How should we test and review this PR?

The exact approach to deprecation can vary
- Include `<token>` in at least some docs for discovery (most likely the
man page)
- Don't warn yet

etc

I also suspect we could reorganize `cargo help login` but wanted to
decouple that from this change.

### Additional information
This commit is contained in:
Weihang Lo 2025-01-28 02:53:08 +00:00 committed by GitHub
commit 9eda47ee04
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 81 additions and 50 deletions

View File

@ -6,7 +6,12 @@ use crate::command_prelude::*;
pub fn cli() -> Command {
subcommand("login")
.about("Log in to a registry.")
.arg(Arg::new("token").value_name("TOKEN").action(ArgAction::Set))
.arg(
Arg::new("token")
.value_name("TOKEN")
.action(ArgAction::Set)
.hide(true),
)
.arg_registry("Registry to use")
.arg(
Arg::new("args")
@ -27,16 +32,18 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
"must not be index URL"
);
let token = args.get_one::<String>("token").map(|s| s.as_str().into());
if token.is_some() {
let _ = gctx
.shell()
.warn("`cargo login <token>` is deprecated in favor of reading `<token>` from stdin");
}
let extra_args = args
.get_many::<String>("args")
.unwrap_or_default()
.map(String::as_str)
.collect::<Vec<_>>();
ops::registry_login(
gctx,
args.get_one::<String>("token").map(|s| s.as_str().into()),
reg.as_ref(),
&extra_args,
)?;
ops::registry_login(gctx, token, reg.as_ref(), &extra_args)?;
Ok(())
}

View File

@ -6,7 +6,7 @@ cargo-login --- Log in to a registry
## SYNOPSIS
`cargo login` [_options_] [_token_] [`--` _args_]
`cargo login` [_options_] [`--` _args_]
## DESCRIPTION
@ -24,7 +24,7 @@ If a registry has a credential-provider specified, it will be used. Otherwise,
the providers from the config value `registry.global-credential-providers` will
be attempted, starting from the end of the list.
If the _token_ argument is not specified, it will be read from stdin.
The _token_ will be read from stdin.
The API token for crates.io may be retrieved from <https://crates.io/me>.

View File

@ -4,7 +4,7 @@ NAME
cargo-login — Log in to a registry
SYNOPSIS
cargo login [options] [token] [-- args]
cargo login [options] [-- args]
DESCRIPTION
This command will run a credential provider to save a token so that
@ -23,7 +23,7 @@ DESCRIPTION
registry.global-credential-providers will be attempted, starting from
the end of the list.
If the token argument is not specified, it will be read from stdin.
The token will be read from stdin.
The API token for crates.io may be retrieved from
<https://crates.io/me>.

View File

@ -6,7 +6,7 @@ cargo-login --- Log in to a registry
## SYNOPSIS
`cargo login` [_options_] [_token_] [`--` _args_]
`cargo login` [_options_] [`--` _args_]
## DESCRIPTION
@ -24,7 +24,7 @@ If a registry has a credential-provider specified, it will be used. Otherwise,
the providers from the config value `registry.global-credential-providers` will
be attempted, starting from the end of the list.
If the _token_ argument is not specified, it will be read from stdin.
The _token_ will be read from stdin.
The API token for crates.io may be retrieved from <https://crates.io/me>.

View File

@ -6,7 +6,7 @@
.SH "NAME"
cargo\-login \[em] Log in to a registry
.SH "SYNOPSIS"
\fBcargo login\fR [\fIoptions\fR] [\fItoken\fR] [\fB\-\-\fR \fIargs\fR]
\fBcargo login\fR [\fIoptions\fR] [\fB\-\-\fR \fIargs\fR]
.SH "DESCRIPTION"
This command will run a credential provider to save a token so that commands
that require authentication, such as \fBcargo\-publish\fR(1), will be
@ -22,7 +22,7 @@ If a registry has a credential\-provider specified, it will be used. Otherwise,
the providers from the config value \fBregistry.global\-credential\-providers\fR will
be attempted, starting from the end of the list.
.sp
If the \fItoken\fR argument is not specified, it will be read from stdin.
The \fItoken\fR will be read from stdin.
.sp
The API token for crates.io may be retrieved from <https://crates.io/me>\&.
.sp

View File

@ -814,7 +814,8 @@ fn no_api() {
"#]])
.run();
p.cargo("login --registry alternative TOKEN")
p.cargo("login --registry alternative")
.with_stdin("TOKEN")
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] registry `alternative` does not support API commands

View File

@ -1,4 +1,4 @@
<svg width="827px" height="470px" xmlns="http://www.w3.org/2000/svg">
<svg width="827px" height="452px" xmlns="http://www.w3.org/2000/svg">
<style>
.fg { fill: #AAAAAA }
.bg { background: #000000 }
@ -23,51 +23,49 @@
</tspan>
<tspan x="10px" y="46px">
</tspan>
<tspan x="10px" y="64px"><tspan class="fg-green bold">Usage:</tspan><tspan> </tspan><tspan class="fg-cyan bold">cargo[EXE] login</tspan><tspan> </tspan><tspan class="fg-cyan">[OPTIONS]</tspan><tspan> </tspan><tspan class="fg-cyan">[TOKEN]</tspan><tspan> </tspan><tspan class="fg-cyan bold">[--</tspan><tspan> </tspan><tspan class="fg-cyan">[args]...</tspan><tspan class="fg-cyan bold">]</tspan>
<tspan x="10px" y="64px"><tspan class="fg-green bold">Usage:</tspan><tspan> </tspan><tspan class="fg-cyan bold">cargo[EXE] login</tspan><tspan> </tspan><tspan class="fg-cyan">[OPTIONS]</tspan><tspan> </tspan><tspan class="fg-cyan bold">[--</tspan><tspan> </tspan><tspan class="fg-cyan">[args]...</tspan><tspan class="fg-cyan bold">]</tspan>
</tspan>
<tspan x="10px" y="82px">
</tspan>
<tspan x="10px" y="100px"><tspan class="fg-green bold">Arguments:</tspan>
</tspan>
<tspan x="10px" y="118px"><tspan> </tspan><tspan class="fg-cyan">[TOKEN]</tspan><tspan> </tspan>
<tspan x="10px" y="118px"><tspan> </tspan><tspan class="fg-cyan">[args]...</tspan><tspan> Additional arguments for the credential provider</tspan>
</tspan>
<tspan x="10px" y="136px"><tspan> </tspan><tspan class="fg-cyan">[args]...</tspan><tspan> Additional arguments for the credential provider</tspan>
<tspan x="10px" y="136px">
</tspan>
<tspan x="10px" y="154px">
<tspan x="10px" y="154px"><tspan class="fg-green bold">Options:</tspan>
</tspan>
<tspan x="10px" y="172px"><tspan class="fg-green bold">Options:</tspan>
<tspan x="10px" y="172px"><tspan> </tspan><tspan class="fg-cyan bold">--registry</tspan><tspan class="fg-cyan"> </tspan><tspan class="fg-cyan">&lt;REGISTRY&gt;</tspan><tspan> Registry to use</tspan>
</tspan>
<tspan x="10px" y="190px"><tspan> </tspan><tspan class="fg-cyan bold">--registry</tspan><tspan class="fg-cyan"> </tspan><tspan class="fg-cyan">&lt;REGISTRY&gt;</tspan><tspan> Registry to use</tspan>
<tspan x="10px" y="190px"><tspan> </tspan><tspan class="fg-cyan bold">-v</tspan><tspan>, </tspan><tspan class="fg-cyan bold">--verbose</tspan><tspan class="fg-cyan">...</tspan><tspan> Use verbose output (-vv very verbose/build.rs output)</tspan>
</tspan>
<tspan x="10px" y="208px"><tspan> </tspan><tspan class="fg-cyan bold">-v</tspan><tspan>, </tspan><tspan class="fg-cyan bold">--verbose</tspan><tspan class="fg-cyan">...</tspan><tspan> Use verbose output (-vv very verbose/build.rs output)</tspan>
<tspan x="10px" y="208px"><tspan> </tspan><tspan class="fg-cyan bold">-q</tspan><tspan>, </tspan><tspan class="fg-cyan bold">--quiet</tspan><tspan> Do not print cargo log messages</tspan>
</tspan>
<tspan x="10px" y="226px"><tspan> </tspan><tspan class="fg-cyan bold">-q</tspan><tspan>, </tspan><tspan class="fg-cyan bold">--quiet</tspan><tspan> Do not print cargo log messages</tspan>
<tspan x="10px" y="226px"><tspan> </tspan><tspan class="fg-cyan bold">--color</tspan><tspan class="fg-cyan"> </tspan><tspan class="fg-cyan">&lt;WHEN&gt;</tspan><tspan> Coloring: auto, always, never</tspan>
</tspan>
<tspan x="10px" y="244px"><tspan> </tspan><tspan class="fg-cyan bold">--color</tspan><tspan class="fg-cyan"> </tspan><tspan class="fg-cyan">&lt;WHEN&gt;</tspan><tspan> Coloring: auto, always, never</tspan>
<tspan x="10px" y="244px"><tspan> </tspan><tspan class="fg-cyan bold">--config</tspan><tspan class="fg-cyan"> </tspan><tspan class="fg-cyan">&lt;KEY=VALUE|PATH&gt;</tspan><tspan> Override a configuration value</tspan>
</tspan>
<tspan x="10px" y="262px"><tspan> </tspan><tspan class="fg-cyan bold">--config</tspan><tspan class="fg-cyan"> </tspan><tspan class="fg-cyan">&lt;KEY=VALUE|PATH&gt;</tspan><tspan> Override a configuration value</tspan>
<tspan x="10px" y="262px"><tspan> </tspan><tspan class="fg-cyan bold">-Z</tspan><tspan class="fg-cyan"> </tspan><tspan class="fg-cyan">&lt;FLAG&gt;</tspan><tspan> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for</tspan>
</tspan>
<tspan x="10px" y="280px"><tspan> </tspan><tspan class="fg-cyan bold">-Z</tspan><tspan class="fg-cyan"> </tspan><tspan class="fg-cyan">&lt;FLAG&gt;</tspan><tspan> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for</tspan>
<tspan x="10px" y="280px"><tspan> details</tspan>
</tspan>
<tspan x="10px" y="298px"><tspan> details</tspan>
<tspan x="10px" y="298px"><tspan> </tspan><tspan class="fg-cyan bold">-h</tspan><tspan>, </tspan><tspan class="fg-cyan bold">--help</tspan><tspan> Print help</tspan>
</tspan>
<tspan x="10px" y="316px"><tspan> </tspan><tspan class="fg-cyan bold">-h</tspan><tspan>, </tspan><tspan class="fg-cyan bold">--help</tspan><tspan> Print help</tspan>
<tspan x="10px" y="316px">
</tspan>
<tspan x="10px" y="334px">
<tspan x="10px" y="334px"><tspan class="fg-green bold">Manifest Options:</tspan>
</tspan>
<tspan x="10px" y="352px"><tspan class="fg-green bold">Manifest Options:</tspan>
<tspan x="10px" y="352px"><tspan> </tspan><tspan class="fg-cyan bold">--locked</tspan><tspan> Assert that `Cargo.lock` will remain unchanged</tspan>
</tspan>
<tspan x="10px" y="370px"><tspan> </tspan><tspan class="fg-cyan bold">--locked</tspan><tspan> Assert that `Cargo.lock` will remain unchanged</tspan>
<tspan x="10px" y="370px"><tspan> </tspan><tspan class="fg-cyan bold">--offline</tspan><tspan> Run without accessing the network</tspan>
</tspan>
<tspan x="10px" y="388px"><tspan> </tspan><tspan class="fg-cyan bold">--offline</tspan><tspan> Run without accessing the network</tspan>
<tspan x="10px" y="388px"><tspan> </tspan><tspan class="fg-cyan bold">--frozen</tspan><tspan> Equivalent to specifying both --locked and --offline</tspan>
</tspan>
<tspan x="10px" y="406px"><tspan> </tspan><tspan class="fg-cyan bold">--frozen</tspan><tspan> Equivalent to specifying both --locked and --offline</tspan>
<tspan x="10px" y="406px">
</tspan>
<tspan x="10px" y="424px">
<tspan x="10px" y="424px"><tspan>Run `</tspan><tspan class="fg-cyan bold">cargo help login</tspan><tspan class="bold">` for more detailed information.</tspan>
</tspan>
<tspan x="10px" y="442px"><tspan>Run `</tspan><tspan class="fg-cyan bold">cargo help login</tspan><tspan class="bold">` for more detailed information.</tspan>
</tspan>
<tspan x="10px" y="460px">
<tspan x="10px" y="442px">
</tspan>
</text>

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -95,7 +95,8 @@ fn basic_unsupported() {
.credential_provider(&["cargo:token-from-stdout", "false"])
.build();
cargo_process("login abcdefg")
cargo_process("login")
.with_stdin("abcdefg")
.replace_crates_io(registry.index_url())
.with_status(101)
.with_stderr_data(str![[r#"
@ -132,7 +133,8 @@ fn login() {
])
.build();
cargo_process("login abcdefg -- cmd3 --cmd4")
cargo_process("login -- cmd3 --cmd4")
.with_stdin("abcdefg")
.replace_crates_io(registry.index_url())
.with_stderr_data(str![[r#"
[UPDATING] crates.io index
@ -383,7 +385,8 @@ fn multiple_providers() {
)
.unwrap();
cargo_process("login -v abcdefg")
cargo_process("login -v")
.with_stdin("abcdefg")
.replace_crates_io(server.index_url())
.with_stderr_data(str![[r#"
[UPDATING] crates.io index
@ -429,7 +432,8 @@ fn registry_provider_overrides_global() {
)
.unwrap();
cargo_process("login -v abcdefg")
cargo_process("login -v")
.with_stdin("abcdefg")
.env("CARGO_REGISTRY_CREDENTIAL_PROVIDER", "cargo:token")
.replace_crates_io(server.index_url())
.with_stderr_data(str![[r#"
@ -460,7 +464,7 @@ fn both_asymmetric_and_token() {
)
.unwrap();
cargo_process("login -Zasymmetric-token -v abcdefg")
cargo_process("login -Zasymmetric-token -v").with_stdin("abcdefg")
.masquerade_as_nightly_cargo(&["asymmetric-token"])
.replace_crates_io(server.index_url())
.with_stderr_data(str![[r#"
@ -675,7 +679,8 @@ fn unsupported_version() {
.credential_provider(&[&provider])
.build();
cargo_process("login abcdefg")
cargo_process("login")
.with_stdin("abcdefg")
.replace_crates_io(registry.index_url())
.with_status(101)
.with_stderr_data(str![[r#"
@ -707,7 +712,8 @@ fn alias_builtin_warning() {
)
.unwrap();
cargo_process("login abcdefg")
cargo_process("login")
.with_stdin("abcdefg")
.replace_crates_io(registry.index_url())
.with_stderr_data(str![[r#"
[UPDATING] crates.io index

View File

@ -81,7 +81,10 @@ fn registry_credentials() {
let reg = "alternative";
cargo_process("login --registry").arg(reg).arg(TOKEN).run();
cargo_process("login --registry")
.arg(reg)
.with_stdin(TOKEN)
.run();
// Ensure that we have not updated the default token
check_token(Some(ORIGINAL_TOKEN), None);
@ -92,7 +95,7 @@ fn registry_credentials() {
let reg2 = "alternative2";
cargo_process("login --registry")
.arg(reg2)
.arg(TOKEN2)
.with_stdin(TOKEN2)
.run();
// Ensure not overwriting 1st alternate registry token with
@ -127,8 +130,24 @@ Caused by:
cargo_process("login")
.replace_crates_io(registry.index_url())
.arg("")
.with_stdin("")
.with_stderr_data(str![[r#"
please paste the token found on [ROOTURL]/api/me below
[ERROR] credential provider `cargo:token` failed action `login`
Caused by:
please provide a non-empty token
"#]])
.with_status(101)
.run();
cargo_process("login")
.replace_crates_io(registry.index_url())
.arg("")
.with_stdin("")
.with_stderr_data(str![[r#"
[WARNING] `cargo login <token>` is deprecated in favor of reading `<token>` from stdin
[ERROR] credential provider `cargo:token` failed action `login`
Caused by:
@ -356,7 +375,7 @@ fn default_registry_configured() {
.unwrap();
cargo_process("login")
.arg("a-new-token")
.with_stdin("a-new-token")
.with_stderr_data(str![[r#"
[UPDATING] `alternative` index
[LOGIN] token for `alternative` saved