1
0
mirror of https://github.com/dani-garcia/vaultwarden.git synced 2024-11-10 04:52:40 +01:00

Support listing and deleting users from collection

This commit is contained in:
Miroslav Prasil 2018-05-29 16:01:38 +01:00 committed by
parent 4de0bf3722
commit 62be23b1c0
4 changed files with 85 additions and 26 deletions

View File

@ -68,6 +68,7 @@ pub fn routes() -> Vec<Route> {
get_collection_users, get_collection_users,
post_organization, post_organization,
post_organization_collections, post_organization_collections,
post_organization_collection_delete_user,
post_organization_collection_update, post_organization_collection_update,
post_organization_collection_delete, post_organization_collection_delete,
post_collections_update, post_collections_update,

View File

@ -192,6 +192,38 @@ fn post_organization_collection_update(org_id: String, col_id: String, headers:
Ok(Json(collection.to_json())) Ok(Json(collection.to_json()))
} }
#[post("/organizations/<org_id>/collections/<col_id>/delete-user/<org_user_id>")]
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)] #[derive(Deserialize, Debug)]
#[allow(non_snake_case)] #[allow(non_snake_case)]
struct DeleteCollectionData { struct DeleteCollectionData {
@ -232,26 +264,21 @@ fn get_org_collection_detail(org_id: String, coll_id: String, headers: AdminHead
#[get("/organizations/<org_id>/collections/<coll_id>/users")] #[get("/organizations/<org_id>/collections/<coll_id>/users")]
fn get_collection_users(org_id: String, coll_id: String, headers: AdminHeaders, conn: DbConn) -> JsonResult { 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 // 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 // Get the users from collection
let user_list: Vec<Value> = CollectionUser::find_by_collection(&collection.uuid, &conn)
/* .iter().map(|col_user| {
The elements from the data array to return have the following structure UserOrganization::find_by_user_and_org(&col_user.user_uuid, &org_id, &conn)
.unwrap()
{ .to_json_collection_user_details(&col_user.read_only, &conn)
OrganizationUserId: <id> }).collect();
AccessAll: true
Name: <user_name>
Email: <user_email>
Type: 0
Status: 2
ReadOnly: false
Object: collectionUser
}
*/
Ok(Json(json!({ Ok(Json(json!({
"Data": [], "Data": user_list,
"Object": "list" "Object": "list"
}))) })))
} }
@ -473,8 +500,11 @@ fn edit_user(org_id: String, user_id: String, data: Json<EditUserData>, headers:
user_to_edit.type_ = new_type; user_to_edit.type_ = new_type;
// Delete all the odd collections // Delete all the odd collections
for c in Collection::find_by_organization_and_user_uuid(&org_id, &user_to_edit.user_uuid, &conn) { for c in CollectionUser::find_by_organization_and_user_uuid(&org_id, &user_to_edit.user_uuid, &conn) {
CollectionUser::delete(&user_to_edit.user_uuid, &c.uuid, &conn); match c.delete(&conn) {
Ok(()) => (),
Err(_) => err!("Failed deleting old collection assignment")
}
} }
// If no accessAll, add the collections received // If no accessAll, add the collections received

View File

@ -188,14 +188,26 @@ impl CollectionUser {
)).execute(&**conn).and(Ok(())) )).execute(&**conn).and(Ok(()))
} }
pub fn delete(user_uuid: &str, collection_uuid: &str, conn: &DbConn) -> bool { pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
match diesel::delete(users_collections::table diesel::delete(users_collections::table
.filter(users_collections::user_uuid.eq(user_uuid)) .filter(users_collections::user_uuid.eq(&self.user_uuid))
.filter(users_collections::collection_uuid.eq(collection_uuid))) .filter(users_collections::collection_uuid.eq(&self.collection_uuid)))
.execute(&**conn) { .execute(&**conn).and(Ok(()))
Ok(1) => true, // One row deleted }
_ => false,
} pub fn find_by_collection(collection_uuid: &str, conn: &DbConn) -> Vec<Self> {
users_collections::table
.filter(users_collections::collection_uuid.eq(collection_uuid))
.select(users_collections::all_columns)
.load::<Self>(&**conn).expect("Error loading users_collections")
}
pub fn find_by_collection_and_user(collection_uuid: &str, user_uuid: &str, conn: &DbConn) -> Option<Self> {
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::<Self>(&**conn).ok()
} }
pub fn delete_all_by_collection(collection_uuid: &str, conn: &DbConn) -> QueryResult<()> { pub fn delete_all_by_collection(collection_uuid: &str, conn: &DbConn) -> QueryResult<()> {

View File

@ -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 { pub fn to_json_details(&self, conn: &DbConn) -> JsonValue {
let coll_uuids = if self.access_all { let coll_uuids = if self.access_all {
vec![] // If we have complete access, no need to fill the array vec![] // If we have complete access, no need to fill the array