From 31349a47d3fa12ed15f409654d0af2c0ba0645d2 Mon Sep 17 00:00:00 2001 From: "Shane A. Faulkner" Date: Sat, 14 Jul 2018 01:09:20 -0500 Subject: [PATCH 1/4] Very dirty addition of missing api's --- src/api/core/ciphers.rs | 43 +++++++++++++++++++++++++++++++++++++++++ src/api/core/mod.rs | 3 +++ 2 files changed, 46 insertions(+) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 29f9e8c6..30aab620 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -415,6 +415,32 @@ fn post_attachment(uuid: String, data: Data, content_type: &ContentType, headers Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, &conn))) } +#[post("/ciphers//attachment-admin", format = "multipart/form-data", data = "")] +fn post_attachment_admin(uuid: String, data: Data, content_type: &ContentType, headers: Headers, conn: DbConn) -> JsonResult { + post_attachment(uuid, data, content_type, headers, conn) +} + +#[post("/ciphers//attachment//share", format = "multipart/form-data", data = "")] +fn post_attachment_share(uuid: String, attachment_id: String, data: Data, content_type: &ContentType, headers: Headers, conn: DbConn) -> JsonResult { + + let cipher = match Cipher::find_by_uuid(&uuid, &conn) { + Some(cipher) => cipher, + None => err!("Cipher doesn't exist") + }; + + if !cipher.is_write_accessible_to_user(&headers.user.uuid, &conn) { + err!("Cipher is not write accessible") + }; + + try!(_delete_cipher_attachment_by_uuid(&uuid, &attachment_id, &conn)); + post_attachment(uuid, data, content_type, headers, conn) +} + +#[post("/ciphers//attachment//delete-admin")] +fn delete_attachment_post_admin(uuid: String, attachment_id: String, headers: Headers, conn: DbConn) -> EmptyResult { + delete_attachment(uuid, attachment_id, headers, conn) +} + #[post("/ciphers//attachment//delete")] fn delete_attachment_post(uuid: String, attachment_id: String, headers: Headers, conn: DbConn) -> EmptyResult { delete_attachment(uuid, attachment_id, headers, conn) @@ -578,3 +604,20 @@ fn _delete_cipher_by_uuid(uuid: &str, headers: &Headers, conn: &DbConn) -> Empty Err(_) => err!("Failed deleting cipher") } } + +fn _delete_cipher_attachment_by_uuid(uuid: &str, attachment_id: &str, conn: &DbConn) -> EmptyResult { + let attachment = match Attachment::find_by_id(&attachment_id, &conn) { + Some(attachment) => attachment, + None => err!("Attachment doesn't exist") + }; + + if attachment.cipher_uuid != uuid { + err!("Attachment from other cipher") + } + + // Delete attachment + match attachment.delete(&conn) { + Ok(()) => Ok(()), + Err(_) => err!("Deleting attachement failed") + } +} diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 89df7a1f..513319bc 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -34,7 +34,10 @@ pub fn routes() -> Vec { post_ciphers_admin, post_ciphers_import, post_attachment, + post_attachment_admin, + post_attachment_share, delete_attachment_post, + delete_attachment_post_admin, delete_attachment, post_cipher_admin, post_cipher_share, From 98bae4a0a195eaf611f43669e3cdcfd3ac76a374 Mon Sep 17 00:00:00 2001 From: "Shane A. Faulkner" Date: Wed, 18 Jul 2018 15:35:45 -0500 Subject: [PATCH 2/4] Cleanup and working with 2 or less attachments --- src/api/core/ciphers.rs | 47 +++++++++++------------------------------ 1 file changed, 12 insertions(+), 35 deletions(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 30aab620..ec1227bf 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -422,17 +422,7 @@ fn post_attachment_admin(uuid: String, data: Data, content_type: &ContentType, h #[post("/ciphers//attachment//share", format = "multipart/form-data", data = "")] fn post_attachment_share(uuid: String, attachment_id: String, data: Data, content_type: &ContentType, headers: Headers, conn: DbConn) -> JsonResult { - - let cipher = match Cipher::find_by_uuid(&uuid, &conn) { - Some(cipher) => cipher, - None => err!("Cipher doesn't exist") - }; - - if !cipher.is_write_accessible_to_user(&headers.user.uuid, &conn) { - err!("Cipher is not write accessible") - }; - - try!(_delete_cipher_attachment_by_uuid(&uuid, &attachment_id, &conn)); + _delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &conn)?; post_attachment(uuid, data, content_type, headers, conn) } @@ -448,29 +438,7 @@ fn delete_attachment_post(uuid: String, attachment_id: String, headers: Headers, #[delete("/ciphers//attachment/")] fn delete_attachment(uuid: String, attachment_id: String, headers: Headers, conn: DbConn) -> EmptyResult { - let attachment = match Attachment::find_by_id(&attachment_id, &conn) { - Some(attachment) => attachment, - None => err!("Attachment doesn't exist") - }; - - if attachment.cipher_uuid != uuid { - err!("Attachment from other cipher") - } - - let cipher = match Cipher::find_by_uuid(&uuid, &conn) { - Some(cipher) => cipher, - None => err!("Cipher doesn't exist") - }; - - if !cipher.is_write_accessible_to_user(&headers.user.uuid, &conn) { - err!("Cipher cannot be deleted by user") - } - - // Delete attachment - match attachment.delete(&conn) { - Ok(()) => Ok(()), - Err(_) => err!("Deleting attachement failed") - } + _delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &conn) } #[post("/ciphers//delete")] @@ -605,7 +573,7 @@ fn _delete_cipher_by_uuid(uuid: &str, headers: &Headers, conn: &DbConn) -> Empty } } -fn _delete_cipher_attachment_by_uuid(uuid: &str, attachment_id: &str, conn: &DbConn) -> EmptyResult { +fn _delete_cipher_attachment_by_id(uuid: &str, attachment_id: &str, headers: &Headers, conn: &DbConn) -> EmptyResult { let attachment = match Attachment::find_by_id(&attachment_id, &conn) { Some(attachment) => attachment, None => err!("Attachment doesn't exist") @@ -615,6 +583,15 @@ fn _delete_cipher_attachment_by_uuid(uuid: &str, attachment_id: &str, conn: &DbC err!("Attachment from other cipher") } + let cipher = match Cipher::find_by_uuid(&uuid, &conn) { + Some(cipher) => cipher, + None => err!("Cipher doesn't exist") + }; + + if !cipher.is_write_accessible_to_user(&headers.user.uuid, &conn) { + err!("Cipher cannot be deleted by user") + } + // Delete attachment match attachment.delete(&conn) { Ok(()) => Ok(()), From 2872f40d13682e9905771da900e13bc8045d509f Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 31 Jul 2018 15:07:17 +0100 Subject: [PATCH 3/4] WAL journal mode and delete retry added --- src/db/models/attachment.rs | 31 +++++++++++++++++++++++++------ src/main.rs | 5 +++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/db/models/attachment.rs b/src/db/models/attachment.rs index 1ce4edfe..1f5e29a7 100644 --- a/src/db/models/attachment.rs +++ b/src/db/models/attachment.rs @@ -64,14 +64,33 @@ impl Attachment { pub fn delete(self, conn: &DbConn) -> QueryResult<()> { use util; + use std::{thread, time}; - util::delete_file(&self.get_file_path()); + let mut retries = 10; + + loop { + match diesel::delete( + attachments::table.filter( + attachments::id.eq(&self.id) + ) + ).execute(&**conn) { + Ok(_) => break, + Err(err) => { + if retries < 1 { + println!("ERROR: Failed with 10 retries"); + return Err(err) + } else { + retries = retries - 1; + println!("Had to retry! Retries left: {}", retries); + thread::sleep(time::Duration::from_millis(500)); + continue + } + } + } + } - diesel::delete( - attachments::table.filter( - attachments::id.eq(self.id) - ) - ).execute(&**conn).and(Ok(())) + util::delete_file(&self.get_file_path()); + Ok(()) } pub fn delete_all_by_cipher(cipher_uuid: &str, conn: &DbConn) -> QueryResult<()> { diff --git a/src/main.rs b/src/main.rs index 17b63794..59840b9c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -83,6 +83,11 @@ fn check_db() { exit(1); } } + + // Turn on WAL in SQLite + use diesel::RunQueryDsl; + let connection = db::get_connection().expect("Can't conect to DB"); + diesel::sql_query("PRAGMA journal_mode=wal").execute(&connection).expect("Failed to turn on WAL"); } fn check_rsa_keys() { From d335f45e34e566bee01a6c754eea61bb3c17e016 Mon Sep 17 00:00:00 2001 From: "Shane A. Faulkner" Date: Tue, 31 Jul 2018 12:07:03 -0500 Subject: [PATCH 4/4] Bump version to 0.12.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 31445dd1..fb5adafb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bitwarden_rs" -version = "0.11.0" +version = "0.12.0" authors = ["Daniel GarcĂ­a "] [dependencies]