Spiegel von
https://github.com/dani-garcia/vaultwarden.git
synchronisiert 2024-11-26 05:50:29 +01:00
Implement deleting collections
Dieser Commit ist enthalten in:
Ursprung
e2a065cb09
Commit
a0d2ca3f24
5 geänderte Dateien mit 61 neuen und 17 gelöschten Zeilen
|
@ -68,6 +68,7 @@ pub fn routes() -> Vec<Route> {
|
||||||
post_organization,
|
post_organization,
|
||||||
post_organization_collections,
|
post_organization_collections,
|
||||||
post_organization_collection_update,
|
post_organization_collection_update,
|
||||||
|
post_organization_collection_delete,
|
||||||
post_collections_admin,
|
post_collections_admin,
|
||||||
get_org_details,
|
get_org_details,
|
||||||
get_org_users,
|
get_org_users,
|
||||||
|
|
|
@ -150,7 +150,7 @@ fn post_organization_collections(org_id: String, headers: Headers, data: Json<Ne
|
||||||
collection.save(&conn);
|
collection.save(&conn);
|
||||||
|
|
||||||
if !org_user.access_all {
|
if !org_user.access_all {
|
||||||
CollectionUsers::save(&headers.user.uuid, &collection.uuid, false, &conn);
|
CollectionUser::save(&headers.user.uuid, &collection.uuid, false, &conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Json(collection.to_json()))
|
Ok(Json(collection.to_json()))
|
||||||
|
@ -183,6 +183,35 @@ fn post_organization_collection_update(org_id: String, col_id: String, headers:
|
||||||
Ok(Json(collection.to_json()))
|
Ok(Json(collection.to_json()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
struct DeleteCollectionData {
|
||||||
|
id: String,
|
||||||
|
orgId: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/organizations/<org_id>/collections/<col_id>/delete", data = "<data>")]
|
||||||
|
fn post_organization_collection_delete(org_id: String, col_id: String, headers: Headers, data: Json<DeleteCollectionData>, 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 collection.delete(&conn) {
|
||||||
|
Ok(()) => Ok(()),
|
||||||
|
Err(_) => err!("Failed deleting collection")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err!("Collection and Organization id do not match")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err!("Not enought rights to delete Collection")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[get("/organizations/<org_id>/collections/<coll_id>/details")]
|
#[get("/organizations/<org_id>/collections/<coll_id>/details")]
|
||||||
fn get_org_collection_detail(org_id: String, coll_id: String, headers: Headers, conn: DbConn) -> JsonResult {
|
fn get_org_collection_detail(org_id: String, coll_id: String, headers: Headers, conn: DbConn) -> JsonResult {
|
||||||
match Collection::find_by_uuid_and_user(&coll_id, &headers.user.uuid, &conn) {
|
match Collection::find_by_uuid_and_user(&coll_id, &headers.user.uuid, &conn) {
|
||||||
|
@ -309,7 +338,7 @@ fn send_invite(org_id: String, data: Json<InviteData>, headers: Headers, conn: D
|
||||||
if !data.accessAll {
|
if !data.accessAll {
|
||||||
for collection in data.collections.iter() {
|
for collection in data.collections.iter() {
|
||||||
// TODO: Check that collection is in org
|
// TODO: Check that collection is in org
|
||||||
CollectionUsers::save(&headers.user.uuid, &collection.id, collection.readOnly, &conn);
|
CollectionUser::save(&headers.user.uuid, &collection.id, collection.readOnly, &conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,14 +464,14 @@ fn edit_user(org_id: String, user_id: String, data: Json<EditUserData>, headers:
|
||||||
|
|
||||||
// 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 Collection::find_by_organization_and_user_uuid(&org_id, &user_to_edit.user_uuid, &conn) {
|
||||||
CollectionUsers::delete(&user_to_edit.user_uuid, &c.uuid, &conn);
|
CollectionUser::delete(&user_to_edit.user_uuid, &c.uuid, &conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no accessAll, add the collections received
|
// If no accessAll, add the collections received
|
||||||
if !data.accessAll {
|
if !data.accessAll {
|
||||||
for collection in data.collections.iter() {
|
for collection in data.collections.iter() {
|
||||||
// TODO: Check that collection is in org
|
// TODO: Check that collection is in org
|
||||||
CollectionUsers::save(&user_to_edit.user_uuid, &collection.id, collection.readOnly, &conn);
|
CollectionUser::save(&user_to_edit.user_uuid, &collection.id, collection.readOnly, &conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,7 +516,7 @@ fn delete_user(org_id: String, user_id: String, headers: Headers, conn: DbConn)
|
||||||
user_to_delete.delete(&conn);
|
user_to_delete.delete(&conn);
|
||||||
|
|
||||||
for c in Collection::find_by_organization_and_user_uuid(&org_id, ¤t_user.uuid, &conn) {
|
for c in Collection::find_by_organization_and_user_uuid(&org_id, ¤t_user.uuid, &conn) {
|
||||||
CollectionUsers::delete(¤t_user.uuid, &c.uuid, &conn);
|
CollectionUser::delete(¤t_user.uuid, &c.uuid, &conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -51,13 +51,15 @@ impl Collection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete(self, conn: &DbConn) -> bool {
|
pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
|
||||||
match diesel::delete(collections::table.filter(
|
CollectionCipher::delete_all_by_collection(&self.uuid, &conn)?;
|
||||||
collections::uuid.eq(self.uuid)))
|
CollectionUser::delete_all_by_collection(&self.uuid, &conn)?;
|
||||||
.execute(&**conn) {
|
|
||||||
Ok(1) => true, // One row deleted
|
diesel::delete(
|
||||||
_ => false,
|
collections::table.filter(
|
||||||
}
|
collections::uuid.eq(self.uuid)
|
||||||
|
)
|
||||||
|
).execute(&**conn).and(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_by_uuid(uuid: &str, conn: &DbConn) -> Option<Self> {
|
pub fn find_by_uuid(uuid: &str, conn: &DbConn) -> Option<Self> {
|
||||||
|
@ -130,14 +132,14 @@ use super::User;
|
||||||
#[belongs_to(User, foreign_key = "user_uuid")]
|
#[belongs_to(User, foreign_key = "user_uuid")]
|
||||||
#[belongs_to(Collection, foreign_key = "collection_uuid")]
|
#[belongs_to(Collection, foreign_key = "collection_uuid")]
|
||||||
#[primary_key(user_uuid, collection_uuid)]
|
#[primary_key(user_uuid, collection_uuid)]
|
||||||
pub struct CollectionUsers {
|
pub struct CollectionUser {
|
||||||
pub user_uuid: String,
|
pub user_uuid: String,
|
||||||
pub collection_uuid: String,
|
pub collection_uuid: String,
|
||||||
pub read_only: bool,
|
pub read_only: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Database methods
|
/// Database methods
|
||||||
impl CollectionUsers {
|
impl CollectionUser {
|
||||||
pub fn find_by_organization_and_user_uuid(org_uuid: &str, user_uuid: &str, conn: &DbConn) -> Vec<Self> {
|
pub fn find_by_organization_and_user_uuid(org_uuid: &str, user_uuid: &str, conn: &DbConn) -> Vec<Self> {
|
||||||
users_collections::table
|
users_collections::table
|
||||||
.filter(users_collections::user_uuid.eq(user_uuid))
|
.filter(users_collections::user_uuid.eq(user_uuid))
|
||||||
|
@ -168,6 +170,12 @@ impl CollectionUsers {
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn delete_all_by_collection(collection_uuid: &str, conn: &DbConn) -> QueryResult<()> {
|
||||||
|
diesel::delete(users_collections::table
|
||||||
|
.filter(users_collections::collection_uuid.eq(collection_uuid))
|
||||||
|
).execute(&**conn).and(Ok(()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use super::Cipher;
|
use super::Cipher;
|
||||||
|
@ -210,4 +218,10 @@ impl CollectionCipher {
|
||||||
.filter(ciphers_collections::cipher_uuid.eq(cipher_uuid))
|
.filter(ciphers_collections::cipher_uuid.eq(cipher_uuid))
|
||||||
).execute(&**conn).and(Ok(()))
|
).execute(&**conn).and(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn delete_all_by_collection(collection_uuid: &str, conn: &DbConn) -> QueryResult<()> {
|
||||||
|
diesel::delete(ciphers_collections::table
|
||||||
|
.filter(ciphers_collections::collection_uuid.eq(collection_uuid))
|
||||||
|
).execute(&**conn).and(Ok(()))
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -14,4 +14,4 @@ pub use self::folder::{Folder, FolderCipher};
|
||||||
pub use self::user::User;
|
pub use self::user::User;
|
||||||
pub use self::organization::Organization;
|
pub use self::organization::Organization;
|
||||||
pub use self::organization::{UserOrganization, UserOrgStatus, UserOrgType};
|
pub use self::organization::{UserOrganization, UserOrgStatus, UserOrgType};
|
||||||
pub use self::collection::{Collection, CollectionUsers, CollectionCipher};
|
pub use self::collection::{Collection, CollectionUser, CollectionCipher};
|
||||||
|
|
|
@ -188,8 +188,8 @@ impl UserOrganization {
|
||||||
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
|
||||||
} else {
|
} else {
|
||||||
use super::CollectionUsers;
|
use super::CollectionUser;
|
||||||
let collections = CollectionUsers::find_by_organization_and_user_uuid(&self.org_uuid, &self.user_uuid, conn);
|
let collections = CollectionUser::find_by_organization_and_user_uuid(&self.org_uuid, &self.user_uuid, conn);
|
||||||
collections.iter().map(|c| json!({"Id": c.collection_uuid, "ReadOnly": c.read_only})).collect()
|
collections.iter().map(|c| json!({"Id": c.collection_uuid, "ReadOnly": c.read_only})).collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Laden …
In neuem Issue referenzieren