commit 56cad93e0fecd2d42a321e761c2124d2c64d0847
parent 3cf67e0b8ddc8d4f00dc122de511cbff6b650d58
Author: Stefan Melmuk <stefan.melmuk@gmail.com>
Date: Sat, 18 Mar 2023 20:52:55 +0100
add endpoint to bulk delete collections
Diffstat:
2 files changed, 81 insertions(+), 20 deletions(-)
diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs
@@ -39,6 +39,7 @@ pub fn routes() -> Vec<Route> {
put_organization_collection_update,
delete_organization_collection,
post_organization_collection_delete,
+ bulk_delete_organization_collections,
get_org_details,
get_org_users,
send_invite,
@@ -538,28 +539,27 @@ async fn post_organization_collection_delete_user(
delete_organization_collection_user(org_id, col_id, org_user_id, headers, conn).await
}
-#[delete("/organizations/<org_id>/collections/<col_id>")]
-async fn delete_organization_collection(
- org_id: String,
- col_id: String,
- headers: ManagerHeaders,
- mut conn: DbConn,
+async fn _delete_organization_collection(
+ org_id: &str,
+ col_id: &str,
+ headers: &ManagerHeaders,
+ conn: &mut DbConn,
) -> EmptyResult {
- match Collection::find_by_uuid(&col_id, &mut conn).await {
+ match Collection::find_by_uuid(col_id, conn).await {
None => err!("Collection not found"),
Some(collection) => {
if collection.org_uuid == org_id {
log_event(
EventType::CollectionDeleted as i32,
&collection.uuid,
- org_id,
+ org_id.to_string(),
headers.user.uuid.clone(),
headers.device.atype,
&headers.ip.ip,
- &mut conn,
+ conn,
)
.await;
- collection.delete(&mut conn).await
+ collection.delete(conn).await
} else {
err!("Collection and Organization id do not match")
}
@@ -567,6 +567,16 @@ async fn delete_organization_collection(
}
}
+#[delete("/organizations/<org_id>/collections/<col_id>")]
+async fn delete_organization_collection(
+ org_id: String,
+ col_id: String,
+ headers: ManagerHeaders,
+ mut conn: DbConn,
+) -> EmptyResult {
+ _delete_organization_collection(&org_id, &col_id, &headers, &mut conn).await
+}
+
#[derive(Deserialize, Debug)]
#[allow(non_snake_case, dead_code)]
struct DeleteCollectionData {
@@ -580,9 +590,36 @@ async fn post_organization_collection_delete(
col_id: String,
headers: ManagerHeaders,
_data: JsonUpcase<DeleteCollectionData>,
- conn: DbConn,
+ mut conn: DbConn,
+) -> EmptyResult {
+ _delete_organization_collection(&org_id, &col_id, &headers, &mut conn).await
+}
+
+#[derive(Deserialize, Debug)]
+#[allow(non_snake_case)]
+struct BulkCollectionIds {
+ Ids: Vec<String>,
+ OrganizationId: String,
+}
+
+#[delete("/organizations/<org_id>/collections", data = "<data>")]
+async fn bulk_delete_organization_collections(
+ org_id: &str,
+ headers: ManagerHeadersLoose,
+ data: JsonUpcase<BulkCollectionIds>,
+ mut conn: DbConn,
) -> EmptyResult {
- delete_organization_collection(org_id, col_id, headers, conn).await
+ let data: BulkCollectionIds = data.into_inner().data;
+ assert!(org_id == data.OrganizationId);
+
+ let collections = data.Ids;
+
+ let headers = ManagerHeaders::from_loose(headers, &collections, &mut conn).await?;
+
+ for col_id in collections {
+ _delete_organization_collection(org_id, &col_id, &headers, &mut conn).await?
+ }
+ Ok(())
}
#[get("/organizations/<org_id>/collections/<coll_id>/details")]
diff --git a/src/auth.rs b/src/auth.rs
@@ -598,14 +598,7 @@ impl<'r> FromRequest<'r> for ManagerHeaders {
_ => err_handler!("Error getting DB"),
};
- if !headers.org_user.has_full_access()
- && !Collection::has_access_by_collection_and_user_uuid(
- &col_id,
- &headers.org_user.user_uuid,
- &mut conn,
- )
- .await
- {
+ if !can_access_collection(&headers.org_user, &col_id, &mut conn).await {
err_handler!("The current user isn't a manager for this collection")
}
}
@@ -642,6 +635,7 @@ pub struct ManagerHeadersLoose {
pub host: String,
pub device: Device,
pub user: User,
+ pub org_user: UserOrganization,
pub org_user_type: UserOrgType,
pub ip: ClientIp,
}
@@ -657,6 +651,7 @@ impl<'r> FromRequest<'r> for ManagerHeadersLoose {
host: headers.host,
device: headers.device,
user: headers.user,
+ org_user: headers.org_user,
org_user_type: headers.org_user_type,
ip: headers.ip,
})
@@ -676,6 +671,35 @@ impl From<ManagerHeadersLoose> for Headers {
}
}
}
+async fn can_access_collection(org_user: &UserOrganization, col_id: &str, conn: &mut DbConn) -> bool {
+ org_user.has_full_access()
+ || Collection::has_access_by_collection_and_user_uuid(col_id, &org_user.user_uuid, conn).await
+}
+
+impl ManagerHeaders {
+ pub async fn from_loose(
+ h: ManagerHeadersLoose,
+ collections: &Vec<String>,
+ conn: &mut DbConn,
+ ) -> Result<ManagerHeaders, Error> {
+ for col_id in collections {
+ if uuid::Uuid::parse_str(col_id).is_err() {
+ err!("Collection Id is malformed!");
+ }
+ if !can_access_collection(&h.org_user, col_id, conn).await {
+ err!("You don't have access to all collections!");
+ }
+ }
+
+ Ok(ManagerHeaders {
+ host: h.host,
+ device: h.device,
+ user: h.user,
+ org_user_type: h.org_user_type,
+ ip: h.ip,
+ })
+ }
+}
pub struct OwnerHeaders {
pub host: String,