feat(users): invite user without email (#3328)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
Rachit Naithani
2024-01-11 17:26:31 +05:30
committed by GitHub
parent ed07c5ba90
commit 6a4706323c
5 changed files with 38 additions and 25 deletions

View File

@ -86,6 +86,7 @@ pub struct InviteUserRequest {
#[derive(Debug, serde::Serialize)] #[derive(Debug, serde::Serialize)]
pub struct InviteUserResponse { pub struct InviteUserResponse {
pub is_email_sent: bool, pub is_email_sent: bool,
pub password: Option<Secret<String>>,
} }
#[derive(Debug, serde::Deserialize, serde::Serialize)] #[derive(Debug, serde::Deserialize, serde::Serialize)]

View File

@ -1,7 +1,5 @@
use api_models::user as user_api; use api_models::user as user_api;
#[cfg(feature = "email")] use diesel_models::{enums::UserStatus, user as storage_user, user_role::UserRoleNew};
use diesel_models::user_role::UserRoleNew;
use diesel_models::{enums::UserStatus, user as storage_user};
#[cfg(feature = "email")] #[cfg(feature = "email")]
use error_stack::IntoReport; use error_stack::IntoReport;
use error_stack::ResultExt; use error_stack::ResultExt;
@ -342,7 +340,6 @@ pub async fn reset_password(
Ok(ApplicationResponse::StatusOk) Ok(ApplicationResponse::StatusOk)
} }
#[cfg(feature = "email")]
pub async fn invite_user( pub async fn invite_user(
state: AppState, state: AppState,
request: user_api::InviteUserRequest, request: user_api::InviteUserRequest,
@ -395,6 +392,7 @@ pub async fn invite_user(
Ok(ApplicationResponse::Json(user_api::InviteUserResponse { Ok(ApplicationResponse::Json(user_api::InviteUserResponse {
is_email_sent: false, is_email_sent: false,
password: None,
})) }))
} else if invitee_user } else if invitee_user
.as_ref() .as_ref()
@ -432,25 +430,37 @@ pub async fn invite_user(
} }
})?; })?;
let email_contents = email_types::InviteUser { let is_email_sent;
recipient_email: invitee_email, #[cfg(feature = "email")]
user_name: domain::UserName::new(new_user.get_name())?, {
settings: state.conf.clone(), let email_contents = email_types::InviteUser {
subject: "You have been invited to join Hyperswitch Community!", recipient_email: invitee_email,
}; user_name: domain::UserName::new(new_user.get_name())?,
settings: state.conf.clone(),
let send_email_result = state subject: "You have been invited to join Hyperswitch Community!",
.email_client };
.compose_and_send_email( let send_email_result = state
Box::new(email_contents), .email_client
state.conf.proxy.https_url.as_ref(), .compose_and_send_email(
) Box::new(email_contents),
.await; state.conf.proxy.https_url.as_ref(),
)
logger::info!(?send_email_result); .await;
logger::info!(?send_email_result);
is_email_sent = send_email_result.is_ok();
}
#[cfg(not(feature = "email"))]
{
is_email_sent = false;
}
Ok(ApplicationResponse::Json(user_api::InviteUserResponse { Ok(ApplicationResponse::Json(user_api::InviteUserResponse {
is_email_sent: send_email_result.is_ok(), is_email_sent,
password: if cfg!(not(feature = "email")) {
Some(new_user.get_password().get_secret())
} else {
None
},
})) }))
} else { } else {
Err(UserErrors::InternalServerError.into()) Err(UserErrors::InternalServerError.into())

View File

@ -879,6 +879,7 @@ impl User {
.service(web::resource("/user/update_role").route(web::post().to(update_user_role))) .service(web::resource("/user/update_role").route(web::post().to(update_user_role)))
.service(web::resource("/role/list").route(web::get().to(list_roles))) .service(web::resource("/role/list").route(web::get().to(list_roles)))
.service(web::resource("/role/{role_id}").route(web::get().to(get_role))) .service(web::resource("/role/{role_id}").route(web::get().to(get_role)))
.service(web::resource("/user/invite").route(web::post().to(invite_user)))
.service( .service(
web::resource("/data") web::resource("/data")
.route(web::get().to(get_multiple_dashboard_metadata)) .route(web::get().to(get_multiple_dashboard_metadata))
@ -901,7 +902,6 @@ impl User {
) )
.service(web::resource("/forgot_password").route(web::post().to(forgot_password))) .service(web::resource("/forgot_password").route(web::post().to(forgot_password)))
.service(web::resource("/reset_password").route(web::post().to(reset_password))) .service(web::resource("/reset_password").route(web::post().to(reset_password)))
.service(web::resource("/user/invite").route(web::post().to(invite_user)))
.service( .service(
web::resource("/signup_with_merchant_id") web::resource("/signup_with_merchant_id")
.route(web::post().to(user_signup_with_merchant_id)), .route(web::post().to(user_signup_with_merchant_id)),

View File

@ -333,7 +333,6 @@ pub async fn reset_password(
.await .await
} }
#[cfg(feature = "email")]
pub async fn invite_user( pub async fn invite_user(
state: web::Data<AppState>, state: web::Data<AppState>,
req: HttpRequest, req: HttpRequest,

View File

@ -489,6 +489,10 @@ impl NewUser {
self.new_merchant.clone() self.new_merchant.clone()
} }
pub fn get_password(&self) -> UserPassword {
self.password.clone()
}
pub async fn insert_user_in_db( pub async fn insert_user_in_db(
&self, &self,
db: &dyn StorageInterface, db: &dyn StorageInterface,
@ -683,8 +687,7 @@ impl TryFrom<InviteeUserRequestWithInvitedUserToken> for NewUser {
let user_id = uuid::Uuid::new_v4().to_string(); let user_id = uuid::Uuid::new_v4().to_string();
let email = value.0.email.clone().try_into()?; let email = value.0.email.clone().try_into()?;
let name = UserName::new(value.0.name.clone())?; let name = UserName::new(value.0.name.clone())?;
let password = password::generate_password_hash(uuid::Uuid::new_v4().to_string().into())?; let password = UserPassword::new(uuid::Uuid::new_v4().to_string().into())?;
let password = UserPassword::new(password)?;
let new_merchant = NewUserMerchant::try_from(value)?; let new_merchant = NewUserMerchant::try_from(value)?;
Ok(Self { Ok(Self {