To handle sign-up requests, we need a POST method handler for the /signup path. We can declare it in the following way:
(POST) (/signup) => {
let data = post_input!(request, {
email: String,
password: String,
})?;
let user_email = data.email.trim().to_lowercase();
let user_password = pbkdf2_simple(&data.password, 12345)?;
{
use self::schema::users::dsl::*;
let conn = pool.get()?;
let user_exists: bool = select(exists(users.filter(email.eq(user_email.clone()))))
.get_result(&conn)?;
if !user_exists {
let uuid = format!("{}", uuid::Uuid::new_v4());
let new_user = models::NewUser {
id: &uuid,
email: &user_email,
password: &user_password,
};
diesel::insert_into(schema::users::table).values(&new_user).execute(&conn)?;
Response::json(&())
} else {
Response::text(format!("user {} exists", data.email))
.with_status_code(400)
}
}
}
This handler is more complex and also demonstrates how to parse the parameters of a request. We need to parse an HTML form with two parameters—email and password. To do this, we used the post_input! macro, which expects a request instance and a form declaration with types. The form structure declaration looks like a simple struct declaration without a name, but with fields. We added two necessary fields and the post_input! macro parsed a request to fill an object with the corresponding fields.
Since parsed parameters only fit types, we also had to add extra processing to it. The email field is a String type, and we used the trim method to remove unnecessary spacing and the to_lowercase method to convert it to lowercase. We used the password field without any changes and passed it as a parameter to the pbkdf2_simple method of the rust-crypto crate.
After we prepared parameters, we used them with object-relational mapping methods. First, to check whether the user with the provided email exists, we use a DSL generated by the diesel crate and, if the user doesn't exist, we generate a unique ID for the user using the uuid crate. The handler fills the NewUser instance with corresponding values and inserts it into a database. Upon success, it returns an empty JSON response. If the user already exists, the handler returns a response with a 400 status code (Bad Response) with a message to the effect that the user with the provided email already exists. Let's look at how to sign in with a stored user value.