Client side atproto account migrator in your web browser, along with services for backups and adversarial migrations. pdsmoover.com
pds atproto migrations moo cow
at main 59 lines 2.0 kB view raw
1use crate::db::Db; 2use crate::jobs::AnyhowErrorWrapper; 3use crate::storage::backup_base; 4use anyhow::{Result, anyhow}; 5use apalis::prelude::*; 6use s3::Bucket; 7use serde::{Deserialize, Serialize}; 8use sqlx::{Pool, Postgres}; 9 10use std::sync::Arc; 11pub const JOB_NAMESPACE: &str = "apalis::RemoveRepo"; 12 13#[derive(Debug, Deserialize, Serialize, Clone)] 14pub struct RemoveRepoJobContext { 15 pub did: String, 16} 17 18/// Execute the remove-repo operation: delete all S3 objects under users/{did}/ and 19/// remove DB rows (blobs, missing_blobs, account) for the DID. 20pub async fn run( 21 ctx: RemoveRepoJobContext, 22 pool: Data<Pool<Postgres>>, 23 s3_bucket: Data<Arc<Box<Bucket>>>, 24) -> Result<(), Error> { 25 let did = ctx.did; 26 log::info!("Removing repo for DID {}", did); 27 let db = Db::new(&*pool); 28 // 1) Delete all S3 objects for this DID under users/{did}/ 29 let prefix = format!("{}/", backup_base(did.clone())); 30 let list_results = s3_bucket 31 .list(prefix.clone(), None) 32 .await 33 .map_err(|e| Error::Failed(Arc::new(Box::new(AnyhowErrorWrapper(anyhow!(e))))))?; 34 for page in list_results { 35 for obj in page.contents { 36 // Best-effort deletion; fail-fast on error to avoid DB partial delete 37 s3_bucket 38 .delete_object(&obj.key) 39 .await 40 //I hate it too 41 .map_err(|e| Error::Failed(Arc::new(Box::new(AnyhowErrorWrapper(anyhow!(e))))))?; 42 } 43 } 44 45 // 2) Delete DB rows: blobs, missing_blobs, then account 46 let _ = db 47 .delete_blobs_by_did(&did) 48 .await 49 .map_err(|e| Error::Failed(Arc::new(Box::new(AnyhowErrorWrapper(anyhow!(e))))))?; 50 51 // Best-effort missing_blobs cleanup 52 let _ = db.delete_missing_blobs_by_did(&did).await.ok(); 53 let _ = db 54 .delete_account_by_did(&did) 55 .await 56 .map_err(|e| Error::Failed(Arc::new(Box::new(AnyhowErrorWrapper(anyhow!(e))))))?; 57 log::info!("All data for the repo {} has been deleted", did); 58 Ok(()) 59}