diff --git a/crates/common/src/auth/access_token.rs b/crates/common/src/auth/access_token.rs index 408746c..95c82b4 100644 --- a/crates/common/src/auth/access_token.rs +++ b/crates/common/src/auth/access_token.rs @@ -143,6 +143,29 @@ impl Server { } } } + // inbuxa: AL-7: a delegate reaches the whole locked account, + // mail, calendars, contacts and files, even a kind it holds + // none of yet, so an empty one reads as empty rather than + // refused. What it may see or change there is still each + // container's grant. + for delegation in delegations.iter() { + let whole: Bitmap = Bitmap::from_iter([ + Collection::Mailbox, + Collection::Email, + Collection::Calendar, + Collection::CalendarEvent, + Collection::AddressBook, + Collection::ContactCard, + Collection::FileNode, + ]); + match access_to.iter_mut().find(|a| a.account_id == delegation.account_id) { + Some(entry) => entry.collections.union(&whole), + None => access_to.push(AccessTo { + account_id: delegation.account_id, + collections: whole, + }), + } + } let now = now(); let mut credential_version = 0; diff --git a/tests/src/system/account_lock.rs b/tests/src/system/account_lock.rs index 40067d0..9b37538 100644 --- a/tests/src/system/account_lock.rs +++ b/tests/src/system/account_lock.rs @@ -36,6 +36,9 @@ const USING: &[&str] = &[ "urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail", "urn:ietf:params:jmap:submission", + "urn:ietf:params:jmap:calendars", + "urn:ietf:params:jmap:contacts", + "urn:ietf:params:jmap:filenode", "urn:inbuxa:jmap", ]; @@ -179,6 +182,17 @@ pub async fn test(test: &mut TestServer) { assert_eq!(delegation["access"], "read", "AL-7"); assert_eq!(delegation["sendAs"], false, "AL-7"); + // AL-7: the whole account, not only mail: even a kind the owner holds + // none of (no files here) reads as empty rather than refused + for (method, arguments) in [ + ("FileNode/query", json!({"accountId": owner_id})), + ("Calendar/get", json!({"accountId": owner_id, "ids": null})), + ("AddressBook/get", json!({"accountId": owner_id, "ids": null})), + ] { + let (name, response) = delegate.call(method, arguments).await; + assert_eq!(name, method, "AL-7: {method} refused to the delegate: {response}"); + } + // The delegate reads the mail that arrived let (_, found) = delegate .call(