From cfeed3ac782821f3f21d55d579e5700ac0818fc4 Mon Sep 17 00:00:00 2001 From: 0xZensh Date: Wed, 23 Oct 2024 17:41:26 +0800 Subject: [PATCH] chore: improve 'delete_folder' API --- Cargo.lock | 12 +++--- Cargo.toml | 2 +- src/ic_oss_bucket/src/api_update.rs | 2 +- src/ic_oss_bucket/src/store.rs | 59 ++++++++++++++++++++++------- 4 files changed, 53 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c3d13b2..3028619 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1324,7 +1324,7 @@ dependencies = [ [[package]] name = "ic-oss" -version = "0.9.7" +version = "0.9.8" dependencies = [ "bytes", "candid", @@ -1341,7 +1341,7 @@ dependencies = [ [[package]] name = "ic-oss-can" -version = "0.9.7" +version = "0.9.8" dependencies = [ "candid", "ciborium", @@ -1354,7 +1354,7 @@ dependencies = [ [[package]] name = "ic-oss-cli" -version = "0.9.7" +version = "0.9.8" dependencies = [ "anyhow", "candid", @@ -1375,7 +1375,7 @@ dependencies = [ [[package]] name = "ic-oss-types" -version = "0.9.7" +version = "0.9.8" dependencies = [ "base64 0.22.1", "candid", @@ -1466,7 +1466,7 @@ dependencies = [ [[package]] name = "ic_oss_bucket" -version = "0.9.7" +version = "0.9.8" dependencies = [ "base64 0.22.1", "candid", @@ -1486,7 +1486,7 @@ dependencies = [ [[package]] name = "ic_oss_cluster" -version = "0.9.7" +version = "0.9.8" dependencies = [ "candid", "ciborium", diff --git a/Cargo.toml b/Cargo.toml index cd9ad16..7d22fd0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ strip = true opt-level = 's' [workspace.package] -version = "0.9.7" +version = "0.9.8" edition = "2021" repository = "https://github.com/ldclabs/ic-oss" keywords = ["file", "storage", "oss", "s3", "icp"] diff --git a/src/ic_oss_bucket/src/api_update.rs b/src/ic_oss_bucket/src/api_update.rs index 6cc9820..3844ab5 100644 --- a/src/ic_oss_bucket/src/api_update.rs +++ b/src/ic_oss_bucket/src/api_update.rs @@ -379,7 +379,7 @@ fn delete_folder(id: u32, access_token: Option) -> Result }; store::fs::delete_folder(id, now_ms, |folder| { - match permission::check_file_delete(&ctx.ps, &canister, folder.parent) { + match permission::check_folder_delete(&ctx.ps, &canister, folder.parent) { true => Ok(()), false => Err("permission denied".to_string()), } diff --git a/src/ic_oss_bucket/src/store.rs b/src/ic_oss_bucket/src/store.rs index 1e34fe5..054e26e 100644 --- a/src/ic_oss_bucket/src/store.rs +++ b/src/ic_oss_bucket/src/store.rs @@ -722,12 +722,7 @@ impl FoldersTree { }); } - fn delete_folder( - &mut self, - id: u32, - now_ms: u64, - checker: impl FnOnce(&FolderMetadata) -> Result<(), String>, - ) -> Result { + fn delete_folder(&mut self, id: u32, now_ms: u64) -> Result { if id == 0 { Err("root folder cannot be deleted".to_string())?; } @@ -735,7 +730,6 @@ impl FoldersTree { let parent_id = match self.get(&id) { None => return Ok(false), Some(folder) => { - checker(folder)?; if folder.status > 0 { Err("folder is readonly".to_string())?; } @@ -1349,7 +1343,44 @@ pub mod fs { now_ms: u64, checker: impl FnOnce(&FolderMetadata) -> Result<(), String>, ) -> Result { - FOLDERS.with(|r| r.borrow_mut().delete_folder(id, now_ms, checker)) + if id == 0 { + Err("root folder cannot be deleted".to_string())?; + } + + FOLDERS.with(|r| { + let mut folders = r.borrow_mut(); + let folder = folders.parent_to_update(id)?; + let files = folder.files.clone(); + checker(&folder)?; + + FS_METADATA_STORE.with(|r| { + let mut fs_metadata = r.borrow_mut(); + + FS_CHUNKS_STORE.with(|r| { + let mut fs_data = r.borrow_mut(); + for id in files { + match fs_metadata.get(&id) { + Some(file) => { + if file.status < 1 && fs_metadata.remove(&id).is_some() { + folder.files.remove(&id); + if let Some(hash) = file.hash { + HASHS.with(|r| r.borrow_mut().remove(&hash)); + } + + for i in 0..file.chunks { + fs_data.remove(&FileId(id, i)); + } + } + } + None => { + folder.files.remove(&id); + } + } + } + }); + }); + folders.delete_folder(id, now_ms) + }) } pub fn delete_file( @@ -2139,11 +2170,11 @@ mod test { fn test_folders_delete_folder() { let mut tree = FoldersTree::new(); assert!(tree - .delete_folder(0, 99, |_| Ok(())) + .delete_folder(0, 99) .err() .unwrap() .contains("root folder cannot be deleted")); - assert!(!tree.delete_folder(1, 99, |_| Ok(())).unwrap()); + assert!(!tree.delete_folder(1, 99).unwrap()); tree.add_folder( FolderMetadata { parent: 0, @@ -2158,25 +2189,25 @@ mod test { ) .unwrap(); assert!(tree - .delete_folder(1, 99, |_| Ok(())) + .delete_folder(1, 99) .err() .unwrap() .contains("folder is readonly")); tree.get_mut(&1).unwrap().status = 0; assert!(tree - .delete_folder(1, 99, |_| Ok(())) + .delete_folder(1, 99) .err() .unwrap() .contains("folder is not empty")); tree.get_mut(&1).unwrap().files.clear(); tree.get_mut(&0).unwrap().status = 1; assert!(tree - .delete_folder(1, 99, |_| Ok(())) + .delete_folder(1, 99) .err() .unwrap() .contains("parent folder is not writable")); tree.get_mut(&0).unwrap().status = 0; - assert!(tree.delete_folder(1, 99, |_| Ok(())).unwrap()); + assert!(tree.delete_folder(1, 99).unwrap()); assert_eq!(tree.len(), 1); assert_eq!(tree.get_mut(&0).unwrap().folders, BTreeSet::new()); assert_eq!(tree.get_mut(&0).unwrap().updated_at, 99);