mirror of
https://gitlab.com/comunic/comunicapiv3
synced 2025-06-20 00:15:17 +00:00
Upgrade password system
This commit is contained in:
@ -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