geforkt von mirrored/vaultwarden
Merge pull request #107 from shauder/bug/attachments_for_orgs
Bug/attachments for orgs
Dieser Commit ist enthalten in:
Commit
56b3afa77c
5 geänderte Dateien mit 77 neuen und 30 gelöschten Zeilen
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "bitwarden_rs"
|
name = "bitwarden_rs"
|
||||||
version = "0.11.0"
|
version = "0.12.0"
|
||||||
authors = ["Daniel García <dani-garcia@users.noreply.github.com>"]
|
authors = ["Daniel García <dani-garcia@users.noreply.github.com>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
|
@ -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)))
|
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")]
|
#[post("/ciphers/<uuid>/attachment/<attachment_id>/delete")]
|
||||||
fn delete_attachment_post(uuid: String, attachment_id: String, headers: Headers, conn: DbConn) -> EmptyResult {
|
fn delete_attachment_post(uuid: String, attachment_id: String, headers: Headers, conn: DbConn) -> EmptyResult {
|
||||||
delete_attachment(uuid, attachment_id, headers, conn)
|
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>")]
|
#[delete("/ciphers/<uuid>/attachment/<attachment_id>")]
|
||||||
fn delete_attachment(uuid: String, attachment_id: String, headers: Headers, conn: DbConn) -> EmptyResult {
|
fn delete_attachment(uuid: String, attachment_id: String, headers: Headers, conn: DbConn) -> EmptyResult {
|
||||||
let attachment = match Attachment::find_by_id(&attachment_id, &conn) {
|
_delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &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")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/ciphers/<uuid>/delete")]
|
#[post("/ciphers/<uuid>/delete")]
|
||||||
|
@ -578,3 +572,29 @@ fn _delete_cipher_by_uuid(uuid: &str, headers: &Headers, conn: &DbConn) -> Empty
|
||||||
Err(_) => err!("Failed deleting cipher")
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -34,7 +34,10 @@ pub fn routes() -> Vec<Route> {
|
||||||
post_ciphers_admin,
|
post_ciphers_admin,
|
||||||
post_ciphers_import,
|
post_ciphers_import,
|
||||||
post_attachment,
|
post_attachment,
|
||||||
|
post_attachment_admin,
|
||||||
|
post_attachment_share,
|
||||||
delete_attachment_post,
|
delete_attachment_post,
|
||||||
|
delete_attachment_post_admin,
|
||||||
delete_attachment,
|
delete_attachment,
|
||||||
post_cipher_admin,
|
post_cipher_admin,
|
||||||
post_cipher_share,
|
post_cipher_share,
|
||||||
|
|
|
@ -64,14 +64,33 @@ impl Attachment {
|
||||||
|
|
||||||
pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
|
pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
|
||||||
use util;
|
use util;
|
||||||
|
use std::{thread, time};
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
util::delete_file(&self.get_file_path());
|
util::delete_file(&self.get_file_path());
|
||||||
|
Ok(())
|
||||||
diesel::delete(
|
|
||||||
attachments::table.filter(
|
|
||||||
attachments::id.eq(self.id)
|
|
||||||
)
|
|
||||||
).execute(&**conn).and(Ok(()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_all_by_cipher(cipher_uuid: &str, conn: &DbConn) -> QueryResult<()> {
|
pub fn delete_all_by_cipher(cipher_uuid: &str, conn: &DbConn) -> QueryResult<()> {
|
||||||
|
|
|
@ -83,6 +83,11 @@ fn check_db() {
|
||||||
exit(1);
|
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() {
|
fn check_rsa_keys() {
|
||||||
|
|
Laden …
In neuem Issue referenzieren