JMAP: Use primary accountId when missing (closes #1936)

This commit is contained in:
mdecimus
2025-09-29 19:08:02 +02:00
parent c8e0a1b2cb
commit 7ab80bcf07
3 changed files with 91 additions and 45 deletions

View File

@@ -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());
}
}

View File

@@ -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),