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 {
|
pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
|
||||||
|
config.load_credentials()?;
|
||||||
|
|
||||||
let registry = args.registry(config)?;
|
let registry = args.registry(config)?;
|
||||||
let ws = args.workspace(config)?;
|
let ws = args.workspace(config)?;
|
||||||
let index = args.index(config)?;
|
let index = args.index(config)?;
|
||||||
|
@ -746,7 +746,6 @@ impl Config {
|
|||||||
})
|
})
|
||||||
.chain_err(|| "could not load Cargo configuration")?;
|
.chain_err(|| "could not load Cargo configuration")?;
|
||||||
|
|
||||||
self.load_credentials(&mut cfg)?;
|
|
||||||
match cfg {
|
match cfg {
|
||||||
CV::Table(map, _) => Ok(map),
|
CV::Table(map, _) => Ok(map),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@ -979,9 +978,8 @@ impl Config {
|
|||||||
Ok(url)
|
Ok(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Loads credentials config from the credentials file into the `ConfigValue` object, if
|
/// Loads credentials config from the credentials file, if present.
|
||||||
/// present.
|
pub fn load_credentials(&mut self) -> CargoResult<()> {
|
||||||
fn load_credentials(&self, cfg: &mut ConfigValue) -> CargoResult<()> {
|
|
||||||
let home_path = self.home_path.clone().into_path_unlocked();
|
let home_path = self.home_path.clone().into_path_unlocked();
|
||||||
let credentials = match self.get_file_path(&home_path, "credentials", true)? {
|
let credentials = match self.get_file_path(&home_path, "credentials", true)? {
|
||||||
Some(credentials) => credentials,
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -2237,6 +2237,32 @@ fn recompile_space_in_name() {
|
|||||||
foo.cargo("build").with_stdout("").run();
|
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)]
|
#[cfg(unix)]
|
||||||
#[cargo_test]
|
#[cargo_test]
|
||||||
fn ignore_bad_directories() {
|
fn ignore_bad_directories() {
|
||||||
|
@ -111,28 +111,6 @@ fn credentials_work_with_extension() {
|
|||||||
assert!(check_token(TOKEN, None));
|
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]
|
#[cargo_test]
|
||||||
fn login_with_old_and_new_credentials() {
|
fn login_with_old_and_new_credentials() {
|
||||||
setup_new_credentials();
|
setup_new_credentials();
|
||||||
@ -161,7 +139,9 @@ fn new_credentials_is_used_instead_old() {
|
|||||||
.arg(TOKEN)
|
.arg(TOKEN)
|
||||||
.run();
|
.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);
|
let token = config.get_string("registry.token").unwrap().map(|p| p.val);
|
||||||
assert_eq!(token.unwrap(), TOKEN);
|
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