feat(users): Add new API get the user and role details of specific user (#3988)

This commit is contained in:
Mani Chandra
2024-03-07 11:53:24 +05:30
committed by GitHub
parent 3fc3874057
commit ba42fbaed0
7 changed files with 106 additions and 15 deletions

View File

@ -11,11 +11,11 @@ use crate::user::{
GetMetaDataRequest, GetMetaDataResponse, GetMultipleMetaDataPayload, SetMetaDataRequest, GetMetaDataRequest, GetMetaDataResponse, GetMultipleMetaDataPayload, SetMetaDataRequest,
}, },
AcceptInviteFromEmailRequest, AuthorizeResponse, ChangePasswordRequest, ConnectAccountRequest, AcceptInviteFromEmailRequest, AuthorizeResponse, ChangePasswordRequest, ConnectAccountRequest,
CreateInternalUserRequest, DashboardEntryResponse, ForgotPasswordRequest, GetUsersResponse, CreateInternalUserRequest, DashboardEntryResponse, ForgotPasswordRequest,
InviteUserRequest, InviteUserResponse, ReInviteUserRequest, ResetPasswordRequest, GetUserDetailsRequest, GetUserDetailsResponse, InviteUserRequest, InviteUserResponse,
SendVerifyEmailRequest, SignInResponse, SignUpRequest, SignUpWithMerchantIdRequest, ListUsersResponse, ReInviteUserRequest, ResetPasswordRequest, SendVerifyEmailRequest,
SwitchMerchantIdRequest, UpdateUserAccountDetailsRequest, UserMerchantCreate, SignInResponse, SignUpRequest, SignUpWithMerchantIdRequest, SwitchMerchantIdRequest,
VerifyEmailRequest, UpdateUserAccountDetailsRequest, UserMerchantCreate, VerifyEmailRequest,
}; };
impl ApiEventMetric for DashboardEntryResponse { impl ApiEventMetric for DashboardEntryResponse {
@ -48,7 +48,7 @@ common_utils::impl_misc_api_event_type!(
SwitchMerchantIdRequest, SwitchMerchantIdRequest,
CreateInternalUserRequest, CreateInternalUserRequest,
UserMerchantCreate, UserMerchantCreate,
GetUsersResponse, ListUsersResponse,
AuthorizeResponse, AuthorizeResponse,
ConnectAccountRequest, ConnectAccountRequest,
ForgotPasswordRequest, ForgotPasswordRequest,
@ -60,7 +60,9 @@ common_utils::impl_misc_api_event_type!(
SendVerifyEmailRequest, SendVerifyEmailRequest,
AcceptInviteFromEmailRequest, AcceptInviteFromEmailRequest,
SignInResponse, SignInResponse,
UpdateUserAccountDetailsRequest UpdateUserAccountDetailsRequest,
GetUserDetailsRequest,
GetUserDetailsResponse
); );
#[cfg(feature = "dummy_connector")] #[cfg(feature = "dummy_connector")]

View File

@ -1,3 +1,4 @@
use common_enums::{PermissionGroup, RoleScope};
use common_utils::{crypto::OptionalEncryptableName, pii}; use common_utils::{crypto::OptionalEncryptableName, pii};
use masking::Secret; use masking::Secret;
@ -141,7 +142,7 @@ pub struct UserMerchantCreate {
} }
#[derive(Debug, serde::Serialize)] #[derive(Debug, serde::Serialize)]
pub struct GetUsersResponse(pub Vec<UserDetails>); pub struct ListUsersResponse(pub Vec<UserDetails>);
#[derive(Debug, serde::Serialize)] #[derive(Debug, serde::Serialize)]
pub struct UserDetails { pub struct UserDetails {
@ -154,6 +155,24 @@ pub struct UserDetails {
pub last_modified_at: time::PrimitiveDateTime, pub last_modified_at: time::PrimitiveDateTime,
} }
#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct GetUserDetailsRequest {
pub email: pii::Email,
}
#[derive(Debug, serde::Serialize)]
pub struct GetUserDetailsResponse {
pub email: pii::Email,
pub name: Secret<String>,
pub role_id: String,
pub role_name: String,
pub status: UserStatus,
#[serde(with = "common_utils::custom_serde::iso8601")]
pub last_modified_at: time::PrimitiveDateTime,
pub groups: Vec<PermissionGroup>,
pub role_scope: RoleScope,
}
#[derive(Debug, serde::Deserialize, serde::Serialize)] #[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct VerifyEmailRequest { pub struct VerifyEmailRequest {
pub token: Secret<String>, pub token: Secret<String>,

View File

@ -1200,10 +1200,53 @@ pub async fn list_merchant_ids_for_user(
)) ))
} }
pub async fn get_users_for_merchant_account( pub async fn get_user_details_in_merchant_account(
state: AppState, state: AppState,
user_from_token: auth::UserFromToken, user_from_token: auth::UserFromToken,
) -> UserResponse<user_api::GetUsersResponse> { request: user_api::GetUserDetailsRequest,
) -> UserResponse<user_api::GetUserDetailsResponse> {
let required_user = utils::user::get_user_from_db_by_email(&state, request.email.try_into()?)
.await
.to_not_found_response(UserErrors::InvalidRoleOperation)?;
let required_user_role = state
.store
.find_user_role_by_user_id_merchant_id(
required_user.get_user_id(),
&user_from_token.merchant_id,
)
.await
.to_not_found_response(UserErrors::InvalidRoleOperation)
.attach_printable("User not found in the merchant account")?;
let role_info = roles::RoleInfo::from_role_id(
&state,
&required_user_role.role_id,
&user_from_token.merchant_id,
&user_from_token.org_id,
)
.await
.change_context(UserErrors::InternalServerError)
.attach_printable("User role exists but the corresponding role doesn't")?;
Ok(ApplicationResponse::Json(
user_api::GetUserDetailsResponse {
email: required_user.get_email(),
name: required_user.get_name(),
role_id: role_info.get_role_id().to_string(),
role_name: role_info.get_role_name().to_string(),
status: required_user_role.status.foreign_into(),
last_modified_at: required_user_role.last_modified,
groups: role_info.get_permission_groups().to_vec(),
role_scope: role_info.get_scope(),
},
))
}
pub async fn list_users_for_merchant_account(
state: AppState,
user_from_token: auth::UserFromToken,
) -> UserResponse<user_api::ListUsersResponse> {
let users_and_user_roles = state let users_and_user_roles = state
.store .store
.find_users_and_roles_by_merchant_id(user_from_token.merchant_id.as_str()) .find_users_and_roles_by_merchant_id(user_from_token.merchant_id.as_str())
@ -1242,7 +1285,7 @@ pub async fn get_users_for_merchant_account(
}) })
.collect(); .collect();
Ok(ApplicationResponse::Json(user_api::GetUsersResponse( Ok(ApplicationResponse::Json(user_api::ListUsersResponse(
user_details_vec, user_details_vec,
))) )))
} }

View File

@ -1120,7 +1120,10 @@ impl User {
// User management // User management
route = route.service( route = route.service(
web::scope("/user") web::scope("/user")
.service(web::resource("/list").route(web::get().to(get_user_details))) .service(web::resource("").route(web::get().to(get_user_role_details)))
.service(
web::resource("/list").route(web::get().to(list_users_for_merchant_account)),
)
.service(web::resource("/invite").route(web::post().to(invite_user))) .service(web::resource("/invite").route(web::post().to(invite_user)))
.service( .service(
web::resource("/invite_multiple").route(web::post().to(invite_multiple_user)), web::resource("/invite_multiple").route(web::post().to(invite_multiple_user)),

View File

@ -185,6 +185,7 @@ impl From<Flow> for ApiIdentifier {
| Flow::DeleteSampleData | Flow::DeleteSampleData
| Flow::UserMerchantAccountList | Flow::UserMerchantAccountList
| Flow::GetUserDetails | Flow::GetUserDetails
| Flow::ListUsersForMerchantAccount
| Flow::ForgotPassword | Flow::ForgotPassword
| Flow::ResetPassword | Flow::ResetPassword
| Flow::InviteUser | Flow::InviteUser

View File

@ -314,14 +314,35 @@ pub async fn list_merchant_ids_for_user(
.await .await
} }
pub async fn get_user_details(state: web::Data<AppState>, req: HttpRequest) -> HttpResponse { pub async fn get_user_role_details(
state: web::Data<AppState>,
req: HttpRequest,
payload: web::Query<user_api::GetUserDetailsRequest>,
) -> HttpResponse {
let flow = Flow::GetUserDetails; let flow = Flow::GetUserDetails;
Box::pin(api::server_wrap(
flow,
state.clone(),
&req,
payload.into_inner(),
user_core::get_user_details_in_merchant_account,
&auth::JWTAuth(Permission::UsersRead),
api_locking::LockAction::NotApplicable,
))
.await
}
pub async fn list_users_for_merchant_account(
state: web::Data<AppState>,
req: HttpRequest,
) -> HttpResponse {
let flow = Flow::ListUsersForMerchantAccount;
Box::pin(api::server_wrap( Box::pin(api::server_wrap(
flow, flow,
state.clone(), state.clone(),
&req, &req,
(), (),
|state, user, _| user_core::get_users_for_merchant_account(state, user), |state, user, _| user_core::list_users_for_merchant_account(state, user),
&auth::JWTAuth(Permission::UsersRead), &auth::JWTAuth(Permission::UsersRead),
api_locking::LockAction::NotApplicable, api_locking::LockAction::NotApplicable,
)) ))

View File

@ -336,8 +336,10 @@ pub enum Flow {
DeleteSampleData, DeleteSampleData,
/// List merchant accounts for user /// List merchant accounts for user
UserMerchantAccountList, UserMerchantAccountList,
/// Get users for merchant account /// Get details of a user in a merchant account
GetUserDetails, GetUserDetails,
/// List users for merchant account
ListUsersForMerchantAccount,
/// PaymentMethodAuth Link token create /// PaymentMethodAuth Link token create
PmAuthLinkTokenCreate, PmAuthLinkTokenCreate,
/// PaymentMethodAuth Exchange token create /// PaymentMethodAuth Exchange token create