mirror of
https://github.com/dani-garcia/vaultwarden
synced 2024-11-15 14:33:09 +01:00
Merge pull request #32 from mprasil/collection_users
Support listing and deleting users from collection
This commit is contained in:
commit
4f7cc5e190
4 changed files with 80 additions and 26 deletions
|
@ -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,
|
||||||
|
|
|
@ -192,6 +192,33 @@ 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: 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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
struct DeleteCollectionData {
|
struct DeleteCollectionData {
|
||||||
|
@ -232,26 +259,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 +495,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
|
||||||
|
|
|
@ -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<()> {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue