mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
feat(authz): Make info APIs support ParentGroup (#6440)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -2,8 +2,9 @@ use common_utils::events::{ApiEventMetric, ApiEventsType};
|
||||
|
||||
use crate::user_role::{
|
||||
role::{
|
||||
CreateRoleRequest, GetRoleRequest, ListRolesAtEntityLevelRequest, ListRolesRequest,
|
||||
RoleInfoResponseNew, RoleInfoWithGroupsResponse, UpdateRoleRequest,
|
||||
CreateRoleRequest, GetRoleRequest, GroupsAndResources, ListRolesAtEntityLevelRequest,
|
||||
ListRolesRequest, RoleInfoResponseNew, RoleInfoWithGroupsResponse, RoleInfoWithParents,
|
||||
UpdateRoleRequest,
|
||||
},
|
||||
AuthorizationInfoResponse, DeleteUserRoleRequest, ListUsersInEntityRequest,
|
||||
UpdateUserRoleRequest,
|
||||
@ -22,6 +23,8 @@ common_utils::impl_api_event_type!(
|
||||
RoleInfoResponseNew,
|
||||
RoleInfoWithGroupsResponse,
|
||||
ListUsersInEntityRequest,
|
||||
ListRolesRequest
|
||||
ListRolesRequest,
|
||||
GroupsAndResources,
|
||||
RoleInfoWithParents
|
||||
)
|
||||
);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
pub use common_enums::PermissionGroup;
|
||||
use common_enums::{EntityType, RoleScope};
|
||||
use common_enums::{
|
||||
EntityType, ParentGroup, PermissionGroup, PermissionScope, Resource, RoleScope,
|
||||
};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct CreateRoleRequest {
|
||||
@ -22,6 +23,21 @@ pub struct RoleInfoWithGroupsResponse {
|
||||
pub role_scope: RoleScope,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize)]
|
||||
pub struct RoleInfoWithParents {
|
||||
pub role_id: String,
|
||||
pub parent_groups: Vec<ParentGroupInfo>,
|
||||
pub role_name: String,
|
||||
pub role_scope: RoleScope,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize)]
|
||||
pub struct ParentGroupInfo {
|
||||
pub name: ParentGroup,
|
||||
pub description: String,
|
||||
pub scopes: Vec<PermissionScope>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct ListRolesRequest {
|
||||
pub entity_type: Option<EntityType>,
|
||||
@ -57,3 +73,9 @@ pub struct MinimalRoleInfo {
|
||||
pub role_id: String,
|
||||
pub role_name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize)]
|
||||
pub struct GroupsAndResources {
|
||||
pub groups: Vec<PermissionGroup>,
|
||||
pub resources: Vec<Resource>,
|
||||
}
|
||||
|
||||
@ -2884,10 +2884,15 @@ pub enum PermissionGroup {
|
||||
AnalyticsView,
|
||||
UsersView,
|
||||
UsersManage,
|
||||
// TODO: To be deprecated, make sure DB is migrated before removing
|
||||
MerchantDetailsView,
|
||||
// TODO: To be deprecated, make sure DB is migrated before removing
|
||||
MerchantDetailsManage,
|
||||
// TODO: To be deprecated, make sure DB is migrated before removing
|
||||
OrganizationManage,
|
||||
ReconOps,
|
||||
AccountView,
|
||||
AccountManage,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize, PartialEq, Eq, Hash, strum::EnumIter)]
|
||||
@ -2897,14 +2902,12 @@ pub enum ParentGroup {
|
||||
Workflows,
|
||||
Analytics,
|
||||
Users,
|
||||
#[serde(rename = "MerchantAccess")]
|
||||
Merchant,
|
||||
#[serde(rename = "OrganizationAccess")]
|
||||
Organization,
|
||||
Recon,
|
||||
Account,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, serde::Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Resource {
|
||||
Payment,
|
||||
Refund,
|
||||
@ -2925,10 +2928,11 @@ pub enum Resource {
|
||||
Recon,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, serde::Serialize, Hash)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum PermissionScope {
|
||||
Read,
|
||||
Write,
|
||||
Read = 0,
|
||||
Write = 1,
|
||||
}
|
||||
|
||||
/// Name of banks supported by Hyperswitch
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use api_models::{user as user_api, user_role as user_role_api};
|
||||
use api_models::{
|
||||
user as user_api,
|
||||
user_role::{self as user_role_api, role as role_api},
|
||||
};
|
||||
use diesel_models::{
|
||||
enums::{UserRoleVersion, UserStatus},
|
||||
organization::OrganizationBridge,
|
||||
@ -16,7 +19,11 @@ use crate::{
|
||||
routes::{app::ReqState, SessionState},
|
||||
services::{
|
||||
authentication as auth,
|
||||
authorization::{info, permission_groups::PermissionGroupExt, roles},
|
||||
authorization::{
|
||||
info,
|
||||
permission_groups::{ParentGroupExt, PermissionGroupExt},
|
||||
roles,
|
||||
},
|
||||
ApplicationResponse,
|
||||
},
|
||||
types::domain,
|
||||
@ -72,6 +79,40 @@ pub async fn get_authorization_info_with_group_tag(
|
||||
))
|
||||
}
|
||||
|
||||
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(
|
||||
&state,
|
||||
&user_from_token.role_id,
|
||||
&user_from_token.merchant_id,
|
||||
&user_from_token.org_id,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(UserErrors::InvalidRoleId)?;
|
||||
|
||||
let parent_groups = ParentGroup::get_descriptions_for_groups(
|
||||
role_info.get_entity_type(),
|
||||
PermissionGroup::iter().collect(),
|
||||
)
|
||||
.into_iter()
|
||||
.map(|(parent_group, description)| role_api::ParentGroupInfo {
|
||||
name: parent_group.clone(),
|
||||
description,
|
||||
scopes: PermissionGroup::iter()
|
||||
.filter_map(|group| (group.parent() == parent_group).then_some(group.scope()))
|
||||
// TODO: Remove this hashset conversion when merhant access
|
||||
// and organization access groups are removed
|
||||
.collect::<HashSet<_>>()
|
||||
.into_iter()
|
||||
.collect(),
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Ok(ApplicationResponse::Json(parent_groups))
|
||||
}
|
||||
|
||||
pub async fn update_user_role(
|
||||
state: SessionState,
|
||||
user_from_token: auth::UserFromToken,
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use api_models::user_role::role::{self as role_api};
|
||||
use common_enums::{EntityType, RoleScope};
|
||||
use common_enums::{EntityType, ParentGroup, PermissionGroup, RoleScope};
|
||||
use common_utils::generate_id_with_default_len;
|
||||
use diesel_models::role::{RoleNew, RoleUpdate};
|
||||
use error_stack::{report, ResultExt};
|
||||
@ -9,7 +11,10 @@ use crate::{
|
||||
routes::{app::ReqState, SessionState},
|
||||
services::{
|
||||
authentication::{blacklist, UserFromToken},
|
||||
authorization::roles::{self, predefined_roles::PREDEFINED_ROLES},
|
||||
authorization::{
|
||||
permission_groups::{ParentGroupExt, PermissionGroupExt},
|
||||
roles::{self, predefined_roles::PREDEFINED_ROLES},
|
||||
},
|
||||
ApplicationResponse,
|
||||
},
|
||||
types::domain::user::RoleName,
|
||||
@ -19,7 +24,7 @@ use crate::{
|
||||
pub async fn get_role_from_token_with_groups(
|
||||
state: SessionState,
|
||||
user_from_token: UserFromToken,
|
||||
) -> UserResponse<Vec<role_api::PermissionGroup>> {
|
||||
) -> UserResponse<Vec<PermissionGroup>> {
|
||||
let role_info = user_from_token
|
||||
.get_role_info_from_db(&state)
|
||||
.await
|
||||
@ -30,6 +35,29 @@ pub async fn get_role_from_token_with_groups(
|
||||
Ok(ApplicationResponse::Json(permissions))
|
||||
}
|
||||
|
||||
pub async fn get_groups_and_resources_for_role_from_token(
|
||||
state: SessionState,
|
||||
user_from_token: UserFromToken,
|
||||
) -> UserResponse<role_api::GroupsAndResources> {
|
||||
let role_info = user_from_token.get_role_info_from_db(&state).await?;
|
||||
|
||||
let groups = role_info
|
||||
.get_permission_groups()
|
||||
.into_iter()
|
||||
.collect::<Vec<_>>();
|
||||
let resources = groups
|
||||
.iter()
|
||||
.flat_map(|group| group.resources())
|
||||
.collect::<HashSet<_>>()
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
Ok(ApplicationResponse::Json(role_api::GroupsAndResources {
|
||||
groups,
|
||||
resources,
|
||||
}))
|
||||
}
|
||||
|
||||
pub async fn create_role(
|
||||
state: SessionState,
|
||||
user_from_token: UserFromToken,
|
||||
@ -111,6 +139,52 @@ pub async fn get_role_with_groups(
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn get_parent_info_for_role(
|
||||
state: SessionState,
|
||||
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)?;
|
||||
|
||||
if role_info.is_internal() {
|
||||
return Err(UserErrors::InvalidRoleId.into());
|
||||
}
|
||||
|
||||
let parent_groups = ParentGroup::get_descriptions_for_groups(
|
||||
role_info.get_entity_type(),
|
||||
role_info.get_permission_groups().to_vec(),
|
||||
)
|
||||
.into_iter()
|
||||
.map(|(parent_group, description)| role_api::ParentGroupInfo {
|
||||
name: parent_group.clone(),
|
||||
description,
|
||||
scopes: role_info
|
||||
.get_permission_groups()
|
||||
.iter()
|
||||
.filter_map(|group| (group.parent() == parent_group).then_some(group.scope()))
|
||||
// TODO: Remove this hashset conversion when merhant access
|
||||
// and organization access groups are removed
|
||||
.collect::<HashSet<_>>()
|
||||
.into_iter()
|
||||
.collect(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(ApplicationResponse::Json(role_api::RoleInfoWithParents {
|
||||
role_id: role.role_id,
|
||||
parent_groups,
|
||||
role_name: role_info.get_role_name().to_string(),
|
||||
role_scope: role_info.get_scope(),
|
||||
}))
|
||||
}
|
||||
|
||||
pub async fn update_role(
|
||||
state: SessionState,
|
||||
user_from_token: UserFromToken,
|
||||
|
||||
@ -1819,9 +1819,14 @@ impl User {
|
||||
web::resource("/permission_info")
|
||||
.route(web::get().to(user_role::get_authorization_info)),
|
||||
)
|
||||
// TODO: To be deprecated
|
||||
.service(
|
||||
web::resource("/module/list").route(web::get().to(user_role::get_role_information)),
|
||||
)
|
||||
.service(
|
||||
web::resource("/parent/list")
|
||||
.route(web::get().to(user_role::get_parent_group_info)),
|
||||
)
|
||||
.service(
|
||||
web::resource("/update").route(web::post().to(user::update_user_account_details)),
|
||||
)
|
||||
@ -2017,6 +2022,9 @@ impl User {
|
||||
.route(web::get().to(user_role::get_role_from_token))
|
||||
.route(web::post().to(user_role::create_role)),
|
||||
)
|
||||
.service(web::resource("/v2").route(
|
||||
web::get().to(user_role::get_groups_and_resources_for_role_from_token),
|
||||
))
|
||||
// TODO: To be deprecated
|
||||
.service(
|
||||
web::resource("/v2/list")
|
||||
@ -2039,6 +2047,10 @@ impl User {
|
||||
web::resource("/{role_id}")
|
||||
.route(web::get().to(user_role::get_role))
|
||||
.route(web::put().to(user_role::update_role)),
|
||||
)
|
||||
.service(
|
||||
web::resource("/{role_id}/v2")
|
||||
.route(web::get().to(user_role::get_parent_info_for_role)),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@ -263,10 +263,13 @@ impl From<Flow> for ApiIdentifier {
|
||||
| Flow::ListInvitableRolesAtEntityLevel
|
||||
| Flow::ListUpdatableRolesAtEntityLevel
|
||||
| Flow::GetRole
|
||||
| Flow::GetRoleV2
|
||||
| Flow::GetRoleFromToken
|
||||
| Flow::GetRoleFromTokenV2
|
||||
| Flow::UpdateUserRole
|
||||
| Flow::GetAuthorizationInfo
|
||||
| Flow::GetRolesInfo
|
||||
| Flow::GetParentGroupInfo
|
||||
| Flow::AcceptInvitationsV2
|
||||
| Flow::AcceptInvitationsPreAuth
|
||||
| Flow::DeleteUserRole
|
||||
|
||||
@ -55,6 +55,26 @@ pub async fn get_role_from_token(state: web::Data<AppState>, req: HttpRequest) -
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_groups_and_resources_for_role_from_token(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
) -> HttpResponse {
|
||||
let flow = Flow::GetRoleFromTokenV2;
|
||||
|
||||
Box::pin(api::server_wrap(
|
||||
flow,
|
||||
state.clone(),
|
||||
&req,
|
||||
(),
|
||||
|state, user, _, _| async move {
|
||||
role_core::get_groups_and_resources_for_role_from_token(state, user).await
|
||||
},
|
||||
&auth::DashboardNoPermissionAuth,
|
||||
api_locking::LockAction::NotApplicable,
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn create_role(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
@ -100,6 +120,31 @@ pub async fn get_role(
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_parent_info_for_role(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
path: web::Path<String>,
|
||||
) -> HttpResponse {
|
||||
let flow = Flow::GetRoleV2;
|
||||
let request_payload = user_role_api::role::GetRoleRequest {
|
||||
role_id: path.into_inner(),
|
||||
};
|
||||
Box::pin(api::server_wrap(
|
||||
flow,
|
||||
state.clone(),
|
||||
&req,
|
||||
request_payload,
|
||||
|state, user, payload, _| async move {
|
||||
role_core::get_parent_info_for_role(state, user, payload).await
|
||||
},
|
||||
&auth::JWTAuth {
|
||||
permission: Permission::ProfileUserRead,
|
||||
},
|
||||
api_locking::LockAction::NotApplicable,
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn update_role(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
@ -226,6 +271,28 @@ pub async fn get_role_information(
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_parent_group_info(
|
||||
state: web::Data<AppState>,
|
||||
http_req: HttpRequest,
|
||||
) -> HttpResponse {
|
||||
let flow = Flow::GetParentGroupInfo;
|
||||
|
||||
Box::pin(api::server_wrap(
|
||||
flow,
|
||||
state.clone(),
|
||||
&http_req,
|
||||
(),
|
||||
|state, user_from_token, _, _| async move {
|
||||
user_role_core::get_parent_group_info(state, user_from_token).await
|
||||
},
|
||||
&auth::JWTAuth {
|
||||
permission: Permission::ProfileUserRead,
|
||||
},
|
||||
api_locking::LockAction::NotApplicable,
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn list_users_in_lineage(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
|
||||
@ -37,32 +37,13 @@ fn get_group_description(group: PermissionGroup) -> &'static str {
|
||||
PermissionGroup::AnalyticsView => "View Analytics",
|
||||
PermissionGroup::UsersView => "View Users",
|
||||
PermissionGroup::UsersManage => "Manage and invite Users to the Team",
|
||||
PermissionGroup::MerchantDetailsView => "View Merchant Details",
|
||||
PermissionGroup::MerchantDetailsManage => "Create, modify and delete Merchant Details like api keys, webhooks, etc",
|
||||
PermissionGroup::MerchantDetailsView | PermissionGroup::AccountView => "View Merchant Details",
|
||||
PermissionGroup::MerchantDetailsManage | PermissionGroup::AccountManage => "Create, modify and delete Merchant Details like api keys, webhooks, etc",
|
||||
PermissionGroup::OrganizationManage => "Manage organization level tasks like create new Merchant accounts, Organization level roles, etc",
|
||||
PermissionGroup::ReconOps => "View and manage reconciliation reports",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_parent_name(group: PermissionGroup) -> ParentGroup {
|
||||
match group {
|
||||
PermissionGroup::OperationsView | PermissionGroup::OperationsManage => {
|
||||
ParentGroup::Operations
|
||||
}
|
||||
PermissionGroup::ConnectorsView | PermissionGroup::ConnectorsManage => {
|
||||
ParentGroup::Connectors
|
||||
}
|
||||
PermissionGroup::WorkflowsView | PermissionGroup::WorkflowsManage => ParentGroup::Workflows,
|
||||
PermissionGroup::AnalyticsView => ParentGroup::Analytics,
|
||||
PermissionGroup::UsersView | PermissionGroup::UsersManage => ParentGroup::Users,
|
||||
PermissionGroup::MerchantDetailsView | PermissionGroup::MerchantDetailsManage => {
|
||||
ParentGroup::Merchant
|
||||
}
|
||||
PermissionGroup::OrganizationManage => ParentGroup::Organization,
|
||||
PermissionGroup::ReconOps => ParentGroup::Recon,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_parent_group_description(group: ParentGroup) -> &'static str {
|
||||
match group {
|
||||
ParentGroup::Operations => "Payments, Refunds, Payouts, Mandates, Disputes and Customers",
|
||||
@ -70,8 +51,7 @@ pub fn get_parent_group_description(group: ParentGroup) -> &'static str {
|
||||
ParentGroup::Workflows => "Create, modify and delete Routing, 3DS Decision Manager, Surcharge Decision Manager",
|
||||
ParentGroup::Analytics => "View Analytics",
|
||||
ParentGroup::Users => "Manage and invite Users to the Team",
|
||||
ParentGroup::Merchant => "Create, modify and delete Merchant Details like api keys, webhooks, etc",
|
||||
ParentGroup::Organization =>"Manage organization level tasks like create new Merchant accounts, Organization level roles, etc",
|
||||
ParentGroup::Account => "Create, modify and delete Merchant Details like api keys, webhooks, etc",
|
||||
ParentGroup::Recon => "View and manage reconciliation reports",
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,9 @@
|
||||
use common_enums::{ParentGroup, PermissionGroup, PermissionScope, Resource};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use common_enums::{EntityType, ParentGroup, PermissionGroup, PermissionScope, Resource};
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use super::permissions::{self, ResourceExt};
|
||||
|
||||
pub trait PermissionGroupExt {
|
||||
fn scope(&self) -> PermissionScope;
|
||||
@ -15,7 +20,8 @@ impl PermissionGroupExt for PermissionGroup {
|
||||
| Self::WorkflowsView
|
||||
| Self::AnalyticsView
|
||||
| Self::UsersView
|
||||
| Self::MerchantDetailsView => PermissionScope::Read,
|
||||
| Self::MerchantDetailsView
|
||||
| Self::AccountView => PermissionScope::Read,
|
||||
|
||||
Self::OperationsManage
|
||||
| Self::ConnectorsManage
|
||||
@ -23,7 +29,8 @@ impl PermissionGroupExt for PermissionGroup {
|
||||
| Self::UsersManage
|
||||
| Self::MerchantDetailsManage
|
||||
| Self::OrganizationManage
|
||||
| Self::ReconOps => PermissionScope::Write,
|
||||
| Self::ReconOps
|
||||
| Self::AccountManage => PermissionScope::Write,
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,9 +41,12 @@ impl PermissionGroupExt for PermissionGroup {
|
||||
Self::WorkflowsView | Self::WorkflowsManage => ParentGroup::Workflows,
|
||||
Self::AnalyticsView => ParentGroup::Analytics,
|
||||
Self::UsersView | Self::UsersManage => ParentGroup::Users,
|
||||
Self::MerchantDetailsView | Self::MerchantDetailsManage => ParentGroup::Merchant,
|
||||
Self::OrganizationManage => ParentGroup::Organization,
|
||||
Self::ReconOps => ParentGroup::Recon,
|
||||
Self::MerchantDetailsView
|
||||
| Self::OrganizationManage
|
||||
| Self::MerchantDetailsManage
|
||||
| Self::AccountView
|
||||
| Self::AccountManage => ParentGroup::Account,
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,10 +62,14 @@ impl PermissionGroupExt for PermissionGroup {
|
||||
Self::ConnectorsView => vec![Self::ConnectorsView],
|
||||
Self::ConnectorsManage => vec![Self::ConnectorsView, Self::ConnectorsManage],
|
||||
|
||||
Self::WorkflowsView => vec![Self::WorkflowsView],
|
||||
Self::WorkflowsManage => vec![Self::WorkflowsView, Self::WorkflowsManage],
|
||||
Self::WorkflowsView => vec![Self::WorkflowsView, Self::ConnectorsView],
|
||||
Self::WorkflowsManage => vec![
|
||||
Self::WorkflowsView,
|
||||
Self::WorkflowsManage,
|
||||
Self::ConnectorsView,
|
||||
],
|
||||
|
||||
Self::AnalyticsView => vec![Self::AnalyticsView],
|
||||
Self::AnalyticsView => vec![Self::AnalyticsView, Self::OperationsView],
|
||||
|
||||
Self::UsersView => vec![Self::UsersView],
|
||||
Self::UsersManage => {
|
||||
@ -70,12 +84,19 @@ impl PermissionGroupExt for PermissionGroup {
|
||||
}
|
||||
|
||||
Self::OrganizationManage => vec![Self::OrganizationManage],
|
||||
|
||||
Self::AccountView => vec![Self::AccountView],
|
||||
Self::AccountManage => vec![Self::AccountView, Self::AccountManage],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ParentGroupExt {
|
||||
fn resources(&self) -> Vec<Resource>;
|
||||
fn get_descriptions_for_groups(
|
||||
entity_type: EntityType,
|
||||
groups: Vec<PermissionGroup>,
|
||||
) -> HashMap<ParentGroup, String>;
|
||||
}
|
||||
|
||||
impl ParentGroupExt for ParentGroup {
|
||||
@ -86,10 +107,38 @@ impl ParentGroupExt for ParentGroup {
|
||||
Self::Workflows => WORKFLOWS.to_vec(),
|
||||
Self::Analytics => ANALYTICS.to_vec(),
|
||||
Self::Users => USERS.to_vec(),
|
||||
Self::Merchant | Self::Organization => ACCOUNT.to_vec(),
|
||||
Self::Account => ACCOUNT.to_vec(),
|
||||
Self::Recon => RECON.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_descriptions_for_groups(
|
||||
entity_type: EntityType,
|
||||
groups: Vec<PermissionGroup>,
|
||||
) -> HashMap<Self, String> {
|
||||
Self::iter()
|
||||
.filter_map(|parent| {
|
||||
let scopes = groups
|
||||
.iter()
|
||||
.filter(|group| group.parent() == parent)
|
||||
.map(|group| group.scope())
|
||||
.max()?;
|
||||
|
||||
let resources = parent
|
||||
.resources()
|
||||
.iter()
|
||||
.filter(|res| res.entities().iter().any(|entity| entity <= &entity_type))
|
||||
.map(|res| permissions::get_resource_name(res, &entity_type))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
||||
Some((
|
||||
parent,
|
||||
format!("{} {}", permissions::get_scope_name(&scopes), resources),
|
||||
))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
pub static OPERATIONS: [Resource; 8] = [
|
||||
@ -105,11 +154,10 @@ pub static OPERATIONS: [Resource; 8] = [
|
||||
|
||||
pub static CONNECTORS: [Resource; 2] = [Resource::Connector, Resource::Account];
|
||||
|
||||
pub static WORKFLOWS: [Resource; 5] = [
|
||||
pub static WORKFLOWS: [Resource; 4] = [
|
||||
Resource::Routing,
|
||||
Resource::ThreeDsDecisionManager,
|
||||
Resource::SurchargeDecisionManager,
|
||||
Resource::Connector,
|
||||
Resource::Account,
|
||||
];
|
||||
|
||||
|
||||
@ -73,3 +73,34 @@ generate_permissions! {
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
pub fn get_resource_name(resource: &Resource, entity_type: &EntityType) -> &'static str {
|
||||
match (resource, entity_type) {
|
||||
(Resource::Payment, _) => "Payments",
|
||||
(Resource::Refund, _) => "Refunds",
|
||||
(Resource::Dispute, _) => "Disputes",
|
||||
(Resource::Mandate, _) => "Mandates",
|
||||
(Resource::Customer, _) => "Customers",
|
||||
(Resource::Payout, _) => "Payouts",
|
||||
(Resource::ApiKey, _) => "Api Keys",
|
||||
(Resource::Connector, _) => "Payment Processors, Payout Processors, Fraud & Risk Managers",
|
||||
(Resource::Routing, _) => "Routing",
|
||||
(Resource::ThreeDsDecisionManager, _) => "3DS Decision Manager",
|
||||
(Resource::SurchargeDecisionManager, _) => "Surcharge Decision Manager",
|
||||
(Resource::Analytics, _) => "Analytics",
|
||||
(Resource::Report, _) => "Operation Reports",
|
||||
(Resource::User, _) => "Users",
|
||||
(Resource::WebhookEvent, _) => "Webhook Events",
|
||||
(Resource::Recon, _) => "Reconciliation Reports",
|
||||
(Resource::Account, EntityType::Profile) => "Business Profile Account",
|
||||
(Resource::Account, EntityType::Merchant) => "Merchant Account",
|
||||
(Resource::Account, EntityType::Organization) => "Organization Account",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_scope_name(scope: &PermissionScope) -> &'static str {
|
||||
match scope {
|
||||
PermissionScope::Read => "View",
|
||||
PermissionScope::Write => "View and Manage",
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,9 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
PermissionGroup::UsersView,
|
||||
PermissionGroup::UsersManage,
|
||||
PermissionGroup::MerchantDetailsView,
|
||||
PermissionGroup::AccountView,
|
||||
PermissionGroup::MerchantDetailsManage,
|
||||
PermissionGroup::AccountManage,
|
||||
PermissionGroup::OrganizationManage,
|
||||
PermissionGroup::ReconOps,
|
||||
],
|
||||
@ -48,6 +50,7 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
PermissionGroup::AnalyticsView,
|
||||
PermissionGroup::UsersView,
|
||||
PermissionGroup::MerchantDetailsView,
|
||||
PermissionGroup::AccountView,
|
||||
],
|
||||
role_id: common_utils::consts::ROLE_ID_INTERNAL_VIEW_ONLY_USER.to_string(),
|
||||
role_name: "internal_view_only".to_string(),
|
||||
@ -75,7 +78,9 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
PermissionGroup::UsersView,
|
||||
PermissionGroup::UsersManage,
|
||||
PermissionGroup::MerchantDetailsView,
|
||||
PermissionGroup::AccountView,
|
||||
PermissionGroup::MerchantDetailsManage,
|
||||
PermissionGroup::AccountManage,
|
||||
PermissionGroup::OrganizationManage,
|
||||
PermissionGroup::ReconOps,
|
||||
],
|
||||
@ -105,7 +110,9 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
PermissionGroup::UsersView,
|
||||
PermissionGroup::UsersManage,
|
||||
PermissionGroup::MerchantDetailsView,
|
||||
PermissionGroup::AccountView,
|
||||
PermissionGroup::MerchantDetailsManage,
|
||||
PermissionGroup::AccountManage,
|
||||
PermissionGroup::ReconOps,
|
||||
],
|
||||
role_id: consts::user_role::ROLE_ID_MERCHANT_ADMIN.to_string(),
|
||||
@ -128,6 +135,7 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
PermissionGroup::AnalyticsView,
|
||||
PermissionGroup::UsersView,
|
||||
PermissionGroup::MerchantDetailsView,
|
||||
PermissionGroup::AccountView,
|
||||
],
|
||||
role_id: consts::user_role::ROLE_ID_MERCHANT_VIEW_ONLY.to_string(),
|
||||
role_name: "merchant_view_only".to_string(),
|
||||
@ -148,6 +156,7 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
PermissionGroup::UsersView,
|
||||
PermissionGroup::UsersManage,
|
||||
PermissionGroup::MerchantDetailsView,
|
||||
PermissionGroup::AccountView,
|
||||
],
|
||||
role_id: consts::user_role::ROLE_ID_MERCHANT_IAM_ADMIN.to_string(),
|
||||
role_name: "merchant_iam".to_string(),
|
||||
@ -168,7 +177,9 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
PermissionGroup::AnalyticsView,
|
||||
PermissionGroup::UsersView,
|
||||
PermissionGroup::MerchantDetailsView,
|
||||
PermissionGroup::AccountView,
|
||||
PermissionGroup::MerchantDetailsManage,
|
||||
PermissionGroup::AccountManage,
|
||||
],
|
||||
role_id: consts::user_role::ROLE_ID_MERCHANT_DEVELOPER.to_string(),
|
||||
role_name: "merchant_developer".to_string(),
|
||||
@ -191,6 +202,7 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
PermissionGroup::AnalyticsView,
|
||||
PermissionGroup::UsersView,
|
||||
PermissionGroup::MerchantDetailsView,
|
||||
PermissionGroup::AccountView,
|
||||
],
|
||||
role_id: consts::user_role::ROLE_ID_MERCHANT_OPERATOR.to_string(),
|
||||
role_name: "merchant_operator".to_string(),
|
||||
@ -210,6 +222,7 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
PermissionGroup::AnalyticsView,
|
||||
PermissionGroup::UsersView,
|
||||
PermissionGroup::MerchantDetailsView,
|
||||
PermissionGroup::AccountView,
|
||||
],
|
||||
role_id: consts::user_role::ROLE_ID_MERCHANT_CUSTOMER_SUPPORT.to_string(),
|
||||
role_name: "customer_support".to_string(),
|
||||
@ -237,7 +250,9 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
PermissionGroup::UsersView,
|
||||
PermissionGroup::UsersManage,
|
||||
PermissionGroup::MerchantDetailsView,
|
||||
PermissionGroup::AccountView,
|
||||
PermissionGroup::MerchantDetailsManage,
|
||||
PermissionGroup::AccountManage,
|
||||
],
|
||||
role_id: consts::user_role::ROLE_ID_PROFILE_ADMIN.to_string(),
|
||||
role_name: "profile_admin".to_string(),
|
||||
@ -259,6 +274,7 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
PermissionGroup::AnalyticsView,
|
||||
PermissionGroup::UsersView,
|
||||
PermissionGroup::MerchantDetailsView,
|
||||
PermissionGroup::AccountView,
|
||||
],
|
||||
role_id: consts::user_role::ROLE_ID_PROFILE_VIEW_ONLY.to_string(),
|
||||
role_name: "profile_view_only".to_string(),
|
||||
@ -279,6 +295,7 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
PermissionGroup::UsersView,
|
||||
PermissionGroup::UsersManage,
|
||||
PermissionGroup::MerchantDetailsView,
|
||||
PermissionGroup::AccountView,
|
||||
],
|
||||
role_id: consts::user_role::ROLE_ID_PROFILE_IAM_ADMIN.to_string(),
|
||||
role_name: "profile_iam".to_string(),
|
||||
@ -299,7 +316,9 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
PermissionGroup::AnalyticsView,
|
||||
PermissionGroup::UsersView,
|
||||
PermissionGroup::MerchantDetailsView,
|
||||
PermissionGroup::AccountView,
|
||||
PermissionGroup::MerchantDetailsManage,
|
||||
PermissionGroup::AccountManage,
|
||||
],
|
||||
role_id: consts::user_role::ROLE_ID_PROFILE_DEVELOPER.to_string(),
|
||||
role_name: "profile_developer".to_string(),
|
||||
@ -322,6 +341,7 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
PermissionGroup::AnalyticsView,
|
||||
PermissionGroup::UsersView,
|
||||
PermissionGroup::MerchantDetailsView,
|
||||
PermissionGroup::AccountView,
|
||||
],
|
||||
role_id: consts::user_role::ROLE_ID_PROFILE_OPERATOR.to_string(),
|
||||
role_name: "profile_operator".to_string(),
|
||||
@ -341,6 +361,7 @@ pub static PREDEFINED_ROLES: Lazy<HashMap<&'static str, RoleInfo>> = Lazy::new(|
|
||||
PermissionGroup::AnalyticsView,
|
||||
PermissionGroup::UsersView,
|
||||
PermissionGroup::MerchantDetailsView,
|
||||
PermissionGroup::AccountView,
|
||||
],
|
||||
role_id: consts::user_role::ROLE_ID_PROFILE_CUSTOMER_SUPPORT.to_string(),
|
||||
role_name: "profile_customer_support".to_string(),
|
||||
|
||||
@ -374,6 +374,8 @@ pub enum Flow {
|
||||
GetAuthorizationInfo,
|
||||
/// Get Roles info
|
||||
GetRolesInfo,
|
||||
/// Get Parent Group Info
|
||||
GetParentGroupInfo,
|
||||
/// List roles v2
|
||||
ListRolesV2,
|
||||
/// List invitable roles at entity level
|
||||
@ -382,8 +384,12 @@ pub enum Flow {
|
||||
ListUpdatableRolesAtEntityLevel,
|
||||
/// Get role
|
||||
GetRole,
|
||||
/// Get parent info for role
|
||||
GetRoleV2,
|
||||
/// Get role from token
|
||||
GetRoleFromToken,
|
||||
/// Get resources and groups for role from token
|
||||
GetRoleFromTokenV2,
|
||||
/// Update user role
|
||||
UpdateUserRole,
|
||||
/// Create merchant account for user in a org
|
||||
|
||||
Reference in New Issue
Block a user