mirror of
				https://gitlab.com/comunic/comunicapiv3
				synced 2025-10-31 15:44:05 +00:00 
			
		
		
		
	Upgrade password system
This commit is contained in:
		
							
								
								
									
										55
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										55
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -469,6 +469,18 @@ version = "0.12.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" | ||||
|  | ||||
| [[package]] | ||||
| name = "bcrypt" | ||||
| version = "0.8.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e2cab630912253fb9dc92c0e2fabd0a7b51f5a5a4007177cfa31e517015b7204" | ||||
| dependencies = [ | ||||
|  "base64 0.12.3", | ||||
|  "blowfish", | ||||
|  "byteorder", | ||||
|  "getrandom", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "bigdecimal" | ||||
| version = "0.1.2" | ||||
| @@ -496,7 +508,16 @@ dependencies = [ | ||||
|  "block-padding", | ||||
|  "byte-tools", | ||||
|  "byteorder", | ||||
|  "generic-array", | ||||
|  "generic-array 0.12.3", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "block-cipher" | ||||
| version = "0.8.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f337a3e6da609650eb74e02bc9fac7b735049f7623ab12f2e4c719316fcc7e80" | ||||
| dependencies = [ | ||||
|  "generic-array 0.14.4", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @@ -508,6 +529,17 @@ dependencies = [ | ||||
|  "byte-tools", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "blowfish" | ||||
| version = "0.6.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0f06850ba969bc59388b2cc0a4f186fc6d9d37208863b15b84ae3866ac90ac06" | ||||
| dependencies = [ | ||||
|  "block-cipher", | ||||
|  "byteorder", | ||||
|  "opaque-debug 0.3.0", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "brotli-sys" | ||||
| version = "0.3.2" | ||||
| @@ -621,6 +653,7 @@ dependencies = [ | ||||
|  "actix-rt", | ||||
|  "actix-web", | ||||
|  "actix-web-actors", | ||||
|  "bcrypt", | ||||
|  "bytes", | ||||
|  "chrono", | ||||
|  "dashmap", | ||||
| @@ -802,7 +835,7 @@ version = "0.8.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" | ||||
| dependencies = [ | ||||
|  "generic-array", | ||||
|  "generic-array 0.12.3", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @@ -1121,6 +1154,16 @@ dependencies = [ | ||||
|  "typenum", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "generic-array" | ||||
| version = "0.14.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" | ||||
| dependencies = [ | ||||
|  "typenum", | ||||
|  "version_check", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "getrandom" | ||||
| version = "0.1.14" | ||||
| @@ -1845,6 +1888,12 @@ version = "0.2.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" | ||||
|  | ||||
| [[package]] | ||||
| name = "opaque-debug" | ||||
| version = "0.3.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" | ||||
|  | ||||
| [[package]] | ||||
| name = "openssl" | ||||
| version = "0.10.29" | ||||
| @@ -2361,7 +2410,7 @@ dependencies = [ | ||||
|  "block-buffer", | ||||
|  "digest", | ||||
|  "fake-simd", | ||||
|  "opaque-debug", | ||||
|  "opaque-debug 0.2.3", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
|   | ||||
| @@ -32,4 +32,5 @@ pdf = "0.6.3" | ||||
| regex = "1.4.2" | ||||
| dashmap = "3.11.10" | ||||
| reqwest = { version = "0.10.6", features = ["json", "blocking"] } | ||||
| webrtc-sdp = "0.3.6" | ||||
| webrtc-sdp = "0.3.6" | ||||
| bcrypt = "0.8.0" | ||||
| @@ -1,20 +1,22 @@ | ||||
| use bcrypt::{DEFAULT_COST, hash_with_result, verify}; | ||||
|  | ||||
| use crate::constants::{PASSWORD_RESET_TOKEN_LENGTH, PASSWORD_RESET_TOKEN_LIFETIME}; | ||||
| use crate::constants::database_tables_names::{USER_ACCESS_TOKENS_TABLE, USERS_TABLE}; | ||||
| use crate::controllers::user_ws_controller; | ||||
| use crate::data::account_export::AccountExport; | ||||
| use crate::data::api_client::APIClient; | ||||
| use crate::data::error::{ExecError, ResultBoxError}; | ||||
| use crate::data::error::{ExecError, Res, ResultBoxError}; | ||||
| use crate::data::general_settings::GeneralSettings; | ||||
| use crate::data::lang_settings::LangSettings; | ||||
| use crate::data::new_account::NewAccount; | ||||
| use crate::data::security_settings::SecuritySettings; | ||||
| use crate::data::user::{AccountImageVisibility, UserID, UserPageStatus}; | ||||
| use crate::data::user::{AccountImageVisibility, User, UserID, UserPageStatus}; | ||||
| use crate::data::user_token::UserAccessToken; | ||||
| use crate::helpers::{comments_helper, conversations_helper, custom_emojies_helper, database, events_helper, friends_helper, groups_helper, likes_helper, movies_helper, notifications_helper, posts_helper, survey_helper, user_helper}; | ||||
| use crate::helpers::database::{DeleteQuery, InsertQuery, QueryInfo}; | ||||
| use crate::helpers::events_helper::Event; | ||||
| use crate::helpers::likes_helper::LikeType; | ||||
| use crate::utils::crypt_utils::{crypt_pass, rand_str}; | ||||
| use crate::utils::crypt_utils::{legacy_crypt_pass, rand_str}; | ||||
| use crate::utils::date_utils::{mysql_date, time}; | ||||
| use crate::utils::user_data_utils::user_data_path; | ||||
|  | ||||
| @@ -29,7 +31,7 @@ pub fn create(new_account: &NewAccount) -> ResultBoxError { | ||||
|         .add_str("prenom", &new_account.last_name) | ||||
|         .add_str("date_creation", &mysql_date()) | ||||
|         .add_str("mail", &new_account.email) | ||||
|         .add_str("password", &crypt_pass(&new_account.password)?) | ||||
|         .add_str("password", &hash_password(&new_account.password)?) | ||||
|         .insert_drop_result() | ||||
| } | ||||
|  | ||||
| @@ -41,8 +43,7 @@ pub fn login_user(email: &str, password: &str, client: &APIClient) -> ResultBoxE | ||||
|     let user = user_helper::find_user_by_email(email)?; | ||||
|  | ||||
|     // Validate user password | ||||
|     let password = crypt_pass(password)?; | ||||
|     if !user.password.eq(&password) { | ||||
|     if !validate_password(&user, password)? { | ||||
|         return Err(ExecError::boxed_new("The user gave an invalid password!")); | ||||
|     } | ||||
|  | ||||
| @@ -161,20 +162,16 @@ pub fn get_user_id_from_password_reset_token(token: &str) -> ResultBoxError<User | ||||
|  | ||||
| /// Check current user's password | ||||
| pub fn check_user_password(user_id: &UserID, password: &str) -> ResultBoxError<bool> { | ||||
|     let crypt_pass = crypt_pass(password)?; | ||||
|     let user = user_helper::find_user_by_id(user_id)?; | ||||
|  | ||||
|     database::QueryInfo::new(USERS_TABLE) | ||||
|         .cond_user_id("ID", user_id) | ||||
|         .cond("password", &crypt_pass) | ||||
|         .exec_count() | ||||
|         .map(|r| r > 0) | ||||
|     validate_password(&user, password) | ||||
| } | ||||
|  | ||||
| /// Change the password of a user | ||||
| pub fn change_password(user_id: &UserID, new_password: &String) -> ResultBoxError { | ||||
| pub fn change_password(user_id: &UserID, new_password: &str) -> ResultBoxError { | ||||
|     database::UpdateInfo::new(USERS_TABLE) | ||||
|         .cond_user_id("ID", user_id) | ||||
|         .set_str("password", &crypt_pass(new_password)?) | ||||
|         .set_str("password", &hash_password(new_password)?) | ||||
|         .exec() | ||||
| } | ||||
|  | ||||
| @@ -360,4 +357,34 @@ pub fn delete(user_id: &UserID) -> ResultBoxError { | ||||
|         .exec()?; | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| /// Hash the password to store it inside the database | ||||
| fn hash_password(pass: &str) -> Res<String> { | ||||
|     Ok(hash_with_result(pass, DEFAULT_COST)?.to_string()) | ||||
| } | ||||
|  | ||||
| /// Validate user password. | ||||
| /// | ||||
| /// If the password is encoded using the legacy method, it is automatically upgraded in case of | ||||
| /// success | ||||
| fn validate_password(user: &User, password: &str) -> Res<bool> { | ||||
|  | ||||
|     // We check if the password use the new storage mechanism | ||||
|     if user.password.starts_with("$") { | ||||
|         return Ok(verify(password, &user.password)?); | ||||
|     } | ||||
|  | ||||
|     // We need to upgrade the password | ||||
|     let crypt_pass = legacy_crypt_pass(password)?; | ||||
|  | ||||
|     // If the password is not valid | ||||
|     if !user.password.eq(&crypt_pass) { | ||||
|         return Ok(false); | ||||
|     } | ||||
|  | ||||
|     // Upgrade the password | ||||
|     change_password(&user.id, password)?; | ||||
|  | ||||
|     Ok(true) | ||||
| } | ||||
| @@ -22,18 +22,17 @@ pub fn sha1_str(input: &str) -> String { | ||||
|  | ||||
| /// One-way user password crypt | ||||
| /// | ||||
| /// This method will have to be replaced by a stronger algorithm once this implementation is | ||||
| /// completely built. | ||||
| /// This method is just transitional | ||||
| /// | ||||
| /// It currently depends on PHP | ||||
| /// | ||||
| /// ``` | ||||
| /// use comunic_server::utils::crypt_utils::crypt_pass; | ||||
| /// use comunic_server::utils::crypt_utils::legacy_crypt_pass; | ||||
| /// | ||||
| /// let res = crypt_pass("secret").unwrap(); | ||||
| /// let res = legacy_crypt_pass("secret").unwrap(); | ||||
| /// assert_eq!(res, "e5GUe5kdeUMGs"); | ||||
| /// ``` | ||||
| pub fn crypt_pass(pass: &str) -> ResultBoxError<String> { | ||||
| pub fn legacy_crypt_pass(pass: &str) -> ResultBoxError<String> { | ||||
|     let hash = sha1_str(pass); | ||||
|  | ||||
|     let result = std::process::Command::new("/usr/bin/php") | ||||
|   | ||||
		Reference in New Issue
	
	Block a user