From 941747f9e84eaf336e04b6d4bd1355300402e93e Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Fri, 18 May 2018 16:52:51 +0100 Subject: [PATCH] Implement deleting Organization --- src/api/core/organizations.rs | 32 +++++++++++++++++++-------- src/db/models/cipher.rs | 7 ++++++ src/db/models/collection.rs | 13 +++++++++++ src/db/models/organization.rs | 41 ++++++++++++++++++++++++----------- 4 files changed, 71 insertions(+), 22 deletions(-) diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index 913ec7b5..5271345c 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -55,13 +55,30 @@ fn create_organization(headers: Headers, data: Json, conn: DbConn) -> J } #[post("/organizations//delete", data = "")] -fn delete_organization(org_id: String, data: Json, headers: Headers, conn: DbConn) -> JsonResult { +fn delete_organization(org_id: String, data: Json, headers: Headers, conn: DbConn) -> EmptyResult { let data: PasswordData = data.into_inner(); let password_hash = data.masterPasswordHash; - // TODO: Delete ciphers from organization, collection_users, collections, organization_users and the org itself + if !headers.user.check_valid_password(&password_hash) { + err!("Invalid password") + } - unimplemented!() + let org_user = match UserOrganization::find_by_user_and_org(&headers.user.uuid, &org_id, &conn) { + Some(user) => user, + None => err!("The current user isn't member of the organization") + }; + + if org_user.type_ != UserOrgType::Owner as i32 { + err!("Only owner is able to delete organization") + } + + match Organization::find_by_uuid(&org_id, &conn) { + None => err!("Organization not found"), + Some(org) => match org.delete(&conn) { + Ok(()) => Ok(()), + Err(_) => err!("Failed deleting the organization") + } + } } #[get("/organizations/")] @@ -513,11 +530,8 @@ fn delete_user(org_id: String, user_id: String, headers: Headers, conn: DbConn) } } - user_to_delete.delete(&conn); - - for c in Collection::find_by_organization_and_user_uuid(&org_id, ¤t_user.uuid, &conn) { - CollectionUser::delete(¤t_user.uuid, &c.uuid, &conn); + match user_to_delete.delete(&conn) { + Ok(()) => Ok(()), + Err(_) => err!("Failed deleting user from organization") } - - Ok(()) } \ No newline at end of file diff --git a/src/db/models/cipher.rs b/src/db/models/cipher.rs index 6fccdd64..8a71ceff 100644 --- a/src/db/models/cipher.rs +++ b/src/db/models/cipher.rs @@ -145,6 +145,13 @@ impl Cipher { ).execute(&**conn).and(Ok(())) } + pub fn delete_all_by_organization(org_uuid: &str, conn: &DbConn) -> QueryResult<()> { + for cipher in Self::find_by_org(org_uuid, &conn) { + cipher.delete(&conn)?; + } + Ok(()) + } + pub fn move_to_folder(&self, folder_uuid: Option, user_uuid: &str, conn: &DbConn) -> Result<(), &str> { match self.get_folder_uuid(&user_uuid, &conn) { None => { diff --git a/src/db/models/collection.rs b/src/db/models/collection.rs index ca646d3c..e9143adb 100644 --- a/src/db/models/collection.rs +++ b/src/db/models/collection.rs @@ -62,6 +62,13 @@ impl Collection { ).execute(&**conn).and(Ok(())) } + pub fn delete_all_by_organization(org_uuid: &str, conn: &DbConn) -> QueryResult<()> { + for collection in Self::find_by_organization(org_uuid, &conn) { + collection.delete(&conn)?; + } + Ok(()) + } + pub fn find_by_uuid(uuid: &str, conn: &DbConn) -> Option { collections::table .filter(collections::uuid.eq(uuid)) @@ -176,6 +183,12 @@ impl CollectionUser { .filter(users_collections::collection_uuid.eq(collection_uuid)) ).execute(&**conn).and(Ok(())) } + + pub fn delete_all_by_user(user_uuid: &str, conn: &DbConn) -> QueryResult<()> { + diesel::delete(users_collections::table + .filter(users_collections::user_uuid.eq(user_uuid)) + ).execute(&**conn).and(Ok(())) + } } use super::Cipher; diff --git a/src/db/models/organization.rs b/src/db/models/organization.rs index 658977a4..64053cfb 100644 --- a/src/db/models/organization.rs +++ b/src/db/models/organization.rs @@ -122,13 +122,18 @@ impl Organization { } } - pub fn delete(self, conn: &DbConn) -> bool { - match diesel::delete(organizations::table.filter( - organizations::uuid.eq(self.uuid))) - .execute(&**conn) { - Ok(1) => true, // One row deleted - _ => false, - } + pub fn delete(self, conn: &DbConn) -> QueryResult<()> { + use super::{Cipher, Collection}; + + Cipher::delete_all_by_organization(&self.uuid, &conn)?; + Collection::delete_all_by_organization(&self.uuid, &conn)?; + UserOrganization::delete_all_by_organization(&self.uuid, &conn)?; + + diesel::delete( + organizations::table.filter( + organizations::uuid.eq(self.uuid) + ) + ).execute(&**conn).and(Ok(())) } pub fn find_by_uuid(uuid: &str, conn: &DbConn) -> Option { @@ -215,13 +220,23 @@ impl UserOrganization { } } - pub fn delete(self, conn: &DbConn) -> bool { - match diesel::delete(users_organizations::table.filter( - users_organizations::uuid.eq(self.uuid))) - .execute(&**conn) { - Ok(1) => true, // One row deleted - _ => false, + pub fn delete(self, conn: &DbConn) -> QueryResult<()> { + use super::CollectionUser; + + CollectionUser::delete_all_by_user(&self.user_uuid, &conn)?; + + diesel::delete( + users_organizations::table.filter( + users_organizations::uuid.eq(self.uuid) + ) + ).execute(&**conn).and(Ok(())) + } + + pub fn delete_all_by_organization(org_uuid: &str, conn: &DbConn) -> QueryResult<()> { + for user_org in Self::find_by_org(&org_uuid, &conn) { + user_org.delete(&conn)?; } + Ok(()) } pub fn has_full_access(self) -> bool {