diff options
Diffstat (limited to '')
-rw-r--r-- | src/routes/signup.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/routes/signup.rs b/src/routes/signup.rs new file mode 100644 index 0000000..ae10201 --- /dev/null +++ b/src/routes/signup.rs @@ -0,0 +1,79 @@ +use actix_web::{get, post, web, HttpResponse}; +use serde::Deserialize; + +use crate::notification::{Kind as NotificationKind, Notification}; +use crate::templates; +use crate::Pinussy; +use crate::Result; +use bcrypt::{hash, DEFAULT_COST}; + +#[get("/signup")] +async fn get() -> HttpResponse { + HttpResponse::Ok().body(render!(templates::signup_html, None).unwrap()) +} + +#[derive(Deserialize)] +struct SignupForm { + username: String, + password: String, +} + +#[post("/signup")] +async fn post(state: web::Data<Pinussy>, form: web::Form<SignupForm>) -> Result<HttpResponse> { + let password_hash = hash(&form.password, DEFAULT_COST)?; + match sqlx::query!( + "insert into users(username, password) values ($1, $2)", + &form.username, + password_hash + ) + .execute(&state.db) + .await + { + Ok(_) => { + return Ok(HttpResponse::Ok().body( + render!( + templates::signup_html, + Some(Notification { + kind: NotificationKind::Info, + message: format!("you have successfully registered as {}", &form.username) + }) + ) + .unwrap(), + )) + } + Err(e) => { + match e { + sqlx::Error::Database(e) => { + if e.is_unique_violation() { + return Ok(HttpResponse::Conflict().body( + render!( + templates::signup_html, + Some(Notification { + kind: NotificationKind::Error, + message: format!( + "error: the username \"{}\" already exists", + &form.username + ) + }) + ) + .unwrap(), + )); + } + } + // TODO: log error + _ => {} + } + return Ok(HttpResponse::InternalServerError().body( + render!( + templates::signup_html, + Some(Notification { + kind: NotificationKind::Error, + message: "there was an internal server error. please try again later." + .to_owned() + }) + ) + .unwrap(), + )); + } + }; +} |