1
0
mirror of https://gitlab.com/comunic/comunicapiv3 synced 2025-06-20 00:15:17 +00:00

Upgrade password system

This commit is contained in:
2021-02-13 10:52:04 +01:00
parent 6396271e9c
commit 36c096d415
4 changed files with 99 additions and 23 deletions

View File

@ -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)
}

View File

@ -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")