Skip to content

Commit 0fcd6d1

Browse files
committed
Merge remote-tracking branch 'upstream/master' into sg-test-pagerduty
2 parents 2267c99 + 4ba9fdb commit 0fcd6d1

File tree

69 files changed

+8603
-1236
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+8603
-1236
lines changed

.travis.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,15 @@ matrix:
4747
allow_failures:
4848
- rust: nightly
4949
include:
50-
- rust: nightly-2018-06-26
51-
script:
52-
- cargo install --force clippy --vers 0.0.210
53-
- cargo clippy
5450
- rust: stable
5551
before_install:
5652
- nvm install 10
5753
- rustup component add rustfmt-preview
54+
- rustup component add clippy-preview
5855
script:
5956
- cargo fmt -- --check
57+
# TODO: Once clippy:: lint syntax is stable, remove everything after the -- below
58+
- cargo clippy --all-targets -- -A renamed_and_removed_lints
6059
- cargo build
6160
- cargo test
6261
- npm install

Cargo.lock

Lines changed: 59 additions & 30 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,14 @@ rustdoc-args = [
2828

2929
[dependencies]
3030
cargo-registry-s3 = { path = "src/s3", version = "0.2.0" }
31+
old_semver = { path = "src/old_semver", version = "0.1.0" }
3132
rand = "0.3"
3233
git2 = "0.6.4"
3334
flate2 = "1.0"
34-
semver = "0.5"
35+
semver = { version = "0.9", git = "https://github.com/steveklabnik/semver.git", features = ["diesel", "serde"] }
3536
url = "1.2.1"
3637
tar = "0.4.13"
38+
base64 = "0.9"
3739

3840
openssl = "0.9.14"
3941
oauth2 = "0.3"
@@ -58,6 +60,7 @@ itertools = "0.6.0"
5860
scheduled-thread-pool = "0.2.0"
5961
derive_deref = "1.0.0"
6062
reqwest = "0.9.1"
63+
tempdir = "0.3.7"
6164

6265
lettre = "0.8"
6366
lettre_email = "0.8"
@@ -77,6 +80,7 @@ conduit-test = "0.8"
7780
hyper = "0.12"
7881
hyper-tls = "0.2"
7982
futures = "0.1"
83+
lazy_static = "1.0"
8084
tokio-core = "0.1"
8185
tokio-service = "0.1"
8286

app/controllers/crate/version.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ export default Controller.extend({
3030
keywords: alias('crate.keywords'),
3131
categories: alias('crate.categories'),
3232
badges: alias('crate.badges'),
33-
isOwner: computed('crate.owner_user', 'session.currentUser.login', function() {
34-
return this.get('crate.owner_user').findBy('login', this.get('session.currentUser.login'));
33+
isOwner: computed('crate.owner_user', 'session.currentUser.id', function() {
34+
return this.get('crate.owner_user').findBy('id', this.get('session.currentUser.id'));
3535
}),
3636

3737
sortedVersions: readOnly('crate.versions'),

app/styles/crate.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
@include align-items(center);
3939
}
4040
@media only screen and (max-width: 650px) {
41-
.right { display: none; }
41+
.right { @include justify-content(center); }
4242
}
4343

4444
&.crate-index, &.crate-search {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DROP INDEX index_crates_name_ordering;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CREATE INDEX index_crates_name_ordering ON crates (name);

src/controllers/user/me.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use util::bad_request;
88

99
use models::{Email, Follow, NewEmail, User, Version};
1010
use schema::{crates, emails, follows, users, versions};
11-
use views::{EncodablePrivateUser, EncodableVersion};
11+
use views::{EncodableMe, EncodableVersion};
1212

1313
/// Handles the `GET /me` route.
1414
pub fn me(req: &mut dyn Request) -> CargoResult<Response> {
@@ -40,11 +40,7 @@ pub fn me(req: &mut dyn Request) -> CargoResult<Response> {
4040
let verification_sent = verified || verification_sent;
4141
let user = User { email, ..user };
4242

43-
#[derive(Serialize)]
44-
struct R {
45-
user: EncodablePrivateUser,
46-
}
47-
Ok(req.json(&R {
43+
Ok(req.json(&EncodableMe {
4844
user: user.encodable_private(verified, verification_sent),
4945
}))
5046
}

src/db.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub trait RequestTransaction {
3636
/// Return the lazily initialized postgres connection for this request.
3737
///
3838
/// The connection will live for the lifetime of the request.
39+
// FIXME: This description does not match the implementation below.
3940
fn db_conn(&self) -> CargoResult<DieselPooledConn>;
4041
}
4142

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#![deny(missing_debug_implementations, missing_copy_implementations)]
88
#![deny(bare_trait_objects)]
99
#![recursion_limit = "256"]
10-
#![allow(unknown_lints, proc_macro_derive_resolution_fallback)] // This can be removed after diesel-1.4
10+
#![allow(unknown_lints, proc_macro_derive_resolution_fallback)] // TODO: This can be removed after diesel-1.4
1111

1212
extern crate ammonia;
1313
extern crate chrono;

src/middleware/blacklist_ips.rs renamed to src/middleware/block_ips.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ impl AroundMiddleware for BlockIps {
2727

2828
impl Handler for BlockIps {
2929
fn call(&self, req: &mut dyn Request) -> Result<Response, Box<dyn Error + Send>> {
30-
let has_blacklisted_ip = req
30+
let has_blocked_ip = req
3131
.headers()
3232
.find("X-Forwarded-For")
3333
.unwrap()
3434
.iter()
3535
.any(|v| v.split(", ").any(|ip| self.ips.iter().any(|x| x == ip)));
36-
if has_blacklisted_ip {
36+
if has_blocked_ip {
3737
let body = format!(
3838
"We are unable to process your request at this time. \
3939
Please open an issue at https://github.com/rust-lang/crates.io \

src/middleware/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ pub use self::security_headers::SecurityHeaders;
1313
pub use self::static_or_continue::StaticOrContinue;
1414

1515
pub mod app;
16-
mod blacklist_ips;
16+
mod block_ips;
1717
pub mod current_user;
1818
mod debug;
1919
mod ember_index_rewrite;
2020
mod ensure_well_formed_500;
2121
mod head;
2222
mod log_request;
23+
mod require_user_agent;
2324
mod security_headers;
2425
mod static_or_continue;
2526

@@ -81,10 +82,11 @@ pub fn build_middleware(app: Arc<App>, endpoints: R404) -> MiddlewareBuilder {
8182

8283
m.around(Head::default());
8384

84-
if let Ok(ip_list) = env::var("BLACKLISTED_IPS") {
85+
if let Ok(ip_list) = env::var("BLOCKED_IPS") {
8586
let ips = ip_list.split(',').map(String::from).collect();
86-
m.around(blacklist_ips::BlockIps::new(ips));
87+
m.around(block_ips::BlockIps::new(ips));
8788
}
89+
m.around(require_user_agent::RequireUserAgent::default());
8890

8991
if env != Env::Test {
9092
m.around(log_request::LogRequests::default());
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
We require that all requests include a `User-Agent` header. To allow us to determine the impact your bot has on our service, we ask that your user agent actually identify your bot, and not just report the HTTP client library you're using. Including contact information will also reduce the chance that we will need to take action against your bot.
2+
3+
Bad:
4+
User-Agent: reqwest/0.9.1
5+
6+
Better:
7+
User-Agent: my_crawler
8+
9+
Best:
10+
User-Agent: my_crawler (my_crawler.com/info)
11+
User-Agent: my_crawler (help@my_crawler.com)
12+
13+
If you believe you've received this message in error, please email [email protected] and include the request id {}.

src/middleware/require_user_agent.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//! Middleware that blocks requests with no user-agent header
2+
3+
use super::prelude::*;
4+
5+
use std::collections::HashMap;
6+
use std::io::Cursor;
7+
use util::request_header;
8+
9+
// Can't derive debug because of Handler.
10+
#[allow(missing_debug_implementations)]
11+
#[derive(Default)]
12+
pub struct RequireUserAgent {
13+
handler: Option<Box<dyn Handler>>,
14+
}
15+
16+
impl AroundMiddleware for RequireUserAgent {
17+
fn with_handler(&mut self, handler: Box<dyn Handler>) {
18+
self.handler = Some(handler);
19+
}
20+
}
21+
22+
impl Handler for RequireUserAgent {
23+
fn call(&self, req: &mut dyn Request) -> Result<Response, Box<dyn Error + Send>> {
24+
let has_user_agent = request_header(req, "User-Agent") != "";
25+
if !has_user_agent {
26+
let body = format!(
27+
include_str!("no_user_agent_message.txt"),
28+
request_header(req, "X-Request-Id"),
29+
);
30+
let mut headers = HashMap::new();
31+
headers.insert("Content-Length".to_string(), vec![body.len().to_string()]);
32+
Ok(Response {
33+
status: (403, "Forbidden"),
34+
headers,
35+
body: Box::new(Cursor::new(body.into_bytes())),
36+
})
37+
} else {
38+
self.handler.as_ref().unwrap().call(req)
39+
}
40+
}
41+
}

src/models/dependency.rs

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
use diesel::deserialize::QueryableByName;
2-
use diesel::pg::Pg;
31
use diesel::prelude::*;
4-
use diesel::row::NamedRow;
52
use semver;
63

74
use git;
@@ -11,7 +8,7 @@ use models::{Crate, Version};
118
use schema::*;
129
use views::{EncodableCrateDependency, EncodableDependency};
1310

14-
#[derive(Identifiable, Associations, Debug)]
11+
#[derive(Identifiable, Associations, Debug, Queryable, QueryableByName)]
1512
#[belongs_to(Version)]
1613
#[belongs_to(Crate)]
1714
#[table_name = "dependencies"]
@@ -141,6 +138,7 @@ pub fn add_dependencies(
141138
}
142139

143140
use diesel::deserialize::{self, FromSql};
141+
use diesel::pg::Pg;
144142
use diesel::sql_types::Integer;
145143

146144
impl FromSql<Integer, Pg> for DependencyKind {
@@ -153,51 +151,3 @@ impl FromSql<Integer, Pg> for DependencyKind {
153151
}
154152
}
155153
}
156-
157-
impl Queryable<dependencies::SqlType, Pg> for Dependency {
158-
type Row = (
159-
i32,
160-
i32,
161-
i32,
162-
String,
163-
bool,
164-
bool,
165-
Vec<String>,
166-
Option<String>,
167-
DependencyKind,
168-
);
169-
170-
fn build(row: Self::Row) -> Self {
171-
Dependency {
172-
id: row.0,
173-
version_id: row.1,
174-
crate_id: row.2,
175-
req: semver::VersionReq::parse(&row.3).unwrap(),
176-
optional: row.4,
177-
default_features: row.5,
178-
features: row.6,
179-
target: row.7,
180-
kind: row.8,
181-
}
182-
}
183-
}
184-
185-
impl QueryableByName<Pg> for Dependency {
186-
fn build<R: NamedRow<Pg>>(row: &R) -> deserialize::Result<Self> {
187-
use diesel::dsl::SqlTypeOf;
188-
use schema::dependencies::*;
189-
190-
let req_str = row.get::<SqlTypeOf<req>, String>("req")?;
191-
Ok(Dependency {
192-
id: row.get::<SqlTypeOf<id>, _>("id")?,
193-
version_id: row.get::<SqlTypeOf<version_id>, _>("version_id")?,
194-
crate_id: row.get::<SqlTypeOf<crate_id>, _>("crate_id")?,
195-
req: semver::VersionReq::parse(&req_str)?,
196-
optional: row.get::<SqlTypeOf<optional>, _>("optional")?,
197-
default_features: row.get::<SqlTypeOf<default_features>, _>("default_features")?,
198-
features: row.get::<SqlTypeOf<features>, _>("features")?,
199-
target: row.get::<SqlTypeOf<target>, _>("target")?,
200-
kind: row.get::<SqlTypeOf<kind>, _>("kind")?,
201-
})
202-
}
203-
}

src/models/krate.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ use views::{EncodableCrate, EncodableCrateLinks};
1919
use models::helpers::with_count::*;
2020
use schema::*;
2121

22-
/// Hosts in this blacklist are known to not be hosting documentation,
22+
/// Hosts in this list are known to not be hosting documentation,
2323
/// and are possibly of malicious intent e.g. ad tracking networks, etc.
24-
const DOCUMENTATION_BLACKLIST: [&str; 1] = ["rust-ci.org"];
24+
const DOCUMENTATION_BLOCKLIST: [&str; 1] = ["rust-ci.org"];
2525

2626
#[derive(Debug, Insertable, Queryable, Identifiable, Associations, AsChangeset, Clone, Copy)]
2727
#[belongs_to(Crate)]
@@ -330,7 +330,7 @@ impl Crate {
330330
let keyword_ids = keywords.map(|kws| kws.iter().map(|kw| kw.keyword.clone()).collect());
331331
let category_ids = categories.map(|cats| cats.iter().map(|cat| cat.slug.clone()).collect());
332332
let badges = badges.map(|bs| bs.into_iter().map(|b| b.encodable()).collect());
333-
let documentation = Crate::remove_blacklisted_documentation_urls(documentation);
333+
let documentation = Crate::remove_blocked_documentation_urls(documentation);
334334

335335
EncodableCrate {
336336
id: name.clone(),
@@ -360,8 +360,8 @@ impl Crate {
360360
}
361361
}
362362

363-
/// Return `None` if the documentation URL host matches a blacklisted host
364-
fn remove_blacklisted_documentation_urls(url: Option<String>) -> Option<String> {
363+
/// Return `None` if the documentation URL host matches a blocked host
364+
fn remove_blocked_documentation_urls(url: Option<String>) -> Option<String> {
365365
// Handles if documentation URL is None
366366
let url = match url {
367367
Some(url) => url,
@@ -380,8 +380,8 @@ impl Crate {
380380
None => return None,
381381
};
382382

383-
// Match documentation URL host against blacklisted host array elements
384-
if DOCUMENTATION_BLACKLIST.contains(&url_host) {
383+
// Match documentation URL host against blocked host array elements
384+
if DOCUMENTATION_BLOCKLIST.contains(&url_host) {
385385
None
386386
} else {
387387
Some(url)
@@ -520,32 +520,32 @@ mod tests {
520520
use models::Crate;
521521

522522
#[test]
523-
fn documentation_blacklist_no_url_provided() {
524-
assert_eq!(Crate::remove_blacklisted_documentation_urls(None), None);
523+
fn documentation_blocked_no_url_provided() {
524+
assert_eq!(Crate::remove_blocked_documentation_urls(None), None);
525525
}
526526

527527
#[test]
528-
fn documentation_blacklist_invalid_url() {
528+
fn documentation_blocked_invalid_url() {
529529
assert_eq!(
530-
Crate::remove_blacklisted_documentation_urls(Some(String::from("not a url"))),
530+
Crate::remove_blocked_documentation_urls(Some(String::from("not a url"))),
531531
None
532532
);
533533
}
534534

535535
#[test]
536-
fn documentation_blacklist_url_contains_partial_match() {
536+
fn documentation_blocked_url_contains_partial_match() {
537537
assert_eq!(
538-
Crate::remove_blacklisted_documentation_urls(Some(String::from(
538+
Crate::remove_blocked_documentation_urls(Some(String::from(
539539
"http://rust-ci.organists.com"
540540
)),),
541541
Some(String::from("http://rust-ci.organists.com"))
542542
);
543543
}
544544

545545
#[test]
546-
fn documentation_blacklist_blacklisted_url() {
546+
fn documentation_blocked_url() {
547547
assert_eq!(
548-
Crate::remove_blacklisted_documentation_urls(Some(String::from(
548+
Crate::remove_blocked_documentation_urls(Some(String::from(
549549
"http://rust-ci.org/crate/crate-0.1/doc/crate-0.1",
550550
),),),
551551
None

0 commit comments

Comments
 (0)