commit 795d98afa6ff930c601b175993ff3ce428bfec8c
parent 1e812c0a234929b043534737ab9844a71c322345
Author: Daniel GarcĂa <dani-garcia@users.noreply.github.com>
Date:   Tue, 15 May 2018 20:24:17 +0200
Merge pull request #19 from mprasil/cipher_deleting
Remove dependent items when removing cipher
Diffstat:
6 files changed, 51 insertions(+), 32 deletions(-)
diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs
@@ -169,9 +169,10 @@ fn delete_account(data: Json<PasswordData>, headers: Headers, conn: DbConn) -> E
 
     // Delete ciphers and their attachments
     for cipher in Cipher::find_owned_by_user(&user.uuid, &conn) {
-        for a in Attachment::find_by_cipher(&cipher.uuid, &conn) { a.delete(&conn); }
-
-        cipher.delete(&conn);
+        match cipher.delete(&conn) {
+            Ok(()) => (),
+            Err(_) => err!("Failed deleting cipher")
+        }
     }
 
     // Delete folders
diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs
@@ -450,9 +450,10 @@ fn delete_attachment(uuid: String, attachment_id: String, headers: Headers, conn
     }
 
     // Delete attachment
-    attachment.delete(&conn);
-
-    Ok(())
+    match attachment.delete(&conn) {
+        Ok(()) => Ok(()),
+        Err(_) => err!("Deleting attachement failed")
+    }
 }
 
 #[post("/ciphers/<uuid>/delete")]
@@ -549,7 +550,10 @@ fn delete_all(data: Json<PasswordData>, headers: Headers, conn: DbConn) -> Empty
 
     // Delete ciphers and their attachments
     for cipher in Cipher::find_owned_by_user(&user.uuid, &conn) {
-        _delete_cipher(cipher, &conn);
+        match cipher.delete(&conn) {
+            Ok(()) => (),
+            Err(_) => err!("Failed deleting cipher")
+        }
     }
 
     // Delete folders
@@ -568,15 +572,8 @@ fn _delete_cipher_by_uuid(uuid: &str, headers: &Headers, conn: &DbConn) -> Empty
         err!("Cipher can't be deleted by user")
     }
 
-    _delete_cipher(cipher, conn);
-
-    Ok(())
-}
-
-fn _delete_cipher(cipher: Cipher, conn: &DbConn) {
-    // Delete the attachments
-    for a in Attachment::find_by_cipher(&cipher.uuid, &conn) { a.delete(&conn); }
-
-    // Delete the cipher
-    cipher.delete(conn);
+    match cipher.delete(conn) {
+        Ok(()) => Ok(()),
+        Err(_) => err!("Failed deleting cipher")
+    }
 }
diff --git a/src/db/models/attachment.rs b/src/db/models/attachment.rs
@@ -62,17 +62,23 @@ impl Attachment {
         }
     }
 
-    pub fn delete(self, conn: &DbConn) -> bool {
+    pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
         use util;
 
         util::delete_file(&self.get_file_path());
 
-        match diesel::delete(attachments::table.filter(
-            attachments::id.eq(self.id)))
-            .execute(&**conn) {
-            Ok(1) => true, // One row deleted
-            _ => false,
+        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<()> {
+        for attachement in Attachment::find_by_cipher(&cipher_uuid, &conn) {
+            attachement.delete(&conn)?;
         }
+        Ok(())
     }
 
     pub fn find_by_id(id: &str, conn: &DbConn) -> Option<Self> {
diff --git a/src/db/models/cipher.rs b/src/db/models/cipher.rs
@@ -3,7 +3,7 @@ use serde_json::Value as JsonValue;
 
 use uuid::Uuid;
 
-use super::{User, Organization, UserOrganization, FolderCipher, UserOrgType};
+use super::{User, Organization, UserOrganization, Attachment, FolderCipher, CollectionCipher, UserOrgType};
 
 #[derive(Debug, Identifiable, Queryable, Insertable, Associations)]
 #[table_name = "ciphers"]
@@ -133,13 +133,16 @@ impl Cipher {
         }
     }
 
-    pub fn delete(self, conn: &DbConn) -> bool {
-        match diesel::delete(ciphers::table.filter(
-            ciphers::uuid.eq(self.uuid)))
-            .execute(&**conn) {
-            Ok(1) => true, // One row deleted
-            _ => false,
-        }
+    pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
+        FolderCipher::delete_all_by_cipher(&self.uuid, &conn)?;
+        CollectionCipher::delete_all_by_cipher(&self.uuid, &conn)?;
+        Attachment::delete_all_by_cipher(&self.uuid, &conn)?;
+
+        diesel::delete(
+            ciphers::table.filter(
+                ciphers::uuid.eq(self.uuid)
+            )
+        ).execute(&**conn).and(Ok(()))
     }
 
     pub fn move_to_folder(&self, folder_uuid: Option<String>, user_uuid: &str, conn: &DbConn) -> Result<(), &str> {
diff --git a/src/db/models/collection.rs b/src/db/models/collection.rs
@@ -204,4 +204,10 @@ impl CollectionCipher {
             _ => false,
         }
     }
+
+    pub fn delete_all_by_cipher(cipher_uuid: &str, conn: &DbConn) -> QueryResult<()> {
+        diesel::delete(ciphers_collections::table
+            .filter(ciphers_collections::cipher_uuid.eq(cipher_uuid))
+        ).execute(&**conn).and(Ok(()))
+    }
 }
 \ No newline at end of file
diff --git a/src/db/models/folder.rs b/src/db/models/folder.rs
@@ -117,6 +117,12 @@ impl FolderCipher {
         ).execute(&**conn).and(Ok(()))
     }
 
+    pub fn delete_all_by_cipher(cipher_uuid: &str, conn: &DbConn) -> QueryResult<()> {
+        diesel::delete(folders_ciphers::table
+            .filter(folders_ciphers::cipher_uuid.eq(cipher_uuid))
+        ).execute(&**conn).and(Ok(()))
+    }
+
     pub fn find_by_folder_and_cipher(folder_uuid: &str, cipher_uuid: &str, conn: &DbConn) -> Option<Self> {
         folders_ciphers::table
             .filter(folders_ciphers::folder_uuid.eq(folder_uuid))