From 4df95a26b8a3d52984bd5523b2b7cc563c035a75 Mon Sep 17 00:00:00 2001 From: Justin Geibel Date: Fri, 4 Jan 2019 22:10:41 -0500 Subject: [PATCH] Reject publishing of crates that depend on an alternative registry --- src/models/dependency.rs | 6 ++++ src/tests/builders.rs | 9 +++++ ...llow_empty_alternative_registry_dependency | 36 +++++++++++++++++++ src/tests/krate.rs | 31 ++++++++++++++++ src/views/krate_publish.rs | 1 + 5 files changed, 83 insertions(+) create mode 100644 src/tests/http-data/krate_new_crate_allow_empty_alternative_registry_dependency diff --git a/src/models/dependency.rs b/src/models/dependency.rs index be416e3c5f..10b43576a5 100644 --- a/src/models/dependency.rs +++ b/src/models/dependency.rs @@ -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::(&*conn) diff --git a/src/tests/builders.rs b/src/tests/builders.rs index cbe6d53bb9..4e8d0870d1 100644 --- a/src/tests/builders.rs +++ b/src/tests/builders.rs @@ -522,6 +522,7 @@ impl PublishBuilder { /// A builder for constructing a dependency of another crate. pub struct DependencyBuilder { name: String, + registry: Option, explicit_name_in_toml: Option, version_req: u::EncodableCrateVersionReq, } @@ -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()), } @@ -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 @@ -567,6 +575,7 @@ impl DependencyBuilder { target: None, kind: None, explicit_name_in_toml: self.explicit_name_in_toml, + registry: self.registry, } } } diff --git a/src/tests/http-data/krate_new_crate_allow_empty_alternative_registry_dependency b/src/tests/http-data/krate_new_crate_allow_empty_alternative_registry_dependency new file mode 100644 index 0000000000..7069f1d6bf --- /dev/null +++ b/src/tests/http-data/krate_new_crate_allow_empty_alternative_registry_dependency @@ -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": "" + } + } +] diff --git a/src/tests/krate.rs b/src/tests/krate.rs index f3fb03b76e..ad642f1e5e 100644 --- a/src/tests/krate.rs +++ b/src/tests/krate.rs @@ -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(); diff --git a/src/views/krate_publish.rs b/src/views/krate_publish.rs index da9d0c1a0c..0fb3c496ce 100644 --- a/src/views/krate_publish.rs +++ b/src/views/krate_publish.rs @@ -63,6 +63,7 @@ pub struct EncodableCrateDependency { pub target: Option, pub kind: Option, pub explicit_name_in_toml: Option, + pub registry: Option, } impl<'de> Deserialize<'de> for EncodableCrateName {