mirror of
https://gitlab.com/comunic/comunicapiv3
synced 2024-11-22 13:29:21 +00:00
Upgrade password system
This commit is contained in:
parent
6396271e9c
commit
36c096d415
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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
|
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]]
|
[[package]]
|
||||||
name = "bigdecimal"
|
name = "bigdecimal"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
@ -496,7 +508,16 @@ dependencies = [
|
|||||||
"block-padding",
|
"block-padding",
|
||||||
"byte-tools",
|
"byte-tools",
|
||||||
"byteorder",
|
"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]]
|
[[package]]
|
||||||
@ -508,6 +529,17 @@ dependencies = [
|
|||||||
"byte-tools",
|
"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]]
|
[[package]]
|
||||||
name = "brotli-sys"
|
name = "brotli-sys"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
@ -621,6 +653,7 @@ dependencies = [
|
|||||||
"actix-rt",
|
"actix-rt",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"actix-web-actors",
|
"actix-web-actors",
|
||||||
|
"bcrypt",
|
||||||
"bytes",
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
@ -802,7 +835,7 @@ version = "0.8.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array",
|
"generic-array 0.12.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1121,6 +1154,16 @@ dependencies = [
|
|||||||
"typenum",
|
"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]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.1.14"
|
version = "0.1.14"
|
||||||
@ -1845,6 +1888,12 @@ version = "0.2.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opaque-debug"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl"
|
name = "openssl"
|
||||||
version = "0.10.29"
|
version = "0.10.29"
|
||||||
@ -2361,7 +2410,7 @@ dependencies = [
|
|||||||
"block-buffer",
|
"block-buffer",
|
||||||
"digest",
|
"digest",
|
||||||
"fake-simd",
|
"fake-simd",
|
||||||
"opaque-debug",
|
"opaque-debug 0.2.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -32,4 +32,5 @@ pdf = "0.6.3"
|
|||||||
regex = "1.4.2"
|
regex = "1.4.2"
|
||||||
dashmap = "3.11.10"
|
dashmap = "3.11.10"
|
||||||
reqwest = { version = "0.10.6", features = ["json", "blocking"] }
|
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::{PASSWORD_RESET_TOKEN_LENGTH, PASSWORD_RESET_TOKEN_LIFETIME};
|
||||||
use crate::constants::database_tables_names::{USER_ACCESS_TOKENS_TABLE, USERS_TABLE};
|
use crate::constants::database_tables_names::{USER_ACCESS_TOKENS_TABLE, USERS_TABLE};
|
||||||
use crate::controllers::user_ws_controller;
|
use crate::controllers::user_ws_controller;
|
||||||
use crate::data::account_export::AccountExport;
|
use crate::data::account_export::AccountExport;
|
||||||
use crate::data::api_client::APIClient;
|
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::general_settings::GeneralSettings;
|
||||||
use crate::data::lang_settings::LangSettings;
|
use crate::data::lang_settings::LangSettings;
|
||||||
use crate::data::new_account::NewAccount;
|
use crate::data::new_account::NewAccount;
|
||||||
use crate::data::security_settings::SecuritySettings;
|
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::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::{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::database::{DeleteQuery, InsertQuery, QueryInfo};
|
||||||
use crate::helpers::events_helper::Event;
|
use crate::helpers::events_helper::Event;
|
||||||
use crate::helpers::likes_helper::LikeType;
|
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::date_utils::{mysql_date, time};
|
||||||
use crate::utils::user_data_utils::user_data_path;
|
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("prenom", &new_account.last_name)
|
||||||
.add_str("date_creation", &mysql_date())
|
.add_str("date_creation", &mysql_date())
|
||||||
.add_str("mail", &new_account.email)
|
.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()
|
.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)?;
|
let user = user_helper::find_user_by_email(email)?;
|
||||||
|
|
||||||
// Validate user password
|
// Validate user password
|
||||||
let password = crypt_pass(password)?;
|
if !validate_password(&user, password)? {
|
||||||
if !user.password.eq(&password) {
|
|
||||||
return Err(ExecError::boxed_new("The user gave an invalid 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
|
/// Check current user's password
|
||||||
pub fn check_user_password(user_id: &UserID, password: &str) -> ResultBoxError<bool> {
|
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)
|
validate_password(&user, password)
|
||||||
.cond_user_id("ID", user_id)
|
|
||||||
.cond("password", &crypt_pass)
|
|
||||||
.exec_count()
|
|
||||||
.map(|r| r > 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change the password of a user
|
/// 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)
|
database::UpdateInfo::new(USERS_TABLE)
|
||||||
.cond_user_id("ID", user_id)
|
.cond_user_id("ID", user_id)
|
||||||
.set_str("password", &crypt_pass(new_password)?)
|
.set_str("password", &hash_password(new_password)?)
|
||||||
.exec()
|
.exec()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,4 +357,34 @@ pub fn delete(user_id: &UserID) -> ResultBoxError {
|
|||||||
.exec()?;
|
.exec()?;
|
||||||
|
|
||||||
Ok(())
|
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
|
/// One-way user password crypt
|
||||||
///
|
///
|
||||||
/// This method will have to be replaced by a stronger algorithm once this implementation is
|
/// This method is just transitional
|
||||||
/// completely built.
|
|
||||||
///
|
///
|
||||||
/// It currently depends on PHP
|
/// 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");
|
/// 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 hash = sha1_str(pass);
|
||||||
|
|
||||||
let result = std::process::Command::new("/usr/bin/php")
|
let result = std::process::Command::new("/usr/bin/php")
|
||||||
|
Loading…
Reference in New Issue
Block a user