Skip to content

Commit

Permalink
Reject publishing of crates that depend on an alternative registry
Browse files Browse the repository at this point in the history
  • Loading branch information
jtgeibel committed Jan 21, 2019
1 parent f7fbc01 commit 4df95a2
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/models/dependency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ pub fn add_dependencies(
let git_and_new_dependencies = deps
.iter()
.map(|dep| {
if let Some(registry) = &dep.registry {
if !registry.is_empty() {
return Err(human(&format_args!("Dependency `{}` is hosted on another registry. Cross-registry dependencies are not permitted on crates.io.", &*dep.name)));
}
}

// Match only identical names to ensure the index always references the original crate name
let krate = Crate::by_exact_name(&dep.name)
.first::<Crate>(&*conn)
Expand Down
9 changes: 9 additions & 0 deletions src/tests/builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,7 @@ impl PublishBuilder {
/// A builder for constructing a dependency of another crate.
pub struct DependencyBuilder {
name: String,
registry: Option<String>,
explicit_name_in_toml: Option<u::EncodableCrateName>,
version_req: u::EncodableCrateVersionReq,
}
Expand All @@ -531,6 +532,7 @@ impl DependencyBuilder {
pub fn new(name: &str) -> Self {
DependencyBuilder {
name: name.to_string(),
registry: None,
explicit_name_in_toml: None,
version_req: u::EncodableCrateVersionReq(semver::VersionReq::parse(">= 0").unwrap()),
}
Expand All @@ -542,6 +544,12 @@ impl DependencyBuilder {
self
}

/// Set an alternative registry for this dependency.
pub fn registry(mut self, registry: &str) -> Self {
self.registry = Some(registry.to_string());
self
}

/// Set the version requirement for this dependency.
///
/// # Panics
Expand All @@ -567,6 +575,7 @@ impl DependencyBuilder {
target: None,
kind: None,
explicit_name_in_toml: self.explicit_name_in_toml,
registry: self.registry,
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[
{
"request": {
"uri": "http://alexcrichton-test.s3.amazonaws.com/crates/foo/foo-1.0.0.crate",
"method": "PUT",
"headers": [
[
"accept",
"*/*"
],
[
"content-length",
"35"
],
[
"host",
"alexcrichton-test.s3.amazonaws.com"
],
[
"accept-encoding",
"gzip"
],
[
"content-type",
"application/x-tar"
]
],
"body": "H4sIAAAAAAAA/+3AAQEAAACCIP+vbkhQwKsBLq+17wAEAAA="
},
"response": {
"status": 200,
"headers": [],
"body": ""
}
}
]
31 changes: 31 additions & 0 deletions src/tests/krate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,37 @@ fn reject_new_krate_with_non_exact_dependency() {
token.publish(crate_to_publish).bad_with_status(200);
}

#[test]
fn new_crate_allow_empty_alternative_registry_dependency() {
let (app, _, user, token) = TestApp::with_proxy().with_token();

app.db(|conn| {
CrateBuilder::new("foo-dep", user.as_model().id).expect_build(conn);
});

let dependency = DependencyBuilder::new("foo-dep").registry("");
let crate_to_publish = PublishBuilder::new("foo").dependency(dependency);
token.publish(crate_to_publish).good();
}

#[test]
fn reject_new_crate_with_alternative_registry_dependency() {
let (_, _, _, token) = TestApp::init().with_token();

let dependency =
DependencyBuilder::new("dep").registry("https://server.example/path/to/registry");

let crate_to_publish = PublishBuilder::new("depends-on-alt-registry").dependency(dependency);
let json = token.publish(crate_to_publish).bad_with_status(200);
assert!(
json.errors[0]
.detail
.contains("Cross-registry dependencies are not permitted on crates.io."),
"{:?}",
json.errors
);
}

#[test]
fn new_krate_with_wildcard_dependency() {
let (app, _, user, token) = TestApp::init().with_token();
Expand Down
1 change: 1 addition & 0 deletions src/views/krate_publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pub struct EncodableCrateDependency {
pub target: Option<String>,
pub kind: Option<DependencyKind>,
pub explicit_name_in_toml: Option<EncodableCrateName>,
pub registry: Option<String>,
}

impl<'de> Deserialize<'de> for EncodableCrateName {
Expand Down

0 comments on commit 4df95a2

Please sign in to comment.