From 7dcffccf3f16de5e40f61a302beb318035c3e88b Mon Sep 17 00:00:00 2001 From: Mani Chandra <84711804+ThisIsMani@users.noreply.github.com> Date: Wed, 30 Oct 2024 12:58:41 +0530 Subject: [PATCH] feat(authz): Make info APIs support `ParentGroup` (#6440) Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> --- crates/api_models/src/events/user_role.rs | 9 ++- crates/api_models/src/user_role/role.rs | 26 +++++- crates/common_enums/src/enums.rs | 20 +++-- crates/router/src/core/user_role.rs | 45 ++++++++++- crates/router/src/core/user_role/role.rs | 80 ++++++++++++++++++- crates/router/src/routes/app.rs | 12 +++ crates/router/src/routes/lock_utils.rs | 3 + crates/router/src/routes/user_role.rs | 67 ++++++++++++++++ .../router/src/services/authorization/info.rs | 26 +----- .../authorization/permission_groups.rs | 70 +++++++++++++--- .../src/services/authorization/permissions.rs | 31 +++++++ .../authorization/roles/predefined_roles.rs | 21 +++++ crates/router_env/src/logger/types.rs | 6 ++ 13 files changed, 364 insertions(+), 52 deletions(-) diff --git a/crates/api_models/src/events/user_role.rs b/crates/api_models/src/events/user_role.rs index a2c76ecc394..e0df36a3349 100644 --- a/crates/api_models/src/events/user_role.rs +++ b/crates/api_models/src/events/user_role.rs @@ -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 ) ); diff --git a/crates/api_models/src/user_role/role.rs b/crates/api_models/src/user_role/role.rs index 885ec455e4c..7c877cd7477 100644 --- a/crates/api_models/src/user_role/role.rs +++ b/crates/api_models/src/user_role/role.rs @@ -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, + pub role_name: String, + pub role_scope: RoleScope, +} + +#[derive(Debug, serde::Serialize)] +pub struct ParentGroupInfo { + pub name: ParentGroup, + pub description: String, + pub scopes: Vec, +} + #[derive(Debug, serde::Deserialize, serde::Serialize)] pub struct ListRolesRequest { pub entity_type: Option, @@ -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, + pub resources: Vec, +} diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index c103153eec8..faae71eda22 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -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 diff --git a/crates/router/src/core/user_role.rs b/crates/router/src/core/user_role.rs index 284be4ab4ba..27c1e2ae494 100644 --- a/crates/router/src/core/user_role.rs +++ b/crates/router/src/core/user_role.rs @@ -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> { + 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::>() + .into_iter() + .collect(), + }) + .collect::>(); + + Ok(ApplicationResponse::Json(parent_groups)) +} + pub async fn update_user_role( state: SessionState, user_from_token: auth::UserFromToken, diff --git a/crates/router/src/core/user_role/role.rs b/crates/router/src/core/user_role/role.rs index b5b5cab421f..1d37f7ac8d1 100644 --- a/crates/router/src/core/user_role/role.rs +++ b/crates/router/src/core/user_role/role.rs @@ -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> { +) -> UserResponse> { 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 { + let role_info = user_from_token.get_role_info_from_db(&state).await?; + + let groups = role_info + .get_permission_groups() + .into_iter() + .collect::>(); + let resources = groups + .iter() + .flat_map(|group| group.resources()) + .collect::>() + .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 { + 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::>() + .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, diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs index f11840edf63..f54895ce7da 100644 --- a/crates/router/src/routes/app.rs +++ b/crates/router/src/routes/app.rs @@ -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)), ), ); diff --git a/crates/router/src/routes/lock_utils.rs b/crates/router/src/routes/lock_utils.rs index a0c5c0f9902..ac17cf80210 100644 --- a/crates/router/src/routes/lock_utils.rs +++ b/crates/router/src/routes/lock_utils.rs @@ -263,10 +263,13 @@ impl From 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 diff --git a/crates/router/src/routes/user_role.rs b/crates/router/src/routes/user_role.rs index 74847f06474..9910cef3950 100644 --- a/crates/router/src/routes/user_role.rs +++ b/crates/router/src/routes/user_role.rs @@ -55,6 +55,26 @@ pub async fn get_role_from_token(state: web::Data, req: HttpRequest) - .await } +pub async fn get_groups_and_resources_for_role_from_token( + state: web::Data, + 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, req: HttpRequest, @@ -100,6 +120,31 @@ pub async fn get_role( .await } +pub async fn get_parent_info_for_role( + state: web::Data, + req: HttpRequest, + path: web::Path, +) -> 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, req: HttpRequest, @@ -226,6 +271,28 @@ pub async fn get_role_information( .await } +pub async fn get_parent_group_info( + state: web::Data, + 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, req: HttpRequest, diff --git a/crates/router/src/services/authorization/info.rs b/crates/router/src/services/authorization/info.rs index dba96dac188..bd987e2fe9a 100644 --- a/crates/router/src/services/authorization/info.rs +++ b/crates/router/src/services/authorization/info.rs @@ -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", } } diff --git a/crates/router/src/services/authorization/permission_groups.rs b/crates/router/src/services/authorization/permission_groups.rs index 3d1a0c8ea5b..57c385565a8 100644 --- a/crates/router/src/services/authorization/permission_groups.rs +++ b/crates/router/src/services/authorization/permission_groups.rs @@ -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; + fn get_descriptions_for_groups( + entity_type: EntityType, + groups: Vec, + ) -> HashMap; } 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, + ) -> HashMap { + 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::>() + .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, ]; diff --git a/crates/router/src/services/authorization/permissions.rs b/crates/router/src/services/authorization/permissions.rs index 0521db7acc1..6e472d55623 100644 --- a/crates/router/src/services/authorization/permissions.rs +++ b/crates/router/src/services/authorization/permissions.rs @@ -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", + } +} diff --git a/crates/router/src/services/authorization/roles/predefined_roles.rs b/crates/router/src/services/authorization/roles/predefined_roles.rs index 33a1d5f53ca..39f6d47f824 100644 --- a/crates/router/src/services/authorization/roles/predefined_roles.rs +++ b/crates/router/src/services/authorization/roles/predefined_roles.rs @@ -24,7 +24,9 @@ pub static PREDEFINED_ROLES: Lazy> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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(), diff --git a/crates/router_env/src/logger/types.rs b/crates/router_env/src/logger/types.rs index 8d853ded338..652ce2b81db 100644 --- a/crates/router_env/src/logger/types.rs +++ b/crates/router_env/src/logger/types.rs @@ -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