diff --git a/crates/jmap/src/api/request.rs b/crates/jmap/src/api/request.rs index 449b3e30..3acf54fa 100644 --- a/crates/jmap/src/api/request.rs +++ b/crates/jmap/src/api/request.rs @@ -37,7 +37,7 @@ use jmap_proto::{ response::{Response, ResponseMethod, SetResponseMethod}, }; use trc::JmapEvent; -use types::collection::Collection; +use types::{collection::Collection, id::Id}; use std::future::Future; @@ -185,136 +185,163 @@ impl RequestHandler for Server { // Check permissions access_token.assert_has_jmap_permission(&method, method_name.obj)?; - let todo = "use account id if missing"; // Handle method let response = match method { RequestMethod::Get(req) => match req { - GetRequestMethod::Email(req) => { + GetRequestMethod::Email(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_has_access(req.account_id, Collection::Email)?; self.email_get(req, access_token).await?.into() } - GetRequestMethod::Mailbox(req) => { + GetRequestMethod::Mailbox(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_has_access(req.account_id, Collection::Mailbox)?; self.mailbox_get(req, access_token).await?.into() } - GetRequestMethod::Thread(req) => { + GetRequestMethod::Thread(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_has_access(req.account_id, Collection::Email)?; self.thread_get(req).await?.into() } - GetRequestMethod::Identity(req) => { + GetRequestMethod::Identity(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.identity_get(req).await?.into() } - GetRequestMethod::EmailSubmission(req) => { + GetRequestMethod::EmailSubmission(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.email_submission_get(req).await?.into() } - GetRequestMethod::PushSubscription(req) => { + GetRequestMethod::PushSubscription(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); self.push_subscription_get(req, access_token).await?.into() } - GetRequestMethod::Sieve(req) => { + GetRequestMethod::Sieve(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.sieve_script_get(req).await?.into() } - GetRequestMethod::VacationResponse(req) => { + GetRequestMethod::VacationResponse(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.vacation_response_get(req).await?.into() } GetRequestMethod::Principal(req) => self.principal_get(req).await?.into(), - GetRequestMethod::Quota(req) => { + GetRequestMethod::Quota(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.quota_get(req, access_token).await?.into() } - GetRequestMethod::Blob(req) => { + GetRequestMethod::Blob(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.blob_get(req, access_token).await?.into() } }, RequestMethod::Query(req) => match req { - QueryRequestMethod::Email(req) => { + QueryRequestMethod::Email(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_has_access(req.account_id, Collection::Email)?; self.email_query(req, access_token).await?.into() } - QueryRequestMethod::Mailbox(req) => { + QueryRequestMethod::Mailbox(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_has_access(req.account_id, Collection::Mailbox)?; self.mailbox_query(req, access_token).await?.into() } - QueryRequestMethod::EmailSubmission(req) => { + QueryRequestMethod::EmailSubmission(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.email_submission_query(req).await?.into() } - QueryRequestMethod::Sieve(req) => { + QueryRequestMethod::Sieve(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.sieve_script_query(req).await?.into() } - QueryRequestMethod::Principal(req) => { + QueryRequestMethod::Principal(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); self.principal_query(req, session).await?.into() } - QueryRequestMethod::Quota(req) => { + QueryRequestMethod::Quota(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.quota_query(req, access_token).await?.into() } }, RequestMethod::Set(req) => match req { - SetRequestMethod::Email(req) => { + SetRequestMethod::Email(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_has_access(req.account_id, Collection::Email)?; self.email_set(req, access_token, session).await?.into() } - SetRequestMethod::Mailbox(req) => { + SetRequestMethod::Mailbox(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_has_access(req.account_id, Collection::Mailbox)?; self.mailbox_set(req, access_token).await?.into() } - SetRequestMethod::Identity(req) => { + SetRequestMethod::Identity(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.identity_set(req).await?.into() } - SetRequestMethod::EmailSubmission(req) => { + SetRequestMethod::EmailSubmission(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.email_submission_set(req, &session.instance, next_call) .await? .into() } - SetRequestMethod::PushSubscription(req) => { + SetRequestMethod::PushSubscription(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); self.push_subscription_set(req, access_token).await?.into() } - SetRequestMethod::Sieve(req) => { + SetRequestMethod::Sieve(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.sieve_script_set(req, access_token, session) .await? .into() } - SetRequestMethod::VacationResponse(req) => { + SetRequestMethod::VacationResponse(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.vacation_response_set(req, access_token).await?.into() } }, - RequestMethod::Changes(req) => self - .changes(req, method_name.obj, access_token) - .await? - .into_method_response(), + RequestMethod::Changes(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); + + self.changes(req, method_name.obj, access_token) + .await? + .into_method_response() + } RequestMethod::Copy(req) => match req { - CopyRequestMethod::Email(req) => { + CopyRequestMethod::Email(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); + access_token .assert_has_access(req.account_id, Collection::Email)? .assert_has_access(req.from_account_id, Collection::Email)?; @@ -323,39 +350,46 @@ impl RequestHandler for Server { .await? .into() } - CopyRequestMethod::Blob(req) => { + CopyRequestMethod::Blob(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.blob_copy(req, access_token).await?.into() } }, - RequestMethod::ImportEmail(req) => { + RequestMethod::ImportEmail(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_has_access(req.account_id, Collection::Email)?; self.email_import(req, access_token, session).await?.into() } - RequestMethod::ParseEmail(req) => { + RequestMethod::ParseEmail(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_has_access(req.account_id, Collection::Email)?; self.email_parse(req, access_token).await?.into() } RequestMethod::QueryChanges(req) => self.query_changes(req, access_token).await?.into(), - RequestMethod::SearchSnippet(req) => { + RequestMethod::SearchSnippet(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_has_access(req.account_id, Collection::Email)?; self.email_search_snippet(req, access_token).await?.into() } - RequestMethod::ValidateScript(req) => { + RequestMethod::ValidateScript(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.sieve_script_validate(req, access_token).await?.into() } - RequestMethod::LookupBlob(req) => { + RequestMethod::LookupBlob(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.blob_lookup(req).await?.into() } - RequestMethod::UploadBlob(req) => { + RequestMethod::UploadBlob(mut req) => { + set_account_id_if_missing(&mut req.account_id, access_token); access_token.assert_is_member(req.account_id)?; self.blob_upload_many(req, access_token).await?.into() @@ -375,3 +409,10 @@ impl RequestHandler for Server { Ok(response) } } + +#[inline] +pub(crate) fn set_account_id_if_missing(account_id: &mut Id, access_token: &AccessToken) { + if !account_id.is_valid() { + *account_id = Id::from(access_token.primary_id()); + } +} diff --git a/crates/jmap/src/changes/query.rs b/crates/jmap/src/changes/query.rs index fcfa4d96..f14bd2f9 100644 --- a/crates/jmap/src/changes/query.rs +++ b/crates/jmap/src/changes/query.rs @@ -6,7 +6,8 @@ use super::get::ChangesLookup; use crate::{ - email::query::EmailQuery, mailbox::query::MailboxQuery, sieve::query::SieveScriptQuery, + api::request::set_account_id_if_missing, email::query::EmailQuery, + mailbox::query::MailboxQuery, sieve::query::SieveScriptQuery, submission::query::EmailSubmissionQuery, }; use common::{Server, auth::AccessToken}; @@ -42,8 +43,9 @@ impl QueryChanges for Server { let up_to_id; match request { - QueryChangesRequestMethod::Email(request) => { + QueryChangesRequestMethod::Email(mut request) => { // Query changes + set_account_id_if_missing(&mut request.account_id, access_token); changes = self .changes( build_changes_request(&request), @@ -69,8 +71,9 @@ impl QueryChanges for Server { results = self.email_query(request.into(), access_token).await?; } - QueryChangesRequestMethod::Mailbox(request) => { + QueryChangesRequestMethod::Mailbox(mut request) => { // Query changes + set_account_id_if_missing(&mut request.account_id, access_token); changes = self .changes( build_changes_request(&request), @@ -90,8 +93,9 @@ impl QueryChanges for Server { up_to_id = request.up_to_id; results = self.mailbox_query(request.into(), access_token).await?; } - QueryChangesRequestMethod::EmailSubmission(request) => { + QueryChangesRequestMethod::EmailSubmission(mut request) => { // Query changes + set_account_id_if_missing(&mut request.account_id, access_token); changes = self .changes( build_changes_request(&request), @@ -111,8 +115,9 @@ impl QueryChanges for Server { up_to_id = request.up_to_id; results = self.email_submission_query(request.into()).await?; } - QueryChangesRequestMethod::Sieve(request) => { + QueryChangesRequestMethod::Sieve(mut request) => { // Query changes + set_account_id_if_missing(&mut request.account_id, access_token); changes = self .changes( build_changes_request(&request), diff --git a/tests/src/jmap/mod.rs b/tests/src/jmap/mod.rs index 294ea488..12d375e3 100644 --- a/tests/src/jmap/mod.rs +++ b/tests/src/jmap/mod.rs @@ -88,7 +88,7 @@ async fn jmap_tests() { .await; webhooks::test(&mut params).await; - /*email_query::test(&mut params, delete).await; + email_query::test(&mut params, delete).await; email_get::test(&mut params).await; email_set::test(&mut params).await; email_parse::test(&mut params).await; @@ -109,9 +109,9 @@ async fn jmap_tests() { vacation_response::test(&mut params).await; email_submission::test(&mut params).await; websocket::test(&mut params).await; - quota::test(&mut params).await;* + quota::test(&mut params).await; crypto::test(&mut params).await; - blob::test(&mut params).await;*/ + blob::test(&mut params).await; permissions::test(¶ms).await; purge::test(&mut params).await; enterprise::test(&mut params).await;