diff options
| author | mrw1593 <botahamec@outlook.com> | 2023-05-12 22:54:38 -0400 |
|---|---|---|
| committer | mrw1593 <botahamec@outlook.com> | 2023-05-29 10:45:40 -0400 |
| commit | 3aff5f0123778aa453ab5396cb880a83267ae4ee (patch) | |
| tree | 82d5bddb485cedfcb5a2f1e6abb8fbbed1f701e8 /src/api | |
| parent | 8ec105595db9d2957c7327112e7a0b63d9d59400 (diff) | |
Add an update_user endpoint
Diffstat (limited to 'src/api')
| -rw-r--r-- | src/api/users.rs | 66 |
1 files changed, 52 insertions, 14 deletions
diff --git a/src/api/users.rs b/src/api/users.rs index 5e409fd..edade22 100644 --- a/src/api/users.rs +++ b/src/api/users.rs @@ -1,46 +1,46 @@ use actix_web::http::{header, StatusCode}; -use actix_web::{post, web, HttpResponse, ResponseError, Scope}; +use actix_web::{post, put, web, HttpResponse, ResponseError, Scope}; use raise::yeet; use serde::Deserialize; use sqlx::MySqlPool; use thiserror::Error; +use uuid::Uuid; 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; +use crate::services::{db, id}; #[derive(Clone, Deserialize)] -struct CreateUser { +struct UserRequest { username: Box<str>, password: Box<str>, } #[derive(Debug, Clone, Hash, Error)] #[error("An account with the given username already exists.")] -struct CreateUserError { +struct UsernameTakenError { username: Box<str>, } -impl ResponseError for CreateUserError { +impl ResponseError for UsernameTakenError { fn status_code(&self) -> StatusCode { StatusCode::CONFLICT } } -#[post("")] +#[post("/")] async fn create_user( - body: web::Json<CreateUser>, + body: web::Json<UserRequest>, conn: web::Data<MySqlPool>, -) -> Result<HttpResponse, CreateUserError> { +) -> Result<HttpResponse, UsernameTakenError> { let conn = conn.get_ref(); - let user_id = new_user_id(conn).await.unwrap(); + let user_id = 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 }); + if db::username_is_used(conn, &body.username).await.unwrap() { + yeet!(UsernameTakenError { username }); } let user = User { @@ -49,7 +49,7 @@ async fn create_user( password, }; - new_user(conn, user).await.unwrap(); + db::new_user(conn, &user).await.unwrap(); let response = HttpResponse::Created() .insert_header((header::LOCATION, format!("users/{user_id}"))) @@ -57,6 +57,44 @@ async fn create_user( Ok(response) } +#[put("/{user_id}")] +async fn update_user( + user_id: web::Path<Uuid>, + body: web::Json<UserRequest>, + conn: web::Data<MySqlPool>, +) -> Result<HttpResponse, UsernameTakenError> { + let conn = conn.get_ref(); + + let user_id = user_id.to_owned(); + let username = body.username.clone(); + let password = PasswordHash::new(&body.password).unwrap(); + + let old_username = db::get_username(conn, user_id) + .await + .unwrap() + .unwrap() + .into_boxed_str(); + if username != old_username && db::username_is_used(conn, &body.username).await.unwrap() { + yeet!(UsernameTakenError { username }) + } + + let user = User { + user_id, + username, + password, + }; + + db::update_username(conn, &user).await.unwrap(); + + let response = HttpResponse::NoContent() + .insert_header((header::LOCATION, format!("users/{user_id}"))) + .finish(); + + Ok(response) +} + pub fn service() -> Scope { - web::scope("users").service(create_user) + web::scope("/users") + .service(create_user) + .service(update_user) } |
