diff --git a/crates/api_models/src/user_role.rs b/crates/api_models/src/user_role.rs index 02e40e2fe1af..5319c81385a8 100644 --- a/crates/api_models/src/user_role.rs +++ b/crates/api_models/src/user_role.rs @@ -38,6 +38,19 @@ pub enum Permission { GenerateReport, } +#[derive(Clone, Debug, serde::Serialize, PartialEq, Eq, Hash)] +pub enum ParentGroup { + Operations, + Connectors, + Workflows, + Analytics, + Users, + #[serde(rename = "MerchantAccess")] + Merchant, + #[serde(rename = "OrganizationAccess")] + Organization, +} + #[derive(Debug, serde::Serialize)] pub enum PermissionModule { Payments, @@ -63,6 +76,7 @@ pub struct AuthorizationInfoResponse(pub Vec); pub enum AuthorizationInfo { Module(ModuleInfo), Group(GroupInfo), + GroupWithTag(ParentInfo), } #[derive(Debug, serde::Serialize)] @@ -79,6 +93,13 @@ pub struct GroupInfo { pub permissions: Vec, } +#[derive(Debug, serde::Serialize, Clone)] +pub struct ParentInfo { + pub name: ParentGroup, + pub description: &'static str, + pub groups: Vec, +} + #[derive(Debug, serde::Serialize)] pub struct PermissionInfo { pub enum_name: Permission, diff --git a/crates/router/src/core/user_role.rs b/crates/router/src/core/user_role.rs index f2fddd61bb62..d9ee8f218052 100644 --- a/crates/router/src/core/user_role.rs +++ b/crates/router/src/core/user_role.rs @@ -1,9 +1,12 @@ +use std::collections::HashMap; + use api_models::{user as user_api, user_role as user_role_api}; use diesel_models::{ enums::{UserRoleVersion, UserStatus}, user_role::UserRoleUpdate, }; use error_stack::{report, ResultExt}; +use once_cell::sync::Lazy; use router_env::logger; use crate::{ @@ -18,8 +21,9 @@ use crate::{ types::domain, utils, }; - pub mod role; +use common_enums::PermissionGroup; +use strum::IntoEnumIterator; // TODO: To be deprecated once groups are stable pub async fn get_authorization_info_with_modules( @@ -47,6 +51,38 @@ pub async fn get_authorization_info_with_groups( ), )) } +pub async fn get_authorization_info_with_group_tag( +) -> UserResponse { + static GROUPS_WITH_PARENT_TAGS: Lazy> = Lazy::new(|| { + PermissionGroup::iter() + .map(|value| (info::get_parent_name(value), value)) + .fold( + HashMap::new(), + |mut acc: HashMap>, + (key, value)| { + acc.entry(key).or_default().push(value); + acc + }, + ) + .into_iter() + .map(|(name, value)| user_role_api::ParentInfo { + name: name.clone(), + description: info::get_parent_group_description(name), + groups: value, + }) + .collect() + }); + + Ok(ApplicationResponse::Json( + user_role_api::AuthorizationInfoResponse( + GROUPS_WITH_PARENT_TAGS + .iter() + .cloned() + .map(user_role_api::AuthorizationInfo::GroupWithTag) + .collect(), + ), + )) +} pub async fn update_user_role( state: SessionState, diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs index 5fe71a6a8da1..3d6fcb103c4a 100644 --- a/crates/router/src/routes/app.rs +++ b/crates/router/src/routes/app.rs @@ -1611,6 +1611,7 @@ impl User { .route(web::get().to(list_merchants_for_user)), ) .service(web::resource("/permission_info").route(web::get().to(get_authorization_info))) + .service(web::resource("/module/list").route(web::get().to(get_role_information))) .service(web::resource("/update").route(web::post().to(update_user_account_details))) .service( web::resource("/data") diff --git a/crates/router/src/routes/lock_utils.rs b/crates/router/src/routes/lock_utils.rs index 9f073853d88c..a0e8ed2f8b7e 100644 --- a/crates/router/src/routes/lock_utils.rs +++ b/crates/router/src/routes/lock_utils.rs @@ -250,6 +250,7 @@ impl From for ApiIdentifier { | Flow::GetRoleFromToken | Flow::UpdateUserRole | Flow::GetAuthorizationInfo + | Flow::GetRolesInfo | Flow::AcceptInvitation | Flow::MerchantSelect | Flow::DeleteUserRole diff --git a/crates/router/src/routes/user_role.rs b/crates/router/src/routes/user_role.rs index 4239f2d38146..bce0e6da1472 100644 --- a/crates/router/src/routes/user_role.rs +++ b/crates/router/src/routes/user_role.rs @@ -268,3 +268,23 @@ pub async fn delete_user_role( )) .await } + +pub async fn get_role_information( + state: web::Data, + http_req: HttpRequest, +) -> HttpResponse { + let flow = Flow::GetRolesInfo; + + Box::pin(api::server_wrap( + flow, + state.clone(), + &http_req, + (), + |_, _: (), _, _| async move { + user_role_core::get_authorization_info_with_group_tag().await + }, + &auth::JWTAuth(Permission::UsersRead), + api_locking::LockAction::NotApplicable, + )) + .await +} diff --git a/crates/router/src/services/authorization/info.rs b/crates/router/src/services/authorization/info.rs index 371087cc303f..ca5a66893950 100644 --- a/crates/router/src/services/authorization/info.rs +++ b/crates/router/src/services/authorization/info.rs @@ -1,4 +1,4 @@ -use api_models::user_role::{GroupInfo, PermissionInfo}; +use api_models::user_role::{GroupInfo, ParentGroup, PermissionInfo}; use common_enums::PermissionGroup; use strum::{EnumIter, IntoEnumIterator}; @@ -217,3 +217,33 @@ fn get_group_description(group: PermissionGroup) -> &'static str { PermissionGroup::OrganizationManage => "Manage organization level tasks like create new Merchant accounts, Organization level roles, etc", } } + +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, + } +} + +pub fn get_parent_group_description(group: ParentGroup) -> &'static str { + match group { + ParentGroup::Operations => "Payments, Refunds, Payouts, Mandates, Disputes and Customers", + ParentGroup::Connectors => "Create, modify and delete connectors like Payment Processors, Payout Processors and Fraud & Risk Manager", + 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", + } +} diff --git a/crates/router_env/src/logger/types.rs b/crates/router_env/src/logger/types.rs index f1d2e5d8dccb..8142aa437ed0 100644 --- a/crates/router_env/src/logger/types.rs +++ b/crates/router_env/src/logger/types.rs @@ -354,6 +354,8 @@ pub enum Flow { SwitchMerchant, /// Get permission info GetAuthorizationInfo, + /// Get Roles info + GetRolesInfo, /// List roles ListRoles, /// Get role