Skip to content

Commit f88cd8d

Browse files
committed
at rest we can either have a credential process or a token
1 parent a77ed9b commit f88cd8d

File tree

2 files changed

+60
-21
lines changed

2 files changed

+60
-21
lines changed

src/cargo/ops/registry.rs

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,45 @@ mod auth;
3939
pub struct RegistryConfig {
4040
/// The index URL. If `None`, use crates.io.
4141
pub index: Option<String>,
42+
pub credential: Credential,
43+
}
44+
45+
#[derive(Debug)]
46+
pub enum Credential {
47+
None,
4248
/// The authentication token.
43-
pub token: Option<String>,
49+
Token(String),
4450
/// Process used for fetching a token.
45-
pub credential_process: Option<(PathBuf, Vec<String>)>,
51+
Process((PathBuf, Vec<String>)),
52+
}
53+
54+
impl RegistryConfig {
55+
/// Returns `true` if the credential is [`None`].
56+
///
57+
/// [`None`]: Credential::None
58+
pub fn is_none(&self) -> bool {
59+
matches!(&self.credential, Credential::None)
60+
}
61+
/// Returns `true` if the credential is [`Token`].
62+
///
63+
/// [`Token`]: Credential::Token
64+
pub fn is_token(&self) -> bool {
65+
matches!(&self.credential, Credential::Token(..))
66+
}
67+
pub fn as_token(&self) -> Option<&str> {
68+
if let Credential::Token(v) = &self.credential {
69+
Some(&*v)
70+
} else {
71+
None
72+
}
73+
}
74+
pub fn as_process(&self) -> Option<&(PathBuf, Vec<String>)> {
75+
if let Credential::Process(v) = &self.credential {
76+
Some(v)
77+
} else {
78+
None
79+
}
80+
}
4681
}
4782

4883
pub struct PublishOpts<'cfg> {
@@ -347,10 +382,10 @@ pub fn registry_configuration(
347382
let (index, token, process) = match registry {
348383
Some(registry) => {
349384
let index = Some(config.get_registry_index(registry)?.to_string());
350-
let token_key = format!("registries.{}.token", registry);
385+
let token_key = format!("registries.{registry}.token");
351386
let token = config.get_string(&token_key)?.map(|p| p.val);
352387
let process = if config.cli_unstable().credential_process {
353-
let mut proc_key = format!("registries.{}.credential-process", registry);
388+
let mut proc_key = format!("registries.{registry}.credential-process");
354389
let mut process = config.get::<Option<config::PathAndArgs>>(&proc_key)?;
355390
if process.is_none() && token.is_none() {
356391
// This explicitly ignores the global credential-process if
@@ -389,8 +424,12 @@ pub fn registry_configuration(
389424

390425
Ok(RegistryConfig {
391426
index,
392-
token,
393-
credential_process,
427+
credential: match (token, credential_process) {
428+
(None, None) => Credential::None,
429+
(None, Some(process)) => Credential::Process(process),
430+
(Some(x), None) => Credential::Token(x),
431+
(Some(_), Some(_)) => unreachable!("Only one of these values may be set."),
432+
},
394433
})
395434
}
396435

@@ -459,7 +498,7 @@ fn registry(
459498
// people. It will affect those using source replacement, but
460499
// hopefully that's a relatively small set of users.
461500
if token.is_none()
462-
&& reg_cfg.token.is_some()
501+
&& reg_cfg.is_token()
463502
&& registry.is_none()
464503
&& !sid.is_default_registry()
465504
&& !crates_io::is_url_crates_io(&api_host)
@@ -471,13 +510,12 @@ fn registry(
471510
see <https://github.com/rust-lang/cargo/issues/xxx>.\n\
472511
Use the --token command-line flag to remove this warning.",
473512
)?;
474-
reg_cfg.token.clone()
513+
reg_cfg.as_token().map(|t| t.to_owned())
475514
} else {
476515
let token = auth::auth_token(
477516
config,
478517
token.as_deref(),
479-
reg_cfg.token.as_deref(),
480-
reg_cfg.credential_process.as_ref(),
518+
&reg_cfg.credential,
481519
registry.as_deref(),
482520
&api_host,
483521
)?;
@@ -714,7 +752,7 @@ pub fn registry_login(
714752
}
715753
};
716754

717-
if let Some(old_token) = &reg_cfg.token {
755+
if let Credential::Token(old_token) = &reg_cfg.credential {
718756
if old_token == &token {
719757
config.shell().status("Login", "already logged in")?;
720758
return Ok(());
@@ -724,7 +762,7 @@ pub fn registry_login(
724762
auth::login(
725763
config,
726764
token,
727-
reg_cfg.credential_process.as_ref(),
765+
reg_cfg.as_process(),
728766
reg.as_deref(),
729767
registry.host(),
730768
)?;
@@ -742,7 +780,7 @@ pub fn registry_login(
742780
pub fn registry_logout(config: &Config, reg: Option<String>) -> CargoResult<()> {
743781
let (registry, reg_cfg, _) = registry(config, None, None, reg.clone(), false, false)?;
744782
let reg_name = reg.as_deref().unwrap_or(CRATES_IO_DOMAIN);
745-
if reg_cfg.credential_process.is_none() && reg_cfg.token.is_none() {
783+
if reg_cfg.is_none() {
746784
config.shell().status(
747785
"Logout",
748786
format!("not currently logged in to `{}`", reg_name),
@@ -751,7 +789,7 @@ pub fn registry_logout(config: &Config, reg: Option<String>) -> CargoResult<()>
751789
}
752790
auth::logout(
753791
config,
754-
reg_cfg.credential_process.as_ref(),
792+
reg_cfg.as_process(),
755793
reg.as_deref(),
756794
registry.host(),
757795
)?;

src/cargo/ops/registry/auth.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ use std::io::{Read, Write};
88
use std::path::PathBuf;
99
use std::process::{Command, Stdio};
1010

11+
use super::Credential;
12+
1113
enum Action {
1214
Get,
1315
Store(String),
@@ -18,18 +20,17 @@ enum Action {
1820
pub(super) fn auth_token(
1921
config: &Config,
2022
cli_token: Option<&str>,
21-
config_token: Option<&str>,
22-
credential_process: Option<&(PathBuf, Vec<String>)>,
23+
credential: &Credential,
2324
registry_name: Option<&str>,
2425
api_url: &str,
2526
) -> CargoResult<String> {
26-
let token = match (cli_token, config_token, credential_process) {
27-
(None, None, None) => {
27+
let token = match (cli_token, credential) {
28+
(None, Credential::None) => {
2829
bail!("no upload token found, please run `cargo login` or pass `--token`");
2930
}
30-
(Some(cli_token), _, _) => cli_token.to_string(),
31-
(None, Some(config_token), _) => config_token.to_string(),
32-
(None, None, Some(process)) => {
31+
(Some(cli_token), _) => cli_token.to_string(),
32+
(None, Credential::Token(config_token)) => config_token.to_string(),
33+
(None, Credential::Process(process)) => {
3334
let registry_name = registry_name.unwrap_or(CRATES_IO_REGISTRY);
3435
run_command(config, process, registry_name, api_url, Action::Get)?.unwrap()
3536
}

0 commit comments

Comments
 (0)