mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 04:04:43 +08:00
feat(user_roles): get user role details (#5777)
This commit is contained in:
@ -5,7 +5,7 @@ use std::{
|
||||
|
||||
use api_models::{
|
||||
payments::RedirectionResponse,
|
||||
user::{self as user_api, InviteMultipleUserResponse},
|
||||
user::{self as user_api, InviteMultipleUserResponse, NameIdUnit},
|
||||
};
|
||||
use common_enums::EntityType;
|
||||
use common_utils::{type_name, types::keymanager::Identifier};
|
||||
@ -1407,6 +1407,237 @@ pub async fn get_user_details_in_merchant_account(
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn list_user_roles_details(
|
||||
state: SessionState,
|
||||
user_from_token: auth::UserFromToken,
|
||||
request: user_api::GetUserRoleDetailsRequest,
|
||||
_req_state: ReqState,
|
||||
) -> UserResponse<Vec<user_api::GetUserRoleDetailsResponseV2>> {
|
||||
let required_user = utils::user::get_user_from_db_by_email(&state, request.email.try_into()?)
|
||||
.await
|
||||
.to_not_found_response(UserErrors::InvalidRoleOperation)?;
|
||||
|
||||
let requestor_role_info = roles::RoleInfo::from_role_id(
|
||||
&state,
|
||||
&user_from_token.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(UserErrors::InternalServerError)
|
||||
.attach_printable("Failed to fetch role info")?;
|
||||
|
||||
let user_roles_set: HashSet<_> = state
|
||||
.store
|
||||
.list_user_roles_by_user_id(ListUserRolesByUserIdPayload {
|
||||
user_id: required_user.get_user_id(),
|
||||
org_id: Some(&user_from_token.org_id),
|
||||
merchant_id: (requestor_role_info.get_entity_type() <= EntityType::Merchant)
|
||||
.then_some(&user_from_token.merchant_id),
|
||||
profile_id: (requestor_role_info.get_entity_type() <= EntityType::Profile)
|
||||
.then_some(&user_from_token.profile_id)
|
||||
.cloned()
|
||||
.flatten()
|
||||
.as_ref(),
|
||||
entity_id: None,
|
||||
version: None,
|
||||
status: None,
|
||||
limit: None,
|
||||
})
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("Failed to fetch user roles")?
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
let org_name = state
|
||||
.store
|
||||
.find_organization_by_org_id(&user_from_token.org_id)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("Org id not found")?
|
||||
.get_organization_name();
|
||||
|
||||
let org = NameIdUnit {
|
||||
id: user_from_token.org_id.clone(),
|
||||
name: org_name,
|
||||
};
|
||||
|
||||
let (merchant_ids, merchant_profile_ids) = user_roles_set.iter().try_fold(
|
||||
(Vec::new(), Vec::new()),
|
||||
|(mut merchant, mut merchant_profile), user_role| {
|
||||
let entity_type = user_role
|
||||
.get_entity_id_and_type()
|
||||
.ok_or(UserErrors::InternalServerError)
|
||||
.attach_printable("Failed to fetch entity id and type")?
|
||||
.1;
|
||||
match entity_type {
|
||||
EntityType::Merchant => {
|
||||
let merchant_id = user_role
|
||||
.merchant_id
|
||||
.clone()
|
||||
.ok_or(UserErrors::InternalServerError)
|
||||
.attach_printable(
|
||||
"Merchant id not found in user role for merchant level entity",
|
||||
)?;
|
||||
merchant.push(merchant_id)
|
||||
}
|
||||
EntityType::Profile => {
|
||||
let merchant_id = user_role
|
||||
.merchant_id
|
||||
.clone()
|
||||
.ok_or(UserErrors::InternalServerError)
|
||||
.attach_printable(
|
||||
"Merchant id not found in user role for merchant level entity",
|
||||
)?;
|
||||
let profile_id = user_role
|
||||
.profile_id
|
||||
.clone()
|
||||
.ok_or(UserErrors::InternalServerError)
|
||||
.attach_printable(
|
||||
"Profile id not found in user role for profile level entity",
|
||||
)?;
|
||||
|
||||
merchant.push(merchant_id.clone());
|
||||
merchant_profile.push((merchant_id, profile_id))
|
||||
}
|
||||
EntityType::Internal => {
|
||||
return Err(UserErrors::InvalidRoleOperationWithMessage(
|
||||
"Internal roles are not allowed for this operation".to_string(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
EntityType::Organization => (),
|
||||
};
|
||||
|
||||
Ok::<_, error_stack::Report<UserErrors>>((merchant, merchant_profile))
|
||||
},
|
||||
)?;
|
||||
|
||||
let merchant_map: HashMap<_, _> = state
|
||||
.store
|
||||
.list_multiple_merchant_accounts(&(&state).into(), merchant_ids)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("Error while listing merchant accounts")?
|
||||
.into_iter()
|
||||
.map(|merchant_account| {
|
||||
(
|
||||
merchant_account.get_id().to_owned(),
|
||||
merchant_account.merchant_name.clone(),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let key_manager_state = &(&state).into();
|
||||
|
||||
let profile_map: HashMap<_, _> =
|
||||
futures::future::try_join_all(merchant_profile_ids.iter().map(
|
||||
|merchant_profile_id| async {
|
||||
let merchant_key_store = state
|
||||
.store
|
||||
.get_merchant_key_store_by_merchant_id(
|
||||
key_manager_state,
|
||||
&merchant_profile_id.0,
|
||||
&state.store.get_master_key().to_vec().into(),
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("Failed to retrieve merchant key store by merchant_id")?;
|
||||
|
||||
state
|
||||
.store
|
||||
.find_business_profile_by_profile_id(
|
||||
key_manager_state,
|
||||
&merchant_key_store,
|
||||
&merchant_profile_id.1,
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("Failed to retrieve business profile")
|
||||
},
|
||||
))
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("Failed to construct proifle map")?
|
||||
.into_iter()
|
||||
.map(|profile| (profile.get_id().to_owned(), profile.profile_name))
|
||||
.collect();
|
||||
|
||||
let role_details_list: Vec<_> = user_roles_set
|
||||
.iter()
|
||||
.map(|user_role| {
|
||||
let entity_type = user_role
|
||||
.get_entity_id_and_type()
|
||||
.ok_or(UserErrors::InternalServerError)?
|
||||
.1;
|
||||
let (merchant, profile) = match entity_type {
|
||||
EntityType::Internal => {
|
||||
return Err(UserErrors::InvalidRoleOperationWithMessage(
|
||||
"Internal roles are not allowed for this operation".to_string(),
|
||||
));
|
||||
}
|
||||
EntityType::Organization => (None, None),
|
||||
EntityType::Merchant => {
|
||||
let merchant_id = &user_role
|
||||
.merchant_id
|
||||
.clone()
|
||||
.ok_or(UserErrors::InternalServerError)?;
|
||||
|
||||
(
|
||||
Some(NameIdUnit {
|
||||
id: merchant_id.clone(),
|
||||
name: merchant_map
|
||||
.get(merchant_id)
|
||||
.ok_or(UserErrors::InternalServerError)?
|
||||
.to_owned(),
|
||||
}),
|
||||
None,
|
||||
)
|
||||
}
|
||||
EntityType::Profile => {
|
||||
let merchant_id = &user_role
|
||||
.merchant_id
|
||||
.clone()
|
||||
.ok_or(UserErrors::InternalServerError)?;
|
||||
let profile_id = &user_role
|
||||
.profile_id
|
||||
.clone()
|
||||
.ok_or(UserErrors::InternalServerError)?;
|
||||
|
||||
(
|
||||
Some(NameIdUnit {
|
||||
id: merchant_id.clone(),
|
||||
name: merchant_map
|
||||
.get(merchant_id)
|
||||
.ok_or(UserErrors::InternalServerError)?
|
||||
.to_owned(),
|
||||
}),
|
||||
Some(NameIdUnit {
|
||||
id: profile_id.clone(),
|
||||
name: profile_map
|
||||
.get(profile_id)
|
||||
.ok_or(UserErrors::InternalServerError)?
|
||||
.to_owned(),
|
||||
}),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
Ok(user_api::GetUserRoleDetailsResponseV2 {
|
||||
role_id: user_role.role_id.clone(),
|
||||
org: org.clone(),
|
||||
merchant,
|
||||
profile,
|
||||
status: user_role.status.foreign_into(),
|
||||
entity_type,
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>, UserErrors>>()?;
|
||||
|
||||
Ok(ApplicationResponse::Json(role_details_list))
|
||||
}
|
||||
|
||||
pub async fn list_users_for_merchant_account(
|
||||
state: SessionState,
|
||||
user_from_token: auth::UserFromToken,
|
||||
|
||||
Reference in New Issue
Block a user