From 62be23b1c01c277020eca1ec36f2d4cd4d9b881d Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 29 May 2018 16:01:38 +0100 Subject: [PATCH 1/2] Support listing and deleting users from collection --- src/api/core/mod.rs | 1 + src/api/core/organizations.rs | 66 +++++++++++++++++++++++++---------- src/db/models/collection.rs | 28 ++++++++++----- src/db/models/organization.rs | 16 +++++++++ 4 files changed, 85 insertions(+), 26 deletions(-) diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 9d6df4f2..30713517 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -68,6 +68,7 @@ pub fn routes() -> Vec { get_collection_users, post_organization, post_organization_collections, + post_organization_collection_delete_user, post_organization_collection_update, post_organization_collection_delete, post_collections_update, diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index 4747e8e5..7d650cf2 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -192,6 +192,38 @@ fn post_organization_collection_update(org_id: String, col_id: String, headers: Ok(Json(collection.to_json())) } +#[post("/organizations//collections//delete-user/")] +fn post_organization_collection_delete_user(org_id: String, col_id: String, org_user_id: String, headers: Headers, conn: DbConn) -> EmptyResult { + match UserOrganization::find_by_user_and_org(&headers.user.uuid, &org_id, &conn) { + None => err!("Not a member of Organization"), + Some(user_org) => if user_org.has_full_access() { + match Collection::find_by_uuid(&col_id, &conn) { + None => err!("Collection not found"), + Some(collection) => if collection.org_uuid == org_id { + match UserOrganization::find_by_uuid(&org_user_id, &conn) { + None => err!("User not found in organization"), + Some(user_org) => { + match CollectionUser::find_by_collection_and_user(&collection.uuid, &user_org.user_uuid, &conn) { + None => err!("User not assigned to collection"), + Some(col_user) => { + match col_user.delete(&conn) { + Ok(()) => Ok(()), + Err(_) => err!("Failed removing user from collection") + } + } + } + } + } + } else { + err!("Collection and Organization id do not match") + } + } + } else { + err!("Not enough rights to delete Collection") + } + } +} + #[derive(Deserialize, Debug)] #[allow(non_snake_case)] struct DeleteCollectionData { @@ -232,26 +264,21 @@ fn get_org_collection_detail(org_id: String, coll_id: String, headers: AdminHead #[get("/organizations//collections//users")] fn get_collection_users(org_id: String, coll_id: String, headers: AdminHeaders, conn: DbConn) -> JsonResult { // Get org and collection, check that collection is from org + let collection = match Collection::find_by_uuid_and_org(&coll_id, &org_id, &conn) { + None => err!("Collection not found in Organization"), + Some(collection) => collection + }; // Get the users from collection - - /* - The elements from the data array to return have the following structure - - { - OrganizationUserId: - AccessAll: true - Name: - Email: - Type: 0 - Status: 2 - ReadOnly: false - Object: collectionUser - } - */ + let user_list: Vec = CollectionUser::find_by_collection(&collection.uuid, &conn) + .iter().map(|col_user| { + UserOrganization::find_by_user_and_org(&col_user.user_uuid, &org_id, &conn) + .unwrap() + .to_json_collection_user_details(&col_user.read_only, &conn) + }).collect(); Ok(Json(json!({ - "Data": [], + "Data": user_list, "Object": "list" }))) } @@ -473,8 +500,11 @@ fn edit_user(org_id: String, user_id: String, data: Json, headers: user_to_edit.type_ = new_type; // Delete all the odd collections - for c in Collection::find_by_organization_and_user_uuid(&org_id, &user_to_edit.user_uuid, &conn) { - CollectionUser::delete(&user_to_edit.user_uuid, &c.uuid, &conn); + for c in CollectionUser::find_by_organization_and_user_uuid(&org_id, &user_to_edit.user_uuid, &conn) { + match c.delete(&conn) { + Ok(()) => (), + Err(_) => err!("Failed deleting old collection assignment") + } } // If no accessAll, add the collections received diff --git a/src/db/models/collection.rs b/src/db/models/collection.rs index c2c49769..ed741ba0 100644 --- a/src/db/models/collection.rs +++ b/src/db/models/collection.rs @@ -188,14 +188,26 @@ impl CollectionUser { )).execute(&**conn).and(Ok(())) } - pub fn delete(user_uuid: &str, collection_uuid: &str, conn: &DbConn) -> bool { - match diesel::delete(users_collections::table - .filter(users_collections::user_uuid.eq(user_uuid)) - .filter(users_collections::collection_uuid.eq(collection_uuid))) - .execute(&**conn) { - Ok(1) => true, // One row deleted - _ => false, - } + pub fn delete(self, conn: &DbConn) -> QueryResult<()> { + diesel::delete(users_collections::table + .filter(users_collections::user_uuid.eq(&self.user_uuid)) + .filter(users_collections::collection_uuid.eq(&self.collection_uuid))) + .execute(&**conn).and(Ok(())) + } + + pub fn find_by_collection(collection_uuid: &str, conn: &DbConn) -> Vec { + users_collections::table + .filter(users_collections::collection_uuid.eq(collection_uuid)) + .select(users_collections::all_columns) + .load::(&**conn).expect("Error loading users_collections") + } + + pub fn find_by_collection_and_user(collection_uuid: &str, user_uuid: &str, conn: &DbConn) -> Option { + users_collections::table + .filter(users_collections::collection_uuid.eq(collection_uuid)) + .filter(users_collections::user_uuid.eq(user_uuid)) + .select(users_collections::all_columns) + .first::(&**conn).ok() } pub fn delete_all_by_collection(collection_uuid: &str, conn: &DbConn) -> QueryResult<()> { diff --git a/src/db/models/organization.rs b/src/db/models/organization.rs index 64053cfb..17599000 100644 --- a/src/db/models/organization.rs +++ b/src/db/models/organization.rs @@ -189,6 +189,22 @@ impl UserOrganization { }) } + pub fn to_json_collection_user_details(&self, read_only: &bool, conn: &DbConn) -> JsonValue { + use super::User; + let user = User::find_by_uuid(&self.user_uuid, conn).unwrap(); + + json!({ + "OrganizationUserId": self.uuid, + "AccessAll": self.access_all, + "Name": user.name, + "Email": user.email, + "Type": self.type_, + "Status": self.status, + "ReadOnly": read_only, + "Object": "collectionUser", + }) + } + pub fn to_json_details(&self, conn: &DbConn) -> JsonValue { let coll_uuids = if self.access_all { vec![] // If we have complete access, no need to fill the array From 46f3b229ee8dd7619d5aa493f4e885056f6f7eb3 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Wed, 30 May 2018 16:01:56 +0100 Subject: [PATCH 2/2] Removed unnecessary checks, simplified the code a bit --- src/api/core/organizations.rs | 43 ++++++++++++++++------------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index 7d650cf2..4cba2949 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -193,33 +193,28 @@ fn post_organization_collection_update(org_id: String, col_id: String, headers: } #[post("/organizations//collections//delete-user/")] -fn post_organization_collection_delete_user(org_id: String, col_id: String, org_user_id: String, headers: Headers, conn: DbConn) -> EmptyResult { - match UserOrganization::find_by_user_and_org(&headers.user.uuid, &org_id, &conn) { - None => err!("Not a member of Organization"), - Some(user_org) => if user_org.has_full_access() { - match Collection::find_by_uuid(&col_id, &conn) { - None => err!("Collection not found"), - Some(collection) => if collection.org_uuid == org_id { - match UserOrganization::find_by_uuid(&org_user_id, &conn) { - None => err!("User not found in organization"), - Some(user_org) => { - match CollectionUser::find_by_collection_and_user(&collection.uuid, &user_org.user_uuid, &conn) { - None => err!("User not assigned to collection"), - Some(col_user) => { - match col_user.delete(&conn) { - Ok(()) => Ok(()), - Err(_) => err!("Failed removing user from collection") - } - } - } - } +fn post_organization_collection_delete_user(org_id: String, col_id: String, org_user_id: String, headers: AdminHeaders, conn: DbConn) -> EmptyResult { + let collection = match Collection::find_by_uuid(&col_id, &conn) { + None => err!("Collection not found"), + Some(collection) => if collection.org_uuid == org_id { + collection + } else { + err!("Collection and Organization id do not match") + } + }; + + match UserOrganization::find_by_uuid(&org_user_id, &conn) { + None => err!("User not found in organization"), + Some(user_org) => { + match CollectionUser::find_by_collection_and_user(&collection.uuid, &user_org.user_uuid, &conn) { + None => err!("User not assigned to collection"), + Some(col_user) => { + match col_user.delete(&conn) { + Ok(()) => Ok(()), + Err(_) => err!("Failed removing user from collection") } - } else { - err!("Collection and Organization id do not match") } } - } else { - err!("Not enough rights to delete Collection") } } }