turned on WAL on db, fix force update of passwords
This commit is contained in:
@@ -106,10 +106,15 @@ fn hash_password(password: &str) -> anyhow::Result<String> {
|
||||
|
||||
// Verify an incoming password against stored hash
|
||||
fn verify_password(password: &str, stored_hash: &str) -> bool {
|
||||
let parsed_hash = PasswordHash::new(stored_hash).unwrap();
|
||||
|
||||
let parsed_hash = match PasswordHash::new(&stored_hash) {
|
||||
Ok(hash) => hash,
|
||||
Err(_) => return false,
|
||||
};
|
||||
|
||||
Argon2::default()
|
||||
.verify_password(password.as_bytes(), &parsed_hash)
|
||||
.is_ok()
|
||||
.verify_password(password.as_bytes(), &parsed_hash).is_ok()
|
||||
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
@@ -155,6 +160,133 @@ pub async fn register_user (
|
||||
Ok((StatusCode::CREATED, "User registered successfully"))
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ForceUpdatePasswordValues{
|
||||
username: String,
|
||||
newpassword: String,
|
||||
hotel_id: i32,
|
||||
admin_pass: String,
|
||||
}
|
||||
|
||||
//pub struct ForceUpdatePasswordPayload (pub ForceUpdatePasswordValues);
|
||||
|
||||
pub async fn ForceUpdatePassword(
|
||||
State(state): State<AppState>,
|
||||
Json(payload): Json<ForceUpdatePasswordValues>,
|
||||
) -> impl IntoResponse {
|
||||
|
||||
let conn = match state.logs_pool.get() {
|
||||
Ok(c) => c,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB, conn failed").into_response()
|
||||
};
|
||||
|
||||
let user_row = match conn.query_row(
|
||||
"SELECT id FROM users WHERE username = ?1 AND hotel_id = ?2",
|
||||
params![&payload.username, &payload.hotel_id],
|
||||
|row|{
|
||||
let user_id: i32 = row.get(0)?;
|
||||
//let hotel_id: i32 = row.get(1)?;
|
||||
Ok((user_id))
|
||||
},
|
||||
).optional() {
|
||||
Ok(opt) => opt,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB query error")
|
||||
.into_response(),
|
||||
};
|
||||
|
||||
let (user_id) = match user_row {
|
||||
Some(u) => u,
|
||||
None => return (StatusCode::UNAUTHORIZED, "Not correct user")
|
||||
.into_response(),
|
||||
};
|
||||
|
||||
let admin_check: String = "my_admin_password".to_string();
|
||||
|
||||
if &payload.admin_pass != &admin_check {
|
||||
return (StatusCode::UNAUTHORIZED, "Invalid Amin Password").into_response()
|
||||
};
|
||||
|
||||
|
||||
let hashed_password = match hash_password(&payload.newpassword) {
|
||||
Ok(h) => h,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "Password hashing failed").into_response(),
|
||||
};
|
||||
|
||||
let result = conn.execute(
|
||||
"UPDATE users SET password = ?1 WHERE id = ?2",
|
||||
params![&hashed_password, &user_id],
|
||||
);
|
||||
|
||||
match result {
|
||||
Ok(rows) if rows > 0 => (StatusCode::OK, "Password updated").into_response(),
|
||||
Ok(_) => (StatusCode::NOT_FOUND, "User not found").into_response(),
|
||||
Err(_) => (StatusCode::INTERNAL_SERVER_ERROR, "Failed to update password").into_response(),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct UpdatePasswordValues{
|
||||
username: String,
|
||||
current_password: String,
|
||||
newpassword: String,
|
||||
hotel_id: i32,
|
||||
|
||||
}
|
||||
|
||||
pub async fn UpdatePassword(
|
||||
State(state): State<AppState>,
|
||||
Json(payload): Json<UpdatePasswordValues>,
|
||||
) -> impl IntoResponse {
|
||||
|
||||
let conn = match state.logs_pool.get() {
|
||||
Ok(c) => c,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB, conn failed").into_response()
|
||||
};
|
||||
|
||||
let user_row = match conn.query_row(
|
||||
"SELECT password, id FROM users WHERE username = ?1 AND current_password = ?2",
|
||||
params![&payload.username, &payload.current_password],
|
||||
|row|{
|
||||
let password: String = row.get(0)?;
|
||||
let id: i32 = row.get(1)?;
|
||||
Ok((password, id))
|
||||
},
|
||||
).optional() {
|
||||
Ok(opt) => opt,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB query error")
|
||||
.into_response(),
|
||||
};
|
||||
|
||||
let (password, user_id) = match user_row {
|
||||
Some(u) => u,
|
||||
None => return (StatusCode::UNAUTHORIZED, "Not correct user")
|
||||
.into_response(),
|
||||
};
|
||||
|
||||
if verify_password( &payload.current_password, &password ) {
|
||||
return (StatusCode::UNAUTHORIZED, "Invalid Password").into_response()
|
||||
};
|
||||
|
||||
|
||||
let hashed_password = match hash_password(&payload.newpassword) {
|
||||
Ok(h) => h,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "Password hashing failed").into_response(),
|
||||
};
|
||||
|
||||
let result = conn.execute(
|
||||
"UPDATE users SET password = ?1 WHERE id = ?2",
|
||||
params![&hashed_password, &user_id],
|
||||
);
|
||||
|
||||
match result {
|
||||
Ok(rows) if rows > 0 => (StatusCode::OK, "Password updated").into_response(),
|
||||
Ok(_) => (StatusCode::NOT_FOUND, "User not found").into_response(),
|
||||
Err(_) => (StatusCode::INTERNAL_SERVER_ERROR, "Failed to update password").into_response(),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct LoginValues {
|
||||
username : String,
|
||||
@@ -227,11 +359,14 @@ pub async fn clean_auth_loging(
|
||||
return (StatusCode::UNAUTHORIZED, "Invelid credentials").into_response();
|
||||
}
|
||||
|
||||
let expiration = chrono::Utc::now()
|
||||
.checked_add_signed(chrono::Duration::hours(15))
|
||||
.unwrap()
|
||||
.timestamp() as usize;
|
||||
|
||||
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,
|
||||
@@ -251,6 +386,11 @@ pub async fn clean_auth_loging(
|
||||
Json(LoginResponse { token }).into_response()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
fn internal_error<E: std::fmt::Display>(err: E) -> (StatusCode, String) {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, format!("Internal error: {}", err))
|
||||
}
|
||||
@@ -15,6 +15,8 @@ pub fn utils_routes() -> Router<AppState> {
|
||||
.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))
|
||||
|
||||
//.with_state(state)
|
||||
}
|
||||
Reference in New Issue
Block a user