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

Sending an email to a user to confirm their email address #1045

Merged
merged 67 commits into from Sep 16, 2017

Conversation

natboehm
Copy link
Contributor

@natboehm natboehm commented Sep 6, 2017

This PR addresses issue #808, allow editing your own email address. Following the discussion on the issue, this implements the second of three parts, the ability to send a confirmation email to a user for verification. For a full explanation of the issue, see this comment I left which should fully explain the changes made, as well as parts 1 and 3.

In short, I added two tables to the database: one for the user's email, the other for a confirmation token associated with the email. Once the user clicks the link sent, the associated token is deleted from the token table and email_verified is set to true in the email table. It is indicated to the user if they have not verified their email on the account settings page, a message and email resend button being displayed. Sending emails requires Mailgun to be added to the crates.io Heroku account.

This has applications for issue #924 in that we should now be able to send an email to a user, if they have added their email. I know there was a lot of discussion on that issue regarding the ability to send users an email to be added as an owner.

Copy link
Member

@carols10cents carols10cents left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this is great!! This is a lot of work with a whole bunch of pieces, and it's really close!! Just a few polishing things :)

let email = this.get('user.email');
let verified = this.get('user.email_verified');

if (email != null && !verified) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could shorten this if/else to just return (email != null && !verified);, what do you think?

@@ -1,5 +0,0 @@
<h1>Something Went Wrong!</h1>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this template not used anywhere anymore? Looks like it was removed in 63facf5, was that intentional? I don't know enough about ember, but it kinda looks like this template is used for generic errors? ex: #240

src/lib.rs Outdated
#![deny(warnings)]
#![deny(missing_debug_implementations, missing_copy_implementations)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we put this deny back please :) I'm happy to help fixing any errors!

src/lib.rs Outdated
@@ -1,11 +1,9 @@
//! This crate implements the backend server for https://crates.io/
//!
//! All implemented routes are defined in the [middleware](fn.middleware.html) function and
//! implemented in the [category](category/index.html), [keyword](keyword/index.html),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I'm not sure why heroku would have a problem with the category link in this doc comment? (This was changed in ae3683b). There's still the category::index, category::show, and category::slugs functions that go with routes...?

src/user/mod.rs Outdated
}

fn send_user_confirm_email(email: &str, user_name: &str, token: &str) -> CargoResult<()> {
// perhaps use crate lettre and heroku service Mailgun
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these comments can be removed since you are using lettre and mailgun :)

src/user/mod.rs Outdated
smtp_password: env::var("MAILGUN_SMTP_PASSWORD").unwrap_or_else(|_| {
String::from("Not found")
}),
smtp_server: env::var("MAILGUN_SMTP_SERVER").unwrap_or_else(|_| String::from("Not found")),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooh another thing we should add is some commented-out placeholders for these environment variables in .env.sample, explaining that these are for sending emails and can be optionally configured locally if you want to try out sending emails but you need a mailgun account, and then probably some longer docs in CONTRIBUTING.md?

Are you up for adding these docs? I'm also happy to help!

Err(_) => (None, false),
};

let user = User {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wdyt about doing:

let user = User {
    email: email,
    ..user_info
};

here, to make it clearer that only the email is different? Does that work?

let user = users.filter(id.eq(user_id)).first::<User>(&*conn)?;

let user_info = users.filter(id.eq(u_id)).first::<User>(&*conn)?;
let email_result = emails.filter(user_id.eq(u_id)).first::<Email>(&*conn);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can get the User and the Email in one query? Maybe not worth it...

src/user/mod.rs Outdated
).as_str(),
)
.build()
.expect("Failed to build confirm email message");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if this expect gets an Err, this would crash the server, which normally would make me go 😱 🙀 😱 🙀 😱 🙀 but looking at lettre's code, the only way building an email would fail is if:

  • no from address was set, and we're definitely calling from with something we control
  • the to address is empty string, and we reject empty emails before calling send_user_confirm_email in update_user

I'm trying to figure out if it's possible that we get Some("") from github and therefore would insert an empty string into the email table and then get an empty email here? I'm going to try some testing and see what happens.

This is also starting to feel a bit spooky-action-at-a-distance since the code that is ensuring the to email isn't empty is far away from here. This could be an issue for any email we send.... Hmmmm.... I wonder if, when the generic email functionality is extracted into a function, if we should pass the generic function strings for to, from, subject, and body, and then the generic function first checks to make sure to isn't an empty string and returns an Err if so, and then we can call expect and point to the line checking that should be nearby as proof that the expect won't fail?

}

fn generate_token() -> String {
let token: String = thread_rng().gen_ascii_chars().take(26).collect();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool!!

… generated, preliminary test for functionality added
… - added confirm route that submits PUT request to backend with error handling
…confirmed, deleted & displays error message when token not found
…and navigating to account settings page.

Uses GET request to `/me` to get the latest version of the model upon returning successfully from the PUT request to `/confirm`.
One part uses the env variables if found, the other
uses an email stub that prints to the env_logger.
…email` will send output to a file named {message_id}.txt in user's `\tmp` directory
@carols10cents
Copy link
Member

bors: r+

bors-voyager bot added a commit that referenced this pull request Sep 15, 2017
1045: Sending an email to a user to confirm their email address r=carols10cents

This PR addresses issue #808, allow editing your own email address. Following the discussion on the issue, this implements the second of three parts, the ability to send a confirmation email to a user for verification. For a full explanation of the issue, see [this comment](#808 (comment)) I left which should fully explain the changes made, as well as parts 1 and 3. 

In short, I added two tables to the database: one for the user's email, the other for a confirmation token associated with the email. Once the user clicks the link sent, the associated token is deleted from the token table and `email_verified` is set to `true` in the email table. It is indicated to the user if they have not verified their email on the account settings page, a message and email resend button being displayed. Sending emails requires Mailgun to be added to the crates.io Heroku account. 

This has applications for issue #924 in that we should now be able to send an email to a user, if they have added their email. I know there was a lot of discussion on that issue regarding the ability to send users an email to be added as an owner.
@bors-voyager
Copy link
Contributor

bors-voyager bot commented Sep 15, 2017

Timed out

@carols10cents
Copy link
Member

bors: r+

bors-voyager bot added a commit that referenced this pull request Sep 15, 2017
1045: Sending an email to a user to confirm their email address r=carols10cents

This PR addresses issue #808, allow editing your own email address. Following the discussion on the issue, this implements the second of three parts, the ability to send a confirmation email to a user for verification. For a full explanation of the issue, see [this comment](#808 (comment)) I left which should fully explain the changes made, as well as parts 1 and 3. 

In short, I added two tables to the database: one for the user's email, the other for a confirmation token associated with the email. Once the user clicks the link sent, the associated token is deleted from the token table and `email_verified` is set to `true` in the email table. It is indicated to the user if they have not verified their email on the account settings page, a message and email resend button being displayed. Sending emails requires Mailgun to be added to the crates.io Heroku account. 

This has applications for issue #924 in that we should now be able to send an email to a user, if they have added their email. I know there was a lot of discussion on that issue regarding the ability to send users an email to be added as an owner.
@bors-voyager
Copy link
Contributor

bors-voyager bot commented Sep 15, 2017

Timed out

@carols10cents
Copy link
Member

bors: r+

bors-voyager bot added a commit that referenced this pull request Sep 15, 2017
1045: Sending an email to a user to confirm their email address r=carols10cents

This PR addresses issue #808, allow editing your own email address. Following the discussion on the issue, this implements the second of three parts, the ability to send a confirmation email to a user for verification. For a full explanation of the issue, see [this comment](#808 (comment)) I left which should fully explain the changes made, as well as parts 1 and 3. 

In short, I added two tables to the database: one for the user's email, the other for a confirmation token associated with the email. Once the user clicks the link sent, the associated token is deleted from the token table and `email_verified` is set to `true` in the email table. It is indicated to the user if they have not verified their email on the account settings page, a message and email resend button being displayed. Sending emails requires Mailgun to be added to the crates.io Heroku account. 

This has applications for issue #924 in that we should now be able to send an email to a user, if they have added their email. I know there was a lot of discussion on that issue regarding the ability to send users an email to be added as an owner.
@bors-voyager
Copy link
Contributor

bors-voyager bot commented Sep 16, 2017

Build succeeded

@bors-voyager bors-voyager bot merged commit 26254f4 into rust-lang:master Sep 16, 2017
@natboehm natboehm deleted the confirm-user-email branch September 25, 2017 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants