#
cargo/ops/registry/
login.rs

    1//! Interacts with the registry [login API][1].
    2//!
    3//! This doesn't really call any web API at this moment. Instead, it's just an
    4//! operation for `cargo login`.
    5//!
    6//! [1]: https://doc.rust-lang.org/nightly/cargo/reference/registry-web-api.html#login
    7
    8use std::io::IsTerminal;
    9
    10use crate::CargoResult;
    11use crate::GlobalContext;
    12use crate::util::auth;
    13use crate::util::auth::AuthorizationError;
    14use cargo_credential::LoginOptions;
    15use cargo_credential::Secret;
    16
    17use super::RegistryOrIndex;
    18use super::get_source_id;
    19use super::registry;
    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}