mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 09:38:33 +08:00
fix(users): remove internal entity type for users (#6013)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -3144,7 +3144,6 @@ pub enum ApiVersion {
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum EntityType {
|
||||
Internal = 3,
|
||||
Organization = 2,
|
||||
Merchant = 1,
|
||||
Profile = 0,
|
||||
|
||||
@ -33,11 +33,6 @@ impl UserRole {
|
||||
let org_id = self.org_id.clone()?.get_string_repr().to_string();
|
||||
Some((org_id, EntityType::Organization))
|
||||
}
|
||||
(enums::UserRoleVersion::V1, consts::ROLE_ID_INTERNAL_VIEW_ONLY_USER)
|
||||
| (enums::UserRoleVersion::V1, consts::ROLE_ID_INTERNAL_ADMIN) => {
|
||||
let merchant_id = self.merchant_id.clone()?.get_string_repr().to_string();
|
||||
Some((merchant_id, EntityType::Internal))
|
||||
}
|
||||
(enums::UserRoleVersion::V1, _) => {
|
||||
let merchant_id = self.merchant_id.clone()?.get_string_repr().to_string();
|
||||
Some((merchant_id, EntityType::Merchant))
|
||||
|
||||
@ -650,7 +650,6 @@ async fn handle_existing_user_invitation(
|
||||
};
|
||||
|
||||
let _user_role = match role_info.get_entity_type() {
|
||||
EntityType::Internal => return Err(UserErrors::InvalidRoleId.into()),
|
||||
EntityType::Organization => return Err(UserErrors::InvalidRoleId.into()),
|
||||
EntityType::Merchant => {
|
||||
user_role
|
||||
@ -682,7 +681,6 @@ async fn handle_existing_user_invitation(
|
||||
{
|
||||
let invitee_email = domain::UserEmail::from_pii_email(request.email.clone())?;
|
||||
let entity = match role_info.get_entity_type() {
|
||||
EntityType::Internal => return Err(UserErrors::InvalidRoleId.into()),
|
||||
EntityType::Organization => return Err(UserErrors::InvalidRoleId.into()),
|
||||
EntityType::Merchant => email_types::Entity {
|
||||
entity_id: user_from_token.merchant_id.get_string_repr().to_owned(),
|
||||
@ -769,7 +767,6 @@ async fn handle_new_user_invitation(
|
||||
};
|
||||
|
||||
let _user_role = match role_info.get_entity_type() {
|
||||
EntityType::Internal => return Err(UserErrors::InvalidRoleId.into()),
|
||||
EntityType::Organization => return Err(UserErrors::InvalidRoleId.into()),
|
||||
EntityType::Merchant => {
|
||||
user_role
|
||||
@ -805,7 +802,6 @@ async fn handle_new_user_invitation(
|
||||
let _ = req_state.clone();
|
||||
let invitee_email = domain::UserEmail::from_pii_email(request.email.clone())?;
|
||||
let entity = match role_info.get_entity_type() {
|
||||
EntityType::Internal => return Err(UserErrors::InvalidRoleId.into()),
|
||||
EntityType::Organization => return Err(UserErrors::InvalidRoleId.into()),
|
||||
EntityType::Merchant => email_types::Entity {
|
||||
entity_id: user_from_token.merchant_id.get_string_repr().to_owned(),
|
||||
@ -1089,15 +1085,13 @@ pub async fn create_internal_user(
|
||||
}
|
||||
})?;
|
||||
|
||||
let internal_merchant_id = common_utils::id_type::MerchantId::get_internal_user_merchant_id(
|
||||
consts::user_role::INTERNAL_USER_MERCHANT_ID,
|
||||
);
|
||||
|
||||
let internal_merchant = state
|
||||
.store
|
||||
.find_merchant_account_by_merchant_id(
|
||||
key_manager_state,
|
||||
&common_utils::id_type::MerchantId::get_internal_user_merchant_id(
|
||||
consts::user_role::INTERNAL_USER_MERCHANT_ID,
|
||||
),
|
||||
&key_store,
|
||||
)
|
||||
.find_merchant_account_by_merchant_id(key_manager_state, &internal_merchant_id, &key_store)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
if e.current_context().is_db_not_found() {
|
||||
@ -1130,8 +1124,9 @@ pub async fn create_internal_user(
|
||||
common_utils::consts::ROLE_ID_INTERNAL_VIEW_ONLY_USER.to_string(),
|
||||
UserStatus::Active,
|
||||
)
|
||||
.add_entity(domain::InternalLevel {
|
||||
.add_entity(domain::MerchantLevel {
|
||||
org_id: internal_merchant.organization_id,
|
||||
merchant_id: internal_merchant_id,
|
||||
})
|
||||
.insert_in_v1_and_v2(&state)
|
||||
.await
|
||||
@ -1443,6 +1438,13 @@ pub async fn list_user_roles_details(
|
||||
.to_not_found_response(UserErrors::InternalServerError)
|
||||
.attach_printable("Failed to fetch role info")?;
|
||||
|
||||
if requestor_role_info.is_internal() {
|
||||
return Err(UserErrors::InvalidRoleOperationWithMessage(
|
||||
"Internal roles are not allowed for this operation".to_string(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
let user_roles_set = state
|
||||
.store
|
||||
.list_user_roles_by_user_id(ListUserRolesByUserIdPayload {
|
||||
@ -1517,12 +1519,6 @@ pub async fn list_user_roles_details(
|
||||
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 => (),
|
||||
};
|
||||
|
||||
@ -1609,11 +1605,6 @@ pub async fn list_user_roles_details(
|
||||
.ok_or(UserErrors::InternalServerError)?;
|
||||
|
||||
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
|
||||
@ -2623,9 +2614,14 @@ pub async fn list_orgs_for_user(
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
let orgs = match role_info.get_entity_type() {
|
||||
EntityType::Internal => return Err(UserErrors::InvalidRoleOperation.into()),
|
||||
EntityType::Organization | EntityType::Merchant | EntityType::Profile => state
|
||||
if role_info.is_internal() {
|
||||
return Err(UserErrors::InvalidRoleOperationWithMessage(
|
||||
"Internal roles are not allowed for this operation".to_string(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
let orgs = state
|
||||
.store
|
||||
.list_user_roles_by_user_id(ListUserRolesByUserIdPayload {
|
||||
user_id: user_from_token.user_id.as_str(),
|
||||
@ -2641,8 +2637,7 @@ pub async fn list_orgs_for_user(
|
||||
.change_context(UserErrors::InternalServerError)?
|
||||
.into_iter()
|
||||
.filter_map(|user_role| user_role.org_id)
|
||||
.collect::<HashSet<_>>(),
|
||||
};
|
||||
.collect::<HashSet<_>>();
|
||||
|
||||
let resp = futures::future::try_join_all(
|
||||
orgs.iter()
|
||||
@ -2676,8 +2671,16 @@ pub async fn list_merchants_for_user_in_org(
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
if role_info.is_internal() {
|
||||
return Err(UserErrors::InvalidRoleOperationWithMessage(
|
||||
"Internal roles are not allowed for this operation".to_string(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
let merchant_accounts = match role_info.get_entity_type() {
|
||||
EntityType::Organization | EntityType::Internal => state
|
||||
EntityType::Organization => state
|
||||
.store
|
||||
.list_merchant_accounts_by_organization_id(&(&state).into(), &user_from_token.org_id)
|
||||
.await
|
||||
@ -2752,7 +2755,7 @@ pub async fn list_profiles_for_user_in_org_and_merchant_account(
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
let profiles = match role_info.get_entity_type() {
|
||||
EntityType::Organization | EntityType::Merchant | EntityType::Internal => state
|
||||
EntityType::Organization | EntityType::Merchant => state
|
||||
.store
|
||||
.list_profile_by_merchant_id(
|
||||
key_manager_state,
|
||||
@ -2831,7 +2834,7 @@ pub async fn switch_org_for_user(
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("Failed to retrieve role information")?;
|
||||
|
||||
if role_info.get_entity_type() == EntityType::Internal {
|
||||
if role_info.is_internal() {
|
||||
return Err(UserErrors::InvalidRoleOperationWithMessage(
|
||||
"Org switching not allowed for Internal role".to_string(),
|
||||
)
|
||||
@ -2910,8 +2913,8 @@ pub async fn switch_merchant_for_user_in_org(
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("Failed to retrieve role information")?;
|
||||
|
||||
let (org_id, merchant_id, profile_id, role_id) = match role_info.get_entity_type() {
|
||||
EntityType::Internal => {
|
||||
// Check if the role is internal and handle separately
|
||||
let (org_id, merchant_id, profile_id, role_id) = if role_info.is_internal() {
|
||||
let merchant_key_store = state
|
||||
.store
|
||||
.get_merchant_key_store_by_merchant_id(
|
||||
@ -2954,8 +2957,9 @@ pub async fn switch_merchant_for_user_in_org(
|
||||
profile_id,
|
||||
user_from_token.role_id.clone(),
|
||||
)
|
||||
}
|
||||
|
||||
} else {
|
||||
// Match based on the other entity types
|
||||
match role_info.get_entity_type() {
|
||||
EntityType::Organization => {
|
||||
let merchant_key_store = state
|
||||
.store
|
||||
@ -2987,7 +2991,11 @@ pub async fn switch_merchant_for_user_in_org(
|
||||
|
||||
let profile_id = state
|
||||
.store
|
||||
.list_profile_by_merchant_id(key_manager_state, &merchant_key_store, &merchant_id)
|
||||
.list_profile_by_merchant_id(
|
||||
key_manager_state,
|
||||
&merchant_key_store,
|
||||
&merchant_id,
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("Failed to list business profiles by merchant_id")?
|
||||
@ -3027,43 +3035,17 @@ pub async fn switch_merchant_for_user_in_org(
|
||||
"No user role associated with the requested merchant_id".to_string(),
|
||||
))?;
|
||||
|
||||
let profile_id = if let Some(profile_id) = &user_role.profile_id {
|
||||
profile_id.clone()
|
||||
} else {
|
||||
let merchant_key_store = state
|
||||
.store
|
||||
.get_merchant_key_store_by_merchant_id(
|
||||
key_manager_state,
|
||||
&request.merchant_id,
|
||||
&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
|
||||
.list_profile_by_merchant_id(
|
||||
key_manager_state,
|
||||
&merchant_key_store,
|
||||
&request.merchant_id,
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("Failed to list business profiles for the given merchant_id")?
|
||||
.pop()
|
||||
.ok_or(UserErrors::InternalServerError)
|
||||
.attach_printable("No business profile found for the given merchant_id")?
|
||||
.get_id()
|
||||
.to_owned()
|
||||
};
|
||||
let (merchant_id, profile_id) =
|
||||
utils::user_role::get_single_merchant_id_and_profile_id(&state, &user_role)
|
||||
.await?;
|
||||
(
|
||||
user_from_token.org_id,
|
||||
request.merchant_id,
|
||||
merchant_id,
|
||||
profile_id,
|
||||
user_role.role_id,
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let token = utils::user::generate_jwt_auth_token_with_attributes(
|
||||
@ -3116,7 +3098,7 @@ pub async fn switch_profile_for_user_in_org_and_merchant(
|
||||
.attach_printable("Failed to retrieve role information")?;
|
||||
|
||||
let (profile_id, role_id) = match role_info.get_entity_type() {
|
||||
EntityType::Internal | EntityType::Organization | EntityType::Merchant => {
|
||||
EntityType::Organization | EntityType::Merchant => {
|
||||
let merchant_key_store = state
|
||||
.store
|
||||
.get_merchant_key_store_by_merchant_id(
|
||||
|
||||
@ -734,7 +734,6 @@ pub async fn list_users_in_lineage(
|
||||
)
|
||||
.await?
|
||||
}
|
||||
EntityType::Internal => HashSet::new(),
|
||||
};
|
||||
|
||||
let mut email_map = state
|
||||
@ -859,10 +858,13 @@ pub async fn list_invitations_for_user(
|
||||
.clone()
|
||||
.ok_or(UserErrors::InternalServerError)?,
|
||||
)),
|
||||
EntityType::Internal => return Err(report!(UserErrors::InternalServerError)),
|
||||
}
|
||||
|
||||
Ok((org_ids, merchant_ids, profile_ids_with_merchant_ids))
|
||||
Ok::<_, error_stack::Report<UserErrors>>((
|
||||
org_ids,
|
||||
merchant_ids,
|
||||
profile_ids_with_merchant_ids,
|
||||
))
|
||||
},
|
||||
)?;
|
||||
|
||||
@ -953,7 +955,6 @@ pub async fn list_invitations_for_user(
|
||||
.as_ref()
|
||||
.map(|profile_id| profile_name_map.get(profile_id).cloned())
|
||||
.ok_or(UserErrors::InternalServerError)?,
|
||||
EntityType::Internal => return Err(report!(UserErrors::InternalServerError)),
|
||||
};
|
||||
|
||||
Ok(user_role_api::ListInvitationForUserResponse {
|
||||
|
||||
@ -224,6 +224,13 @@ pub async fn list_roles_with_info(
|
||||
.await
|
||||
.attach_printable("Invalid role_id in JWT")?;
|
||||
|
||||
if user_role_info.is_internal() {
|
||||
return Err(UserErrors::InvalidRoleOperationWithMessage(
|
||||
"Internal roles are not allowed for this operation".to_string(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
let mut role_info_vec = PREDEFINED_ROLES
|
||||
.iter()
|
||||
.map(|(_, role_info)| role_info.clone())
|
||||
@ -256,12 +263,6 @@ pub async fn list_roles_with_info(
|
||||
.attach_printable("Failed to get roles")?,
|
||||
// TODO: Populate this from Db function when support for profile id and profile level custom roles is added
|
||||
EntityType::Profile => Vec::new(),
|
||||
EntityType::Internal => {
|
||||
return Err(UserErrors::InvalidRoleOperationWithMessage(
|
||||
"Internal roles are not allowed for this operation".to_string(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
};
|
||||
|
||||
role_info_vec.extend(custom_roles.into_iter().map(roles::RoleInfo::from));
|
||||
@ -336,13 +337,6 @@ pub async fn list_roles_at_entity_level(
|
||||
.attach_printable("Failed to get roles")?,
|
||||
// TODO: Populate this from Db function when support for profile id and profile level custom roles is added
|
||||
EntityType::Profile => Vec::new(),
|
||||
|
||||
EntityType::Internal => {
|
||||
return Err(UserErrors::InvalidRoleOperationWithMessage(
|
||||
"Internal roles are not allowed for this operation".to_string(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
};
|
||||
|
||||
role_info_vec.extend(custom_roles.into_iter().map(roles::RoleInfo::from));
|
||||
|
||||
@ -31,7 +31,7 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
role_id: common_utils::consts::ROLE_ID_INTERNAL_ADMIN.to_string(),
|
||||
role_name: "internal_admin".to_string(),
|
||||
scope: RoleScope::Organization,
|
||||
entity_type: EntityType::Internal,
|
||||
entity_type: EntityType::Merchant,
|
||||
is_invitable: false,
|
||||
is_deletable: false,
|
||||
is_updatable: false,
|
||||
@ -52,7 +52,7 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
role_id: common_utils::consts::ROLE_ID_INTERNAL_VIEW_ONLY_USER.to_string(),
|
||||
role_name: "internal_view_only".to_string(),
|
||||
scope: RoleScope::Organization,
|
||||
entity_type: EntityType::Internal,
|
||||
entity_type: EntityType::Merchant,
|
||||
is_invitable: false,
|
||||
is_deletable: false,
|
||||
is_updatable: false,
|
||||
|
||||
@ -1136,11 +1136,6 @@ pub struct ProfileLevel {
|
||||
pub profile_id: id_type::ProfileId,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InternalLevel {
|
||||
pub org_id: id_type::OrganizationId,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct NewUserRole<E: Clone> {
|
||||
pub user_id: String,
|
||||
@ -1316,29 +1311,6 @@ impl NewUserRole<MerchantLevel> {
|
||||
}
|
||||
}
|
||||
|
||||
impl NewUserRole<InternalLevel> {
|
||||
pub async fn insert_in_v1_and_v2(self, state: &SessionState) -> UserResult<UserRole> {
|
||||
let entity = self.entity.clone();
|
||||
let internal_merchant_id = id_type::MerchantId::get_internal_user_merchant_id(
|
||||
consts::user_role::INTERNAL_USER_MERCHANT_ID,
|
||||
);
|
||||
|
||||
let new_v1_role = self
|
||||
.clone()
|
||||
.convert_to_new_v1_role(entity.org_id.clone(), internal_merchant_id.clone());
|
||||
|
||||
let new_v2_role = self.convert_to_new_v2_role(EntityInfo {
|
||||
org_id: entity.org_id.clone(),
|
||||
merchant_id: Some(internal_merchant_id.clone()),
|
||||
profile_id: None,
|
||||
entity_id: internal_merchant_id.get_string_repr().to_owned(),
|
||||
entity_type: EntityType::Internal,
|
||||
});
|
||||
|
||||
Self::insert_v1_and_v2_in_db_and_get_v2(state, new_v1_role, new_v2_role).await
|
||||
}
|
||||
}
|
||||
|
||||
impl NewUserRole<ProfileLevel> {
|
||||
pub async fn insert_in_v2(self, state: &SessionState) -> UserResult<UserRole> {
|
||||
let entity = self.entity.clone();
|
||||
|
||||
@ -239,10 +239,7 @@ pub async fn get_single_merchant_id(
|
||||
.attach_printable("No merchants found for org_id")?
|
||||
.get_id()
|
||||
.clone()),
|
||||
Some(EntityType::Merchant)
|
||||
| Some(EntityType::Internal)
|
||||
| Some(EntityType::Profile)
|
||||
| None => user_role
|
||||
Some(EntityType::Merchant) | Some(EntityType::Profile) | None => user_role
|
||||
.merchant_id
|
||||
.clone()
|
||||
.ok_or(UserErrors::InternalServerError)
|
||||
@ -263,9 +260,7 @@ pub async fn get_lineage_for_user_id_and_entity_for_accepting_invite(
|
||||
)>,
|
||||
> {
|
||||
match entity_type {
|
||||
EntityType::Internal | EntityType::Organization => {
|
||||
Err(UserErrors::InvalidRoleOperation.into())
|
||||
}
|
||||
EntityType::Organization => Err(UserErrors::InvalidRoleOperation.into()),
|
||||
EntityType::Merchant => {
|
||||
let Ok(merchant_id) = id_type::MerchantId::wrap(entity_id) else {
|
||||
return Ok(None);
|
||||
@ -369,7 +364,7 @@ pub async fn get_single_merchant_id_and_profile_id(
|
||||
.get_entity_id_and_type()
|
||||
.ok_or(UserErrors::InternalServerError)?;
|
||||
let profile_id = match entity_type {
|
||||
EntityType::Organization | EntityType::Merchant | EntityType::Internal => {
|
||||
EntityType::Organization | EntityType::Merchant => {
|
||||
let key_store = state
|
||||
.store
|
||||
.get_merchant_key_store_by_merchant_id(
|
||||
@ -438,14 +433,6 @@ pub fn get_min_entity(
|
||||
| (EntityType::Merchant, Some(EntityType::Profile))
|
||||
| (EntityType::Profile, Some(EntityType::Profile)) => Ok(EntityType::Profile),
|
||||
|
||||
(EntityType::Internal, _) => Ok(EntityType::Internal),
|
||||
|
||||
(EntityType::Organization, Some(EntityType::Internal))
|
||||
| (EntityType::Merchant, Some(EntityType::Internal))
|
||||
| (EntityType::Profile, Some(EntityType::Internal)) => {
|
||||
Err(UserErrors::InvalidRoleOperation.into())
|
||||
}
|
||||
|
||||
(EntityType::Merchant, Some(EntityType::Organization))
|
||||
| (EntityType::Profile, Some(EntityType::Organization))
|
||||
| (EntityType::Profile, Some(EntityType::Merchant)) => {
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
UPDATE user_roles SET entity_type = 'internal' where role_id like 'internal%' and version = 'v2';
|
||||
@ -0,0 +1,2 @@
|
||||
-- Your SQL goes here
|
||||
UPDATE user_roles SET entity_type = 'merchant' WHERE entity_type = 'internal';
|
||||
Reference in New Issue
Block a user