Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Email verification warning #1565

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions src/controllers/krate/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use util::{read_fill, read_le_u32};
use controllers::prelude::*;
use models::dependency;
use models::{Badge, Category, Keyword, NewCrate, NewVersion, Rights, User};
use views::{EncodableCrate, EncodableCrateUpload};
use views::{EncodableCrateUpload, GoodCrate, PublishWarnings};

/// Handles the `PUT /crates/new` route.
/// Used by `cargo publish` to publish a new crate or to publish a new version of an
Expand Down Expand Up @@ -64,6 +64,16 @@ pub fn publish(req: &mut dyn Request) -> CargoResult<Response> {
let categories: Vec<_> = categories.iter().map(|k| &***k).collect();

let conn = req.db_conn()?;

let mut other_warnings = vec![];
if !user.has_verified_email(&conn)? {
other_warnings.push(String::from(
"You do not currently have a verified email address associated with your crates.io \
account. Starting 2019-02-28, a verified email will be required to publish crates. \
Visit https://crates.io/me to set and verify your email address.",
));
}

// Create a transaction on the database, if there are no errors,
// commit the transactions to record a new or updated crate.
conn.transaction(|| {
Expand Down Expand Up @@ -196,23 +206,13 @@ pub fn publish(req: &mut dyn Request) -> CargoResult<Response> {
crate_bomb.path = None;
readme_bomb.path = None;

#[derive(Serialize)]
struct Warnings<'a> {
invalid_categories: Vec<&'a str>,
invalid_badges: Vec<&'a str>,
}
let warnings = Warnings {
let warnings = PublishWarnings {
invalid_categories: ignored_invalid_categories,
invalid_badges: ignored_invalid_badges,
other: other_warnings,
};

#[derive(Serialize)]
struct R<'a> {
#[serde(rename = "crate")]
krate: EncodableCrate,
warnings: Warnings<'a>,
}
Ok(req.json(&R {
Ok(req.json(&GoodCrate {
krate: krate.minimal_encodable(&max_version, None, false, None),
warnings,
}))
Expand Down
8 changes: 4 additions & 4 deletions src/models/badge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,11 @@ impl Badge {
serde_json::from_value(serde_json::to_value(self).unwrap()).unwrap()
}

pub fn update_crate<'a>(
pub fn update_crate(
conn: &PgConnection,
krate: &Crate,
badges: Option<&'a HashMap<String, HashMap<String, String>>>,
) -> QueryResult<Vec<&'a str>> {
badges: Option<&HashMap<String, HashMap<String, String>>>,
) -> QueryResult<Vec<String>> {
use diesel::{delete, insert_into};

let mut invalid_badges = vec![];
Expand All @@ -126,7 +126,7 @@ impl Badge {
badges::attributes.eq(attributes_json),
));
} else {
invalid_badges.push(&**k);
invalid_badges.push(k.to_string());
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/models/category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,18 @@ impl Category {
}
}

pub fn update_crate<'a>(
pub fn update_crate(
conn: &PgConnection,
krate: &Crate,
slugs: &[&'a str],
) -> QueryResult<Vec<&'a str>> {
slugs: &[&str],
) -> QueryResult<Vec<String>> {
conn.transaction(|| {
let categories = Category::by_slugs_case_sensitive(slugs).load::<Category>(conn)?;
let invalid_categories = slugs
.iter()
.cloned()
.filter(|s| !categories.iter().any(|c| c.slug == *s))
.map(|s| s.to_string())
.collect();
let crate_categories = categories
.iter()
Expand Down
10 changes: 10 additions & 0 deletions src/models/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,16 @@ impl User {
Ok(best)
}

pub fn has_verified_email(&self, conn: &PgConnection) -> CargoResult<bool> {
use diesel::dsl::exists;
let email_exists = diesel::select(exists(
emails::table
.filter(emails::user_id.eq(self.id))
.filter(emails::verified.eq(true)),
)).get_result(&*conn)?;
Ok(email_exists)
}

/// Converts this `User` model into an `EncodablePrivateUser` for JSON serialization.
pub fn encodable_private(
self,
Expand Down
13 changes: 1 addition & 12 deletions src/tests/all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ use models::{Crate, CrateOwner, Dependency, Team, User, Version};
use models::{NewCategory, NewTeam, NewUser};
use schema::*;
use views::krate_publish as u;
use views::{EncodableCrate, EncodableKeyword, EncodableOwner, EncodableVersion};
use views::{EncodableCrate, EncodableKeyword, EncodableOwner, EncodableVersion, GoodCrate};

macro_rules! t {
($e:expr) => {
Expand Down Expand Up @@ -93,22 +93,11 @@ mod user;
mod util;
mod version;

#[derive(Deserialize, Debug)]
pub struct GoodCrate {
#[serde(rename = "crate")]
krate: EncodableCrate,
warnings: Warnings,
}
#[derive(Deserialize)]
pub struct CrateList {
crates: Vec<EncodableCrate>,
meta: CrateMeta,
}
#[derive(Deserialize, Debug)]
struct Warnings {
invalid_categories: Vec<String>,
invalid_badges: Vec<String>,
}
#[derive(Deserialize)]
struct CrateMeta {
total: i32,
Expand Down
26 changes: 16 additions & 10 deletions src/tests/badge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ fn travis_ci_required_keys() {

let invalid_badges = Badge::update_crate(&conn, &krate, Some(&badges)).unwrap();
assert_eq!(invalid_badges.len(), 1);
assert!(invalid_badges.contains(&"travis-ci"));
assert_eq!(invalid_badges.first().unwrap(), "travis-ci");
assert_eq!(krate.badges(&conn).unwrap(), vec![]);
}

Expand All @@ -384,7 +384,7 @@ fn gitlab_required_keys() {

let invalid_badges = Badge::update_crate(&conn, &krate, Some(&badges)).unwrap();
assert_eq!(invalid_badges.len(), 1);
assert!(invalid_badges.contains(&"gitlab"));
assert_eq!(invalid_badges.first().unwrap(), "gitlab");
assert_eq!(krate.badges(&conn).unwrap(), vec![]);
}

Expand All @@ -406,7 +406,10 @@ fn isitmaintained_issue_resolution_required_keys() {

let invalid_badges = Badge::update_crate(&conn, &krate, Some(&badges)).unwrap();
assert_eq!(invalid_badges.len(), 1);
assert!(invalid_badges.contains(&"isitmaintained_issue_resolution"));
assert_eq!(
invalid_badges.first().unwrap(),
"isitmaintained_issue_resolution"
);
assert_eq!(krate.badges(&conn).unwrap(), vec![]);
}

Expand All @@ -428,7 +431,10 @@ fn isitmaintained_open_issues_required_keys() {

let invalid_badges = Badge::update_crate(&conn, &krate, Some(&badges)).unwrap();
assert_eq!(invalid_badges.len(), 1);
assert!(invalid_badges.contains(&"isitmaintained_open_issues"));
assert_eq!(
invalid_badges.first().unwrap(),
"isitmaintained_open_issues"
);
assert_eq!(krate.badges(&conn).unwrap(), vec![]);
}

Expand All @@ -445,7 +451,7 @@ fn codecov_required_keys() {

let invalid_badges = Badge::update_crate(&conn, &krate, Some(&badges)).unwrap();
assert_eq!(invalid_badges.len(), 1);
assert!(invalid_badges.contains(&"codecov"));
assert_eq!(invalid_badges.first().unwrap(), "codecov");
assert_eq!(krate.badges(&conn).unwrap(), vec![]);
}

Expand All @@ -462,7 +468,7 @@ fn coveralls_required_keys() {

let invalid_badges = Badge::update_crate(&conn, &krate, Some(&badges)).unwrap();
assert_eq!(invalid_badges.len(), 1);
assert!(invalid_badges.contains(&"coveralls"));
assert_eq!(invalid_badges.first().unwrap(), "coveralls");
assert_eq!(krate.badges(&conn).unwrap(), vec![]);
}

Expand All @@ -479,7 +485,7 @@ fn circle_ci_required_keys() {

let invalid_badges = Badge::update_crate(&conn, &krate, Some(&badges)).unwrap();
assert_eq!(invalid_badges.len(), 1);
assert!(invalid_badges.contains(&"circle-ci"));
assert_eq!(invalid_badges.first().unwrap(), "circle-ci");
assert_eq!(krate.badges(&conn).unwrap(), vec![]);
}

Expand All @@ -499,7 +505,7 @@ fn maintenance_required_keys() {

let invalid_badges = Badge::update_crate(&conn, &krate, Some(&badges)).unwrap();
assert_eq!(invalid_badges.len(), 1);
assert!(invalid_badges.contains(&"maintenance"));
assert_eq!(invalid_badges.first().unwrap(), "maintenance");
assert_eq!(krate.badges(&conn).unwrap(), vec![]);
}

Expand All @@ -521,7 +527,7 @@ fn maintenance_invalid_values() {

let invalid_badges = Badge::update_crate(&conn, &krate, Some(&badges)).unwrap();
assert_eq!(invalid_badges.len(), 1);
assert!(invalid_badges.contains(&"maintenance"));
assert_eq!(invalid_badges.first().unwrap(), "maintenance");
assert_eq!(krate.badges(&conn).unwrap(), vec![]);
}

Expand All @@ -542,6 +548,6 @@ fn unknown_badge() {

let invalid_badges = Badge::update_crate(&conn, &krate, Some(&badges)).unwrap();
assert_eq!(invalid_badges.len(), 1);
assert!(invalid_badges.contains(&"not-a-badge"));
assert_eq!(invalid_badges.first().unwrap(), "not-a-badge");
assert_eq!(krate.badges(&conn).unwrap(), vec![]);
}
73 changes: 73 additions & 0 deletions src/tests/http-data/krate_new_krate_with_unverified_email_warns
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
[
{
"request": {
"uri": "http://alexcrichton-test.s3.amazonaws.com/crates/foo_unverified_email/foo_unverified_email-1.0.0.crate",
"method": "PUT",
"headers": [
[
"accept",
"*/*"
],
[
"content-length",
"35"
],
[
"host",
"alexcrichton-test.s3.amazonaws.com"
],
[
"accept-encoding",
"gzip"
],
[
"user-agent",
"reqwest/0.9.1"
],
[
"content-type",
"application/x-tar"
],
[
"authorization",
"AWS AKIAICL5IWUZYWWKA7JA:uDc39eNdF6CcwB+q+JwKsoDLQc4="
],
[
"date",
"Fri, 15 Sep 2017 07:53:06 -0700"
]
],
"body": "H4sIAAAAAAAA/+3AAQEAAACCIP+vbkhQwKsBLq+17wAEAAA="
},
"response": {
"status": 200,
"headers": [
[
"x-amz-request-id",
"26589A5E52F8395C"
],
[
"ETag",
"\"f9016ad360cebb4fe2e6e96e5949f022\""
],
[
"date",
"Fri, 15 Sep 2017 14:53:07 GMT"
],
[
"content-length",
"0"
],
[
"x-amz-id-2",
"JdIvnNTw53aqXjBIqBLNuN4kxf/w1XWX+xuIiGBDYy7yzOSDuAMtBSrTW4ZWetcCIdqCUHuQ51A="
],
[
"Server",
"AmazonS3"
]
],
"body": ""
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
[
{
"request": {
"uri": "http://alexcrichton-test.s3.amazonaws.com/crates/foo_verified_email/foo_verified_email-1.0.0.crate",
"method": "PUT",
"headers": [
[
"accept",
"*/*"
],
[
"content-length",
"35"
],
[
"host",
"alexcrichton-test.s3.amazonaws.com"
],
[
"accept-encoding",
"gzip"
],
[
"user-agent",
"reqwest/0.9.1"
],
[
"content-type",
"application/x-tar"
],
[
"authorization",
"AWS AKIAICL5IWUZYWWKA7JA:uDc39eNdF6CcwB+q+JwKsoDLQc4="
],
[
"date",
"Fri, 15 Sep 2017 07:53:06 -0700"
]
],
"body": "H4sIAAAAAAAA/+3AAQEAAACCIP+vbkhQwKsBLq+17wAEAAA="
},
"response": {
"status": 200,
"headers": [
[
"x-amz-request-id",
"26589A5E52F8395C"
],
[
"ETag",
"\"f9016ad360cebb4fe2e6e96e5949f022\""
],
[
"date",
"Fri, 15 Sep 2017 14:53:07 GMT"
],
[
"content-length",
"0"
],
[
"x-amz-id-2",
"JdIvnNTw53aqXjBIqBLNuN4kxf/w1XWX+xuIiGBDYy7yzOSDuAMtBSrTW4ZWetcCIdqCUHuQ51A="
],
[
"Server",
"AmazonS3"
]
],
"body": ""
}
}
]
Loading