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/6] 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/6] 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 51450a0df96425721e49fbb08a9f8d2a5347d45f Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 24 Jul 2018 12:32:41 +0100 Subject: [PATCH 3/6] Fixed the documentation for https (resolves #101) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f05a6e96..cf526b5a 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,7 @@ docker run -d --name bitwarden \ -v /ssl/keys/:/ssl/ \ -v /bw-data/:/data/ \ -v /icon_cache/ \ - -p 443:443 \ + -p 443:80 \ mprasil/bitwarden:latest ``` Note that you need to mount ssl files and you need to forward appropriate port. From d073f06652c4b90dacfcefa4464cee06f97ab5f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Christian=20Gr=C3=BCnhage?= Date: Thu, 26 Jul 2018 22:42:02 +0100 Subject: [PATCH 4/6] Update matrix.to link in the README Using the room ID instead of an alias isn't supposed to be working for joining rooms, and doesn't work when joining over federation. It only works when your server is already participating in the room. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf526b5a..aa0790a8 100644 --- a/README.md +++ b/README.md @@ -317,4 +317,4 @@ docker run -d --name bitwarden \ To ask an question, [raising an issue](https://github.com/dani-garcia/bitwarden_rs/issues/new) is fine, also please report any bugs spotted here. -If you prefer to chat, we're usually hanging around at [#bitwarden_rs:matrix.org](https://matrix.to/#/!cASGtOHlSftdScFNMs:matrix.org) room on Matrix. Feel free to join us! +If you prefer to chat, we're usually hanging around at [#bitwarden_rs:matrix.org](https://matrix.to/#/#bitwarden_rs:matrix.org) room on Matrix. Feel free to join us! From 2872f40d13682e9905771da900e13bc8045d509f Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 31 Jul 2018 15:07:17 +0100 Subject: [PATCH 5/6] 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 6/6] 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]