feat: delete customer data in compliance with GDPR regulations (#64)

This commit is contained in:
Manoj Ghorela
2022-12-13 19:39:32 +05:30
committed by GitHub
parent 3655c8de82
commit ae8869318b
12 changed files with 246 additions and 35 deletions

View File

@ -2,12 +2,16 @@ use error_stack::ResultExt;
use router_env::{tracing, tracing::instrument};
use crate::{
core::errors::{self, RouterResponse, StorageErrorExt},
core::{
errors::{self, RouterResponse, StorageErrorExt},
payment_methods::cards,
},
db::StorageInterface,
routes::AppState,
services,
types::{
api::customers::{self, CustomerRequestExt},
storage,
storage::{self, enums},
},
};
@ -63,20 +67,99 @@ pub async fn retrieve_customer(
Ok(services::BachResponse::Json(response.into()))
}
#[instrument(skip(db))]
#[instrument(skip_all)]
pub async fn delete_customer(
db: &dyn StorageInterface,
state: &AppState,
merchant_account: storage::MerchantAccount,
req: customers::CustomerId,
) -> RouterResponse<customers::CustomerDeleteResponse> {
let response = db
.delete_customer_by_customer_id_merchant_id(&req.customer_id, &merchant_account.merchant_id)
let db = &state.store;
let cust = db
.find_customer_by_customer_id_merchant_id(&req.customer_id, &merchant_account.merchant_id)
.await
.map(|response| customers::CustomerDeleteResponse {
customer_id: req.customer_id,
deleted: response,
})
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::CustomerNotFound))?;
.map_err(|err| err.to_not_found_response(errors::ApiErrorResponse::CustomerNotFound))?;
if cust.name == Some("Redacted".to_string()) {
Err(errors::ApiErrorResponse::CustomerRedacted)?
}
let customer_mandates = db
.find_mandate_by_merchant_id_customer_id(&merchant_account.merchant_id, &req.customer_id)
.await
.map_err(|err| err.to_not_found_response(errors::ApiErrorResponse::MandateNotFound))?;
for mandate in customer_mandates.into_iter() {
if mandate.mandate_status == enums::MandateStatus::Active {
Err(errors::ApiErrorResponse::MandateActive)?
}
}
let customer_payment_methods = db
.find_payment_method_by_customer_id_merchant_id_list(
&req.customer_id,
&merchant_account.merchant_id,
)
.await
.map_err(|err| {
err.to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)
})?;
for pm in customer_payment_methods.into_iter() {
if pm.payment_method == enums::PaymentMethodType::Card {
cards::delete_card(state, &merchant_account.merchant_id, &pm.payment_method_id).await?;
}
db.delete_payment_method_by_merchant_id_payment_method_id(
&merchant_account.merchant_id,
&pm.payment_method_id,
)
.await
.map_err(|error| {
error.to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)
})?;
}
let update_address = storage::AddressUpdate::Update {
city: Some("Redacted".to_string()),
country: Some("Redacted".to_string()),
line1: Some("Redacted".to_string().into()),
line2: Some("Redacted".to_string().into()),
line3: Some("Redacted".to_string().into()),
state: Some("Redacted".to_string().into()),
zip: Some("Redacted".to_string().into()),
first_name: Some("Redacted".to_string().into()),
last_name: Some("Redacted".to_string().into()),
phone_number: Some("Redacted".to_string().into()),
country_code: Some("Redacted".to_string()),
};
db.update_address_by_merchant_id_customer_id(
&req.customer_id,
&merchant_account.merchant_id,
update_address,
)
.await
.change_context(errors::ApiErrorResponse::AddressNotFound)?;
let updated_customer = storage::CustomerUpdate::Update {
name: Some("Redacted".to_string()),
email: Some("Redacted".to_string().into()),
phone: Some("Redacted".to_string().into()),
description: Some("Redacted".to_string()),
phone_country_code: Some("Redacted".to_string()),
metadata: None,
};
db.update_customer_by_customer_id_merchant_id(
req.customer_id.clone(),
merchant_account.merchant_id,
updated_customer,
)
.await
.change_context(errors::ApiErrorResponse::CustomerNotFound)?;
let response = customers::CustomerDeleteResponse {
customer_id: req.customer_id,
customer_deleted: true,
address_deleted: true,
payment_methods_deleted: true,
};
Ok(services::BachResponse::Json(response))
}