cargo/ops/registry/
login.rs1use std::io::IsTerminal;
9
10use crate::util::auth;
11use crate::util::auth::AuthorizationError;
12use crate::CargoResult;
13use crate::GlobalContext;
14use cargo_credential::LoginOptions;
15use cargo_credential::Secret;
16
17use super::get_source_id;
18use super::registry;
19use super::RegistryOrIndex;
20
21pub fn registry_login(
22 gctx: &GlobalContext,
23 token_from_cmdline: Option<Secret<&str>>,
24 reg_or_index: Option<&RegistryOrIndex>,
25 args: &[&str],
26) -> CargoResult<()> {
27 let source_ids = get_source_id(gctx, reg_or_index)?;
28
29 let login_url = match registry(
30 gctx,
31 &source_ids,
32 token_from_cmdline.clone(),
33 reg_or_index,
34 false,
35 None,
36 ) {
37 Ok((registry, _)) => Some(format!("{}/me", registry.host())),
38 Err(e) if e.is::<AuthorizationError>() => e
39 .downcast::<AuthorizationError>()
40 .unwrap()
41 .login_url
42 .map(|u| u.to_string()),
43 Err(e) => return Err(e),
44 };
45
46 let mut token_from_stdin = None;
47 let token = token_from_cmdline.or_else(|| {
48 if !std::io::stdin().is_terminal() {
49 let token = cargo_credential::read_line().unwrap_or_default();
50 if !token.is_empty() {
51 token_from_stdin = Some(token);
52 }
53 }
54 token_from_stdin.as_deref().map(Secret::from)
55 });
56
57 let options = LoginOptions {
58 token,
59 login_url: login_url.as_deref(),
60 };
61
62 auth::login(gctx, &source_ids.original, options, args)?;
63 Ok(())
64}