diff --git a/services/identity/src/backup.rs b/services/identity/src/backup.rs new file mode 100644 --- /dev/null +++ b/services/identity/src/backup.rs @@ -0,0 +1,41 @@ +use comm_lib::auth::AuthService; + +use crate::{ + config::CONFIG, + constants::{error_types, tonic_status_messages}, +}; + +pub async fn delete_backup_user_data( + user_id: &str, + auth_service: &AuthService, +) -> Result<(), crate::error::Error> { + let path = format!("/user_data/{}", user_id); + let url = CONFIG + .backup_service_url + .join(&path) + .expect("failed to construct backup service URL"); + let services_token = + auth_service.get_services_token().await.map_err(|err| { + tracing::error!( + errorType = error_types::HTTP_LOG, + "Failed to retrieve service-to-service token: {err:?}", + ); + tonic::Status::aborted(tonic_status_messages::UNEXPECTED_ERROR) + })?; + + let client = reqwest::Client::builder().build()?; + let response = client + .delete(url) + .bearer_auth(services_token.as_authorization_token()?) + .send() + .await?; + if !response.status().is_success() { + let response_body = response.text().await?; + tracing::error!( + errorType = error_types::HTTP_LOG, + "Backup service failed to delete user data: {}", + response_body + ) + } + Ok(()) +} diff --git a/services/identity/src/error.rs b/services/identity/src/error.rs --- a/services/identity/src/error.rs +++ b/services/identity/src/error.rs @@ -23,6 +23,8 @@ #[display(...)] Serde(serde_json::Error), #[display(...)] + Reqwest(reqwest::Error), + #[display(...)] CannotOverwrite, #[display(...)] OneTimeKeyUploadLimitExceeded, diff --git a/services/identity/src/grpc_services/authenticated.rs b/services/identity/src/grpc_services/authenticated.rs --- a/services/identity/src/grpc_services/authenticated.rs +++ b/services/identity/src/grpc_services/authenticated.rs @@ -13,6 +13,7 @@ grpc_services::shared::{get_platform_metadata, get_value}, }; use chrono::DateTime; +use comm_lib::auth::AuthService; use comm_opaque2::grpc::protocol_error_to_grpc_status; use tonic::{Request, Response, Status}; use tracing::{debug, error, trace, warn}; @@ -36,6 +37,7 @@ #[derive(derive_more::Constructor)] pub struct AuthenticatedService { db_client: DatabaseClient, + comm_auth_service: AuthService, } fn get_auth_info(req: &Request<()>) -> Option<(String, String, String)> { @@ -107,6 +109,15 @@ }); } +fn spawn_delete_backup_data_task(user_id: String, auth_service: AuthService) { + tokio::spawn(async move { + debug!("Attempting to delete Backup data for user: {}", &user_id); + let result = + crate::backup::delete_backup_user_data(&user_id, &auth_service).await; + consume_error(result); + }); +} + #[tonic::async_trait] impl IdentityClientService for AuthenticatedService { #[tracing::instrument(skip_all)] @@ -570,10 +581,11 @@ let device_ids = self .db_client - .delete_user(user_id) + .delete_user(user_id.clone()) .await .map_err(handle_db_error)?; spawn_delete_tunnelbroker_data_task(device_ids); + spawn_delete_backup_data_task(user_id, self.comm_auth_service.clone()); let response = Empty {}; Ok(Response::new(response)) @@ -657,10 +669,11 @@ let device_ids = self .db_client - .delete_user(user_id) + .delete_user(user_id.clone()) .await .map_err(handle_db_error)?; spawn_delete_tunnelbroker_data_task(device_ids); + spawn_delete_backup_data_task(user_id, self.comm_auth_service.clone()); let response = Empty {}; Ok(Response::new(response)) diff --git a/services/identity/src/main.rs b/services/identity/src/main.rs --- a/services/identity/src/main.rs +++ b/services/identity/src/main.rs @@ -1,3 +1,4 @@ +use comm_lib::auth::AuthService; use comm_lib::aws; use comm_lib::aws::config::timeout::TimeoutConfig; use comm_lib::aws::config::BehaviorVersion; @@ -6,6 +7,7 @@ use tonic::transport::Server; use tonic_web::GrpcWebLayer; +mod backup; mod client_service; mod config; pub mod constants; @@ -83,6 +85,8 @@ .region("us-east-2") .load() .await; + let comm_auth_service = + AuthService::new(&aws_config, "http://localhost:50054".to_string()); let database_client = DatabaseClient::new(&aws_config); let inner_client_service = ClientService::new(database_client.clone()); let client_service = IdentityClientServiceServer::with_interceptor( @@ -90,7 +94,7 @@ grpc_services::shared::version_interceptor, ); let inner_auth_service = - AuthenticatedService::new(database_client.clone()); + AuthenticatedService::new(database_client.clone(), comm_auth_service); let db_client = database_client.clone(); let auth_service = AuthServer::with_interceptor(inner_auth_service, move |req| {