diff --git a/crates/common/src/sharing/resources.rs b/crates/common/src/sharing/resources.rs index c49c588d..f51dd180 100644 --- a/crates/common/src/sharing/resources.rs +++ b/crates/common/src/sharing/resources.rs @@ -61,6 +61,28 @@ impl DavResources { } } + pub fn shared_documents( + &self, + access_token: &AccessToken, + check_acls: impl IntoIterator, + match_any: bool, + ) -> RoaringBitmap { + let shared_containers = self.shared_containers(access_token, check_acls, match_any); + let mut document_ids = shared_containers.clone(); + + if !shared_containers.is_empty() { + for path in &self.paths { + if let Some(parent_id) = path.parent_id + && shared_containers.contains(parent_id) + { + document_ids.insert(self.resources[path.resource_idx].document_id); + } + } + } + + document_ids + } + pub fn has_access_to_container( &self, access_token: &AccessToken, diff --git a/crates/jmap/src/file/get.rs b/crates/jmap/src/file/get.rs index 94d64ff3..528a3254 100644 --- a/crates/jmap/src/file/get.rs +++ b/crates/jmap/src/file/get.rs @@ -76,7 +76,7 @@ impl FileNodeGet for Server { .map(|r| r.document_id) .collect::() } else { - cache.shared_containers(access_token, [Acl::Read, Acl::ReadItems], true) + cache.shared_documents(access_token, [Acl::Read, Acl::ReadItems], true) }; let mut ids = if let Some(ids) = ids { diff --git a/crates/jmap/src/file/query.rs b/crates/jmap/src/file/query.rs index cc9ee494..bff5cc15 100644 --- a/crates/jmap/src/file/query.rs +++ b/crates/jmap/src/file/query.rs @@ -96,15 +96,15 @@ impl FileNodeQuery for Server { _ => None, }; let set = match want_container { - Some(is_container) => RoaringBitmap::from_iter( - cache.resources.iter().filter_map(|r| { + Some(is_container) => { + RoaringBitmap::from_iter(cache.resources.iter().filter_map(|r| { if r.is_container() == is_container { Some(r.document_id) } else { None } - }), - ), + })) + } // TODO: support symlink nodeType once target storage exists None => RoaringBitmap::new(), }; @@ -194,9 +194,9 @@ impl FileNodeQuery for Server { let results = SearchQuery::new(SearchIndex::InMemory) .with_filters(filters) .with_mask(if access_token.is_shared(account_id) { - cache.shared_containers(access_token, [Acl::ReadItems], true) + cache.shared_documents(access_token, [Acl::Read, Acl::ReadItems], true) } else { - cache.document_ids(false).collect() + cache.resources.iter().map(|r| r.document_id).collect() }) .filter() .into_bitmap(); @@ -246,9 +246,9 @@ impl FileNodeQuery for Server { FileNodeComparator::Name => ra .and_then(|r| r.container_name()) .cmp(&rb.and_then(|r| r.container_name())), - FileNodeComparator::Size => ra - .and_then(|r| r.size()) - .cmp(&rb.and_then(|r| r.size())), + FileNodeComparator::Size => { + ra.and_then(|r| r.size()).cmp(&rb.and_then(|r| r.size())) + } FileNodeComparator::NodeType => { // Directories sort before files let a_dir = ra.map(|r| r.is_container()).unwrap_or(false);