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:
Apoorv Dixit
2024-09-26 19:32:21 +05:30
committed by GitHub
parent e0a33f8c20
commit 991ca38b50
10 changed files with 179 additions and 245 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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));

View File

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

View File

@ -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();

View File

@ -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)) => {

View File

@ -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';

View File

@ -0,0 +1,2 @@
-- Your SQL goes here
UPDATE user_roles SET entity_type = 'merchant' WHERE entity_type = 'internal';