diff --git a/src/cargo/util/auth/mod.rs b/src/cargo/util/auth/mod.rs index 0f28c12f5d2..60a356fa093 100644 --- a/src/cargo/util/auth/mod.rs +++ b/src/cargo/util/auth/mod.rs @@ -99,6 +99,7 @@ fn credential_provider(config: &Config, sid: &SourceId) -> CargoResult = provider .iter() @@ -471,8 +473,8 @@ fn credential_action( })?; match provider.perform(®istry, &action, &args[1..]) { Ok(response) => return Ok(response), - Err(cargo_credential::Error::UrlNotSupported) - | Err(cargo_credential::Error::NotFound) => {} + Err(cargo_credential::Error::UrlNotSupported) => {} + Err(cargo_credential::Error::NotFound) => any_not_found = true, e => { return e.with_context(|| { format!( @@ -483,7 +485,11 @@ fn credential_action( } } } - Err(cargo_credential::Error::NotFound.into()) + if any_not_found { + Err(cargo_credential::Error::NotFound.into()) + } else { + anyhow::bail!("no credential providers could handle the request") + } } /// Returns the token to use for the given registry. diff --git a/src/doc/src/reference/unstable.md b/src/doc/src/reference/unstable.md index 11b9406baa0..55084f88e64 100644 --- a/src/doc/src/reference/unstable.md +++ b/src/doc/src/reference/unstable.md @@ -1068,7 +1068,14 @@ specified in the `registries` table: ```toml [registries.my-registry] -global-credential-provider = "/usr/bin/cargo-creds" +credential-provider = "/usr/bin/cargo-creds" +``` + +The credential provider for crates.io can be specified as: + +```toml +[registry] +credential-provider = "/usr/bin/cargo-creds" ``` The value can be a string with spaces separating arguments or it can be a TOML diff --git a/tests/testsuite/credential_process.rs b/tests/testsuite/credential_process.rs index c2ee7491b80..c010c01cd66 100644 --- a/tests/testsuite/credential_process.rs +++ b/tests/testsuite/credential_process.rs @@ -320,6 +320,86 @@ fn build_provider(name: &str, response: &str) -> String { toml_bin(&cred_proj, name) } +#[cargo_test] +fn all_not_found() { + let server = registry::RegistryBuilder::new() + .no_configure_token() + .auth_required() + .http_index() + .build(); + let not_found = build_provider("not_found", r#"{"Err": {"kind": "not-found"}}"#); + cargo_util::paths::append( + &paths::home().join(".cargo/config"), + format!( + r#" + [registry] + global-credential-providers = ["not_found"] + [credential-alias] + not_found = ["{not_found}"] + "#, + ) + .as_bytes(), + ) + .unwrap(); + + cargo_process("install -v foo -Zcredential-process -Zregistry-auth") + .masquerade_as_nightly_cargo(&["credential-process", "registry-auth"]) + .replace_crates_io(server.index_url()) + .with_status(101) + .with_stderr( + r#"[UPDATING] [..] +[CREDENTIAL] [..]not_found[..] get crates-io +{"v":1,"registry":{"index-url":"[..]","name":"crates-io","headers":[[..]"WWW-Authenticate: Cargo login_url=\"https://test-registry-login/me\""[..]]},"kind":"get","operation":"read","args":[]} +[ERROR] failed to query replaced source registry `crates-io` + +Caused by: + no token found, please run `cargo login` + or use environment variable CARGO_REGISTRY_TOKEN +"#, + ) + .run(); +} + +#[cargo_test] +fn all_not_supported() { + let server = registry::RegistryBuilder::new() + .no_configure_token() + .auth_required() + .http_index() + .build(); + let not_supported = + build_provider("not_supported", r#"{"Err": {"kind": "url-not-supported"}}"#); + cargo_util::paths::append( + &paths::home().join(".cargo/config"), + format!( + r#" + [registry] + global-credential-providers = ["not_supported"] + [credential-alias] + not_supported = ["{not_supported}"] + "#, + ) + .as_bytes(), + ) + .unwrap(); + + cargo_process("install -v foo -Zcredential-process -Zregistry-auth") + .masquerade_as_nightly_cargo(&["credential-process", "registry-auth"]) + .replace_crates_io(server.index_url()) + .with_status(101) + .with_stderr( + r#"[UPDATING] [..] +[CREDENTIAL] [..]not_supported[..] get crates-io +{"v":1,"registry":{"index-url":"[..]","name":"crates-io","headers":[[..]"WWW-Authenticate: Cargo login_url=\"https://test-registry-login/me\""[..]]},"kind":"get","operation":"read","args":[]} +[ERROR] failed to query replaced source registry `crates-io` + +Caused by: + no credential providers could handle the request +"#, + ) + .run(); +} + #[cargo_test] fn multiple_providers() { let server = registry::RegistryBuilder::new()