refactor(users): Deprecate unused user APIs and stabilize v1 APIs (#6114)

This commit is contained in:
Mani Chandra
2024-10-04 16:59:11 +05:30
committed by GitHub
parent 98722ae191
commit b2eb56e8d8
18 changed files with 80 additions and 1260 deletions

View File

@ -1135,121 +1135,6 @@ pub async fn create_internal_user(
Ok(ApplicationResponse::StatusOk)
}
pub async fn switch_merchant_id(
state: SessionState,
request: user_api::SwitchMerchantRequest,
user_from_token: auth::UserFromToken,
) -> UserResponse<user_api::DashboardEntryResponse> {
if user_from_token.merchant_id == request.merchant_id {
return Err(UserErrors::InvalidRoleOperationWithMessage(
"User switching to same merchant_id".to_string(),
)
.into());
}
let user = user_from_token.get_user_from_db(&state).await?;
let key_manager_state = &(&state).into();
let role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
&state,
&user_from_token.role_id,
&user_from_token.merchant_id,
&user_from_token.org_id,
)
.await
.to_not_found_response(UserErrors::InternalServerError)?;
let (token, role_id) = if role_info.is_internal() {
let key_store = state
.store
.get_merchant_key_store_by_merchant_id(
key_manager_state,
&request.merchant_id,
&state.store.get_master_key().to_vec().into(),
)
.await
.map_err(|e| {
if e.current_context().is_db_not_found() {
e.change_context(UserErrors::MerchantIdNotFound)
} else {
e.change_context(UserErrors::InternalServerError)
}
})?;
let org_id = state
.store
.find_merchant_account_by_merchant_id(
key_manager_state,
&request.merchant_id,
&key_store,
)
.await
.map_err(|e| {
if e.current_context().is_db_not_found() {
e.change_context(UserErrors::MerchantIdNotFound)
} else {
e.change_context(UserErrors::InternalServerError)
}
})?
.organization_id;
let token = utils::user::generate_jwt_auth_token_with_attributes_without_profile(
&state,
user_from_token.user_id,
request.merchant_id.clone(),
org_id.clone(),
user_from_token.role_id.clone(),
)
.await?;
(token, user_from_token.role_id)
} else {
let user_roles = state
.store
.list_user_roles_by_user_id_and_version(&user_from_token.user_id, UserRoleVersion::V1)
.await
.change_context(UserErrors::InternalServerError)?;
let active_user_roles = user_roles
.into_iter()
.filter(|role| role.status == UserStatus::Active)
.collect::<Vec<_>>();
let user_role = active_user_roles
.iter()
.find_map(|role| {
let Some(ref merchant_id) = role.merchant_id else {
return Some(Err(report!(UserErrors::InternalServerError)));
};
if merchant_id == &request.merchant_id {
Some(Ok(role))
} else {
None
}
})
.transpose()?
.ok_or(report!(UserErrors::InvalidRoleOperation))
.attach_printable("User doesn't have access to switch")?;
let token =
utils::user::generate_jwt_auth_token_without_profile(&state, &user, user_role).await?;
utils::user_role::set_role_permissions_in_cache_by_user_role(&state, user_role).await;
(token, user_role.role_id.clone())
};
let response = user_api::DashboardEntryResponse {
token: token.clone(),
name: user.get_name(),
email: user.get_email(),
user_id: user.get_user_id().to_string(),
verification_days_left: None,
user_role: role_id,
merchant_id: request.merchant_id,
};
auth::cookies::set_cookie_response(response, token)
}
pub async fn create_merchant_account(
state: SessionState,
user_from_token: auth::UserFromToken,
@ -1282,142 +1167,6 @@ pub async fn create_merchant_account(
Ok(ApplicationResponse::StatusOk)
}
pub async fn list_merchants_for_user(
state: SessionState,
user_from_token: auth::UserIdFromAuth,
) -> UserResponse<Vec<user_api::UserMerchantAccount>> {
let user_roles = state
.store
.list_user_roles_by_user_id_and_version(
user_from_token.user_id.as_str(),
UserRoleVersion::V1,
)
.await
.change_context(UserErrors::InternalServerError)?;
let merchant_accounts_map = state
.store
.list_multiple_merchant_accounts(
&(&state).into(),
user_roles
.iter()
.map(|role| {
role.merchant_id
.clone()
.ok_or(UserErrors::InternalServerError)
})
.collect::<Result<Vec<_>, _>>()?,
)
.await
.change_context(UserErrors::InternalServerError)?
.into_iter()
.map(|merchant_account| (merchant_account.get_id().clone(), merchant_account))
.collect::<HashMap<_, _>>();
let roles_map = futures::future::try_join_all(user_roles.iter().map(|user_role| async {
let Some(merchant_id) = &user_role.merchant_id else {
return Err(report!(UserErrors::InternalServerError))
.attach_printable("merchant_id not found for user_role");
};
let Some(org_id) = &user_role.org_id else {
return Err(report!(UserErrors::InternalServerError)
.attach_printable("org_id not found in user_role"));
};
roles::RoleInfo::from_role_id_in_merchant_scope(
&state,
&user_role.role_id,
merchant_id,
org_id,
)
.await
.change_context(UserErrors::InternalServerError)
.attach_printable("Unable to find role info for user role")
}))
.await?
.into_iter()
.map(|role_info| (role_info.get_role_id().to_owned(), role_info))
.collect::<HashMap<_, _>>();
Ok(ApplicationResponse::Json(
user_roles
.into_iter()
.map(|user_role| {
let Some(merchant_id) = &user_role.merchant_id else {
return Err(report!(UserErrors::InternalServerError))
.attach_printable("merchant_id not found for user_role");
};
let Some(org_id) = &user_role.org_id else {
return Err(report!(UserErrors::InternalServerError)
.attach_printable("org_id not found in user_role"));
};
let merchant_account = merchant_accounts_map
.get(merchant_id)
.ok_or(UserErrors::InternalServerError)
.attach_printable("Merchant account for user role doesn't exist")?;
let role_info = roles_map
.get(&user_role.role_id)
.ok_or(UserErrors::InternalServerError)
.attach_printable("Role info for user role doesn't exist")?;
Ok(user_api::UserMerchantAccount {
merchant_id: merchant_id.to_owned(),
merchant_name: merchant_account.merchant_name.clone(),
is_active: user_role.status == UserStatus::Active,
role_id: user_role.role_id,
role_name: role_info.get_role_name().to_string(),
org_id: org_id.to_owned(),
})
})
.collect::<Result<Vec<_>, _>>()?,
))
}
pub async fn get_user_details_in_merchant_account(
state: SessionState,
user_from_token: auth::UserFromToken,
request: user_api::GetUserRoleDetailsRequest,
_req_state: ReqState,
) -> 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)?;
let required_user_role = state
.store
.find_user_role_by_user_id_merchant_id(
required_user.get_user_id(),
&user_from_token.merchant_id,
UserRoleVersion::V1,
)
.await
.to_not_found_response(UserErrors::InvalidRoleOperation)
.attach_printable("User not found in the merchant account")?;
let role_info = roles::RoleInfo::from_role_id_in_merchant_scope(
&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::GetUserRoleDetailsResponse {
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_user_roles_details(
state: SessionState,
user_from_token: auth::UserFromToken,
@ -1670,80 +1419,6 @@ pub async fn list_user_roles_details(
Ok(ApplicationResponse::Json(role_details_list))
}
pub async fn list_users_for_merchant_account(
state: SessionState,
user_from_token: auth::UserFromToken,
) -> UserResponse<user_api::ListUsersResponse> {
let user_roles: HashMap<String, _> = state
.store
.list_user_roles_by_merchant_id(&user_from_token.merchant_id, UserRoleVersion::V1)
.await
.change_context(UserErrors::InternalServerError)
.attach_printable("No user roles for given merchant_id")?
.into_iter()
.map(|role| (role.user_id.clone(), role))
.collect();
let user_ids = user_roles.keys().cloned().collect::<Vec<_>>();
let users = state
.global_store
.find_users_by_user_ids(user_ids)
.await
.change_context(UserErrors::InternalServerError)
.attach_printable("No users for given merchant_id")?;
let users_and_user_roles: Vec<_> = users
.into_iter()
.filter_map(|user| {
user_roles
.get(&user.user_id)
.map(|role| (user.clone(), role.clone()))
})
.collect();
let users_user_roles_and_roles =
futures::future::try_join_all(users_and_user_roles.into_iter().map(
|(user, user_role)| async {
roles::RoleInfo::from_role_id_in_merchant_scope(
&state,
&user_role.role_id.clone(),
user_role
.merchant_id
.as_ref()
.ok_or(UserErrors::InternalServerError)?,
user_role
.org_id
.as_ref()
.ok_or(UserErrors::InternalServerError)?,
)
.await
.map(|role_info| (user, user_role, role_info))
.to_not_found_response(UserErrors::InternalServerError)
},
))
.await?;
let user_details_vec = users_user_roles_and_roles
.into_iter()
.map(|(user, user_role, role_info)| {
let user = domain::UserFromStorage::from(user);
user_api::UserDetails {
email: user.get_email(),
name: user.get_name(),
role_id: user_role.role_id.clone(),
role_name: role_info.get_role_name().to_string(),
status: user_role.status.foreign_into(),
last_modified_at: user_role.last_modified,
}
})
.collect();
Ok(ApplicationResponse::Json(user_api::ListUsersResponse(
user_details_vec,
)))
}
#[cfg(feature = "email")]
pub async fn verify_email_token_only_flow(
state: SessionState,