feat(user): add route to get user details (#4510)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
Apoorv Dixit
2024-05-02 15:05:19 +05:30
committed by GitHub
parent 4b0cf9ce3b
commit be44447c09
7 changed files with 65 additions and 13 deletions

View File

@ -12,10 +12,11 @@ use crate::user::{
},
AcceptInviteFromEmailRequest, AuthorizeResponse, ChangePasswordRequest, ConnectAccountRequest,
CreateInternalUserRequest, DashboardEntryResponse, ForgotPasswordRequest,
GetUserDetailsRequest, GetUserDetailsResponse, InviteUserRequest, ListUsersResponse,
ReInviteUserRequest, ResetPasswordRequest, SendVerifyEmailRequest, SignInResponse,
SignUpRequest, SignUpWithMerchantIdRequest, SwitchMerchantIdRequest,
UpdateUserAccountDetailsRequest, UserMerchantCreate, VerifyEmailRequest,
GetUserDetailsResponse, GetUserRoleDetailsRequest, GetUserRoleDetailsResponse,
InviteUserRequest, ListUsersResponse, ReInviteUserRequest, ResetPasswordRequest,
SendVerifyEmailRequest, SignInResponse, SignUpRequest, SignUpWithMerchantIdRequest,
SwitchMerchantIdRequest, UpdateUserAccountDetailsRequest, UserMerchantCreate,
VerifyEmailRequest,
};
impl ApiEventMetric for DashboardEntryResponse {
@ -60,8 +61,9 @@ common_utils::impl_misc_api_event_type!(
AcceptInviteFromEmailRequest,
SignInResponse,
UpdateUserAccountDetailsRequest,
GetUserDetailsRequest,
GetUserDetailsResponse
GetUserDetailsResponse,
GetUserRoleDetailsRequest,
GetUserRoleDetailsResponse
);
#[cfg(feature = "dummy_connector")]

View File

@ -149,13 +149,25 @@ pub struct UserDetails {
pub last_modified_at: time::PrimitiveDateTime,
}
#[derive(serde::Serialize, Debug, Clone)]
pub struct GetUserDetailsResponse {
pub merchant_id: String,
pub name: Secret<String>,
pub email: pii::Email,
pub verification_days_left: Option<i64>,
pub role_id: String,
// This field is added for audit/debug reasons
#[serde(skip_serializing)]
pub user_id: String,
pub org_id: String,
}
#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct GetUserDetailsRequest {
pub struct GetUserRoleDetailsRequest {
pub email: pii::Email,
}
#[derive(Debug, serde::Serialize)]
pub struct GetUserDetailsResponse {
pub struct GetUserRoleDetailsResponse {
pub email: pii::Email,
pub name: Secret<String>,
pub role_id: String,

View File

@ -71,6 +71,26 @@ pub async fn signup_with_merchant_id(
}))
}
pub async fn get_user_details(
state: AppState,
user_from_token: auth::UserFromToken,
) -> UserResponse<user_api::GetUserDetailsResponse> {
let user = user_from_token.get_user_from_db(&state).await?;
let verification_days_left = utils::user::get_verification_days_left(&state, &user)?;
Ok(ApplicationResponse::Json(
user_api::GetUserDetailsResponse {
merchant_id: user_from_token.merchant_id,
name: user.get_name(),
email: user.get_email(),
user_id: user.get_user_id().to_string(),
verification_days_left,
role_id: user_from_token.role_id,
org_id: user_from_token.org_id,
},
))
}
pub async fn signup(
state: AppState,
request: user_api::SignUpRequest,
@ -1001,9 +1021,9 @@ pub async fn list_merchants_for_user(
pub async fn get_user_details_in_merchant_account(
state: AppState,
user_from_token: auth::UserFromToken,
request: user_api::GetUserDetailsRequest,
request: user_api::GetUserRoleDetailsRequest,
_req_state: ReqState,
) -> UserResponse<user_api::GetUserDetailsResponse> {
) -> UserResponse<user_api::GetUserRoleDetailsResponse> {
let required_user = utils::user::get_user_from_db_by_email(&state, request.email.try_into()?)
.await
.to_not_found_response(UserErrors::InvalidRoleOperation)?;
@ -1029,7 +1049,7 @@ pub async fn get_user_details_in_merchant_account(
.attach_printable("User role exists but the corresponding role doesn't")?;
Ok(ApplicationResponse::Json(
user_api::GetUserDetailsResponse {
user_api::GetUserRoleDetailsResponse {
email: required_user.get_email(),
name: required_user.get_name(),
role_id: role_info.get_role_id().to_string(),

View File

@ -1163,6 +1163,7 @@ impl User {
let mut route = web::scope("/user").app_data(web::Data::new(state));
route = route
.service(web::resource("").route(web::get().to(get_user_details)))
.service(web::resource("/v2/signin").route(web::post().to(user_signin)))
.service(web::resource("/signout").route(web::post().to(signout)))
.service(web::resource("/change_password").route(web::post().to(change_password)))

View File

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

View File

@ -19,6 +19,20 @@ use crate::{
utils::user::dashboard_metadata::{parse_string_to_enums, set_ip_address_if_required},
};
pub async fn get_user_details(state: web::Data<AppState>, req: HttpRequest) -> HttpResponse {
let flow = Flow::GetUserDetails;
Box::pin(api::server_wrap(
flow,
state,
&req,
(),
|state, user, _, _| user_core::get_user_details(state, user),
&auth::DashboardNoPermissionAuth,
api_locking::LockAction::NotApplicable,
))
.await
}
#[cfg(feature = "email")]
pub async fn user_signup_with_merchant_id(
state: web::Data<AppState>,
@ -295,7 +309,7 @@ pub async fn list_merchants_for_user(state: web::Data<AppState>, req: HttpReques
pub async fn get_user_role_details(
state: web::Data<AppState>,
req: HttpRequest,
payload: web::Query<user_api::GetUserDetailsRequest>,
payload: web::Query<user_api::GetUserRoleDetailsRequest>,
) -> HttpResponse {
let flow = Flow::GetUserDetails;
Box::pin(api::server_wrap(

View File

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