feat(user_roles): get user role details (#5777)

This commit is contained in:
Apoorv Dixit
2024-09-05 01:42:20 +05:30
committed by GitHub
parent 28e7a7fc5e
commit eae8d891cd
5 changed files with 275 additions and 6 deletions

View File

@ -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,