diff --git a/ecstore/src/disk/error.rs b/ecstore/src/disk/error.rs index 535273c2f..1b24ffc7a 100644 --- a/ecstore/src/disk/error.rs +++ b/ecstore/src/disk/error.rs @@ -391,3 +391,15 @@ pub fn map_err_not_exists(e: io::Error) -> Error { Error::new(e) } + +pub fn convert_access_error(e: io::Error, per_err: DiskError) -> Error { + if os_is_not_exist(&e) { + return Error::new(DiskError::VolumeNotEmpty); + } else if is_sys_err_io(&e) { + return Error::new(DiskError::FaultyDisk); + } else if os_is_permission(&e) { + return Error::new(per_err); + } + + Error::new(e) +} diff --git a/ecstore/src/disk/local.rs b/ecstore/src/disk/local.rs index a798f7d17..d0949c30f 100644 --- a/ecstore/src/disk/local.rs +++ b/ecstore/src/disk/local.rs @@ -4,7 +4,7 @@ use super::{ os, DeleteOptions, DiskAPI, DiskLocation, FileInfoVersions, FileReader, FileWriter, MetaCacheEntry, ReadMultipleReq, ReadMultipleResp, ReadOptions, RenameDataResp, UpdateMetadataOpts, VolumeInfo, WalkDirOptions, }; -use crate::disk::error::{is_sys_err_not_dir, map_err_not_exists, os_err_to_file_err}; +use crate::disk::error::{convert_access_error, is_sys_err_not_dir, map_err_not_exists, os_err_to_file_err}; use crate::disk::os::check_path_length; use crate::disk::{LocalFileReader, LocalFileWriter, STORAGE_FORMAT_FILE}; use crate::utils::fs::lstat; @@ -585,6 +585,7 @@ impl DiskAPI for LocalDisk { #[must_use] async fn read_all(&self, volume: &str, path: &str) -> Result { + // TOFIX: let p = self.get_object_path(volume, path)?; let (data, _) = read_file_all(&p).await?; @@ -1083,11 +1084,45 @@ impl DiskAPI for LocalDisk { created: modtime, }) } - async fn delete_paths(&self, _volume: &str, _paths: &[&str]) -> Result<()> { - unimplemented!() + async fn delete_paths(&self, volume: &str, paths: &[&str]) -> Result<()> { + let volume_dir = self.get_bucket_path(volume)?; + if !skip_access_checks(volume) { + utils::fs::access(&volume_dir) + .await + .map_err(|e| convert_access_error(e, DiskError::VolumeAccessDenied))? + } + + for path in paths.iter() { + let file_path = volume_dir.join(Path::new(path)); + + check_path_length(&file_path.to_string_lossy().to_string())?; + + self.move_to_trash(&file_path, false, false).await?; + } + + Ok(()) } - async fn update_metadata(&self, _volume: &str, _path: &str, _fi: FileInfo, _opts: UpdateMetadataOpts) { - unimplemented!() + async fn update_metadata(&self, volume: &str, path: &str, fi: FileInfo, _opts: UpdateMetadataOpts) -> Result<()> { + if let Some(metadata) = fi.metadata { + let volume_dir = self.get_bucket_path(&volume)?; + let file_path = volume_dir.join(Path::new(&path)); + + check_path_length(&file_path.to_string_lossy().to_string())?; + + self.read_all(&volume, format!("{}/{}", &path, super::STORAGE_FORMAT_FILE).as_str()) + .await + .map_err(|e| { + if DiskError::FileNotFound.is(&e) && fi.version_id.is_some() { + Error::new(DiskError::FileVersionNotFound) + } else { + e + } + })?; + + // FIXME: + } + + Err(Error::msg("Invalid Argument")) } async fn write_metadata(&self, _org_volume: &str, volume: &str, path: &str, fi: FileInfo) -> Result<()> { let p = self.get_object_path(volume, format!("{}/{}", path, super::STORAGE_FORMAT_FILE).as_str())?; diff --git a/ecstore/src/disk/mod.rs b/ecstore/src/disk/mod.rs index cd8e9af7f..a59d720d5 100644 --- a/ecstore/src/disk/mod.rs +++ b/ecstore/src/disk/mod.rs @@ -90,7 +90,7 @@ pub trait DiskAPI: Debug + Send + Sync + 'static { ) -> Result>>; async fn delete_paths(&self, volume: &str, paths: &[&str]) -> Result<()>; async fn write_metadata(&self, org_volume: &str, volume: &str, path: &str, fi: FileInfo) -> Result<()>; - async fn update_metadata(&self, volume: &str, path: &str, fi: FileInfo, opts: UpdateMetadataOpts); + async fn update_metadata(&self, volume: &str, path: &str, fi: FileInfo, opts: UpdateMetadataOpts) -> Result<()>; async fn read_version( &self, org_volume: &str, diff --git a/ecstore/src/disk/remote.rs b/ecstore/src/disk/remote.rs index 51763c4ae..e035ad9c5 100644 --- a/ecstore/src/disk/remote.rs +++ b/ecstore/src/disk/remote.rs @@ -414,7 +414,7 @@ impl DiskAPI for RemoteDisk { // TODO: unimplemented!() } - async fn update_metadata(&self, _volume: &str, _path: &str, _fi: FileInfo, _opts: UpdateMetadataOpts) { + async fn update_metadata(&self, _volume: &str, _path: &str, _fi: FileInfo, _opts: UpdateMetadataOpts) -> Result<()> { // TODO: unimplemented!() }