Skip to content

Commit 49c62f5

Browse files
committed
Auto merge of #11952 - ehuss:check-token-publish, r=weihanglo
Validate token on publish. The `publish` path was not validating the token like the other API routes were (like owner, or yank). This does not appear to be intentional from what I can tell. This consolidates the relevant code so that it is shared with all the API calls. cc #11600 Closes #11571
2 parents 34cb1ea + 35f5862 commit 49c62f5

File tree

2 files changed

+52
-11
lines changed

2 files changed

+52
-11
lines changed

crates/crates-io/lib.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,15 @@ impl Registry {
219219
self.token = token;
220220
}
221221

222+
fn token(&self) -> Result<&str> {
223+
let token = match self.token.as_ref() {
224+
Some(s) => s,
225+
None => bail!("no upload token found, please run `cargo login`"),
226+
};
227+
check_token(token)?;
228+
Ok(token)
229+
}
230+
222231
pub fn host(&self) -> &str {
223232
&self.host
224233
}
@@ -278,16 +287,12 @@ impl Registry {
278287

279288
let url = format!("{}/api/v1/crates/new", self.host);
280289

281-
let token = match self.token.as_ref() {
282-
Some(s) => s,
283-
None => bail!("no upload token found, please run `cargo login`"),
284-
};
285290
self.handle.put(true)?;
286291
self.handle.url(&url)?;
287292
self.handle.in_filesize(size as u64)?;
288293
let mut headers = List::new();
289294
headers.append("Accept: application/json")?;
290-
headers.append(&format!("Authorization: {}", token))?;
295+
headers.append(&format!("Authorization: {}", self.token()?))?;
291296
self.handle.http_headers(headers)?;
292297

293298
let started = Instant::now();
@@ -390,12 +395,7 @@ impl Registry {
390395
headers.append("Content-Type: application/json")?;
391396

392397
if self.auth_required || authorized == Auth::Authorized {
393-
let token = match self.token.as_ref() {
394-
Some(s) => s,
395-
None => bail!("no upload token found, please run `cargo login`"),
396-
};
397-
check_token(token)?;
398-
headers.append(&format!("Authorization: {}", token))?;
398+
headers.append(&format!("Authorization: {}", self.token()?))?;
399399
}
400400
self.handle.http_headers(headers)?;
401401
match body {

tests/testsuite/publish.rs

+41
Original file line numberDiff line numberDiff line change
@@ -2908,3 +2908,44 @@ You may press ctrl-c to skip waiting; the crate should be available shortly.
29082908

29092909
p.cargo("check").with_status(0).run();
29102910
}
2911+
2912+
#[cargo_test]
2913+
fn invalid_token() {
2914+
// Checks publish behavior with an invalid token.
2915+
let registry = RegistryBuilder::new().http_api().http_index().build();
2916+
2917+
let p = project()
2918+
.file(
2919+
"Cargo.toml",
2920+
r#"
2921+
[package]
2922+
name = "foo"
2923+
version = "0.0.1"
2924+
authors = []
2925+
license = "MIT"
2926+
description = "foo"
2927+
documentation = "foo"
2928+
"#,
2929+
)
2930+
.file("src/main.rs", "fn main() {}")
2931+
.build();
2932+
2933+
p.cargo("publish --no-verify")
2934+
.replace_crates_io(registry.index_url())
2935+
.env("CARGO_REGISTRY_TOKEN", "\x16")
2936+
.with_stderr(
2937+
"\
2938+
[UPDATING] crates.io index
2939+
[PACKAGING] foo v0.0.1 ([ROOT]/foo)
2940+
[PACKAGED] 4 files, [..]
2941+
[UPLOADING] foo v0.0.1 ([ROOT]/foo)
2942+
error: failed to publish to registry at http://127.0.0.1:[..]/
2943+
2944+
Caused by:
2945+
token contains invalid characters.
2946+
Only printable ISO-8859-1 characters are allowed as it is sent in a HTTPS header.
2947+
",
2948+
)
2949+
.with_status(101)
2950+
.run();
2951+
}

0 commit comments

Comments
 (0)