commit b163aeb8caa2502ee3e6f8d62a0ac53d59bb15e3
parent fcb479a45734cf7ea06b6e81f0e18c0b9568f777
Author: Miroslav Prasil <miroslav@prasil.info>
Date: Wed, 1 Aug 2018 11:37:42 +0100
Merge changes in master to beta branch (concurrency fixes)
Diffstat:
6 files changed, 79 insertions(+), 32 deletions(-)
diff --git 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 <dani-garcia@users.noreply.github.com>"]
[dependencies]
diff --git 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.
@@ -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!
diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs
@@ -415,6 +415,22 @@ fn post_attachment(uuid: String, data: Data, content_type: &ContentType, headers
Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, &conn)))
}
+#[post("/ciphers/<uuid>/attachment-admin", format = "multipart/form-data", 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/<uuid>/attachment/<attachment_id>/share", format = "multipart/form-data", data = "<data>")]
+fn post_attachment_share(uuid: String, attachment_id: String, data: Data, content_type: &ContentType, headers: Headers, conn: DbConn) -> JsonResult {
+ _delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &conn)?;
+ post_attachment(uuid, data, content_type, headers, conn)
+}
+
+#[post("/ciphers/<uuid>/attachment/<attachment_id>/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/<uuid>/attachment/<attachment_id>/delete")]
fn delete_attachment_post(uuid: String, attachment_id: String, headers: Headers, conn: DbConn) -> EmptyResult {
delete_attachment(uuid, attachment_id, headers, conn)
@@ -422,29 +438,7 @@ fn delete_attachment_post(uuid: String, attachment_id: String, headers: Headers,
#[delete("/ciphers/<uuid>/attachment/<attachment_id>")]
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/<uuid>/delete")]
@@ -583,3 +577,29 @@ fn _delete_cipher_by_uuid(uuid: &str, headers: &Headers, conn: &DbConn) -> Empty
Err(_) => err!("Failed deleting cipher")
}
}
+
+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")
+ };
+
+ 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")
+ }
+}
diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs
@@ -34,7 +34,10 @@ pub fn routes() -> Vec<Route> {
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,
diff --git 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
@@ -84,6 +84,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() {