mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Load credentials only when needed
Credentials are always loaded, even if these are not used. If access to confidential files such as credentials is not given, `cargo build` fails despite not using credentials. Fixes #7624.
This commit is contained in:
parent
6e1ca924a6
commit
4b70f14903
@ -26,6 +26,8 @@ pub fn cli() -> App {
|
||||
}
|
||||
|
||||
pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
|
||||
config.load_credentials()?;
|
||||
|
||||
let registry = args.registry(config)?;
|
||||
let ws = args.workspace(config)?;
|
||||
let index = args.index(config)?;
|
||||
|
@ -746,7 +746,6 @@ impl Config {
|
||||
})
|
||||
.chain_err(|| "could not load Cargo configuration")?;
|
||||
|
||||
self.load_credentials(&mut cfg)?;
|
||||
match cfg {
|
||||
CV::Table(map, _) => Ok(map),
|
||||
_ => unreachable!(),
|
||||
@ -979,9 +978,8 @@ impl Config {
|
||||
Ok(url)
|
||||
}
|
||||
|
||||
/// Loads credentials config from the credentials file into the `ConfigValue` object, if
|
||||
/// present.
|
||||
fn load_credentials(&self, cfg: &mut ConfigValue) -> CargoResult<()> {
|
||||
/// Loads credentials config from the credentials file, if present.
|
||||
pub fn load_credentials(&mut self) -> CargoResult<()> {
|
||||
let home_path = self.home_path.clone().into_path_unlocked();
|
||||
let credentials = match self.get_file_path(&home_path, "credentials", true)? {
|
||||
Some(credentials) => credentials,
|
||||
@ -1006,7 +1004,28 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
cfg.merge(value, true)?;
|
||||
if let CV::Table(mut map, _) = value {
|
||||
if map.contains_key("registry") {
|
||||
if let Some(mut new_map) = self.values_mut()?.remove("registry") {
|
||||
let token = map.remove("registry").unwrap();
|
||||
new_map.merge(token, true)?;
|
||||
self.values_mut()?.insert("registry".into(), new_map);
|
||||
} else {
|
||||
self.values_mut()?
|
||||
.insert("registry".into(), map.remove("registry").unwrap());
|
||||
}
|
||||
}
|
||||
if map.contains_key("registries") {
|
||||
if let Some(mut new_map) = self.values_mut()?.remove("registries") {
|
||||
let token = map.remove("registries").unwrap();
|
||||
new_map.merge(token, true)?;
|
||||
self.values_mut()?.insert("registries".into(), new_map);
|
||||
} else {
|
||||
self.values_mut()?
|
||||
.insert("registries".into(), map.remove("registries").unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -2237,6 +2237,32 @@ fn recompile_space_in_name() {
|
||||
foo.cargo("build").with_stdout("").run();
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[cargo_test]
|
||||
fn credentials_is_unreadable() {
|
||||
use cargo_test_support::paths::home;
|
||||
use std::os::unix::prelude::*;
|
||||
let p = project()
|
||||
.file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
|
||||
.file("src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
let credentials = home().join(".cargo/credentials");
|
||||
t!(fs::create_dir_all(credentials.parent().unwrap()));
|
||||
t!(t!(File::create(&credentials)).write_all(
|
||||
br#"
|
||||
[registry]
|
||||
token = "api-token"
|
||||
"#
|
||||
));
|
||||
let stat = fs::metadata(credentials.as_path()).unwrap();
|
||||
let mut perms = stat.permissions();
|
||||
perms.set_mode(0o000);
|
||||
fs::set_permissions(credentials, perms.clone()).unwrap();
|
||||
|
||||
p.cargo("build").run();
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[cargo_test]
|
||||
fn ignore_bad_directories() {
|
||||
|
@ -111,28 +111,6 @@ fn credentials_work_with_extension() {
|
||||
assert!(check_token(TOKEN, None));
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn credentials_ambiguous_filename() {
|
||||
registry::init();
|
||||
setup_new_credentials();
|
||||
setup_new_credentials_toml();
|
||||
|
||||
cargo_process("login --host")
|
||||
.arg(registry_url().to_string())
|
||||
.arg(TOKEN)
|
||||
.with_stderr_contains(
|
||||
"\
|
||||
[WARNING] Both `[..]/credentials` and `[..]/credentials.toml` exist. Using `[..]/credentials`
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
||||
// It should use the value from the one without the extension
|
||||
// for backwards compatibility. check_token explicitly checks
|
||||
// 'credentials' without the extension, which is what we want.
|
||||
assert!(check_token(TOKEN, None));
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn login_with_old_and_new_credentials() {
|
||||
setup_new_credentials();
|
||||
@ -161,7 +139,9 @@ fn new_credentials_is_used_instead_old() {
|
||||
.arg(TOKEN)
|
||||
.run();
|
||||
|
||||
let config = Config::new(Shell::new(), cargo_home(), cargo_home());
|
||||
let mut config = Config::new(Shell::new(), cargo_home(), cargo_home());
|
||||
let _ = config.values();
|
||||
let _ = config.load_credentials();
|
||||
|
||||
let token = config.get_string("registry.token").unwrap().map(|p| p.val);
|
||||
assert_eq!(token.unwrap(), TOKEN);
|
||||
|
@ -1261,3 +1261,40 @@ repository = "foo"
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn credentials_ambiguous_filename() {
|
||||
registry::init();
|
||||
|
||||
let credentials_toml = paths::home().join(".cargo/credentials.toml");
|
||||
File::create(&credentials_toml)
|
||||
.unwrap()
|
||||
.write_all(br#"token = "api-token""#)
|
||||
.unwrap();
|
||||
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[project]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
license = "MIT"
|
||||
description = "foo"
|
||||
"#,
|
||||
)
|
||||
.file("src/main.rs", "fn main() {}")
|
||||
.build();
|
||||
|
||||
p.cargo("publish --no-verify --index")
|
||||
.arg(registry_url().to_string())
|
||||
.with_stderr_contains(
|
||||
"\
|
||||
[WARNING] Both `[..]/credentials` and `[..]/credentials.toml` exist. Using `[..]/credentials`
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
||||
validate_upload_foo();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user