diff --git a/db/1.sqlite b/db/1.sqlite index 1258c17..c2779fe 100644 Binary files a/db/1.sqlite and b/db/1.sqlite differ diff --git a/src/chat/extractor.rs b/src/chat/extractor.rs index 2e79e14..f17f399 100644 --- a/src/chat/extractor.rs +++ b/src/chat/extractor.rs @@ -30,3 +30,26 @@ where S: Send + Sync, } } + +#[derive(Deserialize, Debug)] +pub struct AddUserConversationValues{ + pub conv_id: u32, + pub users: Vec +} + +pub struct AddUserConversationPayload(pub AddUserConversationValues); + +impl FromRequest for AddUserConversationPayload +where S: Send + Sync, +{ + type Rejection = (StatusCode, String); + + async fn from_request(req: Request, state: &S) -> Result { + let Json(payload) = Json::::from_request(req, state) + .await + .map_err(|err| (StatusCode::BAD_REQUEST, format!("Invalid body: {}", err)))?; + + Ok(AddUserConversationPayload(payload)) + + } +} \ No newline at end of file diff --git a/src/chat/handlers.rs b/src/chat/handlers.rs index 12113ec..3bfbc9b 100644 --- a/src/chat/handlers.rs +++ b/src/chat/handlers.rs @@ -2,15 +2,13 @@ use axum::{ extract::{ FromRequest,FromRequestParts, State, - }, - response::IntoResponse, - http::StatusCode, + }, http::StatusCode, response::{sse::KeepAlive, IntoResponse} }; use rusqlite::params; use crate::chat::extractor::{ -CreateConversationPayload, +AddUserConversationPayload, CreateConversationPayload }; use crate::utils::db_pool::{AppState}; use crate::utils::auth::AuthClaims; @@ -41,4 +39,52 @@ pub async fn create_conversation( Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Error when creating the conversation : {err}")), } +} + +pub async fn add_user_to_conv( + State(state): State, + AuthClaims {user_id, hotel_id,username}: AuthClaims, + AddUserConversationPayload(payload):AddUserConversationPayload +) -> impl IntoResponse { + + let pool = state.hotel_pools.get_pool(hotel_id); + + let conn = match pool.get(){ + Ok(conn) => conn, + Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error")) + }; + + let mut statement = match conn.prepare( + "SELECT 1 FROM conversation WHERE creator_id = ?1 AND id = ?2" , + ){ + Ok(statement) => statement, + Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "prepare failed".to_string()) + }; + + if !statement.exists(params![user_id, payload.conv_id ]) + .map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Query failed".to_string())).unwrap() + { + // Early exit if not creator + return ((StatusCode::FORBIDDEN, "Not the creator".to_string())); + } + + + for target_id in &payload.users { + let rows_inserted = match conn.execute( + "INSERT INTO conversation_participants (conversation_id, user_id) VALUES (?1, ?2)", + params![payload.conv_id, target_id], + ) { + Ok(n) => n, + Err(err) => { + return (StatusCode::INTERNAL_SERVER_ERROR, format!("Err adding user {}: {}", target_id, err)); + } + }; + + if rows_inserted == 0 { + return (StatusCode::NOT_FOUND, format!("Could not add user {}", target_id)); + } + } + + return (StatusCode::OK, "ok".to_string()); + } \ No newline at end of file diff --git a/src/chat/routes.rs b/src/chat/routes.rs index d867310..3c03755 100644 --- a/src/chat/routes.rs +++ b/src/chat/routes.rs @@ -4,7 +4,9 @@ use axum::{ }; use crate::utils::db_pool::AppState; -use crate::chat::handlers::create_conversation; +use crate::chat::handlers::{ + create_conversation,add_user_to_conv, +}; @@ -14,4 +16,6 @@ pub fn chat_routes() -> Router { Router::new() .route("/create_conversation", put (create_conversation)) -} \ No newline at end of file + .route("/add_users_conv", put(add_user_to_conv)) + + } \ No newline at end of file