From 3c29f8297450c6e43369bc210383bb2d455565c0 Mon Sep 17 00:00:00 2001
From: Mathijs van Veluw <black.dex@gmail.com>
Date: Wed, 29 Jan 2025 20:41:31 +0100
Subject: [PATCH] Allow all manager to create collections again (#5488)

* Allow all manager to create collections again

This commit checks if the member is a manager or better, and if so allows it to createCollections.
We actually check if it is less then a Manager, since the `limitCollectionCreation` should be set to false to allow it and true to prevent.

This should fix an issue discussed in #5484

Signed-off-by: BlackDex <black.dex@gmail.com>

* Fix some small issues

Signed-off-by: BlackDex <black.dex@gmail.com>

---------

Signed-off-by: BlackDex <black.dex@gmail.com>
---
 src/api/core/organizations.rs | 27 ++++++++++++++-------------
 src/db/models/collection.rs   |  5 ++++-
 src/db/models/organization.rs |  2 +-
 3 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs
index 08305839..624ff590 100644
--- a/src/api/core/organizations.rs
+++ b/src/api/core/organizations.rs
@@ -485,7 +485,7 @@ async fn post_organization_collections(
         CollectionUser::save(&headers.membership.user_uuid, &collection.uuid, false, false, false, &mut conn).await?;
     }
 
-    Ok(Json(collection.to_json()))
+    Ok(Json(collection.to_json_details(&headers.membership.user_uuid, None, &mut conn).await))
 }
 
 #[put("/organizations/<org_id>/collections/<col_id>", data = "<data>")]
@@ -722,18 +722,19 @@ async fn get_org_collection_detail(
                 .map(|m| (m.uuid, m.atype))
                 .collect();
 
-            let users: Vec<Value> =
-                CollectionUser::find_by_collection_swap_user_uuid_with_member_uuid(&collection.uuid, &mut conn)
-                    .await
-                    .iter()
-                    .map(|collection_member| {
-                        collection_member.to_json_details_for_member(
-                            *membership_type
-                                .get(&collection_member.membership_uuid)
-                                .unwrap_or(&(MembershipType::User as i32)),
-                        )
-                    })
-                    .collect();
+            let users: Vec<Value> = CollectionUser::find_by_org_and_coll_swap_user_uuid_with_member_uuid(
+                &org_id,
+                &collection.uuid,
+                &mut conn,
+            )
+            .await
+            .iter()
+            .map(|collection_member| {
+                collection_member.to_json_details_for_member(
+                    *membership_type.get(&collection_member.membership_uuid).unwrap_or(&(MembershipType::User as i32)),
+                )
+            })
+            .collect();
 
             let assigned = Collection::can_access_collection(&member, &collection.uuid, &mut conn).await;
 
diff --git a/src/db/models/collection.rs b/src/db/models/collection.rs
index 2286ee04..abe5b400 100644
--- a/src/db/models/collection.rs
+++ b/src/db/models/collection.rs
@@ -589,6 +589,7 @@ impl CollectionUser {
                 .inner_join(collections::table.on(collections::uuid.eq(users_collections::collection_uuid)))
                 .filter(collections::org_uuid.eq(org_uuid))
                 .inner_join(users_organizations::table.on(users_organizations::user_uuid.eq(users_collections::user_uuid)))
+                .filter(users_organizations::org_uuid.eq(org_uuid))
                 .select((users_organizations::uuid, users_collections::collection_uuid, users_collections::read_only, users_collections::hide_passwords, users_collections::manage))
                 .load::<CollectionUserDb>(conn)
                 .expect("Error loading users_collections")
@@ -685,13 +686,15 @@ impl CollectionUser {
         }}
     }
 
-    pub async fn find_by_collection_swap_user_uuid_with_member_uuid(
+    pub async fn find_by_org_and_coll_swap_user_uuid_with_member_uuid(
+        org_uuid: &OrganizationId,
         collection_uuid: &CollectionId,
         conn: &mut DbConn,
     ) -> Vec<CollectionMembership> {
         let col_users = db_run! { conn: {
             users_collections::table
                 .filter(users_collections::collection_uuid.eq(collection_uuid))
+                .filter(users_organizations::org_uuid.eq(org_uuid))
                 .inner_join(users_organizations::table.on(users_organizations::user_uuid.eq(users_collections::user_uuid)))
                 .select((users_organizations::uuid, users_collections::collection_uuid, users_collections::read_only, users_collections::hide_passwords, users_collections::manage))
                 .load::<CollectionUserDb>(conn)
diff --git a/src/db/models/organization.rs b/src/db/models/organization.rs
index aa3e1d01..2b54e1d0 100644
--- a/src/db/models/organization.rs
+++ b/src/db/models/organization.rs
@@ -464,7 +464,7 @@ impl Membership {
             "familySponsorshipValidUntil": null,
             "familySponsorshipToDelete": null,
             "accessSecretsManager": false,
-            "limitCollectionCreation": true,
+            "limitCollectionCreation": self.atype < MembershipType::Manager, // If less then a manager return true, to limit collection creations
             "limitCollectionCreationDeletion": true,
             "limitCollectionDeletion": true,
             "allowAdminAccessToAllCollectionItems": true,