mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 19:46:48 +08:00
refactor(users): remove lineage checks in roles get operations (#6701)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -26,6 +26,7 @@ impl Role {
|
||||
.await
|
||||
}
|
||||
|
||||
// TODO: Remove once find_by_role_id_in_lineage is stable
|
||||
pub async fn find_by_role_id_in_merchant_scope(
|
||||
conn: &PgPooledConn,
|
||||
role_id: &str,
|
||||
@ -43,7 +44,27 @@ impl Role {
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn find_by_role_id_in_org_scope(
|
||||
pub async fn find_by_role_id_in_lineage(
|
||||
conn: &PgPooledConn,
|
||||
role_id: &str,
|
||||
merchant_id: &id_type::MerchantId,
|
||||
org_id: &id_type::OrganizationId,
|
||||
) -> StorageResult<Self> {
|
||||
generics::generic_find_one::<<Self as HasTable>::Table, _, _>(
|
||||
conn,
|
||||
dsl::role_id
|
||||
.eq(role_id.to_owned())
|
||||
.and(dsl::org_id.eq(org_id.to_owned()))
|
||||
.and(
|
||||
dsl::scope.eq(RoleScope::Organization).or(dsl::merchant_id
|
||||
.eq(merchant_id.to_owned())
|
||||
.and(dsl::scope.eq(RoleScope::Merchant))),
|
||||
),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn find_by_role_id_and_org_id(
|
||||
conn: &PgPooledConn,
|
||||
role_id: &str,
|
||||
org_id: &id_type::OrganizationId,
|
||||
@ -88,9 +109,11 @@ impl Role {
|
||||
merchant_id: &id_type::MerchantId,
|
||||
org_id: &id_type::OrganizationId,
|
||||
) -> StorageResult<Vec<Self>> {
|
||||
let predicate = dsl::merchant_id.eq(merchant_id.to_owned()).or(dsl::org_id
|
||||
.eq(org_id.to_owned())
|
||||
.and(dsl::scope.eq(RoleScope::Organization)));
|
||||
let predicate = dsl::org_id.eq(org_id.to_owned()).and(
|
||||
dsl::scope.eq(RoleScope::Organization).or(dsl::merchant_id
|
||||
.eq(merchant_id.to_owned())
|
||||
.and(dsl::scope.eq(RoleScope::Merchant))),
|
||||
);
|
||||
|
||||
generics::generic_filter::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
@ -115,9 +138,10 @@ impl Role {
|
||||
|
||||
if let Some(merchant_id) = merchant_id {
|
||||
query = query.filter(
|
||||
dsl::merchant_id
|
||||
(dsl::merchant_id
|
||||
.eq(merchant_id)
|
||||
.or(dsl::scope.eq(RoleScope::Organization)),
|
||||
.and(dsl::scope.eq(RoleScope::Merchant)))
|
||||
.or(dsl::scope.eq(RoleScope::Organization)),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -29,16 +29,19 @@ pub struct UserRole {
|
||||
|
||||
impl UserRole {
|
||||
pub fn get_entity_id_and_type(&self) -> Option<(String, EntityType)> {
|
||||
match (self.version, self.role_id.as_str()) {
|
||||
(enums::UserRoleVersion::V1, consts::ROLE_ID_ORGANIZATION_ADMIN) => {
|
||||
match (self.version, self.entity_type, self.role_id.as_str()) {
|
||||
(enums::UserRoleVersion::V1, None, consts::ROLE_ID_ORGANIZATION_ADMIN) => {
|
||||
let org_id = self.org_id.clone()?.get_string_repr().to_string();
|
||||
Some((org_id, EntityType::Organization))
|
||||
}
|
||||
(enums::UserRoleVersion::V1, _) => {
|
||||
(enums::UserRoleVersion::V1, None, _) => {
|
||||
let merchant_id = self.merchant_id.clone()?.get_string_repr().to_string();
|
||||
Some((merchant_id, EntityType::Merchant))
|
||||
}
|
||||
(enums::UserRoleVersion::V2, _) => self.entity_id.clone().zip(self.entity_type),
|
||||
(enums::UserRoleVersion::V1, Some(_), _) => {
|
||||
self.entity_id.clone().zip(self.entity_type)
|
||||
}
|
||||
(enums::UserRoleVersion::V2, _, _) => self.entity_id.clone().zip(self.entity_type),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1847,15 +1847,10 @@ pub mod routes {
|
||||
json_payload.into_inner(),
|
||||
|state, auth: UserFromToken, req, _| async move {
|
||||
let role_id = auth.role_id;
|
||||
let role_info = RoleInfo::from_role_id_in_merchant_scope(
|
||||
&state,
|
||||
&role_id,
|
||||
&auth.merchant_id,
|
||||
&auth.org_id,
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.change_context(OpenSearchError::UnknownError)?;
|
||||
let role_info = RoleInfo::from_role_id_and_org_id(&state, &role_id, &auth.org_id)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.change_context(OpenSearchError::UnknownError)?;
|
||||
let permission_groups = role_info.get_permission_groups();
|
||||
if !permission_groups.contains(&common_enums::PermissionGroup::OperationsView) {
|
||||
return Err(OpenSearchError::AccessForbiddenError)?;
|
||||
@ -1887,7 +1882,7 @@ pub mod routes {
|
||||
let role_id = user_role.role_id.clone();
|
||||
let org_id = user_role.org_id.clone().unwrap_or_default();
|
||||
async move {
|
||||
RoleInfo::from_role_id_in_org_scope(&state, &role_id, &org_id)
|
||||
RoleInfo::from_role_id_and_org_id(&state, &role_id, &org_id)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.change_context(OpenSearchError::UnknownError)
|
||||
@ -1974,15 +1969,10 @@ pub mod routes {
|
||||
indexed_req,
|
||||
|state, auth: UserFromToken, req, _| async move {
|
||||
let role_id = auth.role_id;
|
||||
let role_info = RoleInfo::from_role_id_in_merchant_scope(
|
||||
&state,
|
||||
&role_id,
|
||||
&auth.merchant_id,
|
||||
&auth.org_id,
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.change_context(OpenSearchError::UnknownError)?;
|
||||
let role_info = RoleInfo::from_role_id_and_org_id(&state, &role_id, &auth.org_id)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.change_context(OpenSearchError::UnknownError)?;
|
||||
let permission_groups = role_info.get_permission_groups();
|
||||
if !permission_groups.contains(&common_enums::PermissionGroup::OperationsView) {
|
||||
return Err(OpenSearchError::AccessForbiddenError)?;
|
||||
@ -2013,7 +2003,7 @@ pub mod routes {
|
||||
let role_id = user_role.role_id.clone();
|
||||
let org_id = user_role.org_id.clone().unwrap_or_default();
|
||||
async move {
|
||||
RoleInfo::from_role_id_in_org_scope(&state, &role_id, &org_id)
|
||||
RoleInfo::from_role_id_and_org_id(&state, &role_id, &org_id)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.change_context(OpenSearchError::UnknownError)
|
||||
|
||||
@ -104,10 +104,9 @@ pub async fn get_user_details(
|
||||
) -> UserResponse<user_api::GetUserDetailsResponse> {
|
||||
let user = user_from_token.get_user_from_db(&state).await?;
|
||||
let verification_days_left = utils::user::get_verification_days_left(&state, &user)?;
|
||||
let role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let role_info = roles::RoleInfo::from_role_id_and_org_id(
|
||||
&state,
|
||||
&user_from_token.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
@ -553,7 +552,7 @@ async fn handle_invitation(
|
||||
.into());
|
||||
}
|
||||
|
||||
let role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let role_info = roles::RoleInfo::from_role_id_in_lineage(
|
||||
state,
|
||||
&request.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
@ -1371,10 +1370,9 @@ pub async fn list_user_roles_details(
|
||||
.await
|
||||
.to_not_found_response(UserErrors::InvalidRoleOperation)?;
|
||||
|
||||
let requestor_role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let requestor_role_info = roles::RoleInfo::from_role_id_and_org_id(
|
||||
&state,
|
||||
&user_from_token.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
@ -1526,7 +1524,7 @@ pub async fn list_user_roles_details(
|
||||
.collect::<HashSet<_>>()
|
||||
.into_iter()
|
||||
.map(|role_id| async {
|
||||
let role_info = roles::RoleInfo::from_role_id_in_org_scope(
|
||||
let role_info = roles::RoleInfo::from_role_id_and_org_id(
|
||||
&state,
|
||||
&role_id,
|
||||
&user_from_token.org_id,
|
||||
@ -2533,10 +2531,9 @@ pub async fn list_orgs_for_user(
|
||||
state: SessionState,
|
||||
user_from_token: auth::UserFromToken,
|
||||
) -> UserResponse<Vec<user_api::ListOrgsForUserResponse>> {
|
||||
let role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let role_info = roles::RoleInfo::from_role_id_and_org_id(
|
||||
&state,
|
||||
&user_from_token.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
@ -2611,10 +2608,9 @@ pub async fn list_merchants_for_user_in_org(
|
||||
state: SessionState,
|
||||
user_from_token: auth::UserFromToken,
|
||||
) -> UserResponse<Vec<user_api::ListMerchantsForUserInOrgResponse>> {
|
||||
let role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let role_info = roles::RoleInfo::from_role_id_and_org_id(
|
||||
&state,
|
||||
&user_from_token.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
@ -2687,10 +2683,9 @@ pub async fn list_profiles_for_user_in_org_and_merchant_account(
|
||||
state: SessionState,
|
||||
user_from_token: auth::UserFromToken,
|
||||
) -> UserResponse<Vec<user_api::ListProfilesForUserInOrgAndMerchantAccountResponse>> {
|
||||
let role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let role_info = roles::RoleInfo::from_role_id_and_org_id(
|
||||
&state,
|
||||
&user_from_token.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
@ -2780,10 +2775,9 @@ pub async fn switch_org_for_user(
|
||||
.into());
|
||||
}
|
||||
|
||||
let role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let role_info = roles::RoleInfo::from_role_id_and_org_id(
|
||||
&state,
|
||||
&user_from_token.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
@ -2876,13 +2870,8 @@ pub async fn switch_org_for_user(
|
||||
)
|
||||
.await?;
|
||||
|
||||
utils::user_role::set_role_permissions_in_cache_by_role_id_merchant_id_org_id(
|
||||
&state,
|
||||
&role_id,
|
||||
&merchant_id,
|
||||
&request.org_id,
|
||||
)
|
||||
.await;
|
||||
utils::user_role::set_role_info_in_cache_by_role_id_org_id(&state, &role_id, &request.org_id)
|
||||
.await;
|
||||
|
||||
let response = user_api::TokenResponse {
|
||||
token: token.clone(),
|
||||
@ -2905,10 +2894,9 @@ pub async fn switch_merchant_for_user_in_org(
|
||||
}
|
||||
|
||||
let key_manager_state = &(&state).into();
|
||||
let role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let role_info = roles::RoleInfo::from_role_id_and_org_id(
|
||||
&state,
|
||||
&user_from_token.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
@ -3065,13 +3053,7 @@ pub async fn switch_merchant_for_user_in_org(
|
||||
)
|
||||
.await?;
|
||||
|
||||
utils::user_role::set_role_permissions_in_cache_by_role_id_merchant_id_org_id(
|
||||
&state,
|
||||
&role_id,
|
||||
&merchant_id,
|
||||
&org_id,
|
||||
)
|
||||
.await;
|
||||
utils::user_role::set_role_info_in_cache_by_role_id_org_id(&state, &role_id, &org_id).await;
|
||||
|
||||
let response = user_api::TokenResponse {
|
||||
token: token.clone(),
|
||||
@ -3094,10 +3076,9 @@ pub async fn switch_profile_for_user_in_org_and_merchant(
|
||||
}
|
||||
|
||||
let key_manager_state = &(&state).into();
|
||||
let role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let role_info = roles::RoleInfo::from_role_id_and_org_id(
|
||||
&state,
|
||||
&user_from_token.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
@ -3175,10 +3156,9 @@ pub async fn switch_profile_for_user_in_org_and_merchant(
|
||||
)
|
||||
.await?;
|
||||
|
||||
utils::user_role::set_role_permissions_in_cache_by_role_id_merchant_id_org_id(
|
||||
utils::user_role::set_role_info_in_cache_by_role_id_org_id(
|
||||
&state,
|
||||
&role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await;
|
||||
|
||||
@ -83,10 +83,9 @@ pub async fn get_parent_group_info(
|
||||
state: SessionState,
|
||||
user_from_token: auth::UserFromToken,
|
||||
) -> UserResponse<Vec<role_api::ParentGroupInfo>> {
|
||||
let role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let role_info = roles::RoleInfo::from_role_id_and_org_id(
|
||||
&state,
|
||||
&user_from_token.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
@ -119,7 +118,7 @@ pub async fn update_user_role(
|
||||
req: user_role_api::UpdateUserRoleRequest,
|
||||
_req_state: ReqState,
|
||||
) -> UserResponse<()> {
|
||||
let role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let role_info = roles::RoleInfo::from_role_id_in_lineage(
|
||||
&state,
|
||||
&req.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
@ -144,10 +143,9 @@ pub async fn update_user_role(
|
||||
.attach_printable("User Changing their own role");
|
||||
}
|
||||
|
||||
let updator_role = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let updator_role = roles::RoleInfo::from_role_id_and_org_id(
|
||||
&state,
|
||||
&user_from_token.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
@ -181,10 +179,9 @@ pub async fn update_user_role(
|
||||
};
|
||||
|
||||
if let Some(user_role) = v2_user_role_to_be_updated {
|
||||
let role_to_be_updated = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let role_to_be_updated = roles::RoleInfo::from_role_id_and_org_id(
|
||||
&state,
|
||||
&user_role.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
@ -262,10 +259,9 @@ pub async fn update_user_role(
|
||||
};
|
||||
|
||||
if let Some(user_role) = v1_user_role_to_be_updated {
|
||||
let role_to_be_updated = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let role_to_be_updated = roles::RoleInfo::from_role_id_and_org_id(
|
||||
&state,
|
||||
&user_role.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
@ -489,10 +485,9 @@ pub async fn delete_user_role(
|
||||
.attach_printable("User deleting himself");
|
||||
}
|
||||
|
||||
let deletion_requestor_role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let deletion_requestor_role_info = roles::RoleInfo::from_role_id_and_org_id(
|
||||
&state,
|
||||
&user_from_token.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
@ -527,7 +522,7 @@ pub async fn delete_user_role(
|
||||
};
|
||||
|
||||
if let Some(role_to_be_deleted) = user_role_v2 {
|
||||
let target_role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let target_role_info = roles::RoleInfo::from_role_id_in_lineage(
|
||||
&state,
|
||||
&role_to_be_deleted.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
@ -597,7 +592,7 @@ pub async fn delete_user_role(
|
||||
};
|
||||
|
||||
if let Some(role_to_be_deleted) = user_role_v1 {
|
||||
let target_role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let target_role_info = roles::RoleInfo::from_role_id_in_lineage(
|
||||
&state,
|
||||
&role_to_be_deleted.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
@ -685,10 +680,9 @@ pub async fn list_users_in_lineage(
|
||||
user_from_token: auth::UserFromToken,
|
||||
request: user_role_api::ListUsersInEntityRequest,
|
||||
) -> UserResponse<Vec<user_role_api::ListUsersInEntityResponse>> {
|
||||
let requestor_role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let requestor_role_info = roles::RoleInfo::from_role_id_and_org_id(
|
||||
&state,
|
||||
&user_from_token.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
@ -783,7 +777,7 @@ pub async fn list_users_in_lineage(
|
||||
|
||||
let role_info_map =
|
||||
futures::future::try_join_all(user_roles_set.iter().map(|user_role| async {
|
||||
roles::RoleInfo::from_role_id_in_org_scope(
|
||||
roles::RoleInfo::from_role_id_and_org_id(
|
||||
&state,
|
||||
&user_role.role_id,
|
||||
&user_from_token.org_id,
|
||||
|
||||
@ -76,8 +76,10 @@ pub async fn create_role(
|
||||
)
|
||||
.await?;
|
||||
|
||||
let user_role_info = user_from_token.get_role_info_from_db(&state).await?;
|
||||
|
||||
if matches!(req.role_scope, RoleScope::Organization)
|
||||
&& user_from_token.role_id != common_utils::consts::ROLE_ID_ORGANIZATION_ADMIN
|
||||
&& user_role_info.get_entity_type() != EntityType::Organization
|
||||
{
|
||||
return Err(report!(UserErrors::InvalidRoleOperation))
|
||||
.attach_printable("Non org admin user creating org level role");
|
||||
@ -116,14 +118,10 @@ pub async fn get_role_with_groups(
|
||||
user_from_token: UserFromToken,
|
||||
role: role_api::GetRoleRequest,
|
||||
) -> UserResponse<role_api::RoleInfoWithGroupsResponse> {
|
||||
let role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
&state,
|
||||
&role.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(UserErrors::InvalidRoleId)?;
|
||||
let role_info =
|
||||
roles::RoleInfo::from_role_id_and_org_id(&state, &role.role_id, &user_from_token.org_id)
|
||||
.await
|
||||
.to_not_found_response(UserErrors::InvalidRoleId)?;
|
||||
|
||||
if role_info.is_internal() {
|
||||
return Err(UserErrors::InvalidRoleId.into());
|
||||
@ -144,14 +142,10 @@ pub async fn get_parent_info_for_role(
|
||||
user_from_token: UserFromToken,
|
||||
role: role_api::GetRoleRequest,
|
||||
) -> UserResponse<role_api::RoleInfoWithParents> {
|
||||
let role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
&state,
|
||||
&role.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(UserErrors::InvalidRoleId)?;
|
||||
let role_info =
|
||||
roles::RoleInfo::from_role_id_and_org_id(&state, &role.role_id, &user_from_token.org_id)
|
||||
.await
|
||||
.to_not_found_response(UserErrors::InvalidRoleId)?;
|
||||
|
||||
if role_info.is_internal() {
|
||||
return Err(UserErrors::InvalidRoleId.into());
|
||||
@ -207,7 +201,7 @@ pub async fn update_role(
|
||||
utils::user_role::validate_role_groups(groups)?;
|
||||
}
|
||||
|
||||
let role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
|
||||
let role_info = roles::RoleInfo::from_role_id_in_lineage(
|
||||
&state,
|
||||
role_id,
|
||||
&user_from_token.merchant_id,
|
||||
@ -216,8 +210,10 @@ pub async fn update_role(
|
||||
.await
|
||||
.to_not_found_response(UserErrors::InvalidRoleOperation)?;
|
||||
|
||||
let user_role_info = user_from_token.get_role_info_from_db(&state).await?;
|
||||
|
||||
if matches!(role_info.get_scope(), RoleScope::Organization)
|
||||
&& user_from_token.role_id != common_utils::consts::ROLE_ID_ORGANIZATION_ADMIN
|
||||
&& user_role_info.get_entity_type() != EntityType::Organization
|
||||
{
|
||||
return Err(report!(UserErrors::InvalidRoleOperation))
|
||||
.attach_printable("Non org admin user changing org level role");
|
||||
|
||||
@ -3521,6 +3521,7 @@ impl RoleInterface for KafkaStore {
|
||||
self.diesel_store.find_role_by_role_id(role_id).await
|
||||
}
|
||||
|
||||
//TODO:Remove once find_by_role_id_in_lineage is stable
|
||||
async fn find_role_by_role_id_in_merchant_scope(
|
||||
&self,
|
||||
role_id: &str,
|
||||
@ -3532,13 +3533,24 @@ impl RoleInterface for KafkaStore {
|
||||
.await
|
||||
}
|
||||
|
||||
async fn find_role_by_role_id_in_org_scope(
|
||||
async fn find_role_by_role_id_in_lineage(
|
||||
&self,
|
||||
role_id: &str,
|
||||
merchant_id: &id_type::MerchantId,
|
||||
org_id: &id_type::OrganizationId,
|
||||
) -> CustomResult<storage::Role, errors::StorageError> {
|
||||
self.diesel_store
|
||||
.find_role_by_role_id_in_lineage(role_id, merchant_id, org_id)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn find_by_role_id_and_org_id(
|
||||
&self,
|
||||
role_id: &str,
|
||||
org_id: &id_type::OrganizationId,
|
||||
) -> CustomResult<storage::Role, errors::StorageError> {
|
||||
self.diesel_store
|
||||
.find_role_by_role_id_in_org_scope(role_id, org_id)
|
||||
.find_by_role_id_and_org_id(role_id, org_id)
|
||||
.await
|
||||
}
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@ pub trait RoleInterface {
|
||||
role_id: &str,
|
||||
) -> CustomResult<storage::Role, errors::StorageError>;
|
||||
|
||||
//TODO:Remove once find_by_role_id_in_lineage is stable
|
||||
async fn find_role_by_role_id_in_merchant_scope(
|
||||
&self,
|
||||
role_id: &str,
|
||||
@ -30,7 +31,14 @@ pub trait RoleInterface {
|
||||
org_id: &id_type::OrganizationId,
|
||||
) -> CustomResult<storage::Role, errors::StorageError>;
|
||||
|
||||
async fn find_role_by_role_id_in_org_scope(
|
||||
async fn find_role_by_role_id_in_lineage(
|
||||
&self,
|
||||
role_id: &str,
|
||||
merchant_id: &id_type::MerchantId,
|
||||
org_id: &id_type::OrganizationId,
|
||||
) -> CustomResult<storage::Role, errors::StorageError>;
|
||||
|
||||
async fn find_by_role_id_and_org_id(
|
||||
&self,
|
||||
role_id: &str,
|
||||
org_id: &id_type::OrganizationId,
|
||||
@ -86,6 +94,7 @@ impl RoleInterface for Store {
|
||||
.map_err(|error| report!(errors::StorageError::from(error)))
|
||||
}
|
||||
|
||||
//TODO:Remove once find_by_role_id_in_lineage is stable
|
||||
#[instrument(skip_all)]
|
||||
async fn find_role_by_role_id_in_merchant_scope(
|
||||
&self,
|
||||
@ -100,13 +109,26 @@ impl RoleInterface for Store {
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
async fn find_role_by_role_id_in_org_scope(
|
||||
async fn find_role_by_role_id_in_lineage(
|
||||
&self,
|
||||
role_id: &str,
|
||||
merchant_id: &id_type::MerchantId,
|
||||
org_id: &id_type::OrganizationId,
|
||||
) -> CustomResult<storage::Role, errors::StorageError> {
|
||||
let conn = connection::pg_connection_read(self).await?;
|
||||
storage::Role::find_by_role_id_in_lineage(&conn, role_id, merchant_id, org_id)
|
||||
.await
|
||||
.map_err(|error| report!(errors::StorageError::from(error)))
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
async fn find_by_role_id_and_org_id(
|
||||
&self,
|
||||
role_id: &str,
|
||||
org_id: &id_type::OrganizationId,
|
||||
) -> CustomResult<storage::Role, errors::StorageError> {
|
||||
let conn = connection::pg_connection_read(self).await?;
|
||||
storage::Role::find_by_role_id_in_org_scope(&conn, role_id, org_id)
|
||||
storage::Role::find_by_role_id_and_org_id(&conn, role_id, org_id)
|
||||
.await
|
||||
.map_err(|error| report!(errors::StorageError::from(error)))
|
||||
}
|
||||
@ -217,6 +239,7 @@ impl RoleInterface for MockDb {
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: Remove once find_by_role_id_in_lineage is stable
|
||||
async fn find_role_by_role_id_in_merchant_scope(
|
||||
&self,
|
||||
role_id: &str,
|
||||
@ -241,7 +264,33 @@ impl RoleInterface for MockDb {
|
||||
)
|
||||
}
|
||||
|
||||
async fn find_role_by_role_id_in_org_scope(
|
||||
async fn find_role_by_role_id_in_lineage(
|
||||
&self,
|
||||
role_id: &str,
|
||||
merchant_id: &id_type::MerchantId,
|
||||
org_id: &id_type::OrganizationId,
|
||||
) -> CustomResult<storage::Role, errors::StorageError> {
|
||||
let roles = self.roles.lock().await;
|
||||
roles
|
||||
.iter()
|
||||
.find(|role| {
|
||||
role.role_id == role_id
|
||||
&& role.org_id == *org_id
|
||||
&& ((role.scope == enums::RoleScope::Organization)
|
||||
|| (role.merchant_id == *merchant_id
|
||||
&& role.scope == enums::RoleScope::Merchant))
|
||||
})
|
||||
.cloned()
|
||||
.ok_or(
|
||||
errors::StorageError::ValueNotFound(format!(
|
||||
"No role available in merchant scope for role_id = {role_id}, \
|
||||
merchant_id = {merchant_id:?} and org_id = {org_id:?}"
|
||||
))
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
|
||||
async fn find_by_role_id_and_org_id(
|
||||
&self,
|
||||
role_id: &str,
|
||||
org_id: &id_type::OrganizationId,
|
||||
|
||||
@ -33,8 +33,7 @@ where
|
||||
return Ok(role_info.clone());
|
||||
}
|
||||
|
||||
let role_info =
|
||||
get_role_info_from_db(state, &token.role_id, &token.merchant_id, &token.org_id).await?;
|
||||
let role_info = get_role_info_from_db(state, &token.role_id, &token.org_id).await?;
|
||||
|
||||
let token_expiry =
|
||||
i64::try_from(token.exp).change_context(ApiErrorResponse::InternalServerError)?;
|
||||
@ -68,7 +67,6 @@ pub fn get_cache_key_from_role_id(role_id: &str) -> String {
|
||||
async fn get_role_info_from_db<A>(
|
||||
state: &A,
|
||||
role_id: &str,
|
||||
merchant_id: &id_type::MerchantId,
|
||||
org_id: &id_type::OrganizationId,
|
||||
) -> RouterResult<roles::RoleInfo>
|
||||
where
|
||||
@ -76,7 +74,7 @@ where
|
||||
{
|
||||
state
|
||||
.store()
|
||||
.find_role_by_role_id_in_merchant_scope(role_id, merchant_id, org_id)
|
||||
.find_by_role_id_and_org_id(role_id, org_id)
|
||||
.await
|
||||
.map(roles::RoleInfo::from)
|
||||
.to_not_found_response(ApiErrorResponse::InvalidJwtToken)
|
||||
|
||||
@ -116,7 +116,7 @@ impl RoleInfo {
|
||||
acl
|
||||
}
|
||||
|
||||
pub async fn from_role_id_in_merchant_scope(
|
||||
pub async fn from_role_id_in_lineage(
|
||||
state: &SessionState,
|
||||
role_id: &str,
|
||||
merchant_id: &id_type::MerchantId,
|
||||
@ -127,13 +127,13 @@ impl RoleInfo {
|
||||
} else {
|
||||
state
|
||||
.store
|
||||
.find_role_by_role_id_in_merchant_scope(role_id, merchant_id, org_id)
|
||||
.find_role_by_role_id_in_lineage(role_id, merchant_id, org_id)
|
||||
.await
|
||||
.map(Self::from)
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn from_role_id_in_org_scope(
|
||||
pub async fn from_role_id_and_org_id(
|
||||
state: &SessionState,
|
||||
role_id: &str,
|
||||
org_id: &id_type::OrganizationId,
|
||||
@ -143,7 +143,7 @@ impl RoleInfo {
|
||||
} else {
|
||||
state
|
||||
.store
|
||||
.find_role_by_role_id_in_org_scope(role_id, org_id)
|
||||
.find_by_role_id_and_org_id(role_id, org_id)
|
||||
.await
|
||||
.map(Self::from)
|
||||
}
|
||||
|
||||
@ -337,8 +337,7 @@ impl NextFlow {
|
||||
.change_context(UserErrors::InternalServerError)?
|
||||
.pop()
|
||||
.ok_or(UserErrors::InternalServerError)?;
|
||||
utils::user_role::set_role_permissions_in_cache_by_user_role(state, &user_role)
|
||||
.await;
|
||||
utils::user_role::set_role_info_in_cache_by_user_role(state, &user_role).await;
|
||||
|
||||
jwt_flow.generate_jwt(state, self, &user_role).await
|
||||
}
|
||||
@ -357,8 +356,7 @@ impl NextFlow {
|
||||
{
|
||||
self.user.get_verification_days_left(state)?;
|
||||
}
|
||||
utils::user_role::set_role_permissions_in_cache_by_user_role(state, user_role)
|
||||
.await;
|
||||
utils::user_role::set_role_info_in_cache_by_user_role(state, user_role).await;
|
||||
|
||||
jwt_flow.generate_jwt(state, self, user_role).await
|
||||
}
|
||||
|
||||
@ -77,14 +77,9 @@ impl UserFromToken {
|
||||
}
|
||||
|
||||
pub async fn get_role_info_from_db(&self, state: &SessionState) -> UserResult<RoleInfo> {
|
||||
RoleInfo::from_role_id_in_merchant_scope(
|
||||
state,
|
||||
&self.role_id,
|
||||
&self.merchant_id,
|
||||
&self.org_id,
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
RoleInfo::from_role_id_and_org_id(state, &self.role_id, &self.org_id)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -71,55 +71,43 @@ pub async fn validate_role_name(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn set_role_permissions_in_cache_by_user_role(
|
||||
pub async fn set_role_info_in_cache_by_user_role(
|
||||
state: &SessionState,
|
||||
user_role: &UserRole,
|
||||
) -> bool {
|
||||
let Some(ref merchant_id) = user_role.merchant_id else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let Some(ref org_id) = user_role.org_id else {
|
||||
return false;
|
||||
};
|
||||
set_role_permissions_in_cache_if_required(
|
||||
state,
|
||||
user_role.role_id.as_str(),
|
||||
merchant_id,
|
||||
org_id,
|
||||
)
|
||||
.await
|
||||
.map_err(|e| logger::error!("Error setting permissions in cache {:?}", e))
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub async fn set_role_permissions_in_cache_by_role_id_merchant_id_org_id(
|
||||
state: &SessionState,
|
||||
role_id: &str,
|
||||
merchant_id: &id_type::MerchantId,
|
||||
org_id: &id_type::OrganizationId,
|
||||
) -> bool {
|
||||
set_role_permissions_in_cache_if_required(state, role_id, merchant_id, org_id)
|
||||
set_role_info_in_cache_if_required(state, user_role.role_id.as_str(), org_id)
|
||||
.await
|
||||
.map_err(|e| logger::error!("Error setting permissions in cache {:?}", e))
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub async fn set_role_permissions_in_cache_if_required(
|
||||
pub async fn set_role_info_in_cache_by_role_id_org_id(
|
||||
state: &SessionState,
|
||||
role_id: &str,
|
||||
org_id: &id_type::OrganizationId,
|
||||
) -> bool {
|
||||
set_role_info_in_cache_if_required(state, role_id, org_id)
|
||||
.await
|
||||
.map_err(|e| logger::error!("Error setting permissions in cache {:?}", e))
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub async fn set_role_info_in_cache_if_required(
|
||||
state: &SessionState,
|
||||
role_id: &str,
|
||||
merchant_id: &id_type::MerchantId,
|
||||
org_id: &id_type::OrganizationId,
|
||||
) -> UserResult<()> {
|
||||
if roles::predefined_roles::PREDEFINED_ROLES.contains_key(role_id) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let role_info =
|
||||
roles::RoleInfo::from_role_id_in_merchant_scope(state, role_id, merchant_id, org_id)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("Error getting role_info from role_id")?;
|
||||
let role_info = roles::RoleInfo::from_role_id_and_org_id(state, role_id, org_id)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("Error getting role_info from role_id")?;
|
||||
|
||||
authz::set_role_info_in_cache(
|
||||
state,
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
SELECT 1;
|
||||
@ -0,0 +1,10 @@
|
||||
-- Your SQL goes here
|
||||
UPDATE user_roles
|
||||
SET
|
||||
entity_type = CASE
|
||||
WHEN role_id = 'org_admin' THEN 'organization'
|
||||
ELSE 'merchant'
|
||||
END
|
||||
WHERE
|
||||
version = 'v1'
|
||||
AND entity_type IS NULL;
|
||||
Reference in New Issue
Block a user