diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 52283803..6bb8ac70 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -1498,7 +1498,7 @@ pub struct CipherSyncData { pub user_organizations: HashMap, pub user_collections: HashMap, pub user_collections_groups: HashMap, - pub user_groups: HashMap, + pub user_group_full_access_for_organizations: HashSet, } pub enum CipherSyncType { @@ -1560,11 +1560,9 @@ impl CipherSyncData { .collect() .await; - // Generate a HashMap with the group.uuid as key and the Group record - let user_groups = stream::iter(Group::find_by_user(user_uuid, conn).await) - .map(|group| (group.uuid.clone(), group)) - .collect() - .await; + // Get all organizations that the user has full access to via group assignement + let user_group_full_access_for_organizations = + stream::iter(Group::gather_user_organizations_full_access(user_uuid, conn).await).collect().await; Self { cipher_attachments, @@ -1574,7 +1572,7 @@ impl CipherSyncData { user_organizations, user_collections, user_collections_groups, - user_groups, + user_group_full_access_for_organizations, } } } diff --git a/src/db/models/cipher.rs b/src/db/models/cipher.rs index e04adf15..b4446158 100644 --- a/src/db/models/cipher.rs +++ b/src/db/models/cipher.rs @@ -363,12 +363,14 @@ impl Cipher { cipher_sync_data: Option<&CipherSyncData>, conn: &DbConn, ) -> bool { - match cipher_sync_data { - Some(cipher_sync_data) => { - cipher_sync_data.user_groups.iter().any(|hash_map_entry| hash_map_entry.1.access_all) + if let Some(ref org_uuid) = self.organization_uuid { + if let Some(cipher_sync_data) = cipher_sync_data { + return cipher_sync_data.user_group_full_access_for_organizations.get(org_uuid).is_some(); + } else { + return Group::is_in_full_access_group(user_uuid, org_uuid, conn).await; } - None => Group::is_in_full_access_group(user_uuid, conn).await, } + false } /// Returns the user's access restrictions to this cipher. A return value diff --git a/src/db/models/group.rs b/src/db/models/group.rs index d03b0459..eea4bcd2 100644 --- a/src/db/models/group.rs +++ b/src/db/models/group.rs @@ -171,24 +171,26 @@ impl Group { }} } - pub async fn find_by_user(user_uuid: &str, conn: &DbConn) -> Vec { + //Returns all organizations the user has full access to + pub async fn gather_user_organizations_full_access(user_uuid: &str, conn: &DbConn) -> Vec { db_run! { conn: { - groups::table - .inner_join(groups_users::table.on( - groups_users::groups_uuid.eq(groups::uuid) - )) + groups_users::table .inner_join(users_organizations::table.on( users_organizations::uuid.eq(groups_users::users_organizations_uuid) )) + .inner_join(groups::table.on( + groups::uuid.eq(groups_users::groups_uuid) + )) .filter(users_organizations::user_uuid.eq(user_uuid)) - .select(groups::all_columns) - .load::(conn) - .expect("Error loading user groups") - .from_db() + .filter(groups::access_all.eq(true)) + .select(groups::organizations_uuid) + .distinct() + .load::(conn) + .expect("Error loading organization group full access information for user") }} } - pub async fn is_in_full_access_group(user_uuid: &str, conn: &DbConn) -> bool { + pub async fn is_in_full_access_group(user_uuid: &str, org_uuid: &str, conn: &DbConn) -> bool { db_run! { conn: { groups::table .inner_join(groups_users::table.on( @@ -198,6 +200,7 @@ impl Group { users_organizations::uuid.eq(groups_users::users_organizations_uuid) )) .filter(users_organizations::user_uuid.eq(user_uuid)) + .filter(groups::organizations_uuid.eq(org_uuid)) .filter(groups::access_all.eq(true)) .select(groups::access_all) .first::(conn)