| //! Tests for credential-process. |
| |
| use cargo_test_support::prelude::*; |
| use cargo_test_support::registry::{Package, TestRegistry}; |
| use cargo_test_support::{basic_manifest, cargo_process, paths, project, registry, str, 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. |
| /// |
| /// Returns the simple `foo` project to test against and the API server handle. |
| fn get_token_test() -> (Project, TestRegistry) { |
| // API server that checks that the token is included correctly. |
| let server = registry::RegistryBuilder::new() |
| .no_configure_token() |
| .token(cargo_test_support::registry::Token::Plaintext( |
| "sekrit".to_string(), |
| )) |
| .alternative() |
| .http_api() |
| .http_index() |
| .auth_required() |
| .build(); |
| |
| let provider = build_provider( |
| "test-cred", |
| r#"{"Ok":{"kind":"get","token":"sekrit","cache":"session","operation_independent":false}}"#, |
| ); |
| |
| let p = project() |
| .file( |
| ".cargo/config.toml", |
| &format!( |
| r#" |
| [registries.alternative] |
| index = "{}" |
| credential-provider = ["{provider}"] |
| "#, |
| server.index_url(), |
| ), |
| ) |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| edition = "2015" |
| description = "foo" |
| license = "MIT" |
| homepage = "https://example.com/" |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .build(); |
| (p, server) |
| } |
| |
| #[cargo_test] |
| fn publish() { |
| // Checks that credential-process is used for `cargo publish`. |
| let (p, _t) = get_token_test(); |
| |
| p.cargo("publish --no-verify --registry alternative") |
| .with_stderr_data(str![[r#" |
| [UPDATING] `alternative` index |
| {"v":1,"registry":{"index-url":"[..]","name":"alternative","headers":[..]},"kind":"get","operation":"read"} |
| [PACKAGING] foo v0.1.0 ([ROOT]/foo) |
| [PACKAGED] 3 files, [FILE_SIZE]B ([FILE_SIZE]B compressed) |
| [UPLOADING] foo v0.1.0 ([ROOT]/foo) |
| {"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"publish","name":"foo","vers":"0.1.0","cksum":"[..]"} |
| [UPLOADED] foo v0.1.0 to registry `alternative` |
| [NOTE] waiting for `foo v0.1.0` to be available at registry `alternative`. |
| You may press ctrl-c [..] |
| [PUBLISHED] foo v0.1.0 at registry `alternative` |
| |
| "#]]) |
| .run(); |
| } |
| |
| #[cargo_test] |
| 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_process("login abcdefg") |
| .replace_crates_io(registry.index_url()) |
| .with_status(101) |
| .with_stderr_data(str![[r#" |
| [UPDATING] crates.io index |
| [ERROR] credential provider `cargo:token-from-stdout false` failed action `login` |
| |
| Caused by: |
| requested operation not supported |
| |
| "#]]) |
| .run(); |
| |
| cargo_process("logout") |
| .replace_crates_io(registry.index_url()) |
| .with_status(101) |
| .with_stderr_data(str![[r#" |
| [ERROR] credential provider `cargo:token-from-stdout false` failed action `logout` |
| |
| Caused by: |
| requested operation not supported |
| |
| "#]]) |
| .run(); |
| } |
| |
| #[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 abcdefg -- cmd3 --cmd4") |
| .replace_crates_io(registry.index_url()) |
| .with_stderr_data(str![[r#" |
| [UPDATING] crates.io index |
| {"v":1,"registry":{"index-url":"https://github.com/rust-lang/crates.io-index","name":"crates-io"},"kind":"login","token":"abcdefg","login-url":"[ROOTURL]/api/me","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(); |
| |
| cargo_process("logout") |
| .replace_crates_io(server.index_url()) |
| .with_stderr_data(str![[r#" |
| {"v":1,"registry":{"index-url":"https://github.com/rust-lang/crates.io-index","name":"crates-io"},"kind":"logout"} |
| |
| "#]]) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn yank() { |
| let (p, _t) = get_token_test(); |
| |
| p.cargo("yank --version 0.1.0 --registry alternative") |
| .with_stderr_data(str![[r#" |
| [UPDATING] `alternative` index |
| {"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"} |
| [YANK] foo@0.1.0 |
| |
| "#]]) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn owner() { |
| let (p, _t) = get_token_test(); |
| |
| p.cargo("owner --add username --registry alternative") |
| .with_stderr_data(str![[r#" |
| [UPDATING] `alternative` index |
| {"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"} |
| [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") |
| .with_status(101) |
| .with_stderr_data(str![[r#" |
| [UPDATING] `alternative` index |
| [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####" |
| 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) |
| } |
| |
| #[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. |
| cargo_process("install -v foo") |
| .replace_crates_io(registry.index_url()) |
| .with_status(101) |
| .with_stderr_data(str![[r#" |
| [UPDATING] crates.io index |
| [CREDENTIAL] [..]not_found[..] get crates-io |
| {"v":1[..] |
| [ERROR] no token found, please run `cargo login` |
| |
| "#]]) |
| .run(); |
| } |
| |
| #[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.toml"), |
| format!( |
| r#" |
| [registry] |
| global-credential-providers = ["not_found"] |
| [credential-alias] |
| not_found = ["{not_found}"] |
| "#, |
| ) |
| .as_bytes(), |
| ) |
| .unwrap(); |
| |
| // should not suggest a _TOKEN environment variable since the cargo:token provider isn't available. |
| cargo_process("install -v foo") |
| .replace_crates_io(server.index_url()) |
| .with_status(101) |
| .with_stderr_data(str![[r#" |
| [UPDATING] crates.io index |
| [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"} |
| [ERROR] 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.toml"), |
| format!( |
| r#" |
| [registry] |
| global-credential-providers = ["not_supported"] |
| [credential-alias] |
| not_supported = ["{not_supported}"] |
| "#, |
| ) |
| .as_bytes(), |
| ) |
| .unwrap(); |
| |
| cargo_process("install -v foo") |
| .replace_crates_io(server.index_url()) |
| .with_status(101) |
| .with_stderr_data(str![[r#" |
| [UPDATING] crates.io index |
| [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"} |
| [ERROR] no credential providers could handle the request |
| |
| "#]]) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn multiple_providers() { |
| let server = registry::RegistryBuilder::new() |
| .no_configure_token() |
| .build(); |
| |
| // 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.toml"), |
| 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 -v abcdefg") |
| .replace_crates_io(server.index_url()) |
| .with_stderr_data(str![[r#" |
| [UPDATING] crates.io index |
| [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":"[ROOTURL]/api/me"} |
| [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":"[ROOTURL]/api/me"} |
| |
| "#]]) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn both_token_and_provider() { |
| let server = registry::RegistryBuilder::new() |
| .credential_provider(&["cargo:paseto"]) |
| .build(); |
| |
| cargo_process("login -Z asymmetric-token") |
| .masquerade_as_nightly_cargo(&["asymmetric-token"]) |
| .replace_crates_io(server.index_url()) |
| .with_stderr_data(str![[r#" |
| [UPDATING] crates.io index |
| [WARNING] registry `crates-io` has a token configured in [ROOT]/home/.cargo/credentials.toml 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() { |
| let server = registry::RegistryBuilder::new().build(); |
| cargo_util::paths::append( |
| &paths::home().join(".cargo/config.toml"), |
| format!( |
| r#" |
| [registry] |
| global-credential-providers = ["should-not-be-called"] |
| "#, |
| ) |
| .as_bytes(), |
| ) |
| .unwrap(); |
| |
| cargo_process("login -v abcdefg") |
| .env("CARGO_REGISTRY_CREDENTIAL_PROVIDER", "cargo:token") |
| .replace_crates_io(server.index_url()) |
| .with_stderr_data(str![[r#" |
| [UPDATING] crates.io index |
| [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 both_asymmetric_and_token() { |
| let server = registry::RegistryBuilder::new().build(); |
| cargo_util::paths::append( |
| &paths::home().join(".cargo/config.toml"), |
| format!( |
| r#" |
| [registry] |
| token = "foo" |
| secret-key = "bar" |
| "#, |
| ) |
| .as_bytes(), |
| ) |
| .unwrap(); |
| |
| cargo_process("login -Zasymmetric-token -v abcdefg") |
| .masquerade_as_nightly_cargo(&["asymmetric-token"]) |
| .replace_crates_io(server.index_url()) |
| .with_stderr_data(str![[r#" |
| [UPDATING] crates.io index |
| [WARNING] registry `crates-io` has a `secret_key` configured in [..]config.toml 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() |
| .http_index() |
| .build(); |
| |
| // Token should not be re-used if it is expired |
| let expired_provider = build_provider( |
| "expired_provider", |
| r#"{"Ok":{"kind":"get","token":"sekrit","cache":"expires","expiration":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( |
| "non_independent_provider", |
| r#"{"Ok":{"kind":"get","token":"sekrit","cache":"session","operation_independent":false}}"#, |
| ); |
| |
| let p = project() |
| .file( |
| ".cargo/config.toml", |
| &format!( |
| r#" |
| [registries.alternative] |
| index = "{}" |
| credential-provider = ["{expired_provider}"] |
| "#, |
| server.index_url(), |
| ), |
| ) |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| edition = "2015" |
| 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"} |
| [PACKAGING] foo v0.1.0 ([ROOT]/foo) |
| [PACKAGED] 3 files, [FILE_SIZE]B ([FILE_SIZE]B compressed) |
| [UPLOADING] foo v0.1.0 ([ROOT]/foo) |
| {"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"publish","name":"foo","vers":"0.1.0","cksum":"[..]"} |
| [UPLOADED] foo v0.1.0 to registry `alternative` |
| [NOTE] waiting [..] |
| You may press ctrl-c [..] |
| [PUBLISHED] foo v0.1.0 at registry `alternative` |
| "#; |
| |
| // The output should contain two JSON messages from the provider in both cases: |
| // The first because the credential is expired, the second because the provider |
| // indicated that the token was non-operation-independent. |
| p.cargo("publish --registry alternative --no-verify") |
| .with_stderr_data(output) |
| .run(); |
| |
| let output_non_independent = r#"[UPDATING] `alternative` index |
| {"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"read"} |
| [PACKAGING] foo v0.1.1 ([ROOT]/foo) |
| [PACKAGED] 3 files, [FILE_SIZE]B ([FILE_SIZE]B compressed) |
| [UPLOADING] foo v0.1.1 ([ROOT]/foo) |
| {"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"publish","name":"foo","vers":"0.1.1","cksum":"[..]"} |
| [UPLOADED] foo v0.1.1 to registry `alternative` |
| [NOTE] waiting [..] |
| You may press ctrl-c [..] |
| [PUBLISHED] foo v0.1.1 at registry `alternative` |
| "#; |
| |
| p.change_file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.1" |
| edition = "2015" |
| description = "foo" |
| license = "MIT" |
| homepage = "https://example.com/" |
| "#, |
| ); |
| |
| p.change_file( |
| ".cargo/config.toml", |
| &format!( |
| r#" |
| [registries.alternative] |
| index = "{}" |
| credential-provider = ["{non_independent_provider}"] |
| "#, |
| server.index_url(), |
| ), |
| ); |
| |
| p.cargo("publish --registry alternative --no-verify") |
| .with_stderr_data(output_non_independent) |
| .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() |
| .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#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| edition = "2015" |
| 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(); |
| |
| p.cargo("check") |
| .with_stderr_data(str![[r#" |
| [UPDATING] `alternative` index |
| [LOCKING] 1 package to latest compatible version |
| CARGO=Some([..]) |
| CARGO_REGISTRY_NAME_OPT=Some("alternative") |
| CARGO_REGISTRY_INDEX_URL=Some("[ROOTURL]/alternative-registry") |
| [DOWNLOADING] crates ... |
| [DOWNLOADED] bar v0.0.1 (registry `alternative`) |
| [CHECKING] bar v0.0.1 (registry `alternative`) |
| [CHECKING] foo v0.0.1 ([ROOT]/foo) |
| [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s |
| |
| "#]]) |
| .run(); |
| } |
| |
| #[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(); |
| |
| cargo_process("login abcdefg") |
| .replace_crates_io(registry.index_url()) |
| .with_status(101) |
| .with_stderr_data(str![[r#" |
| [UPDATING] crates.io index |
| [ERROR] credential provider `[..]` failed action `login` |
| |
| Caused by: |
| credential provider supports protocol versions [998, 999], while Cargo supports [1] |
| |
| "#]]) |
| .run(); |
| } |
| |
| #[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.toml"), |
| format!( |
| r#" |
| [credential-alias] |
| "cargo:token" = ["ignored"] |
| "#, |
| ) |
| .as_bytes(), |
| ) |
| .unwrap(); |
| |
| cargo_process("login abcdefg") |
| .replace_crates_io(registry.index_url()) |
| .with_stderr_data(str![[r#" |
| [UPDATING] crates.io index |
| [WARNING] credential-alias `cargo:token` (defined in `[ROOT]/home/.cargo/config.toml`) will be ignored because it would shadow a built-in credential-provider |
| [LOGIN] token for `crates-io` saved |
| |
| "#]]) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn login_token_from_stdin() { |
| // Test reading a token from stdin, ensuring newlines are trimmed. |
| let registry = registry::RegistryBuilder::new() |
| .no_configure_token() |
| .credential_provider(&[&build_provider("test-cred", r#"{"Ok": {"kind": "login"}}"#)]) |
| .build(); |
| |
| cargo_process("login") |
| .replace_crates_io(registry.index_url()) |
| .with_stdin("abcdefg\n") |
| .with_stderr_data(str![[r#" |
| [UPDATING] crates.io index |
| {"v":1,"registry":{"index-url":"https://github.com/rust-lang/crates.io-index","name":"crates-io"},"kind":"login","token":"abcdefg","login-url":"[ROOTURL]/api/me"} |
| |
| "#]]) |
| .run(); |
| } |