Skip to content

Commit

Permalink
feat(users): Added get role from jwt api
Browse files Browse the repository at this point in the history
  • Loading branch information
racnan committed Jan 18, 2024
1 parent 059e866 commit acd045a
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 103 deletions.
2 changes: 2 additions & 0 deletions crates/api_models/src/user_role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub enum Permission {
SurchargeDecisionManagerRead,
UsersRead,
UsersWrite,
MerchantAccountCreate,
}

#[derive(Debug, serde::Serialize)]
Expand All @@ -60,6 +61,7 @@ pub enum PermissionModule {
Files,
ThreeDsDecisionManager,
SurchargeDecisionManager,
AccountCreate,
}

#[derive(Debug, serde::Serialize)]
Expand Down
18 changes: 17 additions & 1 deletion crates/router/src/core/user_role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub async fn get_authorization_info(
user_role_api::AuthorizationInfoResponse(
info::get_authorization_info()
.into_iter()
.filter_map(|module| module.try_into().ok())
.map(Into::into)
.collect(),
),
))
Expand Down Expand Up @@ -63,6 +63,22 @@ pub async fn get_role(
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(Into::into)
.collect(),
))
}

pub async fn update_user_role(
state: AppState,
user_from_token: auth::UserFromToken,
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/routes/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,7 @@ impl User {
.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("/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("/user/invite").route(web::post().to(invite_user)))
.service(
Expand Down
8 changes: 5 additions & 3 deletions crates/router/src/routes/lock_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,11 @@ impl From<Flow> for ApiIdentifier {
| Flow::VerifyEmail
| Flow::VerifyEmailRequest => Self::User,

Flow::ListRoles | Flow::GetRole | Flow::UpdateUserRole | Flow::GetAuthorizationInfo => {
Self::UserRole
}
Flow::ListRoles
| Flow::GetRole
| Flow::GetRoleFromToken
| Flow::UpdateUserRole
| Flow::GetAuthorizationInfo => Self::UserRole,

Flow::GetActionUrl | Flow::SyncOnboardingStatus | Flow::ResetTrackingId => {
Self::ConnectorOnboarding
Expand Down
16 changes: 15 additions & 1 deletion crates/router/src/routes/user_role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
core::{api_locking, user_role as user_role_core},
services::{
api,
authentication::{self as auth},
authentication::{self as auth, UserFromToken},
authorization::permissions::Permission,
},
};
Expand Down Expand Up @@ -64,6 +64,20 @@ pub async fn get_role(
.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::JWTAuth(Permission::UsersRead),
api_locking::LockAction::NotApplicable,
))
.await
}

pub async fn update_user_role(
state: web::Data<AppState>,
req: HttpRequest,
Expand Down
26 changes: 15 additions & 11 deletions crates/router/src/services/authorization/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,13 @@ pub struct PermissionInfo {

impl PermissionInfo {
pub fn new(permissions: &[Permission]) -> Vec<Self> {
let mut permission_infos = Vec::with_capacity(permissions.len());
for permission in permissions {
if let Some(description) = Permission::get_permission_description(permission) {
permission_infos.push(Self {
enum_name: permission.clone(),
description,
})
}
}
permission_infos
permissions
.iter()
.map(|per| Self {
description: Permission::get_permission_description(per),
enum_name: per.clone(),
})
.collect()
}
}

Expand All @@ -43,6 +40,7 @@ pub enum PermissionModule {
Files,
ThreeDsDecisionManager,
SurchargeDecisionManager,
AccountCreate,
}

impl PermissionModule {
Expand All @@ -60,7 +58,8 @@ impl PermissionModule {
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::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 you organisation"
}
}
}
Expand Down Expand Up @@ -173,6 +172,11 @@ impl ModuleInfo {
Permission::SurchargeDecisionManagerRead,
]),
},
PermissionModule::AccountCreate => Self {
module: module_name,
description,
permissions: PermissionInfo::new(&[Permission::MerchantAccountCreate]),
},
}
}
}
62 changes: 30 additions & 32 deletions crates/router/src/services/authorization/permissions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,45 +34,43 @@ pub enum Permission {
}

impl Permission {
pub fn get_permission_description(&self) -> Option<&'static str> {
pub fn get_permission_description(&self) -> &'static str {
match self {
Self::PaymentRead => Some("View all payments"),
Self::PaymentWrite => Some("Create payment, download payments data"),
Self::RefundRead => Some("View all refunds"),
Self::RefundWrite => Some("Create refund, download refunds data"),
Self::ApiKeyRead => Some("View API keys (masked generated for the system"),
Self::ApiKeyWrite => Some("Create and update API keys"),
Self::MerchantAccountRead => Some("View merchant account details"),
Self::PaymentRead => "View all payments",
Self::PaymentWrite => "Create payment, download payments data",
Self::RefundRead => "View all refunds",
Self::RefundWrite => "Create refund, download refunds data",
Self::ApiKeyRead => "View API keys (masked generated for the system",
Self::ApiKeyWrite => "Create and update API keys",
Self::MerchantAccountRead => "View merchant account details",
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 => {
Some("Create, update, verify and delete connector configurations")
"Create, update, verify and delete connector configurations"
}
Self::ForexRead => Some("Query Forex data"),
Self::RoutingRead => Some("View routing configuration"),
Self::RoutingWrite => Some("Create and activate routing configurations"),
Self::DisputeRead => Some("View disputes"),
Self::DisputeWrite => Some("Create and update disputes"),
Self::MandateRead => Some("View mandates"),
Self::MandateWrite => Some("Create and update mandates"),
Self::CustomerRead => Some("View customers"),
Self::CustomerWrite => Some("Create, update and delete customers"),
Self::FileRead => Some("View files"),
Self::FileWrite => Some("Create, update and delete files"),
Self::Analytics => Some("Access to analytics module"),
Self::ThreeDsDecisionManagerWrite => Some("Create and update 3DS decision rules"),
Self::ForexRead => "Query Forex data",
Self::RoutingRead => "View routing configuration",
Self::RoutingWrite => "Create and activate routing configurations",
Self::DisputeRead => "View disputes",
Self::DisputeWrite => "Create and update disputes",
Self::MandateRead => "View mandates",
Self::MandateWrite => "Create and update mandates",
Self::CustomerRead => "View customers",
Self::CustomerWrite => "Create, update and delete customers",
Self::FileRead => "View files",
Self::FileWrite => "Create, update and delete files",
Self::Analytics => "Access to analytics module",
Self::ThreeDsDecisionManagerWrite => "Create and update 3DS decision rules",
Self::ThreeDsDecisionManagerRead => {
Some("View all 3DS decision rules configured for a merchant")
"View all 3DS decision rules configured for a merchant"
}
Self::SurchargeDecisionManagerWrite => {
Some("Create and update the surcharge decision rules")
}
Self::SurchargeDecisionManagerRead => Some("View all the surcharge decision rules"),
Self::UsersRead => Some("View all the users for a merchant"),
Self::UsersWrite => Some("Invite users, assign and update roles"),
Self::MerchantAccountCreate => None,
Self::SurchargeDecisionManagerWrite => "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::UsersWrite => "Invite users, assign and update roles",
Self::MerchantAccountCreate => "Create merchant account",
}
}
}
29 changes: 11 additions & 18 deletions crates/router/src/types/domain/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -762,19 +762,13 @@ impl UserFromStorage {
}
}

impl TryFrom<info::ModuleInfo> for user_role_api::ModuleInfo {
type Error = ();
fn try_from(value: info::ModuleInfo) -> Result<Self, Self::Error> {
let mut permissions = Vec::with_capacity(value.permissions.len());
for permission in value.permissions {
let permission = permission.try_into()?;
permissions.push(permission);
}
Ok(Self {
impl From<info::ModuleInfo> for user_role_api::ModuleInfo {
fn from(value: info::ModuleInfo) -> Self {
Self {
module: value.module.into(),
description: value.description,
permissions,
})
permissions: value.permissions.into_iter().map(Into::into).collect(),
}
}
}

Expand All @@ -794,18 +788,17 @@ impl From<info::PermissionModule> for user_role_api::PermissionModule {
info::PermissionModule::Files => Self::Files,
info::PermissionModule::ThreeDsDecisionManager => Self::ThreeDsDecisionManager,
info::PermissionModule::SurchargeDecisionManager => Self::SurchargeDecisionManager,
info::PermissionModule::AccountCreate => Self::AccountCreate,
}
}
}

impl TryFrom<info::PermissionInfo> for user_role_api::PermissionInfo {
type Error = ();
fn try_from(value: info::PermissionInfo) -> Result<Self, Self::Error> {
let enum_name = (&value.enum_name).try_into()?;
Ok(Self {
enum_name,
impl From<info::PermissionInfo> for user_role_api::PermissionInfo {
fn from(value: info::PermissionInfo) -> Self {
Self {
enum_name: (&value.enum_name).into(),
description: value.description,
})
}
}
}

Expand Down
68 changes: 31 additions & 37 deletions crates/router/src/utils/user_role.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use api_models::user_role as user_role_api;
use diesel_models::enums::UserStatus;
use error_stack::ResultExt;
use router_env::logger;

use crate::{
consts,
Expand Down Expand Up @@ -53,43 +52,38 @@ pub fn get_role_name_and_permission_response(
.zip(role_info.get_name())
}

impl TryFrom<&Permission> for user_role_api::Permission {
type Error = ();
fn try_from(value: &Permission) -> Result<Self, Self::Error> {
impl From<&Permission> for user_role_api::Permission {
fn from(value: &Permission) -> Self {
match value {
Permission::PaymentRead => Ok(Self::PaymentRead),
Permission::PaymentWrite => Ok(Self::PaymentWrite),
Permission::RefundRead => Ok(Self::RefundRead),
Permission::RefundWrite => Ok(Self::RefundWrite),
Permission::ApiKeyRead => Ok(Self::ApiKeyRead),
Permission::ApiKeyWrite => Ok(Self::ApiKeyWrite),
Permission::MerchantAccountRead => Ok(Self::MerchantAccountRead),
Permission::MerchantAccountWrite => Ok(Self::MerchantAccountWrite),
Permission::MerchantConnectorAccountRead => Ok(Self::MerchantConnectorAccountRead),
Permission::MerchantConnectorAccountWrite => Ok(Self::MerchantConnectorAccountWrite),
Permission::ForexRead => Ok(Self::ForexRead),
Permission::RoutingRead => Ok(Self::RoutingRead),
Permission::RoutingWrite => Ok(Self::RoutingWrite),
Permission::DisputeRead => Ok(Self::DisputeRead),
Permission::DisputeWrite => Ok(Self::DisputeWrite),
Permission::MandateRead => Ok(Self::MandateRead),
Permission::MandateWrite => Ok(Self::MandateWrite),
Permission::CustomerRead => Ok(Self::CustomerRead),
Permission::CustomerWrite => Ok(Self::CustomerWrite),
Permission::FileRead => Ok(Self::FileRead),
Permission::FileWrite => Ok(Self::FileWrite),
Permission::Analytics => Ok(Self::Analytics),
Permission::ThreeDsDecisionManagerWrite => Ok(Self::ThreeDsDecisionManagerWrite),
Permission::ThreeDsDecisionManagerRead => Ok(Self::ThreeDsDecisionManagerRead),
Permission::SurchargeDecisionManagerWrite => Ok(Self::SurchargeDecisionManagerWrite),
Permission::SurchargeDecisionManagerRead => Ok(Self::SurchargeDecisionManagerRead),
Permission::UsersRead => Ok(Self::UsersRead),
Permission::UsersWrite => Ok(Self::UsersWrite),

Permission::MerchantAccountCreate => {
logger::error!("Invalid use of internal permission");
Err(())
}
Permission::PaymentRead => Self::PaymentRead,
Permission::PaymentWrite => Self::PaymentWrite,
Permission::RefundRead => Self::RefundRead,
Permission::RefundWrite => Self::RefundWrite,
Permission::ApiKeyRead => Self::ApiKeyRead,
Permission::ApiKeyWrite => Self::ApiKeyWrite,
Permission::MerchantAccountRead => Self::MerchantAccountRead,
Permission::MerchantAccountWrite => Self::MerchantAccountWrite,
Permission::MerchantConnectorAccountRead => Self::MerchantConnectorAccountRead,
Permission::MerchantConnectorAccountWrite => Self::MerchantConnectorAccountWrite,
Permission::ForexRead => Self::ForexRead,
Permission::RoutingRead => Self::RoutingRead,
Permission::RoutingWrite => Self::RoutingWrite,
Permission::DisputeRead => Self::DisputeRead,
Permission::DisputeWrite => Self::DisputeWrite,
Permission::MandateRead => Self::MandateRead,
Permission::MandateWrite => Self::MandateWrite,
Permission::CustomerRead => Self::CustomerRead,
Permission::CustomerWrite => Self::CustomerWrite,
Permission::FileRead => Self::FileRead,
Permission::FileWrite => Self::FileWrite,
Permission::Analytics => Self::Analytics,
Permission::ThreeDsDecisionManagerWrite => Self::ThreeDsDecisionManagerWrite,
Permission::ThreeDsDecisionManagerRead => Self::ThreeDsDecisionManagerRead,
Permission::SurchargeDecisionManagerWrite => Self::SurchargeDecisionManagerWrite,
Permission::SurchargeDecisionManagerRead => Self::SurchargeDecisionManagerRead,
Permission::UsersRead => Self::UsersRead,
Permission::UsersWrite => Self::UsersWrite,
Permission::MerchantAccountCreate => Self::MerchantAccountCreate,
}
}
}
2 changes: 2 additions & 0 deletions crates/router_env/src/logger/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ pub enum Flow {
ListRoles,
/// Get role
GetRole,
/// Get role from token
GetRoleFromToken,
/// Update user role
UpdateUserRole,
/// Create merchant account for user in a org
Expand Down

0 comments on commit acd045a

Please sign in to comment.