1 //! Tests for credential-process.
3 use cargo_test_support
::{basic_manifest, cargo_process, paths, project, registry, Project}
;
7 fn toml_bin(proj
: &Project
, name
: &str) -> String
{
8 proj
.bin(name
).display().to_string().replace('
\\'
, "\\\\")
13 registry
::RegistryBuilder
::new()
23 credential-process = "false"
26 .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
27 .file("src/lib.rs", "")
30 p
.cargo("publish --no-verify")
31 .masquerade_as_nightly_cargo()
36 [ERROR] no upload token found, please run `cargo login` or pass `--token`
44 [registry.alternative]
45 credential-process = "false"
49 p
.cargo("publish --no-verify --registry alternative")
50 .masquerade_as_nightly_cargo()
55 [ERROR] no upload token found, please run `cargo login` or pass `--token`
62 fn warn_both_token_and_process() {
63 // Specifying both credential-process and a token in config should issue a warning.
64 registry
::RegistryBuilder
::new()
72 [registries.alternative]
74 credential-process = "false"
86 homepage = "https://example.com/"
89 .file("src
/lib
.rs
", "")
92 p.cargo("publish
--no
-verify
--registry alternative
-Z credential
-process
")
93 .masquerade_as_nightly_cargo()
97 [ERROR
] both `registries
.alternative
.token` and `registries
.alternative
.credential
-process`
\
98 were specified
in the config
\n\
99 Only one of these values may be set
, remove one or the other to proceed
.
104 // Try with global credential-process, and registry-specific `token`.
105 // This should silently use the config token, and not run the "false" exe.
110 credential
-process
= "false"
112 [registries
.alternative
]
116 p.cargo("publish
--no
-verify
--registry alternative
-Z credential
-process
")
117 .masquerade_as_nightly_cargo()
121 [PACKAGING
] foo v0
.1
.0 [..]
122 [UPLOADING
] foo v0
.1
.0 [..]
128 /// Setup for a test that will issue a command that needs to fetch a token.
130 /// This does the following:
132 /// * Spawn a thread that will act as an API server.
133 /// * Create a simple credential-process that will generate a fake token.
134 /// * Create a simple `foo` project to run the test against.
135 /// * Configure the credential-process config.
137 /// Returns a thread handle for the API server, the test should join it when
138 /// finished. Also returns the simple `foo` project to test against.
139 fn get_token_test() -> (Project, thread::JoinHandle<()>) {
140 // API server that checks that the token is included correctly.
141 let server = registry::RegistryBuilder::new()
143 .build_api_server(&|headers| {
146 .any(|header| header == "Authorization
: sekrit
"));
148 (200, &r#"{"ok": true, "msg": "completed!"}
"#)
151 // The credential process to use.
152 let cred_proj = project()
154 .file("Cargo
.toml
", &basic_manifest("test
-cred
", "1.0.0"))
155 .file("src
/main
.rs
", r#"fn main() { println!("sekrit"); }
"#)
157 cred_proj.cargo("build
").run();
164 [registries
.alternative
]
166 credential
-process
= ["{}"]
168 registry::alt_registry_url(),
169 toml_bin(&cred_proj, "test
-cred
")
181 homepage
= "https://example.com/"
184 .file("src
/lib
.rs
", "")
191 // Checks that credential-process is used for `cargo publish`.
192 let (p, t) = get_token_test();
194 p.cargo("publish
--no
-verify
--registry alternative
-Z credential
-process
")
195 .masquerade_as_nightly_cargo()
199 [PACKAGING
] foo v0
.1
.0 [..]
200 [UPLOADING
] foo v0
.1
.0 [..]
205 t.join().ok().unwrap();
209 fn basic_unsupported() {
210 // Non-action commands don't support login/logout.
211 registry::RegistryBuilder::new().add_tokens(false).build();
212 cargo::util::paths::append(
213 &paths::home().join(".cargo
/config
"),
216 credential
-process
= "false"
221 cargo_process("login
-Z credential
-process abcdefg
")
222 .masquerade_as_nightly_cargo()
227 [ERROR
] credential process `
false` cannot be used to log
in, \
228 the credential
-process configuration value must pass the
\
229 `{action}` argument
in the config to support this command
234 cargo_process("logout
-Z credential
-process
")
235 .masquerade_as_nightly_cargo()
239 [ERROR
] credential process `
false` cannot be used to log out
, \
240 the credential
-process configuration value must pass the
\
241 `{action}` argument
in the config to support this command
250 // The credential process to use.
251 let cred_proj = project()
253 .file("Cargo
.toml
", &basic_manifest("test
-cred
", "1.0.0"))
260 assert_eq
!(std
::env
::var("CARGO_REGISTRY_NAME").unwrap(), "crates-io");
261 assert_eq
!(std
::env
::var("CARGO_REGISTRY_API_URL").unwrap(), "__API__");
262 assert_eq
!(std
::env
::args().skip(1).next().unwrap(), "store");
263 let mut buffer
= String
::new();
264 std
::io
::stdin().read_to_string(&mut buffer
).unwrap();
265 assert_eq
!(buffer
, "abcdefg\n");
266 std
::fs
::write("token-store", buffer
).unwrap();
269 .replace("__API__
", ®istry::api_url().to_string()),
272 cred_proj.cargo("build
").run();
274 cargo::util::paths::append(
275 &paths::home().join(".cargo
/config
"),
279 credential
-process
= ["{}", "{{action}}"]
281 toml_bin(&cred_proj, "test
-cred
")
287 cargo_process("login
-Z credential
-process abcdefg
")
288 .masquerade_as_nightly_cargo()
292 [LOGIN
] token
for `crates
.io` saved
297 fs::read_to_string(paths::root().join("token
-store
")).unwrap(),
304 registry::RegistryBuilder::new().add_tokens(false).build();
305 // The credential process to use.
306 let cred_proj = project()
308 .file("Cargo
.toml
", &basic_manifest("test
-cred
", "1.0.0"))
315 assert_eq
!(std
::env
::var("CARGO_REGISTRY_NAME").unwrap(), "crates-io");
316 assert_eq
!(std
::env
::args().skip(1).next().unwrap(), "erase");
317 std
::fs
::write("token-store", "").unwrap();
318 eprintln
!("token for `{}` has been erased!",
319 std
::env
::var("CARGO_REGISTRY_NAME").unwrap());
324 cred_proj.cargo("build
").run();
326 cargo::util::paths::append(
327 &paths::home().join(".cargo
/config
"),
331 credential
-process
= ["{}", "{{action}}"]
333 toml_bin(&cred_proj, "test
-cred
")
339 cargo_process("logout
-Z credential
-process
")
340 .masquerade_as_nightly_cargo()
344 token
for `crates
-io` has been erased
!
345 [LOGOUT
] token
for `crates
.io` has been removed from local storage
350 fs::read_to_string(paths::root().join("token
-store
")).unwrap(),
357 let (p, t) = get_token_test();
359 p.cargo("yank
--vers
0.1.0 --registry alternative
-Z credential
-process
")
360 .masquerade_as_nightly_cargo()
369 t.join().ok().unwrap();
374 let (p, t) = get_token_test();
376 p.cargo("owner
--add username
--registry alternative
-Z credential
-process
")
377 .masquerade_as_nightly_cargo()
386 t.join().ok().unwrap();
391 // cargo: prefixed names use the sysroot
392 registry::RegistryBuilder::new().add_tokens(false).build();
393 cargo::util::paths::append(
394 &paths::home().join(".cargo
/config
"),
397 credential
-process
= "cargo:doesnotexist"
402 cargo_process("login
-Z credential
-process abcdefg
")
403 .masquerade_as_nightly_cargo()
408 [ERROR
] failed to execute `
[..]libexec
/cargo
-credential
-doesnotexist
[EXE
]` to store authentication token
for registry `crates
-io`
412 ", cargo_test_support::no_such_file_err_msg()),
418 fn invalid_token_output() {
419 // Error when credential process does not output the expected format for a token.
420 registry::RegistryBuilder::new()
424 let cred_proj = project()
426 .file("Cargo
.toml
", &basic_manifest("test
-cred
", "1.0.0"))
427 .file("src
/main
.rs
", r#"fn main() { print!("a\nb\n"); }
"#)
429 cred_proj.cargo("build
").run();
431 cargo::util::paths::append(
432 &paths::home().join(".cargo
/config
"),
436 credential
-process
= ["{}"]
438 toml_bin(&cred_proj, "test
-cred
")
445 .file("Cargo
.toml
", &basic_manifest("foo
", "1.0.0"))
446 .file("src
/lib
.rs
", "")
449 p.cargo("publish
--no
-verify
--registry alternative
-Z credential
-process
")
450 .masquerade_as_nightly_cargo()
455 [ERROR
] credential process `
[..]test
-cred
[EXE
]` returned more than one line of output
; expected a single token