summaryrefslogtreecommitdiffstats
path: root/src/tools/cargo/tests/testsuite/credential_process.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/cargo/tests/testsuite/credential_process.rs')
-rw-r--r--src/tools/cargo/tests/testsuite/credential_process.rs640
1 files changed, 397 insertions, 243 deletions
diff --git a/src/tools/cargo/tests/testsuite/credential_process.rs b/src/tools/cargo/tests/testsuite/credential_process.rs
index 8c202c6a3..c010c01cd 100644
--- a/src/tools/cargo/tests/testsuite/credential_process.rs
+++ b/src/tools/cargo/tests/testsuite/credential_process.rs
@@ -1,8 +1,7 @@
//! Tests for credential-process.
-use cargo_test_support::registry::TestRegistry;
+use cargo_test_support::registry::{Package, TestRegistry};
use cargo_test_support::{basic_manifest, cargo_process, paths, project, registry, Project};
-use std::fs::{self, read_to_string};
fn toml_bin(proj: &Project, name: &str) -> String {
proj.bin(name).display().to_string().replace('\\', "\\\\")
@@ -24,7 +23,7 @@ fn gated() {
".cargo/config",
r#"
[registry]
- credential-process = "false"
+ credential-provider = ["false"]
"#,
)
.file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
@@ -65,80 +64,6 @@ or use environment variable CARGO_REGISTRIES_ALTERNATIVE_TOKEN
.run();
}
-#[cargo_test]
-fn warn_both_token_and_process() {
- // Specifying both credential-process and a token in config should issue a warning.
- let _server = registry::RegistryBuilder::new()
- .http_api()
- .http_index()
- .alternative()
- .no_configure_token()
- .build();
- let p = project()
- .file(
- ".cargo/config",
- r#"
- [registries.alternative]
- token = "alternative-sekrit"
- credential-process = "false"
- "#,
- )
- .file(
- "Cargo.toml",
- r#"
- [package]
- name = "foo"
- version = "0.1.0"
- description = "foo"
- authors = []
- license = "MIT"
- homepage = "https://example.com/"
- "#,
- )
- .file("src/lib.rs", "")
- .build();
-
- p.cargo("publish --no-verify --registry alternative -Z credential-process")
- .masquerade_as_nightly_cargo(&["credential-process"])
- .with_status(101)
- .with_stderr(
- "\
-[UPDATING] [..]
-[ERROR] both `token` and `credential-process` were specified in the config for registry `alternative`.
-Only one of these values may be set, remove one or the other to proceed.
-",
- )
- .run();
-
- // Try with global credential-process, and registry-specific `token`.
- // This should silently use the config token, and not run the "false" exe.
- p.change_file(
- ".cargo/config",
- r#"
- [registry]
- credential-process = "false"
-
- [registries.alternative]
- token = "alternative-sekrit"
- "#,
- );
- p.cargo("publish --no-verify --registry alternative -Z credential-process")
- .masquerade_as_nightly_cargo(&["credential-process"])
- .with_stderr(
- "\
-[UPDATING] [..]
-[PACKAGING] foo v0.1.0 [..]
-[PACKAGED] [..]
-[UPLOADING] foo v0.1.0 [..]
-[UPLOADED] foo v0.1.0 [..]
-note: Waiting [..]
-You may press ctrl-c [..]
-[PUBLISHED] foo v0.1.0 [..]
-",
- )
- .run();
-}
-
/// Setup for a test that will issue a command that needs to fetch a token.
///
/// This does the following:
@@ -158,29 +83,14 @@ fn get_token_test() -> (Project, TestRegistry) {
))
.alternative()
.http_api()
+ .http_index()
+ .auth_required()
.build();
- // The credential process to use.
- let cred_proj = project()
- .at("cred_proj")
- .file("Cargo.toml", &basic_manifest("test-cred", "1.0.0"))
- .file(
- "src/main.rs",
- r#"
- use std::fs::File;
- use std::io::Write;
- fn main() {
- let mut f = File::options()
- .write(true)
- .create(true)
- .append(true)
- .open("runs.log")
- .unwrap();
- write!(f, "+");
- println!("sekrit");
- } "#,
- )
- .build();
- cred_proj.cargo("build").run();
+
+ let provider = build_provider(
+ "test-cred",
+ r#"{"Ok":{"kind":"get","token":"sekrit","cache":"session","operation_independent":false}}"#,
+ );
let p = project()
.file(
@@ -189,10 +99,9 @@ fn get_token_test() -> (Project, TestRegistry) {
r#"
[registries.alternative]
index = "{}"
- credential-process = ["{}"]
+ credential-provider = ["{provider}"]
"#,
server.index_url(),
- toml_bin(&cred_proj, "test-cred")
),
)
.file(
@@ -202,7 +111,6 @@ fn get_token_test() -> (Project, TestRegistry) {
name = "foo"
version = "0.1.0"
description = "foo"
- authors = []
license = "MIT"
homepage = "https://example.com/"
"#,
@@ -217,24 +125,22 @@ fn publish() {
// Checks that credential-process is used for `cargo publish`.
let (p, _t) = get_token_test();
- p.cargo("publish --no-verify --registry alternative -Z credential-process")
+ p.cargo("publish --no-verify --registry alternative -Z credential-process -Z registry-auth")
.masquerade_as_nightly_cargo(&["credential-process"])
.with_stderr(
- "\
-[UPDATING] [..]
+ r#"[UPDATING] [..]
+{"v":1,"registry":{"index-url":"[..]","name":"alternative","headers":[..]},"kind":"get","operation":"read","args":[]}
[PACKAGING] foo v0.1.0 [..]
[PACKAGED] [..]
+{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"publish","name":"foo","vers":"0.1.0","cksum":"[..]","args":[]}
[UPLOADING] foo v0.1.0 [..]
[UPLOADED] foo v0.1.0 [..]
note: Waiting [..]
You may press ctrl-c [..]
[PUBLISHED] foo v0.1.0 [..]
-",
+"#,
)
.run();
-
- let calls = read_to_string(p.root().join("runs.log")).unwrap().len();
- assert_eq!(calls, 1);
}
#[cargo_test]
@@ -242,15 +148,8 @@ fn basic_unsupported() {
// Non-action commands don't support login/logout.
let registry = registry::RegistryBuilder::new()
.no_configure_token()
+ .credential_provider(&["cargo:token-from-stdout", "false"])
.build();
- cargo_util::paths::append(
- &paths::home().join(".cargo/config"),
- br#"
- [registry]
- credential-process = "false"
- "#,
- )
- .unwrap();
cargo_process("login -Z credential-process abcdefg")
.replace_crates_io(registry.index_url())
@@ -259,9 +158,10 @@ fn basic_unsupported() {
.with_stderr(
"\
[UPDATING] crates.io index
-[ERROR] credential process `false` cannot be used to log in, \
-the credential-process configuration value must pass the \
-`{action}` argument in the config to support this command
+[ERROR] credential provider `cargo:token-from-stdout false` failed action `login`
+
+Caused by:
+ requested operation not supported
",
)
.run();
@@ -272,9 +172,10 @@ the credential-process configuration value must pass the \
.with_status(101)
.with_stderr(
"\
-[ERROR] credential process `false` cannot be used to log out, \
-the credential-process configuration value must pass the \
-`{action}` argument in the config to support this command
+[ERROR] credential provider `cargo:token-from-stdout false` failed action `logout`
+
+Caused by:
+ requested operation not supported
",
)
.run();
@@ -282,222 +183,475 @@ the credential-process configuration value must pass the \
#[cargo_test]
fn login() {
+ let registry = registry::RegistryBuilder::new()
+ .no_configure_token()
+ .credential_provider(&[
+ &build_provider("test-cred", r#"{"Ok": {"kind": "login"}}"#),
+ "cfg1",
+ "--cfg2",
+ ])
+ .build();
+
+ cargo_process("login -Z credential-process abcdefg -- cmd3 --cmd4")
+ .masquerade_as_nightly_cargo(&["credential-process"])
+ .replace_crates_io(registry.index_url())
+ .with_stderr(
+ r#"[UPDATING] [..]
+{"v":1,"registry":{"index-url":"https://github.com/rust-lang/crates.io-index","name":"crates-io"},"kind":"login","token":"abcdefg","login-url":"[..]","args":["cfg1","--cfg2","cmd3","--cmd4"]}
+"#,
+ )
+ .run();
+}
+
+#[cargo_test]
+fn logout() {
let server = registry::RegistryBuilder::new()
.no_configure_token()
+ .credential_provider(&[&build_provider(
+ "test-cred",
+ r#"{"Ok": {"kind": "logout"}}"#,
+ )])
.build();
- // The credential process to use.
+
+ cargo_process("logout -Z credential-process")
+ .masquerade_as_nightly_cargo(&["credential-process"])
+ .replace_crates_io(server.index_url())
+ .with_stderr(
+ r#"{"v":1,"registry":{"index-url":"https://github.com/rust-lang/crates.io-index","name":"crates-io"},"kind":"logout","args":[]}
+"#,
+ )
+ .run();
+}
+
+#[cargo_test]
+fn yank() {
+ let (p, _t) = get_token_test();
+
+ p.cargo("yank --version 0.1.0 --registry alternative -Zcredential-process -Zregistry-auth")
+ .masquerade_as_nightly_cargo(&["credential-process"])
+ .with_stderr(
+ r#"[UPDATING] [..]
+{"v":1,"registry":{"index-url":"[..]","name":"alternative","headers":[..]},"kind":"get","operation":"read","args":[]}
+{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"yank","name":"foo","vers":"0.1.0","args":[]}
+[YANK] foo@0.1.0
+"#,
+ )
+ .run();
+}
+
+#[cargo_test]
+fn owner() {
+ let (p, _t) = get_token_test();
+
+ p.cargo("owner --add username --registry alternative -Zcredential-process -Zregistry-auth")
+ .masquerade_as_nightly_cargo(&["credential-process"])
+ .with_stderr(
+ r#"[UPDATING] [..]
+{"v":1,"registry":{"index-url":"[..]","name":"alternative","headers":[..]},"kind":"get","operation":"read","args":[]}
+{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"owners","name":"foo","args":[]}
+[OWNER] completed!
+"#,
+ )
+ .run();
+}
+
+#[cargo_test]
+fn invalid_token_output() {
+ // Error when credential process does not output the expected format for a token.
let cred_proj = project()
.at("cred_proj")
.file("Cargo.toml", &basic_manifest("test-cred", "1.0.0"))
+ .file("src/main.rs", r#"fn main() { print!("a\nb\n"); } "#)
+ .build();
+ cred_proj.cargo("build").run();
+ let _server = registry::RegistryBuilder::new()
+ .alternative()
+ .credential_provider(&[
+ "cargo:token-from-stdout",
+ &toml_bin(&cred_proj, "test-cred"),
+ ])
+ .no_configure_token()
+ .build();
+
+ let p = project()
+ .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("publish --no-verify --registry alternative -Z credential-process")
+ .masquerade_as_nightly_cargo(&["credential-process"])
+ .with_status(101)
+ .with_stderr(
+ "\
+[UPDATING] [..]
+[ERROR] credential provider `[..]test-cred[EXE]` failed action `get`
+
+Caused by:
+ process `[..]` returned more than one line of output; expected a single token
+",
+ )
+ .run();
+}
+
+/// Builds a credential provider that echos the request from cargo to stderr,
+/// and prints the `response` to stdout.
+fn build_provider(name: &str, response: &str) -> String {
+ // The credential process to use.
+ let cred_proj = project()
+ .at(name)
+ .file("Cargo.toml", &basic_manifest(name, "1.0.0"))
.file(
"src/main.rs",
- r#"
- use std::io::Read;
-
- fn main() {{
- assert_eq!(std::env::var("CARGO_REGISTRY_NAME_OPT").unwrap(), "crates-io");
- assert_eq!(std::env::var("CARGO_REGISTRY_INDEX_URL").unwrap(), "https://github.com/rust-lang/crates.io-index");
- assert_eq!(std::env::args().skip(1).next().unwrap(), "store");
+ &r####"
+ fn main() {
+ println!(r#"{{"v":[1]}}"#);
+ assert_eq!(std::env::args().skip(1).next().unwrap(), "--cargo-plugin");
let mut buffer = String::new();
- std::io::stdin().read_to_string(&mut buffer).unwrap();
- assert_eq!(buffer, "abcdefg\n");
- std::fs::write("token-store", buffer).unwrap();
- }}
- "#,
+ std::io::stdin().read_line(&mut buffer).unwrap();
+ eprint!("{}", buffer);
+ use std::io::Write;
+ std::io::stdout().write_all(r###"[RESPONSE]"###.as_bytes()).unwrap();
+ println!();
+ } "####
+ .replace("[RESPONSE]", response),
)
.build();
cred_proj.cargo("build").run();
+ 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]
- credential-process = ["{}", "{{action}}"]
+ global-credential-providers = ["not_found"]
+ [credential-alias]
+ not_found = ["{not_found}"]
"#,
- toml_bin(&cred_proj, "test-cred")
)
.as_bytes(),
)
.unwrap();
- cargo_process("login -Z credential-process abcdefg")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ 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(
- "\
-[UPDATING] [..]
-[LOGIN] token for `crates.io` saved
-",
+ 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();
- assert_eq!(
- fs::read_to_string(paths::root().join("token-store")).unwrap(),
- "abcdefg\n"
- );
}
#[cargo_test]
-fn logout() {
+fn all_not_supported() {
let server = registry::RegistryBuilder::new()
.no_configure_token()
+ .auth_required()
+ .http_index()
.build();
- // The credential process to use.
- let cred_proj = project()
- .at("cred_proj")
- .file("Cargo.toml", &basic_manifest("test-cred", "1.0.0"))
- .file(
- "src/main.rs",
- r#"
- use std::io::Read;
-
- fn main() {{
- assert_eq!(std::env::var("CARGO_REGISTRY_NAME_OPT").unwrap(), "crates-io");
- assert_eq!(std::env::var("CARGO_REGISTRY_INDEX_URL").unwrap(), "https://github.com/rust-lang/crates.io-index");
- assert_eq!(std::env::args().skip(1).next().unwrap(), "erase");
- std::fs::write("token-store", "").unwrap();
- eprintln!("token for `crates-io` has been erased!")
- }}
- "#,
- )
- .build();
- cred_proj.cargo("build").run();
-
+ 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]
- credential-process = ["{}", "{{action}}"]
+ global-credential-providers = ["not_supported"]
+ [credential-alias]
+ not_supported = ["{not_supported}"]
"#,
- toml_bin(&cred_proj, "test-cred")
)
.as_bytes(),
)
.unwrap();
- cargo_process("logout -Z credential-process")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ 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(
- "\
-token for `crates-io` has been erased!
-[LOGOUT] token for `crates-io` has been removed from local storage
-[NOTE] This does not revoke the token on the registry server.
- If you need to revoke the token, visit <https://crates.io/me> \
- and follow the instructions there.
-",
+ 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();
- assert_eq!(
- fs::read_to_string(paths::root().join("token-store")).unwrap(),
- ""
- );
}
#[cargo_test]
-fn yank() {
- let (p, _t) = get_token_test();
+fn multiple_providers() {
+ let server = registry::RegistryBuilder::new()
+ .no_configure_token()
+ .build();
- p.cargo("yank --version 0.1.0 --registry alternative -Z credential-process")
+ // Set up two credential providers: the first will fail with "UrlNotSupported"
+ // and Cargo should skip it. The second should succeed.
+ let url_not_supported = build_provider(
+ "url_not_supported",
+ r#"{"Err": {"kind": "url-not-supported"}}"#,
+ );
+
+ let success_provider = build_provider("success_provider", r#"{"Ok": {"kind": "login"}}"#);
+
+ cargo_util::paths::append(
+ &paths::home().join(".cargo/config"),
+ format!(
+ r#"
+ [registry]
+ global-credential-providers = ["success_provider", "url_not_supported"]
+
+ [credential-alias]
+ success_provider = ["{success_provider}"]
+ url_not_supported = ["{url_not_supported}"]
+ "#,
+ )
+ .as_bytes(),
+ )
+ .unwrap();
+
+ cargo_process("login -Z credential-process -v abcdefg")
.masquerade_as_nightly_cargo(&["credential-process"])
+ .replace_crates_io(server.index_url())
.with_stderr(
- "\
-[UPDATING] [..]
-[YANK] foo@0.1.0
-",
+ r#"[UPDATING] [..]
+[CREDENTIAL] [..]url_not_supported[..] login crates-io
+{"v":1,"registry":{"index-url":"https://github.com/rust-lang/crates.io-index","name":"crates-io"},"kind":"login","token":"abcdefg","login-url":"[..]","args":[]}
+[CREDENTIAL] [..]success_provider[..] login crates-io
+{"v":1,"registry":{"index-url":"https://github.com/rust-lang/crates.io-index","name":"crates-io"},"kind":"login","token":"abcdefg","login-url":"[..]","args":[]}
+"#,
)
.run();
}
#[cargo_test]
-fn owner() {
- let (p, _t) = get_token_test();
+fn both_token_and_provider() {
+ let server = registry::RegistryBuilder::new().build();
+ cargo_util::paths::append(
+ &paths::home().join(".cargo/config"),
+ format!(
+ r#"
+ [registry]
+ credential-provider = ["cargo:token"]
+ "#,
+ )
+ .as_bytes(),
+ )
+ .unwrap();
- p.cargo("owner --add username --registry alternative -Z credential-process")
+ cargo_process("login -Z credential-process -v abcdefg")
.masquerade_as_nightly_cargo(&["credential-process"])
+ .replace_crates_io(server.index_url())
.with_stderr(
- "\
-[UPDATING] [..]
-[OWNER] completed!
-",
+ r#"[UPDATING] [..]
+[WARNING] registry `crates-io` has a token configured in [..]credentials.toml that will be ignored because a credential-provider is configured for this registry`
+[CREDENTIAL] cargo:token login crates-io
+[LOGIN] token for `crates-io` saved
+"#,
)
.run();
+ let credentials =
+ std::fs::read_to_string(paths::home().join(".cargo/credentials.toml")).unwrap();
+ assert_eq!(credentials, "[registry]\ntoken = \"abcdefg\"\n");
}
#[cargo_test]
-fn libexec_path() {
- // cargo: prefixed names use the sysroot
- let server = registry::RegistryBuilder::new()
- .no_configure_token()
- .build();
+fn both_asymmetric_and_token() {
+ let server = registry::RegistryBuilder::new().build();
cargo_util::paths::append(
&paths::home().join(".cargo/config"),
- br#"
- [registry]
- credential-process = "cargo:doesnotexist"
- "#,
+ format!(
+ r#"
+ [registry]
+ token = "foo"
+ secret-key = "bar"
+ "#,
+ )
+ .as_bytes(),
)
.unwrap();
- cargo_process("login -Z credential-process abcdefg")
+ cargo_process("login -Z credential-process -v abcdefg")
.masquerade_as_nightly_cargo(&["credential-process"])
.replace_crates_io(server.index_url())
- .with_status(101)
.with_stderr(
- // FIXME: Update "Caused by" error message once rust/pull/87704 is merged.
- // On Windows, changing to a custom executable resolver has changed the
- // error messages.
- &format!("\
-[UPDATING] [..]
-[ERROR] failed to execute `[..]libexec/cargo-credential-doesnotexist[EXE]` to store authentication token for registry `crates-io`
-
-Caused by:
- [..]
-"),
+ r#"[UPDATING] [..]
+[WARNING] registry `crates-io` has a `secret_key` configured in [..]config that will be ignored because a `token` is also configured, and the `cargo:token` provider is configured with higher precedence
+[CREDENTIAL] cargo:token login crates-io
+[LOGIN] token for `crates-io` saved
+"#,
)
.run();
}
#[cargo_test]
-fn invalid_token_output() {
- // Error when credential process does not output the expected format for a token.
- let _server = registry::RegistryBuilder::new()
- .alternative()
+fn token_caching() {
+ let server = registry::RegistryBuilder::new()
.no_configure_token()
+ .no_configure_registry()
+ .token(cargo_test_support::registry::Token::Plaintext(
+ "sekrit".to_string(),
+ ))
+ .alternative()
+ .http_api()
+ .http_index()
.build();
+
+ // Token should not be re-used if it is expired
+ let expired_provider = build_provider(
+ "test-cred",
+ r#"{"Ok":{"kind":"get","token":"sekrit","cache":{"expires":0},"operation_independent":true}}"#,
+ );
+
+ // Token should not be re-used for a different operation if it is not operation_independent
+ let non_independent_provider = build_provider(
+ "test-cred",
+ r#"{"Ok":{"kind":"get","token":"sekrit","cache":"session","operation_independent":false}}"#,
+ );
+
+ let p = project()
+ .file(
+ ".cargo/config",
+ &format!(
+ r#"
+ [registries.alternative]
+ index = "{}"
+ credential-provider = ["{expired_provider}"]
+ "#,
+ server.index_url(),
+ ),
+ )
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ description = "foo"
+ license = "MIT"
+ homepage = "https://example.com/"
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ let output = r#"[UPDATING] `alternative` index
+{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"read","args":[]}
+[PACKAGING] foo v0.1.0 [..]
+[PACKAGED] [..]
+{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"publish","name":"foo","vers":"0.1.0","cksum":"[..]","args":[]}
+[UPLOADING] foo v0.1.0 [..]
+[UPLOADED] foo v0.1.0 [..]
+note: Waiting [..]
+You may press ctrl-c [..]
+[PUBLISHED] foo v0.1.0 [..]
+"#;
+
+ // The output should contain two JSON messages from the provider in boths cases:
+ // The first because the credential is expired, the second because the provider
+ // indicated that the token was non-operation-independent.
+ p.cargo("publish -Z credential-process --registry alternative --no-verify")
+ .masquerade_as_nightly_cargo(&["credential-process"])
+ .with_stderr(output)
+ .run();
+
+ p.change_file(
+ ".cargo/config",
+ &format!(
+ r#"
+ [registries.alternative]
+ index = "{}"
+ credential-provider = ["{non_independent_provider}"]
+ "#,
+ server.index_url(),
+ ),
+ );
+
+ p.cargo("publish -Z credential-process --registry alternative --no-verify")
+ .masquerade_as_nightly_cargo(&["credential-process"])
+ .with_stderr(output)
+ .run();
+}
+
+#[cargo_test]
+fn basic_provider() {
let cred_proj = project()
.at("cred_proj")
.file("Cargo.toml", &basic_manifest("test-cred", "1.0.0"))
- .file("src/main.rs", r#"fn main() { print!("a\nb\n"); } "#)
+ .file("src/main.rs", r#"fn main() {
+ eprintln!("CARGO={:?}", std::env::var("CARGO").ok());
+ eprintln!("CARGO_REGISTRY_NAME_OPT={:?}", std::env::var("CARGO_REGISTRY_NAME_OPT").ok());
+ eprintln!("CARGO_REGISTRY_INDEX_URL={:?}", std::env::var("CARGO_REGISTRY_INDEX_URL").ok());
+ print!("sekrit");
+ }"#)
.build();
cred_proj.cargo("build").run();
- cargo_util::paths::append(
- &paths::home().join(".cargo/config"),
- format!(
+ let _server = registry::RegistryBuilder::new()
+ .no_configure_token()
+ .credential_provider(&[
+ "cargo:token-from-stdout",
+ &toml_bin(&cred_proj, "test-cred"),
+ ])
+ .token(cargo_test_support::registry::Token::Plaintext(
+ "sekrit".to_string(),
+ ))
+ .alternative()
+ .http_api()
+ .auth_required()
+ .build();
+
+ let p = project()
+ .file(
+ "Cargo.toml",
r#"
- [registry]
- credential-process = ["{}"]
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ [dependencies.bar]
+ version = "0.0.1"
+ registry = "alternative"
"#,
- toml_bin(&cred_proj, "test-cred")
)
- .as_bytes(),
- )
- .unwrap();
-
- let p = project()
- .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
- .file("src/lib.rs", "")
+ .file("src/main.rs", "fn main() {}")
.build();
+ Package::new("bar", "0.0.1").alternative(true).publish();
- p.cargo("publish --no-verify --registry alternative -Z credential-process")
- .masquerade_as_nightly_cargo(&["credential-process"])
- .with_status(101)
+ p.cargo("check -Z credential-process -Z registry-auth")
+ .masquerade_as_nightly_cargo(&["credential-process", "registry-auth"])
.with_stderr(
"\
-[UPDATING] [..]
-[ERROR] credential process `[..]test-cred[EXE]` returned more than one line of output; expected a single token
+[UPDATING] `alternative` index
+CARGO=Some([..])
+CARGO_REGISTRY_NAME_OPT=Some(\"alternative\")
+CARGO_REGISTRY_INDEX_URL=Some([..])
+[DOWNLOADING] crates ...
+[DOWNLOADED] bar v0.0.1 (registry `alternative`)
+[CHECKING] bar v0.0.1 (registry `alternative`)
+[CHECKING] foo v0.0.1 ([..])
+[FINISHED] [..]
",
)
.run();