mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-28 04:04:55 +08:00
fix(users): Allow accepting invites for org_admins (#6253)
This commit is contained in:
@ -119,7 +119,7 @@ impl UserRole {
|
||||
conn: &PgPooledConn,
|
||||
user_id: String,
|
||||
org_id: id_type::OrganizationId,
|
||||
merchant_id: id_type::MerchantId,
|
||||
merchant_id: Option<id_type::MerchantId>,
|
||||
profile_id: Option<id_type::ProfileId>,
|
||||
update: UserRoleUpdate,
|
||||
version: UserRoleVersion,
|
||||
|
||||
@ -647,7 +647,14 @@ async fn handle_existing_user_invitation(
|
||||
};
|
||||
|
||||
let _user_role = match role_info.get_entity_type() {
|
||||
EntityType::Organization => return Err(UserErrors::InvalidRoleId.into()),
|
||||
EntityType::Organization => {
|
||||
user_role
|
||||
.add_entity(domain::OrganizationLevel {
|
||||
org_id: user_from_token.org_id.clone(),
|
||||
})
|
||||
.insert_in_v2(state)
|
||||
.await?
|
||||
}
|
||||
EntityType::Merchant => {
|
||||
user_role
|
||||
.add_entity(domain::MerchantLevel {
|
||||
@ -678,7 +685,10 @@ 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::Organization => return Err(UserErrors::InvalidRoleId.into()),
|
||||
EntityType::Organization => email_types::Entity {
|
||||
entity_id: user_from_token.org_id.get_string_repr().to_owned(),
|
||||
entity_type: EntityType::Organization,
|
||||
},
|
||||
EntityType::Merchant => email_types::Entity {
|
||||
entity_id: user_from_token.merchant_id.get_string_repr().to_owned(),
|
||||
entity_type: EntityType::Merchant,
|
||||
@ -806,7 +816,10 @@ 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::Organization => return Err(UserErrors::InvalidRoleId.into()),
|
||||
EntityType::Organization => email_types::Entity {
|
||||
entity_id: user_from_token.org_id.get_string_repr().to_owned(),
|
||||
entity_type: EntityType::Organization,
|
||||
},
|
||||
EntityType::Merchant => email_types::Entity {
|
||||
entity_id: user_from_token.merchant_id.get_string_repr().to_owned(),
|
||||
entity_type: EntityType::Merchant,
|
||||
@ -1012,7 +1025,7 @@ pub async fn accept_invite_from_email_token_only_flow(
|
||||
&state,
|
||||
user_from_db.get_user_id(),
|
||||
&org_id,
|
||||
&merchant_id,
|
||||
merchant_id.as_ref(),
|
||||
profile_id.as_ref(),
|
||||
UserRoleUpdate::UpdateStatus {
|
||||
status: UserStatus::Active,
|
||||
|
||||
@ -174,7 +174,7 @@ pub async fn update_user_role(
|
||||
.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,
|
||||
Some(&user_from_token.merchant_id),
|
||||
user_from_token.profile_id.as_ref(),
|
||||
UserRoleUpdate::UpdateRole {
|
||||
role_id: req.role_id.clone(),
|
||||
@ -247,7 +247,7 @@ pub async fn update_user_role(
|
||||
.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,
|
||||
Some(&user_from_token.merchant_id),
|
||||
user_from_token.profile_id.as_ref(),
|
||||
UserRoleUpdate::UpdateRole {
|
||||
role_id: req.role_id.clone(),
|
||||
@ -296,7 +296,7 @@ pub async fn accept_invitations_v2(
|
||||
&state,
|
||||
user_from_token.user_id.as_str(),
|
||||
org_id,
|
||||
merchant_id,
|
||||
merchant_id.as_ref(),
|
||||
profile_id.as_ref(),
|
||||
UserRoleUpdate::UpdateStatus {
|
||||
status: UserStatus::Active,
|
||||
@ -348,7 +348,7 @@ pub async fn accept_invitations_pre_auth(
|
||||
&state,
|
||||
user_token.user_id.as_str(),
|
||||
org_id,
|
||||
merchant_id,
|
||||
merchant_id.as_ref(),
|
||||
profile_id.as_ref(),
|
||||
UserRoleUpdate::UpdateStatus {
|
||||
status: UserStatus::Active,
|
||||
|
||||
@ -3043,7 +3043,7 @@ impl UserRoleInterface for KafkaStore {
|
||||
&self,
|
||||
user_id: &str,
|
||||
org_id: &id_type::OrganizationId,
|
||||
merchant_id: &id_type::MerchantId,
|
||||
merchant_id: Option<&id_type::MerchantId>,
|
||||
profile_id: Option<&id_type::ProfileId>,
|
||||
update: user_storage::UserRoleUpdate,
|
||||
version: enums::UserRoleVersion,
|
||||
|
||||
@ -52,7 +52,7 @@ pub trait UserRoleInterface {
|
||||
&self,
|
||||
user_id: &str,
|
||||
org_id: &id_type::OrganizationId,
|
||||
merchant_id: &id_type::MerchantId,
|
||||
merchant_id: Option<&id_type::MerchantId>,
|
||||
profile_id: Option<&id_type::ProfileId>,
|
||||
update: storage::UserRoleUpdate,
|
||||
version: enums::UserRoleVersion,
|
||||
@ -120,7 +120,7 @@ impl UserRoleInterface for Store {
|
||||
&self,
|
||||
user_id: &str,
|
||||
org_id: &id_type::OrganizationId,
|
||||
merchant_id: &id_type::MerchantId,
|
||||
merchant_id: Option<&id_type::MerchantId>,
|
||||
profile_id: Option<&id_type::ProfileId>,
|
||||
update: storage::UserRoleUpdate,
|
||||
version: enums::UserRoleVersion,
|
||||
@ -130,7 +130,7 @@ impl UserRoleInterface for Store {
|
||||
&conn,
|
||||
user_id.to_owned(),
|
||||
org_id.to_owned(),
|
||||
merchant_id.to_owned(),
|
||||
merchant_id.cloned(),
|
||||
profile_id.cloned(),
|
||||
update,
|
||||
version,
|
||||
@ -280,7 +280,7 @@ impl UserRoleInterface for MockDb {
|
||||
&self,
|
||||
user_id: &str,
|
||||
org_id: &id_type::OrganizationId,
|
||||
merchant_id: &id_type::MerchantId,
|
||||
merchant_id: Option<&id_type::MerchantId>,
|
||||
profile_id: Option<&id_type::ProfileId>,
|
||||
update: storage::UserRoleUpdate,
|
||||
version: enums::UserRoleVersion,
|
||||
@ -293,11 +293,11 @@ impl UserRoleInterface for MockDb {
|
||||
&& user_role.profile_id.is_none();
|
||||
|
||||
let merchant_level_check = user_role.org_id.as_ref() == Some(org_id)
|
||||
&& user_role.merchant_id.as_ref() == Some(merchant_id)
|
||||
&& user_role.merchant_id.as_ref() == merchant_id
|
||||
&& user_role.profile_id.is_none();
|
||||
|
||||
let profile_level_check = user_role.org_id.as_ref() == Some(org_id)
|
||||
&& user_role.merchant_id.as_ref() == Some(merchant_id)
|
||||
&& user_role.merchant_id.as_ref() == merchant_id
|
||||
&& user_role.profile_id.as_ref() == profile_id;
|
||||
|
||||
// Check if the user role matches the conditions and the version matches
|
||||
|
||||
@ -174,7 +174,7 @@ pub async fn update_v1_and_v2_user_roles_in_db(
|
||||
state: &SessionState,
|
||||
user_id: &str,
|
||||
org_id: &id_type::OrganizationId,
|
||||
merchant_id: &id_type::MerchantId,
|
||||
merchant_id: Option<&id_type::MerchantId>,
|
||||
profile_id: Option<&id_type::ProfileId>,
|
||||
update: UserRoleUpdate,
|
||||
) -> (
|
||||
@ -255,12 +255,57 @@ pub async fn get_lineage_for_user_id_and_entity_for_accepting_invite(
|
||||
) -> UserResult<
|
||||
Option<(
|
||||
id_type::OrganizationId,
|
||||
id_type::MerchantId,
|
||||
Option<id_type::MerchantId>,
|
||||
Option<id_type::ProfileId>,
|
||||
)>,
|
||||
> {
|
||||
match entity_type {
|
||||
EntityType::Organization => Err(UserErrors::InvalidRoleOperation.into()),
|
||||
EntityType::Organization => {
|
||||
let Ok(org_id) =
|
||||
id_type::OrganizationId::try_from(std::borrow::Cow::from(entity_id.clone()))
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let user_roles = state
|
||||
.store
|
||||
.list_user_roles_by_user_id(ListUserRolesByUserIdPayload {
|
||||
user_id,
|
||||
org_id: Some(&org_id),
|
||||
merchant_id: None,
|
||||
profile_id: None,
|
||||
entity_id: None,
|
||||
version: None,
|
||||
status: Some(UserStatus::InvitationSent),
|
||||
limit: None,
|
||||
})
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?
|
||||
.into_iter()
|
||||
.collect::<HashSet<_>>();
|
||||
|
||||
if user_roles.len() > 1 {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
if let Some(user_role) = user_roles.into_iter().next() {
|
||||
let (_entity_id, entity_type) = user_role
|
||||
.get_entity_id_and_type()
|
||||
.ok_or(UserErrors::InternalServerError)?;
|
||||
|
||||
if entity_type != EntityType::Organization {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
return Ok(Some((
|
||||
user_role.org_id.ok_or(UserErrors::InternalServerError)?,
|
||||
None,
|
||||
None,
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
EntityType::Merchant => {
|
||||
let Ok(merchant_id) = id_type::MerchantId::wrap(entity_id) else {
|
||||
return Ok(None);
|
||||
@ -298,7 +343,7 @@ pub async fn get_lineage_for_user_id_and_entity_for_accepting_invite(
|
||||
|
||||
return Ok(Some((
|
||||
user_role.org_id.ok_or(UserErrors::InternalServerError)?,
|
||||
merchant_id,
|
||||
Some(merchant_id),
|
||||
None,
|
||||
)));
|
||||
}
|
||||
@ -343,9 +388,11 @@ pub async fn get_lineage_for_user_id_and_entity_for_accepting_invite(
|
||||
|
||||
return Ok(Some((
|
||||
user_role.org_id.ok_or(UserErrors::InternalServerError)?,
|
||||
user_role
|
||||
.merchant_id
|
||||
.ok_or(UserErrors::InternalServerError)?,
|
||||
Some(
|
||||
user_role
|
||||
.merchant_id
|
||||
.ok_or(UserErrors::InternalServerError)?,
|
||||
),
|
||||
Some(profile_id),
|
||||
)));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user