diff --git a/src/routes/v1/user_add.rs b/src/routes/v1/user_add.rs index 1c2192a..ac60714 100644 --- a/src/routes/v1/user_add.rs +++ b/src/routes/v1/user_add.rs @@ -1,10 +1,13 @@ -use actix_web::HttpResponse; +use actix_web::{HttpResponse, web}; use actix_web::post; use actix_web::web::{Data, Json}; +use log::error; use serde::{Serialize, Deserialize}; use crate::config::CONFIG; use crate::error::{APIError, APIErrorResponse}; +use crate::models::{NewUser, User}; use crate::PgPool; +use diesel::prelude::*; #[derive(Serialize, Deserialize, Clone)] pub struct UserAddRequest { @@ -14,8 +17,18 @@ pub struct UserAddRequest { pub password_hash: String } +#[derive(Serialize, Deserialize, Clone)] +pub struct UserResponse { + pub id: i32, + pub name: String, + pub discord_id: i64, + pub password_hash: String +} + #[post("/v1/user/add")] -pub async fn add_user_request(db: Data, req: Json) -> HttpResponse { +pub async fn add_user_request(pool: Data, req: Json) -> HttpResponse { + use crate::schema::users; + if !CONFIG.authorized_new_user_tokens.contains(&req.token) { return HttpResponse::Unauthorized().json(APIErrorResponse { errors: vec![ @@ -27,5 +40,92 @@ pub async fn add_user_request(db: Data, req: Json) -> Ht }) } - HttpResponse::Ok().body("d") + let req_clone = req.clone(); + let pool_clone = pool.clone(); + let results = match web::block(move || { + let mut conn = pool_clone.get().expect("Unable to get db pool"); + users::table.filter(users::name.eq(&req_clone.name)).load::(&mut conn) + }).await { + Ok(r) => r, + Err(e) => { + error!("Database error: {}", e); + return HttpResponse::InternalServerError().json(APIErrorResponse { + errors: vec![ + APIError { + code: "ERR_BLOCKING_ERROR".to_string(), + message: "There was an error running the database request. Please try again later.".to_string() + } + ] + }) + } + }; + let user_list = match results { + Ok(r) => r, + Err(e) => { + error!("Database error: {}", e); + return HttpResponse::InternalServerError().json(APIErrorResponse { + errors: vec![ + APIError { + code: "ERR_DB_ERROR".to_string(), + message: "There was an error fetching the user. Please try again later.".to_string() + } + ] + }) + } + }; + if !user_list.is_empty() { + return HttpResponse::Unauthorized().json(APIErrorResponse { + errors: vec![ + APIError { + code: "ERR_USER_EXISTS".to_string(), + message: "Cannot create user that already exists".to_string() + } + ] + }) + } + + let new_user = NewUser { + name: req.name.clone(), + discord_id: req.discord_id, + password_hash: req.password_hash.clone(), + }; + + let insert_result: QueryResult = match web::block(move || { + let mut conn = pool.get().expect("Unable to get db pool"); + diesel::insert_into(users::table).values(new_user).get_result(&mut conn) + }).await { + Ok(r) => r, + Err(e) => { + error!("Database error: {}", e); + return HttpResponse::InternalServerError().json(APIErrorResponse { + errors: vec![ + APIError { + code: "ERR_BLOCKING_ERROR".to_string(), + message: "There was an error running the insert database request. Please try again later.".to_string() + } + ] + }) + } + }; + let user = match insert_result { + Ok(r) => r, + Err(e) => { + error!("Database error: {}", e); + return HttpResponse::InternalServerError().json(APIErrorResponse { + errors: vec![ + APIError { + code: "ERR_DB_ERROR".to_string(), + message: "There was an error creating the codereq. Please try again later.".to_string() + } + ] + }) + } + }; + + HttpResponse::Ok().json(UserResponse { + id: user.id, + name: user.name, + discord_id: user.discord_id, + password_hash: user.password_hash, + }) } \ No newline at end of file