mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 21:07:58 +08:00
feat(user_role): Add update by lineage DB function (#5651)
This commit is contained in:
@ -594,19 +594,58 @@ pub async fn reset_password(
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
if let Some(inviter_merchant_id) = email_token.get_merchant_id() {
|
||||
let update_status_result = state
|
||||
let key_manager_state = &(&state).into();
|
||||
|
||||
let key_store = state
|
||||
.store
|
||||
.update_user_role_by_user_id_merchant_id(
|
||||
user.user_id.clone().as_str(),
|
||||
.get_merchant_key_store_by_merchant_id(
|
||||
key_manager_state,
|
||||
inviter_merchant_id,
|
||||
&state.store.get_master_key().to_vec().into(),
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("merchant_key_store not found")?;
|
||||
|
||||
let merchant_account = state
|
||||
.store
|
||||
.find_merchant_account_by_merchant_id(
|
||||
key_manager_state,
|
||||
inviter_merchant_id,
|
||||
&key_store,
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("merchant_account not found")?;
|
||||
|
||||
let (update_v1_result, update_v2_result) =
|
||||
utils::user_role::update_v1_and_v2_user_roles_in_db(
|
||||
&state,
|
||||
user.user_id.clone().as_str(),
|
||||
&merchant_account.organization_id,
|
||||
inviter_merchant_id,
|
||||
None,
|
||||
UserRoleUpdate::UpdateStatus {
|
||||
status: UserStatus::Active,
|
||||
modified_by: user.user_id.clone(),
|
||||
},
|
||||
UserRoleVersion::V1,
|
||||
)
|
||||
.await;
|
||||
logger::info!(?update_status_result);
|
||||
|
||||
if update_v1_result
|
||||
.as_ref()
|
||||
.is_err_and(|err| !err.current_context().is_db_not_found())
|
||||
|| update_v2_result
|
||||
.as_ref()
|
||||
.is_err_and(|err| !err.current_context().is_db_not_found())
|
||||
{
|
||||
return Err(report!(UserErrors::InternalServerError));
|
||||
}
|
||||
|
||||
if update_v1_result.is_err() && update_v2_result.is_err() {
|
||||
return Err(report!(UserErrors::InvalidRoleOperation))
|
||||
.attach_printable("User not found in the organization")?;
|
||||
}
|
||||
}
|
||||
|
||||
let _ = auth::blacklist::insert_email_token_in_blacklist(&state, &token)
|
||||
@ -1014,19 +1053,53 @@ pub async fn accept_invite_from_email(
|
||||
.get_merchant_id()
|
||||
.ok_or(UserErrors::InternalServerError)?;
|
||||
|
||||
let update_status_result = state
|
||||
let key_manager_state = &(&state).into();
|
||||
|
||||
let key_store = state
|
||||
.store
|
||||
.update_user_role_by_user_id_merchant_id(
|
||||
user.get_user_id(),
|
||||
.get_merchant_key_store_by_merchant_id(
|
||||
key_manager_state,
|
||||
merchant_id,
|
||||
UserRoleUpdate::UpdateStatus {
|
||||
status: UserStatus::Active,
|
||||
modified_by: user.get_user_id().to_string(),
|
||||
},
|
||||
UserRoleVersion::V1,
|
||||
&state.store.get_master_key().to_vec().into(),
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("merchant_key_store not found")?;
|
||||
|
||||
let merchant_account = state
|
||||
.store
|
||||
.find_merchant_account_by_merchant_id(key_manager_state, merchant_id, &key_store)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("merchant_account not found")?;
|
||||
|
||||
let (update_v1_result, update_v2_result) = utils::user_role::update_v1_and_v2_user_roles_in_db(
|
||||
&state,
|
||||
user.get_user_id(),
|
||||
&merchant_account.organization_id,
|
||||
merchant_id,
|
||||
None,
|
||||
UserRoleUpdate::UpdateStatus {
|
||||
status: UserStatus::Active,
|
||||
modified_by: user.get_user_id().to_string(),
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
if update_v1_result
|
||||
.as_ref()
|
||||
.is_err_and(|err| !err.current_context().is_db_not_found())
|
||||
|| update_v2_result
|
||||
.as_ref()
|
||||
.is_err_and(|err| !err.current_context().is_db_not_found())
|
||||
{
|
||||
return Err(report!(UserErrors::InternalServerError));
|
||||
}
|
||||
|
||||
if update_v1_result.is_err() && update_v2_result.is_err() {
|
||||
return Err(report!(UserErrors::InvalidRoleOperation))
|
||||
.attach_printable("User not found in the organization")?;
|
||||
}
|
||||
|
||||
let _ = auth::blacklist::insert_email_token_in_blacklist(&state, &token)
|
||||
.await
|
||||
@ -1039,21 +1112,18 @@ pub async fn accept_invite_from_email(
|
||||
.change_context(UserErrors::InternalServerError)?
|
||||
.into();
|
||||
|
||||
let token = utils::user::generate_jwt_auth_token_without_profile(
|
||||
&state,
|
||||
&user_from_db,
|
||||
&update_status_result,
|
||||
)
|
||||
.await?;
|
||||
utils::user_role::set_role_permissions_in_cache_by_user_role(&state, &update_status_result)
|
||||
.await;
|
||||
let user_role = user_from_db
|
||||
.get_preferred_or_active_user_role_from_db(&state)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
let response = utils::user::get_dashboard_entry_response(
|
||||
&state,
|
||||
user_from_db,
|
||||
update_status_result,
|
||||
token.clone(),
|
||||
)?;
|
||||
let token =
|
||||
utils::user::generate_jwt_auth_token_without_profile(&state, &user_from_db, &user_role)
|
||||
.await?;
|
||||
utils::user_role::set_role_permissions_in_cache_by_user_role(&state, &user_role).await;
|
||||
|
||||
let response =
|
||||
utils::user::get_dashboard_entry_response(&state, user_from_db, user_role, token.clone())?;
|
||||
|
||||
auth::cookies::set_cookie_response(response, token)
|
||||
}
|
||||
@ -1091,19 +1161,53 @@ pub async fn accept_invite_from_email_token_only_flow(
|
||||
.get_merchant_id()
|
||||
.ok_or(UserErrors::LinkInvalid)?;
|
||||
|
||||
let user_role = state
|
||||
let key_manager_state = &(&state).into();
|
||||
|
||||
let key_store = state
|
||||
.store
|
||||
.update_user_role_by_user_id_merchant_id(
|
||||
user_from_db.get_user_id(),
|
||||
.get_merchant_key_store_by_merchant_id(
|
||||
key_manager_state,
|
||||
merchant_id,
|
||||
UserRoleUpdate::UpdateStatus {
|
||||
status: UserStatus::Active,
|
||||
modified_by: user_from_db.get_user_id().to_string(),
|
||||
},
|
||||
UserRoleVersion::V1,
|
||||
&state.store.get_master_key().to_vec().into(),
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("merchant_key_store not found")?;
|
||||
|
||||
let merchant_account = state
|
||||
.store
|
||||
.find_merchant_account_by_merchant_id(key_manager_state, merchant_id, &key_store)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("merchant_account not found")?;
|
||||
|
||||
let (update_v1_result, update_v2_result) = utils::user_role::update_v1_and_v2_user_roles_in_db(
|
||||
&state,
|
||||
user_from_db.get_user_id(),
|
||||
&merchant_account.organization_id,
|
||||
merchant_id,
|
||||
None,
|
||||
UserRoleUpdate::UpdateStatus {
|
||||
status: UserStatus::Active,
|
||||
modified_by: user_from_db.get_user_id().to_owned(),
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
if update_v1_result
|
||||
.as_ref()
|
||||
.is_err_and(|err| !err.current_context().is_db_not_found())
|
||||
|| update_v2_result
|
||||
.as_ref()
|
||||
.is_err_and(|err| !err.current_context().is_db_not_found())
|
||||
{
|
||||
return Err(report!(UserErrors::InternalServerError));
|
||||
}
|
||||
|
||||
if update_v1_result.is_err() && update_v2_result.is_err() {
|
||||
return Err(report!(UserErrors::InvalidRoleOperation))
|
||||
.attach_printable("User not found in the organization")?;
|
||||
}
|
||||
|
||||
if !user_from_db.is_verified() {
|
||||
let _ = state
|
||||
@ -1126,6 +1230,11 @@ pub async fn accept_invite_from_email_token_only_flow(
|
||||
)?;
|
||||
let next_flow = current_flow.next(user_from_db.clone(), &state).await?;
|
||||
|
||||
let user_role = user_from_db
|
||||
.get_preferred_or_active_user_role_from_db(&state)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
let token = next_flow
|
||||
.get_token_with_user_role(&state, &user_role)
|
||||
.await?;
|
||||
|
||||
@ -7,10 +7,8 @@ use diesel_models::{
|
||||
};
|
||||
use error_stack::{report, ResultExt};
|
||||
use once_cell::sync::Lazy;
|
||||
use router_env::logger;
|
||||
|
||||
use crate::{
|
||||
consts,
|
||||
core::errors::{StorageErrorExt, UserErrors, UserResponse},
|
||||
routes::{app::ReqState, SessionState},
|
||||
services::{
|
||||
@ -115,103 +113,155 @@ pub async fn update_user_role(
|
||||
.attach_printable("User Changing their own role");
|
||||
}
|
||||
|
||||
let user_role_to_be_updated = user_to_be_updated
|
||||
.get_role_from_db_by_merchant_id(&state, &user_from_token.merchant_id)
|
||||
.await
|
||||
.to_not_found_response(UserErrors::InvalidRoleOperation)?;
|
||||
|
||||
let role_to_be_updated = roles::RoleInfo::from_role_id(
|
||||
let updator_role = roles::RoleInfo::from_role_id(
|
||||
&state,
|
||||
&user_role_to_be_updated.role_id,
|
||||
&user_from_token.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
if !role_to_be_updated.is_updatable() {
|
||||
return Err(report!(UserErrors::InvalidRoleOperation)).attach_printable(format!(
|
||||
"User role cannot be updated from {}",
|
||||
role_to_be_updated.get_role_id()
|
||||
));
|
||||
}
|
||||
let mut is_updated = false;
|
||||
|
||||
state
|
||||
let v2_user_role_to_be_updated = match state
|
||||
.store
|
||||
.update_user_role_by_user_id_merchant_id(
|
||||
user_to_be_updated.get_user_id(),
|
||||
&user_role_to_be_updated
|
||||
.merchant_id
|
||||
.ok_or(UserErrors::InternalServerError)
|
||||
.attach_printable("merchant_id not found in user_role")?,
|
||||
UserRoleUpdate::UpdateRole {
|
||||
role_id: req.role_id.clone(),
|
||||
modified_by: user_from_token.user_id,
|
||||
},
|
||||
UserRoleVersion::V1,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(UserErrors::InvalidRoleOperation)
|
||||
.attach_printable("User with given email is not found in the organization")?;
|
||||
|
||||
auth::blacklist::insert_user_in_blacklist(&state, user_to_be_updated.get_user_id()).await?;
|
||||
|
||||
Ok(ApplicationResponse::StatusOk)
|
||||
}
|
||||
|
||||
pub async fn transfer_org_ownership(
|
||||
state: SessionState,
|
||||
user_from_token: auth::UserFromToken,
|
||||
req: user_role_api::TransferOrgOwnershipRequest,
|
||||
_req_state: ReqState,
|
||||
) -> UserResponse<user_api::DashboardEntryResponse> {
|
||||
if user_from_token.role_id != consts::user_role::ROLE_ID_ORGANIZATION_ADMIN {
|
||||
return Err(report!(UserErrors::InvalidRoleOperation)).attach_printable(format!(
|
||||
"role_id = {} is not org_admin",
|
||||
user_from_token.role_id
|
||||
));
|
||||
}
|
||||
|
||||
let user_to_be_updated =
|
||||
utils::user::get_user_from_db_by_email(&state, domain::UserEmail::try_from(req.email)?)
|
||||
.await
|
||||
.to_not_found_response(UserErrors::InvalidRoleOperation)
|
||||
.attach_printable("User not found in our records".to_string())?;
|
||||
|
||||
if user_from_token.user_id == user_to_be_updated.get_user_id() {
|
||||
return Err(report!(UserErrors::InvalidRoleOperation))
|
||||
.attach_printable("User transferring ownership to themselves".to_string());
|
||||
}
|
||||
|
||||
state
|
||||
.store
|
||||
.transfer_org_ownership_between_users(
|
||||
&user_from_token.user_id,
|
||||
.find_user_role_by_user_id_and_lineage(
|
||||
user_to_be_updated.get_user_id(),
|
||||
&user_from_token.org_id,
|
||||
UserRoleVersion::V1,
|
||||
&user_from_token.merchant_id,
|
||||
None,
|
||||
UserRoleVersion::V2,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(user_role) => Some(user_role),
|
||||
Err(e) => {
|
||||
if e.current_context().is_db_not_found() {
|
||||
None
|
||||
} else {
|
||||
return Err(UserErrors::InternalServerError.into());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(user_role) = v2_user_role_to_be_updated {
|
||||
let role_to_be_updated = roles::RoleInfo::from_role_id(
|
||||
&state,
|
||||
&user_role.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
auth::blacklist::insert_user_in_blacklist(&state, user_to_be_updated.get_user_id()).await?;
|
||||
auth::blacklist::insert_user_in_blacklist(&state, &user_from_token.user_id).await?;
|
||||
if !role_to_be_updated.is_updatable() {
|
||||
return Err(report!(UserErrors::InvalidRoleOperation)).attach_printable(format!(
|
||||
"User role cannot be updated from {}",
|
||||
role_to_be_updated.get_role_id()
|
||||
));
|
||||
}
|
||||
|
||||
let user_from_db = user_from_token.get_user_from_db(&state).await?;
|
||||
let user_role = user_from_db
|
||||
.get_role_from_db_by_merchant_id(&state, &user_from_token.merchant_id)
|
||||
if updator_role.get_entity_type() < role_to_be_updated.get_entity_type() {
|
||||
return Err(report!(UserErrors::InvalidRoleOperation)).attach_printable(format!(
|
||||
"Invalid operation, update requestor = {} cannot update target = {}",
|
||||
updator_role.get_entity_type(),
|
||||
role_to_be_updated.get_entity_type()
|
||||
));
|
||||
}
|
||||
|
||||
state
|
||||
.store
|
||||
.update_user_role_by_user_id_and_lineage(
|
||||
user_to_be_updated.get_user_id(),
|
||||
&user_from_token.org_id,
|
||||
&user_from_token.merchant_id,
|
||||
None,
|
||||
UserRoleUpdate::UpdateRole {
|
||||
role_id: req.role_id.clone(),
|
||||
modified_by: user_from_token.user_id.clone(),
|
||||
},
|
||||
UserRoleVersion::V2,
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
is_updated = true;
|
||||
}
|
||||
|
||||
let v1_user_role_to_be_updated = match state
|
||||
.store
|
||||
.find_user_role_by_user_id_and_lineage(
|
||||
user_to_be_updated.get_user_id(),
|
||||
&user_from_token.org_id,
|
||||
&user_from_token.merchant_id,
|
||||
None,
|
||||
UserRoleVersion::V1,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(UserErrors::InvalidRoleOperation)?;
|
||||
{
|
||||
Ok(user_role) => Some(user_role),
|
||||
Err(e) => {
|
||||
if e.current_context().is_db_not_found() {
|
||||
None
|
||||
} else {
|
||||
return Err(UserErrors::InternalServerError.into());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
utils::user_role::set_role_permissions_in_cache_by_user_role(&state, &user_role).await;
|
||||
if let Some(user_role) = v1_user_role_to_be_updated {
|
||||
let role_to_be_updated = roles::RoleInfo::from_role_id(
|
||||
&state,
|
||||
&user_role.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
let token =
|
||||
utils::user::generate_jwt_auth_token_without_profile(&state, &user_from_db, &user_role)
|
||||
.await?;
|
||||
let response =
|
||||
utils::user::get_dashboard_entry_response(&state, user_from_db, user_role, token.clone())?;
|
||||
if !role_to_be_updated.is_updatable() {
|
||||
return Err(report!(UserErrors::InvalidRoleOperation)).attach_printable(format!(
|
||||
"User role cannot be updated from {}",
|
||||
role_to_be_updated.get_role_id()
|
||||
));
|
||||
}
|
||||
|
||||
auth::cookies::set_cookie_response(response, token)
|
||||
if updator_role.get_entity_type() < role_to_be_updated.get_entity_type() {
|
||||
return Err(report!(UserErrors::InvalidRoleOperation)).attach_printable(format!(
|
||||
"Invalid operation, update requestor = {} cannot update target = {}",
|
||||
updator_role.get_entity_type(),
|
||||
role_to_be_updated.get_entity_type()
|
||||
));
|
||||
}
|
||||
|
||||
state
|
||||
.store
|
||||
.update_user_role_by_user_id_and_lineage(
|
||||
user_to_be_updated.get_user_id(),
|
||||
&user_from_token.org_id,
|
||||
&user_from_token.merchant_id,
|
||||
None,
|
||||
UserRoleUpdate::UpdateRole {
|
||||
role_id: req.role_id.clone(),
|
||||
modified_by: user_from_token.user_id,
|
||||
},
|
||||
UserRoleVersion::V1,
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
is_updated = true;
|
||||
}
|
||||
|
||||
if !is_updated {
|
||||
return Err(report!(UserErrors::InvalidRoleOperation))
|
||||
.attach_printable("User with given email is not found in the organization")?;
|
||||
}
|
||||
|
||||
auth::blacklist::insert_user_in_blacklist(&state, user_to_be_updated.get_user_id()).await?;
|
||||
|
||||
Ok(ApplicationResponse::StatusOk)
|
||||
}
|
||||
|
||||
pub async fn accept_invitation(
|
||||
@ -219,30 +269,43 @@ pub async fn accept_invitation(
|
||||
user_token: auth::UserFromToken,
|
||||
req: user_role_api::AcceptInvitationRequest,
|
||||
) -> UserResponse<()> {
|
||||
futures::future::join_all(req.merchant_ids.iter().map(|merchant_id| async {
|
||||
state
|
||||
.store
|
||||
.update_user_role_by_user_id_merchant_id(
|
||||
user_token.user_id.as_str(),
|
||||
merchant_id,
|
||||
UserRoleUpdate::UpdateStatus {
|
||||
status: UserStatus::Active,
|
||||
modified_by: user_token.user_id.clone(),
|
||||
},
|
||||
UserRoleVersion::V1,
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
logger::error!("Error while accepting invitation {e:?}");
|
||||
})
|
||||
.ok()
|
||||
}))
|
||||
.await
|
||||
.into_iter()
|
||||
.reduce(Option::or)
|
||||
.flatten()
|
||||
.ok_or(UserErrors::MerchantIdNotFound.into())
|
||||
.map(|_| ApplicationResponse::StatusOk)
|
||||
let merchant_accounts = state
|
||||
.store
|
||||
.list_multiple_merchant_accounts(&(&state).into(), req.merchant_ids)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
let update_result =
|
||||
futures::future::join_all(merchant_accounts.iter().map(|merchant_account| async {
|
||||
let (update_v1_result, update_v2_result) =
|
||||
utils::user_role::update_v1_and_v2_user_roles_in_db(
|
||||
&state,
|
||||
user_token.user_id.as_str(),
|
||||
&merchant_account.organization_id,
|
||||
merchant_account.get_id(),
|
||||
None,
|
||||
UserRoleUpdate::UpdateStatus {
|
||||
status: UserStatus::Active,
|
||||
modified_by: user_token.user_id.clone(),
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
if update_v1_result.is_err_and(|err| !err.current_context().is_db_not_found())
|
||||
|| update_v2_result.is_err_and(|err| !err.current_context().is_db_not_found())
|
||||
{
|
||||
Err(report!(UserErrors::InternalServerError))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}))
|
||||
.await;
|
||||
|
||||
if update_result.iter().all(Result::is_err) {
|
||||
return Err(UserErrors::MerchantIdNotFound.into());
|
||||
}
|
||||
|
||||
Ok(ApplicationResponse::StatusOk)
|
||||
}
|
||||
|
||||
pub async fn merchant_select(
|
||||
@ -250,38 +313,55 @@ pub async fn merchant_select(
|
||||
user_token: auth::UserFromSinglePurposeToken,
|
||||
req: user_role_api::MerchantSelectRequest,
|
||||
) -> UserResponse<user_api::TokenOrPayloadResponse<user_api::DashboardEntryResponse>> {
|
||||
let user_role = futures::future::join_all(req.merchant_ids.iter().map(|merchant_id| async {
|
||||
state
|
||||
.store
|
||||
.update_user_role_by_user_id_merchant_id(
|
||||
user_token.user_id.as_str(),
|
||||
merchant_id,
|
||||
UserRoleUpdate::UpdateStatus {
|
||||
status: UserStatus::Active,
|
||||
modified_by: user_token.user_id.clone(),
|
||||
},
|
||||
UserRoleVersion::V1,
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
logger::error!("Error while accepting invitation {e:?}");
|
||||
})
|
||||
.ok()
|
||||
}))
|
||||
.await
|
||||
.into_iter()
|
||||
.reduce(Option::or)
|
||||
.flatten()
|
||||
.ok_or(UserErrors::MerchantIdNotFound)?;
|
||||
let merchant_accounts = state
|
||||
.store
|
||||
.list_multiple_merchant_accounts(&(&state).into(), req.merchant_ids)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
let update_result =
|
||||
futures::future::join_all(merchant_accounts.iter().map(|merchant_account| async {
|
||||
let (update_v1_result, update_v2_result) =
|
||||
utils::user_role::update_v1_and_v2_user_roles_in_db(
|
||||
&state,
|
||||
user_token.user_id.as_str(),
|
||||
&merchant_account.organization_id,
|
||||
merchant_account.get_id(),
|
||||
None,
|
||||
UserRoleUpdate::UpdateStatus {
|
||||
status: UserStatus::Active,
|
||||
modified_by: user_token.user_id.clone(),
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
if update_v1_result.is_err_and(|err| !err.current_context().is_db_not_found())
|
||||
|| update_v2_result.is_err_and(|err| !err.current_context().is_db_not_found())
|
||||
{
|
||||
Err(report!(UserErrors::InternalServerError))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}))
|
||||
.await;
|
||||
|
||||
if update_result.iter().all(Result::is_err) {
|
||||
return Err(UserErrors::MerchantIdNotFound.into());
|
||||
}
|
||||
|
||||
if let Some(true) = req.need_dashboard_entry_response {
|
||||
let user_from_db = state
|
||||
let user_from_db: domain::UserFromStorage = state
|
||||
.global_store
|
||||
.find_user_by_id(user_token.user_id.as_str())
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?
|
||||
.into();
|
||||
|
||||
let user_role = user_from_db
|
||||
.get_preferred_or_active_user_role_from_db(&state)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
utils::user_role::set_role_permissions_in_cache_by_user_role(&state, &user_role).await;
|
||||
|
||||
let token =
|
||||
@ -307,29 +387,41 @@ pub async fn merchant_select_token_only_flow(
|
||||
user_token: auth::UserFromSinglePurposeToken,
|
||||
req: user_role_api::MerchantSelectRequest,
|
||||
) -> UserResponse<user_api::TokenOrPayloadResponse<user_api::DashboardEntryResponse>> {
|
||||
let user_role = futures::future::join_all(req.merchant_ids.iter().map(|merchant_id| async {
|
||||
state
|
||||
.store
|
||||
.update_user_role_by_user_id_merchant_id(
|
||||
user_token.user_id.as_str(),
|
||||
merchant_id,
|
||||
UserRoleUpdate::UpdateStatus {
|
||||
status: UserStatus::Active,
|
||||
modified_by: user_token.user_id.clone(),
|
||||
},
|
||||
UserRoleVersion::V1,
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
logger::error!("Error while accepting invitation {e:?}");
|
||||
})
|
||||
.ok()
|
||||
}))
|
||||
.await
|
||||
.into_iter()
|
||||
.reduce(Option::or)
|
||||
.flatten()
|
||||
.ok_or(UserErrors::MerchantIdNotFound)?;
|
||||
let merchant_accounts = state
|
||||
.store
|
||||
.list_multiple_merchant_accounts(&(&state).into(), req.merchant_ids)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
let update_result =
|
||||
futures::future::join_all(merchant_accounts.iter().map(|merchant_account| async {
|
||||
let (update_v1_result, update_v2_result) =
|
||||
utils::user_role::update_v1_and_v2_user_roles_in_db(
|
||||
&state,
|
||||
user_token.user_id.as_str(),
|
||||
&merchant_account.organization_id,
|
||||
merchant_account.get_id(),
|
||||
None,
|
||||
UserRoleUpdate::UpdateStatus {
|
||||
status: UserStatus::Active,
|
||||
modified_by: user_token.user_id.clone(),
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
if update_v1_result.is_err_and(|err| !err.current_context().is_db_not_found())
|
||||
|| update_v2_result.is_err_and(|err| !err.current_context().is_db_not_found())
|
||||
{
|
||||
Err(report!(UserErrors::InternalServerError))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}))
|
||||
.await;
|
||||
|
||||
if update_result.iter().all(Result::is_err) {
|
||||
return Err(UserErrors::MerchantIdNotFound.into());
|
||||
}
|
||||
|
||||
let user_from_db: domain::UserFromStorage = state
|
||||
.global_store
|
||||
@ -338,6 +430,11 @@ pub async fn merchant_select_token_only_flow(
|
||||
.change_context(UserErrors::InternalServerError)?
|
||||
.into();
|
||||
|
||||
let user_role = user_from_db
|
||||
.get_preferred_or_active_user_role_from_db(&state)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
let current_flow =
|
||||
domain::CurrentFlow::new(user_token, domain::SPTFlow::MerchantSelect.into())?;
|
||||
let next_flow = current_flow.next(user_from_db.clone(), &state).await?;
|
||||
|
||||
Reference in New Issue
Block a user