vw_small

Hardened fork of Vaultwarden (https://github.com/dani-garcia/vaultwarden) with fewer features.
git clone https://git.philomathiclife.com/repos/vw_small
Log | Files | Refs | README

commit 941747f9e84eaf336e04b6d4bd1355300402e93e
parent 726ba36e5bc9b98c93d5636c52c692d94563515a
Author: Miroslav Prasil <miroslav@prasil.info>
Date:   Fri, 18 May 2018 16:52:51 +0100

Implement deleting Organization

Diffstat:
Msrc/api/core/organizations.rs | 32+++++++++++++++++++++++---------
Msrc/db/models/cipher.rs | 7+++++++
Msrc/db/models/collection.rs | 13+++++++++++++
Msrc/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 @@ -55,13 +55,30 @@ fn create_organization(headers: Headers, data: Json<OrgData>, conn: DbConn) -> J } #[post("/organizations/<org_id>/delete", data = "<data>")] -fn delete_organization(org_id: String, data: Json<PasswordData>, headers: Headers, conn: DbConn) -> JsonResult { +fn delete_organization(org_id: String, data: Json<PasswordData>, 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") + } + + 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") + } - unimplemented!() + 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/<org_id>")] @@ -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, &current_user.uuid, &conn) { - CollectionUser::delete(&current_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 @@ -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<String>, 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 @@ -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<Self> { 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 @@ -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<Self> { @@ -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 {