mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 12:06:56 +08:00
feat(users): Added get role from jwt api (#3385)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -43,6 +43,7 @@ pub enum Permission {
|
|||||||
SurchargeDecisionManagerRead,
|
SurchargeDecisionManagerRead,
|
||||||
UsersRead,
|
UsersRead,
|
||||||
UsersWrite,
|
UsersWrite,
|
||||||
|
MerchantAccountCreate,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, serde::Serialize)]
|
#[derive(Debug, serde::Serialize)]
|
||||||
@ -60,6 +61,7 @@ pub enum PermissionModule {
|
|||||||
Files,
|
Files,
|
||||||
ThreeDsDecisionManager,
|
ThreeDsDecisionManager,
|
||||||
SurchargeDecisionManager,
|
SurchargeDecisionManager,
|
||||||
|
AccountCreate,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, serde::Serialize)]
|
#[derive(Debug, serde::Serialize)]
|
||||||
|
|||||||
@ -20,7 +20,7 @@ pub async fn get_authorization_info(
|
|||||||
user_role_api::AuthorizationInfoResponse(
|
user_role_api::AuthorizationInfoResponse(
|
||||||
info::get_authorization_info()
|
info::get_authorization_info()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|module| module.try_into().ok())
|
.map(Into::into)
|
||||||
.collect(),
|
.collect(),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
@ -63,6 +63,22 @@ pub async fn get_role(
|
|||||||
Ok(ApplicationResponse::Json(info))
|
Ok(ApplicationResponse::Json(info))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_role_from_token(
|
||||||
|
_state: AppState,
|
||||||
|
user: auth::UserFromToken,
|
||||||
|
) -> UserResponse<Vec<user_role_api::Permission>> {
|
||||||
|
Ok(ApplicationResponse::Json(
|
||||||
|
predefined_permissions::PREDEFINED_PERMISSIONS
|
||||||
|
.get(user.role_id.as_str())
|
||||||
|
.ok_or(UserErrors::InternalServerError.into())
|
||||||
|
.attach_printable("Invalid Role Id in JWT")?
|
||||||
|
.get_permissions()
|
||||||
|
.iter()
|
||||||
|
.map(|&per| per.into())
|
||||||
|
.collect(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn update_user_role(
|
pub async fn update_user_role(
|
||||||
state: AppState,
|
state: AppState,
|
||||||
user_from_token: auth::UserFromToken,
|
user_from_token: auth::UserFromToken,
|
||||||
|
|||||||
@ -919,6 +919,7 @@ impl User {
|
|||||||
.service(web::resource("/permission_info").route(web::get().to(get_authorization_info)))
|
.service(web::resource("/permission_info").route(web::get().to(get_authorization_info)))
|
||||||
.service(web::resource("/user/update_role").route(web::post().to(update_user_role)))
|
.service(web::resource("/user/update_role").route(web::post().to(update_user_role)))
|
||||||
.service(web::resource("/role/list").route(web::get().to(list_roles)))
|
.service(web::resource("/role/list").route(web::get().to(list_roles)))
|
||||||
|
.service(web::resource("/role").route(web::get().to(get_role_from_token)))
|
||||||
.service(web::resource("/role/{role_id}").route(web::get().to(get_role)))
|
.service(web::resource("/role/{role_id}").route(web::get().to(get_role)))
|
||||||
.service(web::resource("/user/invite").route(web::post().to(invite_user)))
|
.service(web::resource("/user/invite").route(web::post().to(invite_user)))
|
||||||
.service(web::resource("/update").route(web::post().to(update_user_account_details)))
|
.service(web::resource("/update").route(web::post().to(update_user_account_details)))
|
||||||
|
|||||||
@ -181,9 +181,11 @@ impl From<Flow> for ApiIdentifier {
|
|||||||
| Flow::VerifyEmailRequest
|
| Flow::VerifyEmailRequest
|
||||||
| Flow::UpdateUserAccountDetails => Self::User,
|
| Flow::UpdateUserAccountDetails => Self::User,
|
||||||
|
|
||||||
Flow::ListRoles | Flow::GetRole | Flow::UpdateUserRole | Flow::GetAuthorizationInfo => {
|
Flow::ListRoles
|
||||||
Self::UserRole
|
| Flow::GetRole
|
||||||
}
|
| Flow::GetRoleFromToken
|
||||||
|
| Flow::UpdateUserRole
|
||||||
|
| Flow::GetAuthorizationInfo => Self::UserRole,
|
||||||
|
|
||||||
Flow::GetActionUrl | Flow::SyncOnboardingStatus | Flow::ResetTrackingId => {
|
Flow::GetActionUrl | Flow::SyncOnboardingStatus | Flow::ResetTrackingId => {
|
||||||
Self::ConnectorOnboarding
|
Self::ConnectorOnboarding
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use crate::{
|
|||||||
core::{api_locking, user_role as user_role_core},
|
core::{api_locking, user_role as user_role_core},
|
||||||
services::{
|
services::{
|
||||||
api,
|
api,
|
||||||
authentication::{self as auth},
|
authentication::{self as auth, UserFromToken},
|
||||||
authorization::permissions::Permission,
|
authorization::permissions::Permission,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -64,6 +64,20 @@ pub async fn get_role(
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_role_from_token(state: web::Data<AppState>, req: HttpRequest) -> HttpResponse {
|
||||||
|
let flow = Flow::GetRoleFromToken;
|
||||||
|
Box::pin(api::server_wrap(
|
||||||
|
flow,
|
||||||
|
state.clone(),
|
||||||
|
&req,
|
||||||
|
(),
|
||||||
|
|state, user: UserFromToken, _| user_role_core::get_role_from_token(state, user),
|
||||||
|
&auth::DashboardNoPermissionAuth,
|
||||||
|
api_locking::LockAction::NotApplicable,
|
||||||
|
))
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn update_user_role(
|
pub async fn update_user_role(
|
||||||
state: web::Data<AppState>,
|
state: web::Data<AppState>,
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
|
|||||||
@ -15,16 +15,13 @@ pub struct PermissionInfo {
|
|||||||
|
|
||||||
impl PermissionInfo {
|
impl PermissionInfo {
|
||||||
pub fn new(permissions: &[Permission]) -> Vec<Self> {
|
pub fn new(permissions: &[Permission]) -> Vec<Self> {
|
||||||
let mut permission_infos = Vec::with_capacity(permissions.len());
|
permissions
|
||||||
for permission in permissions {
|
.iter()
|
||||||
if let Some(description) = Permission::get_permission_description(permission) {
|
.map(|&per| Self {
|
||||||
permission_infos.push(Self {
|
description: Permission::get_permission_description(&per),
|
||||||
enum_name: permission.clone(),
|
enum_name: per,
|
||||||
description,
|
})
|
||||||
})
|
.collect()
|
||||||
}
|
|
||||||
}
|
|
||||||
permission_infos
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +40,7 @@ pub enum PermissionModule {
|
|||||||
Files,
|
Files,
|
||||||
ThreeDsDecisionManager,
|
ThreeDsDecisionManager,
|
||||||
SurchargeDecisionManager,
|
SurchargeDecisionManager,
|
||||||
|
AccountCreate,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PermissionModule {
|
impl PermissionModule {
|
||||||
@ -60,7 +58,8 @@ impl PermissionModule {
|
|||||||
Self::Disputes => "Everything related to disputes - like creating and viewing dispute related information are within this module",
|
Self::Disputes => "Everything related to disputes - like creating and viewing dispute related information are within this module",
|
||||||
Self::Files => "Permissions for uploading, deleting and viewing files for disputes",
|
Self::Files => "Permissions for uploading, deleting and viewing files for disputes",
|
||||||
Self::ThreeDsDecisionManager => "View and configure 3DS decision rules configured for a merchant",
|
Self::ThreeDsDecisionManager => "View and configure 3DS decision rules configured for a merchant",
|
||||||
Self::SurchargeDecisionManager =>"View and configure surcharge decision rules configured for a merchant"
|
Self::SurchargeDecisionManager =>"View and configure surcharge decision rules configured for a merchant",
|
||||||
|
Self::AccountCreate => "Create new account within your organization"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,6 +172,11 @@ impl ModuleInfo {
|
|||||||
Permission::SurchargeDecisionManagerRead,
|
Permission::SurchargeDecisionManagerRead,
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
|
PermissionModule::AccountCreate => Self {
|
||||||
|
module: module_name,
|
||||||
|
description,
|
||||||
|
permissions: PermissionInfo::new(&[Permission::MerchantAccountCreate]),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use strum::Display;
|
use strum::Display;
|
||||||
|
|
||||||
#[derive(PartialEq, Display, Clone, Debug)]
|
#[derive(PartialEq, Display, Clone, Debug, Copy)]
|
||||||
pub enum Permission {
|
pub enum Permission {
|
||||||
PaymentRead,
|
PaymentRead,
|
||||||
PaymentWrite,
|
PaymentWrite,
|
||||||
@ -34,45 +34,43 @@ pub enum Permission {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Permission {
|
impl Permission {
|
||||||
pub fn get_permission_description(&self) -> Option<&'static str> {
|
pub fn get_permission_description(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Self::PaymentRead => Some("View all payments"),
|
Self::PaymentRead => "View all payments",
|
||||||
Self::PaymentWrite => Some("Create payment, download payments data"),
|
Self::PaymentWrite => "Create payment, download payments data",
|
||||||
Self::RefundRead => Some("View all refunds"),
|
Self::RefundRead => "View all refunds",
|
||||||
Self::RefundWrite => Some("Create refund, download refunds data"),
|
Self::RefundWrite => "Create refund, download refunds data",
|
||||||
Self::ApiKeyRead => Some("View API keys (masked generated for the system"),
|
Self::ApiKeyRead => "View API keys (masked generated for the system",
|
||||||
Self::ApiKeyWrite => Some("Create and update API keys"),
|
Self::ApiKeyWrite => "Create and update API keys",
|
||||||
Self::MerchantAccountRead => Some("View merchant account details"),
|
Self::MerchantAccountRead => "View merchant account details",
|
||||||
Self::MerchantAccountWrite => {
|
Self::MerchantAccountWrite => {
|
||||||
Some("Update merchant account details, configure webhooks, manage api keys")
|
"Update merchant account details, configure webhooks, manage api keys"
|
||||||
}
|
}
|
||||||
Self::MerchantConnectorAccountRead => Some("View connectors configured"),
|
Self::MerchantConnectorAccountRead => "View connectors configured",
|
||||||
Self::MerchantConnectorAccountWrite => {
|
Self::MerchantConnectorAccountWrite => {
|
||||||
Some("Create, update, verify and delete connector configurations")
|
"Create, update, verify and delete connector configurations"
|
||||||
}
|
}
|
||||||
Self::ForexRead => Some("Query Forex data"),
|
Self::ForexRead => "Query Forex data",
|
||||||
Self::RoutingRead => Some("View routing configuration"),
|
Self::RoutingRead => "View routing configuration",
|
||||||
Self::RoutingWrite => Some("Create and activate routing configurations"),
|
Self::RoutingWrite => "Create and activate routing configurations",
|
||||||
Self::DisputeRead => Some("View disputes"),
|
Self::DisputeRead => "View disputes",
|
||||||
Self::DisputeWrite => Some("Create and update disputes"),
|
Self::DisputeWrite => "Create and update disputes",
|
||||||
Self::MandateRead => Some("View mandates"),
|
Self::MandateRead => "View mandates",
|
||||||
Self::MandateWrite => Some("Create and update mandates"),
|
Self::MandateWrite => "Create and update mandates",
|
||||||
Self::CustomerRead => Some("View customers"),
|
Self::CustomerRead => "View customers",
|
||||||
Self::CustomerWrite => Some("Create, update and delete customers"),
|
Self::CustomerWrite => "Create, update and delete customers",
|
||||||
Self::FileRead => Some("View files"),
|
Self::FileRead => "View files",
|
||||||
Self::FileWrite => Some("Create, update and delete files"),
|
Self::FileWrite => "Create, update and delete files",
|
||||||
Self::Analytics => Some("Access to analytics module"),
|
Self::Analytics => "Access to analytics module",
|
||||||
Self::ThreeDsDecisionManagerWrite => Some("Create and update 3DS decision rules"),
|
Self::ThreeDsDecisionManagerWrite => "Create and update 3DS decision rules",
|
||||||
Self::ThreeDsDecisionManagerRead => {
|
Self::ThreeDsDecisionManagerRead => {
|
||||||
Some("View all 3DS decision rules configured for a merchant")
|
"View all 3DS decision rules configured for a merchant"
|
||||||
}
|
}
|
||||||
Self::SurchargeDecisionManagerWrite => {
|
Self::SurchargeDecisionManagerWrite => "Create and update the surcharge decision rules",
|
||||||
Some("Create and update the surcharge decision rules")
|
Self::SurchargeDecisionManagerRead => "View all the surcharge decision rules",
|
||||||
}
|
Self::UsersRead => "View all the users for a merchant",
|
||||||
Self::SurchargeDecisionManagerRead => Some("View all the surcharge decision rules"),
|
Self::UsersWrite => "Invite users, assign and update roles",
|
||||||
Self::UsersRead => Some("View all the users for a merchant"),
|
Self::MerchantAccountCreate => "Create merchant account",
|
||||||
Self::UsersWrite => Some("Invite users, assign and update roles"),
|
|
||||||
Self::MerchantAccountCreate => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -762,19 +762,13 @@ impl UserFromStorage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<info::ModuleInfo> for user_role_api::ModuleInfo {
|
impl From<info::ModuleInfo> for user_role_api::ModuleInfo {
|
||||||
type Error = ();
|
fn from(value: info::ModuleInfo) -> Self {
|
||||||
fn try_from(value: info::ModuleInfo) -> Result<Self, Self::Error> {
|
Self {
|
||||||
let mut permissions = Vec::with_capacity(value.permissions.len());
|
|
||||||
for permission in value.permissions {
|
|
||||||
let permission = permission.try_into()?;
|
|
||||||
permissions.push(permission);
|
|
||||||
}
|
|
||||||
Ok(Self {
|
|
||||||
module: value.module.into(),
|
module: value.module.into(),
|
||||||
description: value.description,
|
description: value.description,
|
||||||
permissions,
|
permissions: value.permissions.into_iter().map(Into::into).collect(),
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -794,18 +788,17 @@ impl From<info::PermissionModule> for user_role_api::PermissionModule {
|
|||||||
info::PermissionModule::Files => Self::Files,
|
info::PermissionModule::Files => Self::Files,
|
||||||
info::PermissionModule::ThreeDsDecisionManager => Self::ThreeDsDecisionManager,
|
info::PermissionModule::ThreeDsDecisionManager => Self::ThreeDsDecisionManager,
|
||||||
info::PermissionModule::SurchargeDecisionManager => Self::SurchargeDecisionManager,
|
info::PermissionModule::SurchargeDecisionManager => Self::SurchargeDecisionManager,
|
||||||
|
info::PermissionModule::AccountCreate => Self::AccountCreate,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<info::PermissionInfo> for user_role_api::PermissionInfo {
|
impl From<info::PermissionInfo> for user_role_api::PermissionInfo {
|
||||||
type Error = ();
|
fn from(value: info::PermissionInfo) -> Self {
|
||||||
fn try_from(value: info::PermissionInfo) -> Result<Self, Self::Error> {
|
Self {
|
||||||
let enum_name = (&value.enum_name).try_into()?;
|
enum_name: value.enum_name.into(),
|
||||||
Ok(Self {
|
|
||||||
enum_name,
|
|
||||||
description: value.description,
|
description: value.description,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
use api_models::user_role as user_role_api;
|
use api_models::user_role as user_role_api;
|
||||||
use diesel_models::enums::UserStatus;
|
use diesel_models::enums::UserStatus;
|
||||||
use error_stack::ResultExt;
|
use error_stack::ResultExt;
|
||||||
use router_env::logger;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
consts,
|
consts,
|
||||||
@ -44,52 +43,50 @@ pub fn validate_role_id(role_id: &str) -> UserResult<()> {
|
|||||||
pub fn get_role_name_and_permission_response(
|
pub fn get_role_name_and_permission_response(
|
||||||
role_info: &RoleInfo,
|
role_info: &RoleInfo,
|
||||||
) -> Option<(Vec<user_role_api::Permission>, &'static str)> {
|
) -> Option<(Vec<user_role_api::Permission>, &'static str)> {
|
||||||
role_info
|
role_info.get_name().map(|name| {
|
||||||
.get_permissions()
|
(
|
||||||
.iter()
|
role_info
|
||||||
.map(TryInto::try_into)
|
.get_permissions()
|
||||||
.collect::<Result<Vec<user_role_api::Permission>, _>>()
|
.iter()
|
||||||
.ok()
|
.map(|&per| per.into())
|
||||||
.zip(role_info.get_name())
|
.collect::<Vec<user_role_api::Permission>>(),
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&Permission> for user_role_api::Permission {
|
impl From<Permission> for user_role_api::Permission {
|
||||||
type Error = ();
|
fn from(value: Permission) -> Self {
|
||||||
fn try_from(value: &Permission) -> Result<Self, Self::Error> {
|
|
||||||
match value {
|
match value {
|
||||||
Permission::PaymentRead => Ok(Self::PaymentRead),
|
Permission::PaymentRead => Self::PaymentRead,
|
||||||
Permission::PaymentWrite => Ok(Self::PaymentWrite),
|
Permission::PaymentWrite => Self::PaymentWrite,
|
||||||
Permission::RefundRead => Ok(Self::RefundRead),
|
Permission::RefundRead => Self::RefundRead,
|
||||||
Permission::RefundWrite => Ok(Self::RefundWrite),
|
Permission::RefundWrite => Self::RefundWrite,
|
||||||
Permission::ApiKeyRead => Ok(Self::ApiKeyRead),
|
Permission::ApiKeyRead => Self::ApiKeyRead,
|
||||||
Permission::ApiKeyWrite => Ok(Self::ApiKeyWrite),
|
Permission::ApiKeyWrite => Self::ApiKeyWrite,
|
||||||
Permission::MerchantAccountRead => Ok(Self::MerchantAccountRead),
|
Permission::MerchantAccountRead => Self::MerchantAccountRead,
|
||||||
Permission::MerchantAccountWrite => Ok(Self::MerchantAccountWrite),
|
Permission::MerchantAccountWrite => Self::MerchantAccountWrite,
|
||||||
Permission::MerchantConnectorAccountRead => Ok(Self::MerchantConnectorAccountRead),
|
Permission::MerchantConnectorAccountRead => Self::MerchantConnectorAccountRead,
|
||||||
Permission::MerchantConnectorAccountWrite => Ok(Self::MerchantConnectorAccountWrite),
|
Permission::MerchantConnectorAccountWrite => Self::MerchantConnectorAccountWrite,
|
||||||
Permission::ForexRead => Ok(Self::ForexRead),
|
Permission::ForexRead => Self::ForexRead,
|
||||||
Permission::RoutingRead => Ok(Self::RoutingRead),
|
Permission::RoutingRead => Self::RoutingRead,
|
||||||
Permission::RoutingWrite => Ok(Self::RoutingWrite),
|
Permission::RoutingWrite => Self::RoutingWrite,
|
||||||
Permission::DisputeRead => Ok(Self::DisputeRead),
|
Permission::DisputeRead => Self::DisputeRead,
|
||||||
Permission::DisputeWrite => Ok(Self::DisputeWrite),
|
Permission::DisputeWrite => Self::DisputeWrite,
|
||||||
Permission::MandateRead => Ok(Self::MandateRead),
|
Permission::MandateRead => Self::MandateRead,
|
||||||
Permission::MandateWrite => Ok(Self::MandateWrite),
|
Permission::MandateWrite => Self::MandateWrite,
|
||||||
Permission::CustomerRead => Ok(Self::CustomerRead),
|
Permission::CustomerRead => Self::CustomerRead,
|
||||||
Permission::CustomerWrite => Ok(Self::CustomerWrite),
|
Permission::CustomerWrite => Self::CustomerWrite,
|
||||||
Permission::FileRead => Ok(Self::FileRead),
|
Permission::FileRead => Self::FileRead,
|
||||||
Permission::FileWrite => Ok(Self::FileWrite),
|
Permission::FileWrite => Self::FileWrite,
|
||||||
Permission::Analytics => Ok(Self::Analytics),
|
Permission::Analytics => Self::Analytics,
|
||||||
Permission::ThreeDsDecisionManagerWrite => Ok(Self::ThreeDsDecisionManagerWrite),
|
Permission::ThreeDsDecisionManagerWrite => Self::ThreeDsDecisionManagerWrite,
|
||||||
Permission::ThreeDsDecisionManagerRead => Ok(Self::ThreeDsDecisionManagerRead),
|
Permission::ThreeDsDecisionManagerRead => Self::ThreeDsDecisionManagerRead,
|
||||||
Permission::SurchargeDecisionManagerWrite => Ok(Self::SurchargeDecisionManagerWrite),
|
Permission::SurchargeDecisionManagerWrite => Self::SurchargeDecisionManagerWrite,
|
||||||
Permission::SurchargeDecisionManagerRead => Ok(Self::SurchargeDecisionManagerRead),
|
Permission::SurchargeDecisionManagerRead => Self::SurchargeDecisionManagerRead,
|
||||||
Permission::UsersRead => Ok(Self::UsersRead),
|
Permission::UsersRead => Self::UsersRead,
|
||||||
Permission::UsersWrite => Ok(Self::UsersWrite),
|
Permission::UsersWrite => Self::UsersWrite,
|
||||||
|
Permission::MerchantAccountCreate => Self::MerchantAccountCreate,
|
||||||
Permission::MerchantAccountCreate => {
|
|
||||||
logger::error!("Invalid use of internal permission");
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -297,6 +297,8 @@ pub enum Flow {
|
|||||||
ListRoles,
|
ListRoles,
|
||||||
/// Get role
|
/// Get role
|
||||||
GetRole,
|
GetRole,
|
||||||
|
/// Get role from token
|
||||||
|
GetRoleFromToken,
|
||||||
/// Update user role
|
/// Update user role
|
||||||
UpdateUserRole,
|
UpdateUserRole,
|
||||||
/// Create merchant account for user in a org
|
/// Create merchant account for user in a org
|
||||||
|
|||||||
Reference in New Issue
Block a user