diff options
| author | mrw1593 <botahamec@outlook.com> | 2023-03-19 13:23:20 -0400 |
|---|---|---|
| committer | mrw1593 <botahamec@outlook.com> | 2023-05-29 10:45:26 -0400 |
| commit | 8ec105595db9d2957c7327112e7a0b63d9d59400 (patch) | |
| tree | a53e2e2c375d2d7155c30058a69dd713be4e5905 /src/api | |
| parent | f149374e2c6682ea5b9b1d692b001d6ab5faea4a (diff) | |
Create user
Diffstat (limited to 'src/api')
| -rw-r--r-- | src/api/liveops.rs | 2 | ||||
| -rw-r--r-- | src/api/mod.rs | 2 | ||||
| -rw-r--r-- | src/api/users.rs | 62 |
3 files changed, 65 insertions, 1 deletions
diff --git a/src/api/liveops.rs b/src/api/liveops.rs index ff44107..2dda41d 100644 --- a/src/api/liveops.rs +++ b/src/api/liveops.rs @@ -7,5 +7,5 @@ async fn ping() -> HttpResponse { } pub fn service() -> Scope { - web::scope("liveops/").service(ping) + web::scope("liveops").service(ping) } diff --git a/src/api/mod.rs b/src/api/mod.rs index f934d0e..7becfbd 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1,3 +1,5 @@ mod liveops; +mod users; pub use liveops::service as liveops; +pub use users::service as users; diff --git a/src/api/users.rs b/src/api/users.rs new file mode 100644 index 0000000..5e409fd --- /dev/null +++ b/src/api/users.rs @@ -0,0 +1,62 @@ +use actix_web::http::{header, StatusCode}; +use actix_web::{post, web, HttpResponse, ResponseError, Scope}; +use raise::yeet; +use serde::Deserialize; +use sqlx::MySqlPool; +use thiserror::Error; + +use crate::models::User; +use crate::services::crypto::PasswordHash; +use crate::services::db::{new_user, username_is_used}; +use crate::services::id::new_user_id; + +#[derive(Clone, Deserialize)] +struct CreateUser { + username: Box<str>, + password: Box<str>, +} + +#[derive(Debug, Clone, Hash, Error)] +#[error("An account with the given username already exists.")] +struct CreateUserError { + username: Box<str>, +} + +impl ResponseError for CreateUserError { + fn status_code(&self) -> StatusCode { + StatusCode::CONFLICT + } +} + +#[post("")] +async fn create_user( + body: web::Json<CreateUser>, + conn: web::Data<MySqlPool>, +) -> Result<HttpResponse, CreateUserError> { + let conn = conn.get_ref(); + + let user_id = new_user_id(conn).await.unwrap(); + let username = body.username.clone(); + let password = PasswordHash::new(&body.password).unwrap(); + + if username_is_used(conn, &body.username).await.unwrap() { + yeet!(CreateUserError { username }); + } + + let user = User { + user_id, + username, + password, + }; + + new_user(conn, user).await.unwrap(); + + let response = HttpResponse::Created() + .insert_header((header::LOCATION, format!("users/{user_id}"))) + .finish(); + Ok(response) +} + +pub fn service() -> Scope { + web::scope("users").service(create_user) +} |
