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, AcceptInviteFromEmailRequest, AuthorizeResponse, ChangePasswordRequest, ConnectAccountRequest,
CreateInternalUserRequest, DashboardEntryResponse, ForgotPasswordRequest, CreateInternalUserRequest, DashboardEntryResponse, ForgotPasswordRequest,
GetUserDetailsRequest, GetUserDetailsResponse, InviteUserRequest, ListUsersResponse, GetUserDetailsResponse, GetUserRoleDetailsRequest, GetUserRoleDetailsResponse,
ReInviteUserRequest, ResetPasswordRequest, SendVerifyEmailRequest, SignInResponse, InviteUserRequest, ListUsersResponse, ReInviteUserRequest, ResetPasswordRequest,
SignUpRequest, SignUpWithMerchantIdRequest, SwitchMerchantIdRequest, SendVerifyEmailRequest, SignInResponse, SignUpRequest, SignUpWithMerchantIdRequest,
UpdateUserAccountDetailsRequest, UserMerchantCreate, VerifyEmailRequest, SwitchMerchantIdRequest, UpdateUserAccountDetailsRequest, UserMerchantCreate,
VerifyEmailRequest,
}; };
impl ApiEventMetric for DashboardEntryResponse { impl ApiEventMetric for DashboardEntryResponse {
@ -60,8 +61,9 @@ common_utils::impl_misc_api_event_type!(
AcceptInviteFromEmailRequest, AcceptInviteFromEmailRequest,
SignInResponse, SignInResponse,
UpdateUserAccountDetailsRequest, UpdateUserAccountDetailsRequest,
GetUserDetailsRequest, GetUserDetailsResponse,
GetUserDetailsResponse GetUserRoleDetailsRequest,
GetUserRoleDetailsResponse
); );
#[cfg(feature = "dummy_connector")] #[cfg(feature = "dummy_connector")]

View File

@ -149,13 +149,25 @@ pub struct UserDetails {
pub last_modified_at: time::PrimitiveDateTime, 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)] #[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct GetUserDetailsRequest { pub struct GetUserRoleDetailsRequest {
pub email: pii::Email, pub email: pii::Email,
} }
#[derive(Debug, serde::Serialize)] #[derive(Debug, serde::Serialize)]
pub struct GetUserDetailsResponse { pub struct GetUserRoleDetailsResponse {
pub email: pii::Email, pub email: pii::Email,
pub name: Secret<String>, pub name: Secret<String>,
pub role_id: 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( pub async fn signup(
state: AppState, state: AppState,
request: user_api::SignUpRequest, request: user_api::SignUpRequest,
@ -1001,9 +1021,9 @@ pub async fn list_merchants_for_user(
pub async fn get_user_details_in_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,
request: user_api::GetUserDetailsRequest, request: user_api::GetUserRoleDetailsRequest,
_req_state: ReqState, _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()?) let required_user = utils::user::get_user_from_db_by_email(&state, request.email.try_into()?)
.await .await
.to_not_found_response(UserErrors::InvalidRoleOperation)?; .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")?; .attach_printable("User role exists but the corresponding role doesn't")?;
Ok(ApplicationResponse::Json( Ok(ApplicationResponse::Json(
user_api::GetUserDetailsResponse { user_api::GetUserRoleDetailsResponse {
email: required_user.get_email(), email: required_user.get_email(),
name: required_user.get_name(), name: required_user.get_name(),
role_id: role_info.get_role_id().to_string(), 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)); let mut route = web::scope("/user").app_data(web::Data::new(state));
route = route 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("/v2/signin").route(web::post().to(user_signin)))
.service(web::resource("/signout").route(web::post().to(signout))) .service(web::resource("/signout").route(web::post().to(signout)))
.service(web::resource("/change_password").route(web::post().to(change_password))) .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::DeleteSampleData
| Flow::UserMerchantAccountList | Flow::UserMerchantAccountList
| Flow::GetUserDetails | Flow::GetUserDetails
| Flow::GetUserRoleDetails
| Flow::ListUsersForMerchantAccount | Flow::ListUsersForMerchantAccount
| Flow::ForgotPassword | Flow::ForgotPassword
| Flow::ResetPassword | Flow::ResetPassword

View File

@ -19,6 +19,20 @@ use crate::{
utils::user::dashboard_metadata::{parse_string_to_enums, set_ip_address_if_required}, 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")] #[cfg(feature = "email")]
pub async fn user_signup_with_merchant_id( pub async fn user_signup_with_merchant_id(
state: web::Data<AppState>, 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( pub async fn get_user_role_details(
state: web::Data<AppState>, state: web::Data<AppState>,
req: HttpRequest, req: HttpRequest,
payload: web::Query<user_api::GetUserDetailsRequest>, payload: web::Query<user_api::GetUserRoleDetailsRequest>,
) -> HttpResponse { ) -> HttpResponse {
let flow = Flow::GetUserDetails; let flow = Flow::GetUserDetails;
Box::pin(api::server_wrap( Box::pin(api::server_wrap(

View File

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