From c9e338574e737f986ccb7b9e5c49fae4cb4d740a Mon Sep 17 00:00:00 2001 From: Romain Mallard Date: Fri, 28 Nov 2025 19:14:55 +0100 Subject: [PATCH] register user token update --- db/auth.sqlite | Bin 53248 -> 53248 bytes db/{auth copy 2.sqlite => auth_copy_2.sqlite} | Bin 57344 -> 65536 bytes ...auth.sqlite-shm => auth_copy_2.sqlite-shm} | Bin 32768 -> 32768 bytes ...auth.sqlite-wal => auth_copy_2.sqlite-wal} | Bin 300792 -> 238992 bytes src/main.rs | 2 +- src/utils/auth.rs | 154 ++++++++++++------ src/utils/routes.rs | 4 +- 7 files changed, 110 insertions(+), 50 deletions(-) rename db/{auth copy 2.sqlite => auth_copy_2.sqlite} (85%) rename db/{auth.sqlite-shm => auth_copy_2.sqlite-shm} (95%) rename db/{auth.sqlite-wal => auth_copy_2.sqlite-wal} (72%) diff --git a/db/auth.sqlite b/db/auth.sqlite index 4e846d859bdaa31ae2d0f79302bb197fe5c6bf36..0662d3bf7beaee6404ddb928acd6d5a6ac0de8c1 100644 GIT binary patch delta 1585 zcmb_cO>7%Q6rTODy}RDsXG0ugRd`oXA`%)k#BQ2a1W`BHG)^76Hg?+NfNQXuAOEc5 zwd1B0Bn}4@%7JQ+J+uhuwMecIR00X95*GwTMLlsyONEdqNFWta)B`iSaaAO^#iRG$ zeDCL5&)a#sahch;%)Gb9>qQ7jSln2gSb8rEhWor|-#cBBbO1TsEG-8_4!mwwx-Wex zf6!T?*!Ftf=gmIhR%BD^a&7WmF2ABsn-sQwKlN6wo_noSXc&c>VJUt*rA5-3nvNWa zX=;z<>rwj!75~iR;^?}yJ4O7JT)A*cO=~C9YCM4@6N?Sn(Q3{xntCn&-_iV%Q7z@x z{=a-tuNO+$C0rhjr?sP6%BIc4qsdG_Q~Ns)A5=S;1A;Kn=EQvzD;LpuQ6bH9%q+_XoWtEtzowXPK+sn&SF?6v7H=hpp%?8)H;D{e6eJ?z z2#33GdSHyj_L}(}sAd&h1Z)xD4qM3%j9;~|O-tfoj9(z{5P1-ix8Pj}w7u#%xxE!U zM+w9UkKix(qwW3pM=*aMdfN8=3iseooOm0|doMrRsfXv`f_wwJKatxv;)i$Y9{|qY z$<6jT?!p7Oh2iHg<8v}YRIPAYaxn_^_&l`N$vj8gwSuvjt?R`?#m&1Izn$Tb#Fr2& zJVcO{zi?j^9(ESKQg;NYrMP)SwGx@V6z4F963Tc~kBy8kFO~A?;=FNexi)1qS0|Fa z$EfB0iIIbi^s$*zGM8FdS%^&NM(AKvn@G)%Rx+ojhO7CJ;_K!&>miwKDZ*oF zc2}txgy>f1Uo*Q&Ezy{I197AwJhz+7B0|*Re-SU{l4m28lPj^2Lu-5U3oCQ;)6ICZ z_e42kq_x>lerW%h`gFmluT`3v$>^cb^x5LkSB`7T#^`MG#9V#Gh+2&{l{YU*tsuYC zYo6QHhM3v)k33Fk48az3%OA>v(lu!eU!8u5UUit~gAImVWi89BGQ`Ssm3ARtE8*j7 zdO3_+n0tzBRwx(p6Yref&>N()=4Z+zG>{7gT8TX*Ik!}?{6EK!C@H%fa0gH4_wW^5 p$CX!LQe*=ZWgmrgJOLQ?2|zPE>*GmUnC4kOZ?{BX13YJ!{sWBrwmAR* delta 827 zcmcIi-%C?b96x90Zo7B8_k6cf#tPjeMOWgMn(QGcH+LagTeIErsikw4nVW5sv4qs< z#fWH}KVT~K+7AZ3g)e&x`$3Se8ouhoNR#lPbEgD@UgPkE^Z9(g-_Q5QISb2VVVS%< zZMPwW6mC{-0=KqOcVCAM^*n1*=oAuV(Vz^#I;=tg!qh2?UW5wP~n=2F?5(L;`LZygIBLmm4Rz=+T# zM3>+>I4gGd9IY(1&S49I8iGSOfEp*afUTF!Y~M>czl~rAwqc+1-+^skYEj@9*Qg>m z3ng0R^m|&VMlS0bJa$iyK8{Uv828`@eB|&01e;C7iyM}h$WPA@yNPr*(t?DE1J@fj z=ub+h3qgXeQ5SzIJ7uoNWyQDHLL?+EMzwR2$lkqh1(WGpu|Qru9}K1L7uAuWz_pP= zaIk%RXm&WH`XhIJH#2H@SnH4HCLcXa7h}b%W6@Y38Mxq|D5^1^8u2IDr}1<2ea?%IOVbu&ABBOW!# pGyal1rHK$D!PsEXCF>Ksh7BID3dSy?VSTzYMxtNY`g}V!`~k@l>}vo3 diff --git a/db/auth copy 2.sqlite b/db/auth_copy_2.sqlite similarity index 85% rename from db/auth copy 2.sqlite rename to db/auth_copy_2.sqlite index 978d5ede4d20de0425e4cbaf69aadc3b6537bbf7..312fa53d20585e7576c5233f4baf807e4e931218 100644 GIT binary patch delta 424 zcmZoTz}(QlGC^8Un1O*o0E(G_wDv?DV{Ksuy)F@6uD=YtT!l=$Ui@eI7x9<#`|wHf zi1Q0_74j|RtKjD0yTql%rL}QlCr5abh%~#nu`y$_e@S9ePHIMeNor1fX>n>%d`@Ow zc6>>00Tv-n=O9?snu!%<+ zPp;#WRYA2P-VlosJd+E#dZPKV8TiGuwVMPW&TQfU(%RaL&Fg)CRdz9Lb%?Zrsen|9`<|;RTQRCoT|LbUvwj?nrC$%UwtthoPBfca*J2fx9B)0%V zfWtY+)iK0XA;i(i$5kN#S$=XMSC4lShX}j4wl-t4JJ`UC{F2lh-O}RJBHf(KylgZs zC#qp+vXd8bDY1gJPM*kV%BTw@MJC_o^ylZxX5bfBS7&Sy1>3P%oM#Uct0KU<1dMyhq~q+#=Zd-M8y(Y<@Rzq&j-fBblOxqd5m+V$oyuaEbR z_Weq%WF8$4*bLcJZ0tGIXESJ1wW-?V_ zP?L@bqzDx3oy=8@XjSXl)V6lCrvtT9t|UU>zX_ZudJ8)X0gnP1&3UX%X9P^3XkWUh zX;f?4(3V=-)xHjqLBNGTR`V`;QWAksAg6^eBtgK1K*_!%R@ayoU9_bn0!e|geO0fa laV;f7juCJnuWWEdl@l literal 32768 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, Json(payload): Json, ) -> impl IntoResponse { @@ -191,7 +191,7 @@ pub async fn ForceUpdatePassword( |row|{ let user_id: i32 = row.get(0)?; //let hotel_id: i32 = row.get(1)?; - Ok((user_id)) + Ok(user_id) }, ).optional() { Ok(opt) => opt, @@ -199,7 +199,7 @@ pub async fn ForceUpdatePassword( .into_response(), }; - let (user_id) = match user_row { + let user_id = match user_row { Some(u) => u, None => return (StatusCode::UNAUTHORIZED, "Not correct user") .into_response(), @@ -239,7 +239,7 @@ pub struct UpdatePasswordValues{ } -pub async fn UpdatePassword( +pub async fn update_password( State(state): State, Json(payload): Json, ) -> impl IntoResponse { @@ -360,7 +360,7 @@ pub async fn clean_auth_loging( Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB query error").into_response(), }; - let (user_id, stored_hash, hotel_id, displayname) = match user_row { + let (user_id, stored_hash, hotel_id, _displayname) = match user_row { Some(u) => u, None => return (StatusCode::UNAUTHORIZED, "Invalid credentials").into_response(), }; @@ -405,7 +405,9 @@ pub struct CreateRefreshTokenValue { } -//TODO: refactor this to impl IntoResponse ans not Result + +//FIXME: weird return type, returning result ? + #[axum::debug_handler] pub async fn create_refresh_token( State(state): State, @@ -433,26 +435,76 @@ pub async fn create_refresh_token( let conn = state.logs_pool.get() .map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "DB connection error".to_string()))?; - let mut stmt = conn.prepare( - "SELECT id, password, hotel_id FROM users WHERE username = ?1" - ).map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "DB prepare error".to_string()))?; + //TODO: prend id username password de users + // let mut stmt = conn.prepare( + // "SELECT id, password FROM users WHERE username = ?1" - let user_rows = stmt - .query_map(params![&payload.username], |row| { + let credentials = match conn.query_row( + "SELECT id, password FROM users WHERE username = ?1", + params![&payload.username], + |row| { let user_id: i32 = row.get(0)?; let password: String = row.get(1)?; - let hotel_id: i32 = row.get(2)?; - Ok((user_id, password, hotel_id)) - }) - .map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "DB query error".to_string()))?; + Ok((user_id, password)) + }, + ) { + Ok(cr) => cr, + Err(_) => return Err((StatusCode::INTERNAL_SERVER_ERROR, "error fetching credentials".to_string())), + + }; + + let (user_id, user_password) = credentials; /* let (user_id, stored_hash, hotel_id) = user_row .ok_or((StatusCode::NOT_FOUND, "User not found".to_string()))?; */ //let mut tokens = Vec::new(); + //TODO: validate password + if !verify_password(&payload.password, &user_password) { + return Err((StatusCode::INTERNAL_SERVER_ERROR, "Invalid credential".to_string())); // Skip rows with invalid password + } + + + //TODO: stmt, querry hotel-id dans hotel-user-link avec l'ID précédant + let mut stmt = match conn.prepare( + "SELECt hotel_id FROM hotel_user_link WHERE user_id = ?1" + ) { + Ok(stmt) => stmt, + Err(_) => return Err((StatusCode::INTERNAL_SERVER_ERROR, "error building user_id fetch stmt".to_string())), + }; + //TODO: compiler les hotel id dans un vecteur pour le feed dans le refresh token + //Deja fait ? + + + + + let hotel_ids = match stmt + .query_map(params![&user_id],|row| row.get (0)) + { + Ok(rows) => rows.collect::,_>>() + .map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Error collecting hotel_ids".to_string()))?, + Err(_) => return Err((StatusCode::INTERNAL_SERVER_ERROR, "Error mapping hotel_ids".to_string())), + }; + + + conn.execute( + "INSERT INTO refresh_token (user_id, token_hash, device_id, user_agent, hotel_id_list) + VALUES (?1, ?2, ?3, ?4, ?5)", + params![ + &user_id, + &hashed_token, + &device_id_str, + &user_agent_str, + &hotel_ids, + ], + ).map_err(|e| { + (StatusCode::INTERNAL_SERVER_ERROR, format!("DB error: {}", e)) + })?; + //TODO: insert single refresh token + /* for user_row_result in user_rows { let (user_id, stored_hash, hotel_id) = user_row_result .map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "DB row error".to_string()))?; @@ -480,7 +532,8 @@ pub async fn create_refresh_token( //tokens.push(raw_token); } - + + */ let cookie_value = format!("refresh_token={}; HttpOnly; Secure; Path=/", raw_token); @@ -499,6 +552,7 @@ pub struct LoginRefreshTokenValues{ refresh_token: String, } +//TODO: LATER : implement hotel-id-selected to allow user to only get part hotels ? pub async fn login_refresh_token ( State(state): State, Extension(keys): Extension, @@ -519,16 +573,19 @@ pub async fn login_refresh_token ( let device_id_str = payload.device_id.to_string(); */ -let user_agent_str = match user_agent { - Some(ua) => ua.to_string(), - None => return (StatusCode::INTERNAL_SERVER_ERROR, "user agent unknown").into_response(), -}; + let user_agent_str = match user_agent { + Some(ua) => ua.to_string(), + None => return (StatusCode::INTERNAL_SERVER_ERROR, "user agent unknown").into_response(), + }; -let device_id_str = payload.device_id.to_string(); + let device_id_str = payload.device_id.to_string(); //"SELECT user_id, token_hash, hotel_id FROM refresh_token WHERE device_id = ?1 AND user_agent = ?2", + //TODO: swap to query row and get hotel-id's list and not single hotel per row + //deserializing the list : + //let hotel_ids: Vec = serde_json::from_str(&stored_value)?; let mut stmt = match conn.prepare( "SELECT user_id, token_hash, hotel_id FROM refresh_token @@ -549,6 +606,8 @@ let device_id_str = payload.device_id.to_string(); Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB query error").into_response(), }; + + let mut entries = Vec::new(); for r in rows { match r { @@ -563,34 +622,35 @@ let device_id_str = payload.device_id.to_string(); let mut tokens = Vec::new(); -for (user_id, token_hash, hotel_id) in entries { - if !verify_password(&payload.refresh_token, &token_hash) { - // skip rows with wrong hash - continue; + //FIXME: swap to "for hotel_id in entries" // interator over vector list + for (user_id, token_hash, hotel_id) in entries { + if !verify_password(&payload.refresh_token, &token_hash) { + // skip rows with wrong hash + continue; + } + //FIXME: single expiration + let expiration = match chrono::Utc::now().checked_add_signed(chrono::Duration::hours(15)) { + Some(time) => time.timestamp() as usize, + None => { + // Handle overflow — probably a 500, since this should never happen + return (StatusCode::INTERNAL_SERVER_ERROR, "Time overflow".to_string()).into_response(); + } + }; + + let claims = serde_json::json!({ + "id": user_id, + "hotel_id": hotel_id, + "exp": expiration + }); + + let token = match encode(&Header::default(), &claims, &keys.encoding) { + Ok(t) => t, + Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "JWT creation failed").into_response(), + }; + + tokens.push(token); } - let expiration = match chrono::Utc::now().checked_add_signed(chrono::Duration::hours(15)) { - Some(time) => time.timestamp() as usize, - None => { - // Handle overflow — probably a 500, since this should never happen - return (StatusCode::INTERNAL_SERVER_ERROR, "Time overflow".to_string()).into_response(); - } - }; - - let claims = serde_json::json!({ - "id": user_id, - "hotel_id": hotel_id, - "exp": expiration - }); - - let token = match encode(&Header::default(), &claims, &keys.encoding) { - Ok(t) => t, - Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "JWT creation failed").into_response(), - }; - - tokens.push(token); -} - if tokens.is_empty() { return (StatusCode::UNAUTHORIZED, "Invalid or mismatched token").into_response(); diff --git a/src/utils/routes.rs b/src/utils/routes.rs index 99ad04a..1e47221 100644 --- a/src/utils/routes.rs +++ b/src/utils/routes.rs @@ -18,8 +18,8 @@ pub fn utils_routes() -> Router { .route("/register", put(register_user)) .route("/ws/", get(ws_handler)) .route("/tokentest", put(token_tester)) - .route("/force_update_password", put(ForceUpdatePassword)) - .route("/update_password", put(UpdatePassword)) + .route("/force_update_password", put(force_update_password)) + .route("/update_password", put(update_password)) .route("/create_refresh", post(create_refresh_token)) .route("/login_refresh_token", post(login_refresh_token))