diff --git a/bucket-api b/bucket-api index d996ac7..50a9b59 160000 --- a/bucket-api +++ b/bucket-api @@ -1 +1 @@ -Subproject commit d996ac7d62f405d384e5044cbce78cff8ada6a08 +Subproject commit 50a9b598e3a97000aeb780cad7e74066325137f4 diff --git a/src/controller/account/authentication.rs b/src/controller/account/authentication.rs index 7182704..85af2b9 100644 --- a/src/controller/account/authentication.rs +++ b/src/controller/account/authentication.rs @@ -75,6 +75,7 @@ pub async fn login( Ok(finish_resp.jwt_token as JwtToken) } + pub async fn register( query_client: &mut QueryClient, email: &str, diff --git a/src/controller/bucket/bucket.rs b/src/controller/bucket/bucket.rs index 5eb2789..5df5825 100644 --- a/src/controller/bucket/bucket.rs +++ b/src/controller/bucket/bucket.rs @@ -1,6 +1,7 @@ use std::error::Error; use std::fmt::Debug; use std::rc::Rc; +use std::str::FromStr; use bucket_common_types::exclusive_share_link::ExclusiveShareLink; use bucket_common_types::share_link::ShareLink; @@ -275,7 +276,7 @@ pub async fn bucket_download( path: file.file_path.clone(), date: None, size_in_bytes: file.file_size_in_bytes, - file_format: file.file_type, + file_format: mime::Mime::from_str(file.file_format.as_str())?, }; let mut download_handler = create_download_handler.handle( virtual_file, diff --git a/src/controller/bucket/download_handler.rs b/src/controller/bucket/download_handler.rs index dc423d9..0860ed8 100644 --- a/src/controller/bucket/download_handler.rs +++ b/src/controller/bucket/download_handler.rs @@ -1,13 +1,13 @@ use crate::controller::bucket::errors::BucketDownloadHandlerErrors; -use crate::encryption_v1::module::{ - DecryptionModule, EncryptionModule, ZeroKnowledgeDecryptionModuleV1, -}; +use crate::controller::bucket::io::file::{BucketFile, BucketFileTrait}; +use crate::encryption_v1::module::DecryptionModule; +use crate::encryption_v1::module::EncryptionModule; +use crate::encryption_v1::module::ZeroKnowledgeDecryptionModuleV1; use async_trait::async_trait; use bucket_common_types::BucketEncryption; -use gloo::file::Blob; +use futures::future::Either; use mime::Mime; -use crate::controller::bucket::io::file::{BucketFile, BucketFileTrait}; - +use std::str::FromStr; #[derive(Debug, thiserror::Error)] pub enum BucketUploadHandlerErrors {} @@ -41,7 +41,7 @@ pub struct WebBucketFileWriter { Error = super::io::web_file::WebBucketFileError, FileHandle = gloo::file::File, >*/ - BucketFile + BucketFile, >, pub offset: u64, pub decryption_module: Option, @@ -63,21 +63,27 @@ impl BucketFileDownloadHandler for WebBucketFileWriter { _encryption: Option, _download_size_in_bytes: u64, ) -> Result<(), Self::Error> { - let blob = Blob::from(self.write_target_file.clone()); + //let blob = Blob::from(self.write_target_file.clone()); //let bytes = read_as_bytes(&blob).await?; - let mime: Mime = from_filename - .split('.') - .last() - .unwrap_or("application/octet-stream") - .parse()?; + let file = BucketFile::new( + from_filename.as_str(), + &Mime::from_str("application/octet-stream").unwrap(), + ) + .unwrap(); - self.write_target_file = gloo::file::File::new_with_options( - &from_filename, - blob, - Some(mime.to_string().as_str()), - None, - ); + /*let mime: Mime = from_filename + .split('.') + .last() + .unwrap_or("application/octet-stream") + .parse()?; + self.write_target_file = gloo::file::File::new_with_options( + &from_filename, + blob, + Some(mime.to_string().as_str()), + None, + ); + */ //write(self.write_target_file, ); Ok(()) } @@ -87,20 +93,28 @@ impl BucketFileDownloadHandler for WebBucketFileWriter { //let end = chunk.len() as u64; //read_as_array_buffer(&self.write_target_file.slice(start, end), |res|{ res.unwrap(); }); //self.write_target_file. - let decrypted_buffer = match &mut self.decryption_module { - Some(x) => { - let mut decrypted_buffer: Vec = chunk.clone(); - decrypted_buffer = x.update(chunk)?; - decrypted_buffer + let decrypted_buffer: futures::future::Either, &Vec> = + match &mut self.decryption_module { + Some(x) => { + let mut decrypted_buffer: Vec = chunk.clone(); + decrypted_buffer = x.update(chunk)?; + Either::Left(decrypted_buffer) + } + None => Either::Right(chunk), + }; + match decrypted_buffer { + Either::Left(decrypted_buffer) => { + self.write_target_file + .write_chunk(&decrypted_buffer, self.offset); + self.offset += decrypted_buffer.len() as u64; } - None => { - chunk + Either::Right(decrypted_buffer) => { + self.write_target_file + .write_chunk(&decrypted_buffer, self.offset); + self.offset += decrypted_buffer.len() as u64; } - }; + } - self.write_target_file - .write_chunk(decrypted_buffer, self.offset); - self.offset += decrypted_buffer.len(); /* * Create custom object for URL to download the file. * The file will be stored as a "xxxx.temp" file. After the download the file is renamed to the correct filename. @@ -119,8 +133,6 @@ impl BucketFileDownloadHandler for WebBucketFileWriter { } // Called when the last chunk has been downloaded. fn on_download_finish(self) -> Result<(), Self::Error> { - //let write_target_file = self.write_target_file; - //read_as_bytes(write_target_file); //TODO: Check if file match checksums. match self.decryption_module { None => {} diff --git a/src/controller/bucket/errors.rs b/src/controller/bucket/errors.rs index 914f96f..628fcee 100644 --- a/src/controller/bucket/errors.rs +++ b/src/controller/bucket/errors.rs @@ -41,6 +41,8 @@ pub enum DownloadError { GetBucketDetailsRequestFailed(#[source] tonic::Status), #[error("GetBucketDetailsFromUrlRequestFailed")] GetBucketDetailsFromUrlRequestFailed(#[source] tonic::Status), + #[error(transparent)] + FromStrError(#[from] FromStrError), } #[derive(Debug, thiserror::Error)] pub enum UploadToUrlError { diff --git a/src/controller/bucket/io/file.rs b/src/controller/bucket/io/file.rs index 208611e..772d36b 100644 --- a/src/controller/bucket/io/file.rs +++ b/src/controller/bucket/io/file.rs @@ -2,8 +2,6 @@ use std::{ io::{Read, Write}, vec, }; -use infer::Type; - use mime::Mime; #[cfg(not(target_family = "wasm"))] use crate::controller::bucket::io::native_file::VirtualNativeBucketFile; @@ -17,9 +15,11 @@ pub struct VirtualFileDetails { pub size_in_bytes: u64, pub file_format: mime::Mime, } + /// Traits to collectively implement the read/write to the local filesystem depending on target. /// While mapping the local file to web file. /// Current supported targets are native using tokio, or web through WASM. +#[tonic::async_trait(?Send)] pub trait BucketFileTrait { type Error; type FileHandle; @@ -30,17 +30,17 @@ pub trait BucketFileTrait { //fn new(create_file_handle:fn() -> Self::FileHandle) -> Self; // DON'T IMPLEMENT THE CREATION OF NEW FILE, ONLY TAKE EXISTING "FILE HANDLE" ONE KEEP IT SIMPLE. - + fn new(filename: &str, mime: &Mime) -> Result where Self: Sized; fn from(file_handle: Self::FileHandle, filename: String) -> Self where Self: Sized; - fn get_file_handle(&self) -> Self::FileHandle; + fn get_file_handle(&self) -> &Self::FileHandle; async fn read_chunk(&self, size: u64, offset: u64) -> Result, Self::Error>; fn read_stream(&self) -> Result, Self::Error>; fn get_extension(&self) -> Result; /// Get the mime-type from the extension. fn get_mime_type(&self) -> Result; /// Uses the first couple of bytes in the file ot determine the mime-type - async fn infer_mime_type(&self) -> Result; - fn write_chunk(&self, chunk: vec::Vec, offset: u64) -> Result<(), Self::Error>; + async fn infer_mime_type(& self) -> Result; + fn write_chunk(&self, chunk: &vec::Vec, offset: u64) -> Result<(), Self::Error>; fn write_stream(&self, stream: &dyn Write) -> Result<(), Self::Error>; fn get_size(&self) -> u64; } @@ -50,146 +50,19 @@ pub trait BucketFileTrait { pub type BuketFile = VirtualWebBucketFile; #[cfg(not(target_family = "wasm"))] pub type BucketFile = VirtualNativeBucketFile; -/* - -pub enum BucketFile { - WebFile(VirtualWebBucketFile), - #[cfg(feature = "native")] - NativeFile(VirtualNativeBucketFile), -} - -impl BucketFileTrait for BucketFile { - type Error = WebBucketFileError; - type FileHandle = WebFileHandle; - - fn from(file_handle: Self::FileHandle, filename: String) -> Self where Self: Sized { - Self::WebFile(VirtualWebBucketFile::from(file_handle, filename)) - } - - fn get_file_handle(&self) -> Self::FileHandle { - match self { - BucketFile::WebFile(web) => { - web.get_file_handle() - } - BucketFile::NativeFile(_) => { panic!() } - } - } - - async fn read_chunk(&self, size: u64, offset: u64) -> Result, Self::Error> { - match self { - BucketFile::WebFile(web) => { - web.read_chunk(size,offset) - } - BucketFile::NativeFile(_) => { panic!() } - } - } - - fn read_stream(&self) -> Result, Self::Error> { - match self { - BucketFile::WebFile(web) => { - web.read_stream() - } - BucketFile::NativeFile(_) => { panic!() } - } - } - - fn get_extension(&self) -> Result { - match self { - BucketFile::WebFile(web) => { - web.get_extension() - } - BucketFile::NativeFile(_) => { panic!() } - } - } - - fn get_mime_type(&self) -> Result { - match self { - BucketFile::WebFile(web) => { - web.get_mime_type() - } - BucketFile::NativeFile(_) => { panic!() } - } - } - - fn infer_mime_type(&self) -> Result { - match self { - BucketFile::WebFile(web) => { - web.infer_mime_type() - } - BucketFile::NativeFile(_) => { panic!() } - } - } - - fn write_chunk(&self, chunk: Vec, offset: u64) -> Result<(), Self::Error> { - match self { - BucketFile::WebFile(web) => { - web.write_chunk(chunk, offset) - } - BucketFile::NativeFile(_) => { panic!() } - } - } - - fn write_stream(&self, stream: &dyn Write) -> Result<(), Self::Error> { - match self { - BucketFile::WebFile(web) => { - web.write_stream(stream) - } - BucketFile::NativeFile(_) => { panic!() } - } - } - - fn get_size(&self) -> u64 { - match self { - BucketFile::WebFile(web) => { - web.get_size() - } - BucketFile::NativeFile(_) => { panic!() } - } - } -} - -#[cfg(feature = "native")] -impl BucketFileTrait for VirtualNativeBucketFile { - type Error = (); - type FileHandle = (); - - fn from(file_handle: Self::FileHandle, filename: String) -> Self where Self: Sized { - todo!() - } - - fn get_file_handle(&self) -> Self::FileHandle { - todo!() - } - - async fn read_chunk(&self, size: u64, offset: u64) -> Result, Self::Error> { - todo!() - } - - fn read_stream(&self) -> Result, Self::Error> { - todo!() - } - - fn get_extension(&self) -> Result { - todo!() - } - fn get_mime_type(&self) -> Result { - todo!() - } - fn infer_mime_type(&self) -> Result { - todo!() - } +#[cfg(test)] +mod tests { + #[test] + fn test_delete() {} - fn write_chunk(&self, chunk: Vec, offset: u64) -> Result<(), Self::Error> { - todo!() - } + #[test] + fn test_file_creation() {} - fn write_stream(&self, stream: &dyn Write) -> Result<(), Self::Error> { - todo!() - } + #[test] + fn test_write() {} - fn get_size(&self) -> u64 { - todo!() - } -}*/ \ No newline at end of file + #[test] + fn test_read() {} +} \ No newline at end of file diff --git a/src/controller/bucket/io/native_file.rs b/src/controller/bucket/io/native_file.rs index 82ebbd6..dd834a2 100644 --- a/src/controller/bucket/io/native_file.rs +++ b/src/controller/bucket/io/native_file.rs @@ -1,9 +1,12 @@ use mime::{FromStrError, Mime}; +use tonic::async_trait; use std::{ io::Write, os::unix::prelude::FileExt, str::FromStr, }; +use std::fs::File; +use std::path::Path; use super::file::BucketFileTrait; @@ -27,11 +30,18 @@ pub enum NativeBucketFileError { FromStrError(#[from] FromStrError), } +#[async_trait(?Send)] impl BucketFileTrait for VirtualNativeBucketFile { type Error = NativeBucketFileError; type FileHandle = std::fs::File; - + fn new(filename: &str, mime:&Mime) -> Result where Self: Sized { + let file = File::create(Path::new(filename))?; + Ok(Self { + file_handle: file, + filename: filename.to_string(), + }) + } fn from(file_handle: Self::FileHandle, filename: String) -> Self { Self { file_handle, @@ -39,8 +49,8 @@ impl BucketFileTrait for VirtualNativeBucketFile { } } - fn get_file_handle(&self) -> Self::FileHandle { - self.file_handle + fn get_file_handle(&self) -> &Self::FileHandle { + &self.file_handle } async fn read_chunk(&self, size: u64, offset: u64) -> Result, Self::Error> { @@ -76,7 +86,7 @@ impl BucketFileTrait for VirtualNativeBucketFile { } } - fn write_chunk(&self, chunk: std::vec::Vec, offset: u64) -> Result<(), Self::Error> { + fn write_chunk(&self, chunk: &std::vec::Vec, offset: u64) -> Result<(), Self::Error> { todo!(); self.file_handle.write_all(&chunk)?; Ok(()) @@ -92,58 +102,3 @@ impl BucketFileTrait for VirtualNativeBucketFile { self.file_handle.metadata().unwrap().len() } } - -// impl BucketFileTrait for VirtualNativeBucketFile { -// type Error = NativeBucketFileError; -// type FileHandle = std::fs::File; - -// fn new(detail: Arc, file_handle: Option) -> Self { -// Self { -// file_details: detail, -// file_handle, -// } -// } - -// fn get_file_handle(&self) -> &Option { -// &self.file_handle -// } - -// fn read_chunk(&self, size: u64, offset: u64) -> Result, Self::Error> { -// let mut buffer = Vec::with_capacity(size as usize); -// match &self.file_handle { -// None => Err(NativeBucketFileError::NoFileToRead), -// Some(file) => { -// file.read_at(buffer.as_mut_slice(), offset)?; -// Ok(buffer) -// } -// } -// } - -// fn get_extension(&self) -> Result { -// todo!() -// } - -// fn get_mime_type(&self) -> Result { -// todo!() -// } - -// fn infer_mime_type(&self) -> Result { -// todo!() -// } - -// fn write_chunk(&self, chunk: std::vec::Vec, offset: u64) -> Result<(), Self::Error> { -// todo!() -// } - -// fn write_stream(&self, stream: &dyn std::io::prelude::Write) -> Result<(), Self::Error> { -// todo!() -// } - -// fn get_size(&self) -> Option { -// todo!() -// } - -// fn read_stream(&self) -> Result, Self::Error> { -// todo!() -// } -// } diff --git a/src/controller/bucket/io/web_file.rs b/src/controller/bucket/io/web_file.rs index bd6863c..bb26fb4 100644 --- a/src/controller/bucket/io/web_file.rs +++ b/src/controller/bucket/io/web_file.rs @@ -62,11 +62,23 @@ pub struct VirtualWebBucketFile { filename: String, } +#[async_trait(?Send)] impl BucketFileTrait for VirtualWebBucketFile { type Error = WebBucketFileError; type FileHandle = WebFileHandle; - + fn new(filename: &str, mime:&Mime) -> Result where Self: Sized { + let file_handle = gloo::file::File::new_with_options( + &filename, + "", + Some(mime.to_string().as_str()), + None, + ); + Ok(Self { + file_handle, + filename: filename.to_string(), + }) + } fn from(file_handle: Self::FileHandle, filename: String) -> Self { Self { file_handle, @@ -117,7 +129,7 @@ impl BucketFileTrait for VirtualWebBucketFile { } } - fn write_chunk(&self, chunk: vec::Vec, offset: u64) -> Result<(), Self::Error> { + fn write_chunk(&self, chunk: &vec::Vec, offset: u64) -> Result<(), Self::Error> { let web_file: &web_sys::File = self.file_handle.as_ref(); let mut writable_stream = WritableStream::from_raw(web_file.stream().unchecked_into()).into_stream(); let mut writer = writable_stream.get_writer(); diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 25a54aa..cb3b28e 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -34,7 +34,7 @@ mod tests { let username = "awesomeusername".to_string(); let password = "awesomepassword".to_string(); let captcha = "".to_string(); - authentication::register(&mut query_client, email, username, password, captcha) + authentication::register(&mut query_client, email.as_str(), username.as_str(), password.as_str(), captcha.as_str()) .await .unwrap(); }