2020-12-01 19:16:16 +00:00
|
|
|
//! Tests for credential-process.
|
|
|
|
|
2023-06-27 16:26:27 +00:00
|
|
|
use cargo_test_support::registry::{Package, TestRegistry};
|
2020-12-01 19:16:16 +00:00
|
|
|
use cargo_test_support::{basic_manifest, cargo_process, paths, project, registry, Project};
|
|
|
|
|
|
|
|
fn toml_bin(proj: &Project, name: &str) -> String {
|
|
|
|
proj.bin(name).display().to_string().replace('\\', "\\\\")
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Setup for a test that will issue a command that needs to fetch a token.
|
|
|
|
///
|
|
|
|
/// This does the following:
|
|
|
|
///
|
|
|
|
/// * Spawn a thread that will act as an API server.
|
|
|
|
/// * Create a simple credential-process that will generate a fake token.
|
|
|
|
/// * Create a simple `foo` project to run the test against.
|
|
|
|
/// * Configure the credential-process config.
|
|
|
|
///
|
2022-10-26 04:15:45 +00:00
|
|
|
/// Returns the simple `foo` project to test against and the API server handle.
|
2022-06-09 03:04:33 +00:00
|
|
|
fn get_token_test() -> (Project, TestRegistry) {
|
2020-12-01 19:16:16 +00:00
|
|
|
// API server that checks that the token is included correctly.
|
2021-01-28 19:54:27 +00:00
|
|
|
let server = registry::RegistryBuilder::new()
|
2022-06-09 03:04:33 +00:00
|
|
|
.no_configure_token()
|
2022-12-12 17:49:22 +00:00
|
|
|
.token(cargo_test_support::registry::Token::Plaintext(
|
|
|
|
"sekrit".to_string(),
|
|
|
|
))
|
2022-06-09 03:04:33 +00:00
|
|
|
.alternative()
|
|
|
|
.http_api()
|
2023-07-21 22:30:01 +00:00
|
|
|
.http_index()
|
|
|
|
.auth_required()
|
2022-06-09 03:04:33 +00:00
|
|
|
.build();
|
2023-06-27 16:26:27 +00:00
|
|
|
|
|
|
|
let provider = build_provider(
|
|
|
|
"test-cred",
|
2023-07-21 22:30:01 +00:00
|
|
|
r#"{"Ok":{"kind":"get","token":"sekrit","cache":"session","operation_independent":false}}"#,
|
2023-06-27 16:26:27 +00:00
|
|
|
);
|
2020-12-01 19:16:16 +00:00
|
|
|
|
|
|
|
let p = project()
|
|
|
|
.file(
|
|
|
|
".cargo/config",
|
|
|
|
&format!(
|
|
|
|
r#"
|
|
|
|
[registries.alternative]
|
|
|
|
index = "{}"
|
2023-06-27 16:26:27 +00:00
|
|
|
credential-provider = ["{provider}"]
|
2020-12-01 19:16:16 +00:00
|
|
|
"#,
|
2022-06-09 03:04:33 +00:00
|
|
|
server.index_url(),
|
2020-12-01 19:16:16 +00:00
|
|
|
),
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
|
|
|
[package]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.1.0"
|
|
|
|
description = "foo"
|
|
|
|
license = "MIT"
|
|
|
|
homepage = "https://example.com/"
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file("src/lib.rs", "")
|
|
|
|
.build();
|
2021-01-28 19:54:27 +00:00
|
|
|
(p, server)
|
2020-12-01 19:16:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cargo_test]
|
|
|
|
fn publish() {
|
|
|
|
// Checks that credential-process is used for `cargo publish`.
|
2022-06-09 03:04:33 +00:00
|
|
|
let (p, _t) = get_token_test();
|
2020-12-01 19:16:16 +00:00
|
|
|
|
2023-09-06 19:00:46 +00:00
|
|
|
p.cargo("publish --no-verify --registry alternative")
|
2020-12-01 19:16:16 +00:00
|
|
|
.with_stderr(
|
2023-06-27 16:26:27 +00:00
|
|
|
r#"[UPDATING] [..]
|
2023-09-05 18:31:23 +00:00
|
|
|
{"v":1,"registry":{"index-url":"[..]","name":"alternative","headers":[..]},"kind":"get","operation":"read"}
|
2020-12-01 19:16:16 +00:00
|
|
|
[PACKAGING] foo v0.1.0 [..]
|
2022-10-19 18:33:17 +00:00
|
|
|
[PACKAGED] [..]
|
2023-09-05 18:31:23 +00:00
|
|
|
{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"publish","name":"foo","vers":"0.1.0","cksum":"[..]"}
|
2020-12-01 19:16:16 +00:00
|
|
|
[UPLOADING] foo v0.1.0 [..]
|
2023-02-17 17:44:53 +00:00
|
|
|
[UPLOADED] foo v0.1.0 [..]
|
2023-02-14 20:57:25 +00:00
|
|
|
note: Waiting [..]
|
|
|
|
You may press ctrl-c [..]
|
2023-02-17 17:44:53 +00:00
|
|
|
[PUBLISHED] foo v0.1.0 [..]
|
2023-06-27 16:26:27 +00:00
|
|
|
"#,
|
2020-12-01 19:16:16 +00:00
|
|
|
)
|
|
|
|
.run();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cargo_test]
|
|
|
|
fn basic_unsupported() {
|
|
|
|
// Non-action commands don't support login/logout.
|
2022-08-31 05:53:47 +00:00
|
|
|
let registry = registry::RegistryBuilder::new()
|
2022-06-09 03:04:33 +00:00
|
|
|
.no_configure_token()
|
2023-08-16 04:56:11 +00:00
|
|
|
.credential_provider(&["cargo:token-from-stdout", "false"])
|
2022-06-09 03:04:33 +00:00
|
|
|
.build();
|
2020-12-01 19:16:16 +00:00
|
|
|
|
2023-09-06 19:00:46 +00:00
|
|
|
cargo_process("login abcdefg")
|
2022-08-31 05:53:47 +00:00
|
|
|
.replace_crates_io(registry.index_url())
|
2020-12-01 19:16:16 +00:00
|
|
|
.with_status(101)
|
|
|
|
.with_stderr(
|
|
|
|
"\
|
2022-10-31 16:44:01 +00:00
|
|
|
[UPDATING] crates.io index
|
2023-08-16 04:56:11 +00:00
|
|
|
[ERROR] credential provider `cargo:token-from-stdout false` failed action `login`
|
2023-06-27 16:26:27 +00:00
|
|
|
|
|
|
|
Caused by:
|
2023-07-31 16:33:06 +00:00
|
|
|
requested operation not supported
|
2020-12-01 19:16:16 +00:00
|
|
|
",
|
|
|
|
)
|
|
|
|
.run();
|
|
|
|
|
2023-09-06 19:00:46 +00:00
|
|
|
cargo_process("logout")
|
2022-08-31 05:53:47 +00:00
|
|
|
.replace_crates_io(registry.index_url())
|
2020-12-01 19:16:16 +00:00
|
|
|
.with_status(101)
|
|
|
|
.with_stderr(
|
|
|
|
"\
|
2023-08-16 04:56:11 +00:00
|
|
|
[ERROR] credential provider `cargo:token-from-stdout false` failed action `logout`
|
2023-06-27 16:26:27 +00:00
|
|
|
|
|
|
|
Caused by:
|
2023-07-31 16:33:06 +00:00
|
|
|
requested operation not supported
|
2020-12-01 19:16:16 +00:00
|
|
|
",
|
|
|
|
)
|
|
|
|
.run();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cargo_test]
|
|
|
|
fn login() {
|
2023-06-27 16:26:27 +00:00
|
|
|
let registry = registry::RegistryBuilder::new()
|
2022-06-09 03:04:33 +00:00
|
|
|
.no_configure_token()
|
2023-08-14 19:47:58 +00:00
|
|
|
.credential_provider(&[
|
|
|
|
&build_provider("test-cred", r#"{"Ok": {"kind": "login"}}"#),
|
|
|
|
"cfg1",
|
|
|
|
"--cfg2",
|
|
|
|
])
|
2022-06-09 03:04:33 +00:00
|
|
|
.build();
|
2020-12-01 19:16:16 +00:00
|
|
|
|
2023-09-06 19:00:46 +00:00
|
|
|
cargo_process("login abcdefg -- cmd3 --cmd4")
|
2023-06-27 16:26:27 +00:00
|
|
|
.replace_crates_io(registry.index_url())
|
2020-12-01 19:16:16 +00:00
|
|
|
.with_stderr(
|
2023-06-27 16:26:27 +00:00
|
|
|
r#"[UPDATING] [..]
|
2023-08-14 19:47:58 +00:00
|
|
|
{"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"]}
|
2023-06-27 16:26:27 +00:00
|
|
|
"#,
|
2020-12-01 19:16:16 +00:00
|
|
|
)
|
|
|
|
.run();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cargo_test]
|
|
|
|
fn logout() {
|
2022-08-31 05:53:47 +00:00
|
|
|
let server = registry::RegistryBuilder::new()
|
2022-06-09 03:04:33 +00:00
|
|
|
.no_configure_token()
|
2023-06-27 16:26:27 +00:00
|
|
|
.credential_provider(&[&build_provider(
|
|
|
|
"test-cred",
|
|
|
|
r#"{"Ok": {"kind": "logout"}}"#,
|
|
|
|
)])
|
2022-06-09 03:04:33 +00:00
|
|
|
.build();
|
2020-12-01 19:16:16 +00:00
|
|
|
|
2023-09-06 19:00:46 +00:00
|
|
|
cargo_process("logout")
|
2022-08-31 05:53:47 +00:00
|
|
|
.replace_crates_io(server.index_url())
|
2020-12-01 19:16:16 +00:00
|
|
|
.with_stderr(
|
2023-09-05 18:31:23 +00:00
|
|
|
r#"{"v":1,"registry":{"index-url":"https://github.com/rust-lang/crates.io-index","name":"crates-io"},"kind":"logout"}
|
2023-06-27 16:26:27 +00:00
|
|
|
"#,
|
2020-12-01 19:16:16 +00:00
|
|
|
)
|
|
|
|
.run();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cargo_test]
|
|
|
|
fn yank() {
|
2022-06-09 03:04:33 +00:00
|
|
|
let (p, _t) = get_token_test();
|
2020-12-01 19:16:16 +00:00
|
|
|
|
2023-09-06 19:00:46 +00:00
|
|
|
p.cargo("yank --version 0.1.0 --registry alternative")
|
2020-12-01 19:16:16 +00:00
|
|
|
.with_stderr(
|
2023-06-27 16:26:27 +00:00
|
|
|
r#"[UPDATING] [..]
|
2023-09-05 18:31:23 +00:00
|
|
|
{"v":1,"registry":{"index-url":"[..]","name":"alternative","headers":[..]},"kind":"get","operation":"read"}
|
|
|
|
{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"yank","name":"foo","vers":"0.1.0"}
|
2022-04-19 21:00:15 +00:00
|
|
|
[YANK] foo@0.1.0
|
2023-06-27 16:26:27 +00:00
|
|
|
"#,
|
2020-12-01 19:16:16 +00:00
|
|
|
)
|
|
|
|
.run();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cargo_test]
|
|
|
|
fn owner() {
|
2022-06-09 03:04:33 +00:00
|
|
|
let (p, _t) = get_token_test();
|
2020-12-01 19:16:16 +00:00
|
|
|
|
2023-09-06 19:00:46 +00:00
|
|
|
p.cargo("owner --add username --registry alternative")
|
2023-06-27 16:26:27 +00:00
|
|
|
.with_stderr(
|
|
|
|
r#"[UPDATING] [..]
|
2023-09-05 18:31:23 +00:00
|
|
|
{"v":1,"registry":{"index-url":"[..]","name":"alternative","headers":[..]},"kind":"get","operation":"read"}
|
|
|
|
{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"owners","name":"foo"}
|
2023-06-27 16:26:27 +00:00
|
|
|
[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()
|
2023-08-16 04:56:11 +00:00
|
|
|
.credential_provider(&[
|
|
|
|
"cargo:token-from-stdout",
|
|
|
|
&toml_bin(&cred_proj, "test-cred"),
|
|
|
|
])
|
2023-06-27 16:26:27 +00:00
|
|
|
.no_configure_token()
|
|
|
|
.build();
|
|
|
|
|
|
|
|
let p = project()
|
|
|
|
.file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
|
|
|
|
.file("src/lib.rs", "")
|
|
|
|
.build();
|
|
|
|
|
2023-09-06 19:00:46 +00:00
|
|
|
p.cargo("publish --no-verify --registry alternative")
|
2023-06-27 16:26:27 +00:00
|
|
|
.with_status(101)
|
2020-12-01 19:16:16 +00:00
|
|
|
.with_stderr(
|
|
|
|
"\
|
|
|
|
[UPDATING] [..]
|
2023-06-27 16:26:27 +00:00
|
|
|
[ERROR] credential provider `[..]test-cred[EXE]` failed action `get`
|
|
|
|
|
|
|
|
Caused by:
|
2023-07-31 16:33:06 +00:00
|
|
|
process `[..]` returned more than one line of output; expected a single token
|
2020-12-01 19:16:16 +00:00
|
|
|
",
|
|
|
|
)
|
|
|
|
.run();
|
|
|
|
}
|
|
|
|
|
2023-06-27 16:26:27 +00:00
|
|
|
/// 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####"
|
|
|
|
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_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)
|
|
|
|
}
|
|
|
|
|
2023-09-08 01:56:56 +00:00
|
|
|
#[cargo_test]
|
|
|
|
fn not_found() {
|
|
|
|
let registry = registry::RegistryBuilder::new()
|
|
|
|
.no_configure_token()
|
|
|
|
.http_index()
|
|
|
|
.auth_required()
|
|
|
|
.credential_provider(&[&build_provider(
|
|
|
|
"not_found",
|
|
|
|
r#"{"Err": {"kind": "not-found"}}"#,
|
|
|
|
)])
|
|
|
|
.build();
|
|
|
|
|
|
|
|
// should not suggest a _TOKEN environment variable since the cargo:token provider isn't available.
|
2023-09-06 19:00:46 +00:00
|
|
|
cargo_process("install -v foo")
|
2023-09-08 01:56:56 +00:00
|
|
|
.replace_crates_io(registry.index_url())
|
|
|
|
.with_status(101)
|
|
|
|
.with_stderr(
|
|
|
|
r#"[UPDATING] [..]
|
|
|
|
[CREDENTIAL] [..]not_found[..] get crates-io
|
|
|
|
{"v":1[..]
|
|
|
|
[ERROR] failed to query replaced source registry `crates-io`
|
|
|
|
|
|
|
|
Caused by:
|
|
|
|
no token found, please run `cargo login`
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.run();
|
|
|
|
}
|
|
|
|
|
2023-08-18 21:14:53 +00:00
|
|
|
#[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();
|
|
|
|
|
2023-09-08 01:56:56 +00:00
|
|
|
// should not suggest a _TOKEN environment variable since the cargo:token provider isn't available.
|
2023-09-06 19:00:46 +00:00
|
|
|
cargo_process("install -v foo")
|
2023-08-18 21:14:53 +00:00
|
|
|
.replace_crates_io(server.index_url())
|
|
|
|
.with_status(101)
|
|
|
|
.with_stderr(
|
|
|
|
r#"[UPDATING] [..]
|
|
|
|
[CREDENTIAL] [..]not_found[..] get crates-io
|
2023-09-05 18:31:23 +00:00
|
|
|
{"v":1,"registry":{"index-url":"[..]","name":"crates-io","headers":[[..]"WWW-Authenticate: Cargo login_url=\"https://test-registry-login/me\""[..]]},"kind":"get","operation":"read"}
|
2023-08-18 21:14:53 +00:00
|
|
|
[ERROR] failed to query replaced source registry `crates-io`
|
|
|
|
|
|
|
|
Caused by:
|
|
|
|
no token found, please run `cargo login`
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.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();
|
|
|
|
|
2023-09-06 19:00:46 +00:00
|
|
|
cargo_process("install -v foo")
|
2023-08-18 21:14:53 +00:00
|
|
|
.replace_crates_io(server.index_url())
|
|
|
|
.with_status(101)
|
|
|
|
.with_stderr(
|
|
|
|
r#"[UPDATING] [..]
|
|
|
|
[CREDENTIAL] [..]not_supported[..] get crates-io
|
2023-09-05 18:31:23 +00:00
|
|
|
{"v":1,"registry":{"index-url":"[..]","name":"crates-io","headers":[[..]"WWW-Authenticate: Cargo login_url=\"https://test-registry-login/me\""[..]]},"kind":"get","operation":"read"}
|
2023-08-18 21:14:53 +00:00
|
|
|
[ERROR] failed to query replaced source registry `crates-io`
|
|
|
|
|
|
|
|
Caused by:
|
|
|
|
no credential providers could handle the request
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.run();
|
|
|
|
}
|
|
|
|
|
2020-12-01 19:16:16 +00:00
|
|
|
#[cargo_test]
|
2023-06-27 16:26:27 +00:00
|
|
|
fn multiple_providers() {
|
2022-08-31 05:53:47 +00:00
|
|
|
let server = registry::RegistryBuilder::new()
|
2022-06-09 03:04:33 +00:00
|
|
|
.no_configure_token()
|
|
|
|
.build();
|
2023-06-27 16:26:27 +00:00
|
|
|
|
|
|
|
// 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"}}"#);
|
|
|
|
|
2021-03-20 20:43:33 +00:00
|
|
|
cargo_util::paths::append(
|
2020-12-01 19:16:16 +00:00
|
|
|
&paths::home().join(".cargo/config"),
|
2023-06-27 16:26:27 +00:00
|
|
|
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(),
|
2020-12-01 19:16:16 +00:00
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
2023-09-06 19:00:46 +00:00
|
|
|
cargo_process("login -v abcdefg")
|
2022-08-31 05:53:47 +00:00
|
|
|
.replace_crates_io(server.index_url())
|
2020-12-01 19:16:16 +00:00
|
|
|
.with_stderr(
|
2023-06-27 16:26:27 +00:00
|
|
|
r#"[UPDATING] [..]
|
|
|
|
[CREDENTIAL] [..]url_not_supported[..] login crates-io
|
2023-09-05 18:31:23 +00:00
|
|
|
{"v":1,"registry":{"index-url":"https://github.com/rust-lang/crates.io-index","name":"crates-io"},"kind":"login","token":"abcdefg","login-url":"[..]"}
|
2023-06-27 16:26:27 +00:00
|
|
|
[CREDENTIAL] [..]success_provider[..] login crates-io
|
2023-09-05 18:31:23 +00:00
|
|
|
{"v":1,"registry":{"index-url":"https://github.com/rust-lang/crates.io-index","name":"crates-io"},"kind":"login","token":"abcdefg","login-url":"[..]"}
|
2023-06-27 16:26:27 +00:00
|
|
|
"#,
|
2020-12-01 19:16:16 +00:00
|
|
|
)
|
|
|
|
.run();
|
|
|
|
}
|
2020-12-04 22:09:06 +00:00
|
|
|
|
|
|
|
#[cargo_test]
|
2023-06-27 16:26:27 +00:00
|
|
|
fn both_token_and_provider() {
|
2023-09-06 15:10:02 +00:00
|
|
|
let server = registry::RegistryBuilder::new()
|
|
|
|
.credential_provider(&["cargo:paseto"])
|
|
|
|
.build();
|
|
|
|
|
2023-09-06 19:00:46 +00:00
|
|
|
cargo_process("login -Z asymmetric-token")
|
|
|
|
.masquerade_as_nightly_cargo(&["asymmetric-token"])
|
2023-09-06 15:10:02 +00:00
|
|
|
.replace_crates_io(server.index_url())
|
|
|
|
.with_stderr(
|
|
|
|
r#"[UPDATING] [..]
|
|
|
|
[WARNING] registry `crates-io` has a token configured in [..] that will be ignored because this registry is configured to use credential-provider `cargo:paseto`
|
|
|
|
k3.public[..]
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.run();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cargo_test]
|
|
|
|
fn registry_provider_overrides_global() {
|
2023-06-27 16:26:27 +00:00
|
|
|
let server = registry::RegistryBuilder::new().build();
|
|
|
|
cargo_util::paths::append(
|
|
|
|
&paths::home().join(".cargo/config"),
|
|
|
|
format!(
|
|
|
|
r#"
|
|
|
|
[registry]
|
2023-09-06 15:10:02 +00:00
|
|
|
global-credential-providers = ["should-not-be-called"]
|
2023-06-27 16:26:27 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.as_bytes(),
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
2023-09-06 19:00:46 +00:00
|
|
|
cargo_process("login -v abcdefg")
|
2023-09-06 15:10:02 +00:00
|
|
|
.env("CARGO_REGISTRY_CREDENTIAL_PROVIDER", "cargo:token")
|
2023-06-27 16:26:27 +00:00
|
|
|
.replace_crates_io(server.index_url())
|
|
|
|
.with_stderr(
|
|
|
|
r#"[UPDATING] [..]
|
|
|
|
[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");
|
|
|
|
}
|
2020-12-04 22:09:06 +00:00
|
|
|
|
2023-06-27 16:26:27 +00:00
|
|
|
#[cargo_test]
|
|
|
|
fn both_asymmetric_and_token() {
|
|
|
|
let server = registry::RegistryBuilder::new().build();
|
2021-03-20 20:43:33 +00:00
|
|
|
cargo_util::paths::append(
|
2020-12-04 22:09:06 +00:00
|
|
|
&paths::home().join(".cargo/config"),
|
|
|
|
format!(
|
|
|
|
r#"
|
|
|
|
[registry]
|
2023-06-27 16:26:27 +00:00
|
|
|
token = "foo"
|
|
|
|
secret-key = "bar"
|
2020-12-04 22:09:06 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.as_bytes(),
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
2023-08-24 05:12:50 +00:00
|
|
|
cargo_process("login -Zasymmetric-token -v abcdefg")
|
|
|
|
.masquerade_as_nightly_cargo(&["asymmetric-token"])
|
2023-06-27 16:26:27 +00:00
|
|
|
.replace_crates_io(server.index_url())
|
|
|
|
.with_stderr(
|
|
|
|
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 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()
|
2023-07-21 22:30:01 +00:00
|
|
|
.http_index()
|
2023-06-27 16:26:27 +00:00
|
|
|
.build();
|
|
|
|
|
|
|
|
// Token should not be re-used if it is expired
|
|
|
|
let expired_provider = build_provider(
|
2023-09-05 19:55:41 +00:00
|
|
|
"expired_provider",
|
|
|
|
r#"{"Ok":{"kind":"get","token":"sekrit","cache":"expires","expiration":0,"operation_independent":true}}"#,
|
2023-06-27 16:26:27 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
// Token should not be re-used for a different operation if it is not operation_independent
|
|
|
|
let non_independent_provider = build_provider(
|
2023-09-05 19:55:41 +00:00
|
|
|
"non_independent_provider",
|
2023-06-27 16:26:27 +00:00
|
|
|
r#"{"Ok":{"kind":"get","token":"sekrit","cache":"session","operation_independent":false}}"#,
|
|
|
|
);
|
|
|
|
|
2020-12-04 22:09:06 +00:00
|
|
|
let p = project()
|
2023-06-27 16:26:27 +00:00
|
|
|
.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/"
|
|
|
|
"#,
|
|
|
|
)
|
2020-12-04 22:09:06 +00:00
|
|
|
.file("src/lib.rs", "")
|
|
|
|
.build();
|
|
|
|
|
2023-06-27 16:26:27 +00:00
|
|
|
let output = r#"[UPDATING] `alternative` index
|
2023-09-05 18:31:23 +00:00
|
|
|
{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"read"}
|
2023-06-27 16:26:27 +00:00
|
|
|
[PACKAGING] foo v0.1.0 [..]
|
|
|
|
[PACKAGED] [..]
|
2023-09-05 18:31:23 +00:00
|
|
|
{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"publish","name":"foo","vers":"0.1.0","cksum":"[..]"}
|
2023-06-27 16:26:27 +00:00
|
|
|
[UPLOADING] foo v0.1.0 [..]
|
|
|
|
[UPLOADED] foo v0.1.0 [..]
|
|
|
|
note: Waiting [..]
|
|
|
|
You may press ctrl-c [..]
|
|
|
|
[PUBLISHED] foo v0.1.0 [..]
|
|
|
|
"#;
|
|
|
|
|
2023-09-19 20:28:38 +00:00
|
|
|
// The output should contain two JSON messages from the provider in both cases:
|
2023-06-27 16:26:27 +00:00
|
|
|
// The first because the credential is expired, the second because the provider
|
|
|
|
// indicated that the token was non-operation-independent.
|
2023-09-06 19:00:46 +00:00
|
|
|
p.cargo("publish --registry alternative --no-verify")
|
2023-06-27 16:26:27 +00:00
|
|
|
.with_stderr(output)
|
|
|
|
.run();
|
|
|
|
|
|
|
|
p.change_file(
|
|
|
|
".cargo/config",
|
|
|
|
&format!(
|
|
|
|
r#"
|
|
|
|
[registries.alternative]
|
|
|
|
index = "{}"
|
|
|
|
credential-provider = ["{non_independent_provider}"]
|
|
|
|
"#,
|
|
|
|
server.index_url(),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
2023-09-06 19:00:46 +00:00
|
|
|
p.cargo("publish --registry alternative --no-verify")
|
2023-06-27 16:26:27 +00:00
|
|
|
.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() {
|
|
|
|
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();
|
|
|
|
|
|
|
|
let _server = registry::RegistryBuilder::new()
|
|
|
|
.no_configure_token()
|
2023-08-16 04:56:11 +00:00
|
|
|
.credential_provider(&[
|
|
|
|
"cargo:token-from-stdout",
|
|
|
|
&toml_bin(&cred_proj, "test-cred"),
|
|
|
|
])
|
2023-06-27 16:26:27 +00:00
|
|
|
.token(cargo_test_support::registry::Token::Plaintext(
|
|
|
|
"sekrit".to_string(),
|
|
|
|
))
|
|
|
|
.alternative()
|
|
|
|
.http_api()
|
|
|
|
.auth_required()
|
|
|
|
.build();
|
|
|
|
|
|
|
|
let p = project()
|
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
|
|
|
[package]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
[dependencies.bar]
|
|
|
|
version = "0.0.1"
|
|
|
|
registry = "alternative"
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file("src/main.rs", "fn main() {}")
|
|
|
|
.build();
|
|
|
|
Package::new("bar", "0.0.1").alternative(true).publish();
|
|
|
|
|
2023-09-06 19:00:46 +00:00
|
|
|
p.cargo("check")
|
2020-12-04 22:09:06 +00:00
|
|
|
.with_stderr(
|
|
|
|
"\
|
2023-06-27 16:26:27 +00:00
|
|
|
[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] [..]
|
2020-12-04 22:09:06 +00:00
|
|
|
",
|
|
|
|
)
|
|
|
|
.run();
|
|
|
|
}
|
2023-08-29 19:52:05 +00:00
|
|
|
|
|
|
|
#[cargo_test]
|
|
|
|
fn unsupported_version() {
|
|
|
|
let cred_proj = project()
|
|
|
|
.at("new-vers")
|
|
|
|
.file("Cargo.toml", &basic_manifest("new-vers", "1.0.0"))
|
|
|
|
.file(
|
|
|
|
"src/main.rs",
|
|
|
|
&r####"
|
|
|
|
fn main() {
|
|
|
|
println!(r#"{{"v":[998, 999]}}"#);
|
|
|
|
assert_eq!(std::env::args().skip(1).next().unwrap(), "--cargo-plugin");
|
|
|
|
let mut buffer = String::new();
|
|
|
|
std::io::stdin().read_line(&mut buffer).unwrap();
|
|
|
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
|
|
|
panic!("child process should have been killed before getting here");
|
|
|
|
} "####,
|
|
|
|
)
|
|
|
|
.build();
|
|
|
|
cred_proj.cargo("build").run();
|
|
|
|
let provider = toml_bin(&cred_proj, "new-vers");
|
|
|
|
|
|
|
|
let registry = registry::RegistryBuilder::new()
|
|
|
|
.no_configure_token()
|
|
|
|
.credential_provider(&[&provider])
|
|
|
|
.build();
|
|
|
|
|
2023-09-06 19:00:46 +00:00
|
|
|
cargo_process("login abcdefg")
|
2023-08-29 19:52:05 +00:00
|
|
|
.replace_crates_io(registry.index_url())
|
|
|
|
.with_status(101)
|
|
|
|
.with_stderr(
|
|
|
|
r#"[UPDATING] [..]
|
|
|
|
[ERROR] credential provider `[..]` failed action `login`
|
|
|
|
|
|
|
|
Caused by:
|
|
|
|
credential provider supports protocol versions [998, 999], while Cargo supports [1]
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.run();
|
|
|
|
}
|
2023-09-14 19:33:51 +00:00
|
|
|
|
|
|
|
#[cargo_test]
|
|
|
|
fn alias_builtin_warning() {
|
|
|
|
let registry = registry::RegistryBuilder::new()
|
|
|
|
.credential_provider(&[&"cargo:token"])
|
|
|
|
.build();
|
|
|
|
|
|
|
|
cargo_util::paths::append(
|
|
|
|
&paths::home().join(".cargo/config"),
|
|
|
|
format!(
|
|
|
|
r#"
|
|
|
|
[credential-alias]
|
|
|
|
"cargo:token" = ["ignored"]
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.as_bytes(),
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
2023-09-06 19:00:46 +00:00
|
|
|
cargo_process("login abcdefg")
|
2023-09-14 19:33:51 +00:00
|
|
|
.replace_crates_io(registry.index_url())
|
|
|
|
.with_stderr(
|
|
|
|
r#"[UPDATING] [..]
|
|
|
|
[WARNING] credential-alias `cargo:token` (defined in `[..]`) will be ignored because it would shadow a built-in credential-provider
|
|
|
|
[LOGIN] token for `crates-io` saved
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.run();
|
|
|
|
}
|