summaryrefslogtreecommitdiffstats
path: root/src/routes/signup.rs
blob: ae10201ca1ddfffaa8ef28b8ff28a8a01f372aa3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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(),
            ));
        }
    };
}