Add bcrypt password hashing and user gender handling in yourchat2
Integrated bcrypt for password verification and updated user profile management to include gender and rights handling. Enhanced room access validation to consider gender restrictions and user rights. Updated database queries and structures to support new fields, ensuring compatibility with existing functionalities.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use crate::types::{ChatState, ClientId, Command, RoomMeta, ServerConfig};
|
||||
use bcrypt::verify as bcrypt_verify;
|
||||
use serde_json::{json, Value};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
@@ -169,7 +170,9 @@ async fn handle_init_command(
|
||||
guard.room_meta.get(&resolved_room_name),
|
||||
&profile.display_name,
|
||||
profile.falukant_user_id,
|
||||
profile.gender_id,
|
||||
profile.age,
|
||||
&profile.right_type_ids,
|
||||
&room_password,
|
||||
) {
|
||||
drop(guard);
|
||||
@@ -189,8 +192,10 @@ async fn handle_init_command(
|
||||
client.color = profile.color.clone();
|
||||
client.falukant_user_id = profile.falukant_user_id;
|
||||
client.chat_user_id = profile.chat_user_id;
|
||||
client.gender_id = profile.gender_id;
|
||||
client.age = profile.age;
|
||||
client.rights = profile.rights.clone();
|
||||
client.right_type_ids = profile.right_type_ids.clone();
|
||||
client.logged_in = true;
|
||||
client.room = resolved_room_name.clone();
|
||||
|
||||
@@ -271,17 +276,25 @@ async fn handle_join_command(
|
||||
send_error(client_id, Arc::clone(&state), "room_not_found_or_join_failed").await;
|
||||
return;
|
||||
};
|
||||
let (name_for_check, falukant_user_id, age) = {
|
||||
let (name_for_check, falukant_user_id, gender_id, age, right_type_ids) = {
|
||||
let Some(client) = guard.clients.get(&client_id) else {
|
||||
return;
|
||||
};
|
||||
(client.user_name.clone(), client.falukant_user_id, client.age)
|
||||
(
|
||||
client.user_name.clone(),
|
||||
client.falukant_user_id,
|
||||
client.gender_id,
|
||||
client.age,
|
||||
client.right_type_ids.clone(),
|
||||
)
|
||||
};
|
||||
if !room_access_allowed(
|
||||
guard.room_meta.get(&resolved_room),
|
||||
&name_for_check,
|
||||
falukant_user_id,
|
||||
gender_id,
|
||||
age,
|
||||
&right_type_ids,
|
||||
&password,
|
||||
) {
|
||||
drop(guard);
|
||||
@@ -770,45 +783,82 @@ fn room_access_allowed(
|
||||
room_meta: Option<&RoomMeta>,
|
||||
_user_name: &str,
|
||||
falukant_user_id: Option<i32>,
|
||||
user_gender_id: Option<i32>,
|
||||
age: Option<i32>,
|
||||
user_right_type_ids: &std::collections::HashSet<i32>,
|
||||
provided_password: &str,
|
||||
) -> bool {
|
||||
let Some(room) = room_meta else {
|
||||
return false;
|
||||
};
|
||||
|
||||
if let Some(required_gender) = room.gender_restriction_id {
|
||||
if required_gender > 0 && user_gender_id != Some(required_gender) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(room_password) = &room.password {
|
||||
if !room_password.is_empty() && room_password != provided_password {
|
||||
if !room_password.is_empty() && !password_matches(room_password, provided_password) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(min_age) = room.min_age {
|
||||
if min_age >= 18 {
|
||||
if min_age > 0 {
|
||||
let Some(fid) = falukant_user_id else {
|
||||
return false;
|
||||
};
|
||||
if fid <= 0 {
|
||||
return false;
|
||||
}
|
||||
if let Some(user_age) = age {
|
||||
if user_age < min_age {
|
||||
return false;
|
||||
}
|
||||
let Some(user_age) = age else {
|
||||
return false;
|
||||
};
|
||||
if user_age < min_age {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(max_age) = room.max_age {
|
||||
if let Some(user_age) = age {
|
||||
if max_age > 0 {
|
||||
let Some(user_age) = age else {
|
||||
return false;
|
||||
};
|
||||
if user_age > max_age {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(required_right) = room.required_user_right_id {
|
||||
if required_right > 0 && !user_right_type_ids.contains(&required_right) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn password_matches(stored_password_or_hash: &str, provided_password: &str) -> bool {
|
||||
if stored_password_or_hash.is_empty() {
|
||||
return true;
|
||||
}
|
||||
if stored_password_or_hash == provided_password {
|
||||
return true;
|
||||
}
|
||||
if provided_password.is_empty() {
|
||||
return false;
|
||||
}
|
||||
if stored_password_or_hash.starts_with("$2a$")
|
||||
|| stored_password_or_hash.starts_with("$2b$")
|
||||
|| stored_password_or_hash.starts_with("$2x$")
|
||||
|| stored_password_or_hash.starts_with("$2y$")
|
||||
{
|
||||
return bcrypt_verify(provided_password, stored_password_or_hash).unwrap_or(false);
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn resolve_room_name(state: &ChatState, requested: &str) -> Option<String> {
|
||||
if state.room_meta.contains_key(requested) {
|
||||
return Some(requested.to_string());
|
||||
|
||||
Reference in New Issue
Block a user