refactor(users): Make password nullable in users table (#4902)

This commit is contained in:
Mani Chandra
2024-06-10 18:25:22 +05:30
committed by GitHub
parent eb0101fa7d
commit e3e31f392b
7 changed files with 47 additions and 45 deletions

View File

@ -368,7 +368,7 @@ pub async fn change_password(
.update_user_by_user_id(
user.get_user_id(),
diesel_models::user::UserUpdate::PasswordUpdate {
password: Some(new_password_hash),
password: new_password_hash,
},
)
.await
@ -459,7 +459,7 @@ pub async fn rotate_password(
.update_user_by_user_id(
&user_token.user_id,
storage_user::UserUpdate::PasswordUpdate {
password: Some(hash_password),
password: hash_password,
},
)
.await
@ -510,7 +510,7 @@ pub async fn reset_password_token_only_flow(
.get_email()
.change_context(UserErrors::InternalServerError)?,
storage_user::UserUpdate::PasswordUpdate {
password: Some(hash_password),
password: hash_password,
},
)
.await
@ -548,7 +548,7 @@ pub async fn reset_password(
.get_email()
.change_context(UserErrors::InternalServerError)?,
storage_user::UserUpdate::PasswordUpdate {
password: Some(hash_password),
password: hash_password,
},
)
.await
@ -838,11 +838,9 @@ async fn handle_new_user_invitation(
Ok(InviteMultipleUserResponse {
is_email_sent,
password: if cfg!(not(feature = "email")) {
Some(new_user.get_password().get_secret())
} else {
None
},
password: new_user
.get_password()
.map(|password| password.get_secret()),
email: request.email.clone(),
error: None,
})

View File

@ -244,7 +244,7 @@ impl UserInterface for MockDb {
..user.to_owned()
},
storage::UserUpdate::PasswordUpdate { password } => storage::User {
password: password.clone().unwrap_or(user.password.clone()),
password: Some(password.clone()),
last_password_modified_at: Some(common_utils::date_time::now()),
..user.to_owned()
},
@ -299,7 +299,7 @@ impl UserInterface for MockDb {
..user.to_owned()
},
storage::UserUpdate::PasswordUpdate { password } => storage::User {
password: password.clone().unwrap_or(user.password.clone()),
password: Some(password.clone()),
last_password_modified_at: Some(common_utils::date_time::now()),
..user.to_owned()
},

View File

@ -1,8 +1,4 @@
use std::{
collections::HashSet,
ops::{self, Not},
str::FromStr,
};
use std::{collections::HashSet, ops, str::FromStr};
use api_models::{
admin as admin_api, organization as api_org, user as user_api, user_role as user_role_api,
@ -517,9 +513,8 @@ pub struct NewUser {
user_id: String,
name: UserName,
email: UserEmail,
password: UserPassword,
password: Option<UserPassword>,
new_merchant: NewUserMerchant,
is_temporary_password: bool,
}
impl NewUser {
@ -539,7 +534,7 @@ impl NewUser {
self.new_merchant.clone()
}
pub fn get_password(&self) -> UserPassword {
pub fn get_password(&self) -> Option<UserPassword> {
self.password.clone()
}
@ -623,7 +618,12 @@ impl TryFrom<NewUser> for storage_user::UserNew {
type Error = error_stack::Report<UserErrors>;
fn try_from(value: NewUser) -> UserResult<Self> {
let hashed_password = password::generate_password_hash(value.password.get_secret())?;
let hashed_password = value
.password
.as_ref()
.map(|password| password::generate_password_hash(password.get_secret()))
.transpose()?;
let now = common_utils::date_time::now();
Ok(Self {
user_id: value.get_user_id(),
@ -637,7 +637,7 @@ impl TryFrom<NewUser> for storage_user::UserNew {
totp_status: TotpStatus::NotSet,
totp_secret: None,
totp_recovery_codes: None,
last_password_modified_at: value.is_temporary_password.not().then_some(now),
last_password_modified_at: value.password.is_some().then_some(now),
})
}
}
@ -655,10 +655,9 @@ impl TryFrom<user_api::SignUpWithMerchantIdRequest> for NewUser {
Ok(Self {
name,
email,
password,
password: Some(password),
user_id,
new_merchant,
is_temporary_password: false,
})
}
}
@ -677,9 +676,8 @@ impl TryFrom<user_api::SignUpRequest> for NewUser {
user_id,
name,
email,
password,
password: Some(password),
new_merchant,
is_temporary_password: false,
})
}
}
@ -691,16 +689,14 @@ impl TryFrom<user_api::ConnectAccountRequest> for NewUser {
let user_id = uuid::Uuid::new_v4().to_string();
let email = value.email.clone().try_into()?;
let name = UserName::try_from(value.email.clone())?;
let password = UserPassword::new(password::get_temp_password())?;
let new_merchant = NewUserMerchant::try_from(value)?;
Ok(Self {
user_id,
name,
email,
password,
password: None,
new_merchant,
is_temporary_password: true,
})
}
}
@ -721,9 +717,8 @@ impl TryFrom<(user_api::CreateInternalUserRequest, String)> for NewUser {
user_id,
name,
email,
password,
password: Some(password),
new_merchant,
is_temporary_password: false,
})
}
}
@ -739,11 +734,12 @@ impl TryFrom<UserMerchantCreateRequestWithToken> for NewUser {
user_id: user.0.user_id,
name: UserName::new(user.0.name)?,
email: user.0.email.clone().try_into()?,
password: UserPassword::new_password_without_validation(user.0.password)?,
password: user
.0
.password
.map(UserPassword::new_password_without_validation)
.transpose()?,
new_merchant,
// This is true because we are not creating a user with this request. And if it is set
// to false, last_password_modified_at will be overwritten if this user is inserted.
is_temporary_password: true,
})
}
}
@ -754,7 +750,8 @@ impl TryFrom<InviteeUserRequestWithInvitedUserToken> for NewUser {
let user_id = uuid::Uuid::new_v4().to_string();
let email = value.0.email.clone().try_into()?;
let name = UserName::new(value.0.name.clone())?;
let password = UserPassword::new(password::get_temp_password())?;
let password = cfg!(not(feature = "email"))
.then_some(UserPassword::new(password::get_temp_password())?);
let new_merchant = NewUserMerchant::try_from(value)?;
Ok(Self {
@ -763,7 +760,6 @@ impl TryFrom<InviteeUserRequestWithInvitedUserToken> for NewUser {
email,
password,
new_merchant,
is_temporary_password: true,
})
}
}
@ -783,10 +779,14 @@ impl UserFromStorage {
}
pub fn compare_password(&self, candidate: &Secret<String>) -> UserResult<()> {
match password::is_correct_password(candidate, &self.0.password) {
Ok(true) => Ok(()),
Ok(false) => Err(UserErrors::InvalidCredentials.into()),
Err(e) => Err(e),
if let Some(password) = self.0.password.as_ref() {
match password::is_correct_password(candidate, password) {
Ok(true) => Ok(()),
Ok(false) => Err(UserErrors::InvalidCredentials.into()),
Err(e) => Err(e),
}
} else {
Err(UserErrors::InvalidCredentials.into())
}
}