Import upstream v0.16.22, stripped
Upstream commit: 474dd0229cb20cf513036619781ed97bd8073c3f Enterprise-only files removed or emptied: 63 Enterprise-only snippets removed: 117 in 50 files Dangling module declarations removed: 5 Cargo edits turning enterprise off: 14 Verification: clean Enterprise feature gates left for rebuilt features: 19 in 18 files Produced by tools/fork/strip.py. The full report is in docs/fork/strip-reports/ on main.
This commit is contained in:
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
object::{AnyId, JmapObjectId},
|
||||
references::{
|
||||
Graph,
|
||||
jsptr::{EvalResults, ResponsePtr},
|
||||
},
|
||||
request::reference::ResultReference,
|
||||
response::{ChangesResponseMethod, GetResponseMethod, Response, ResponseMethod},
|
||||
};
|
||||
use compact_str::format_compact;
|
||||
use jmap_tools::{Element, Key, Property, Value};
|
||||
use types::{blob::BlobId, id::Id};
|
||||
|
||||
impl Response<'_> {
|
||||
pub(crate) fn eval_result_references(&self, rr: &ResultReference) -> trc::Result<EvalResults> {
|
||||
let mut results = EvalResults::default();
|
||||
|
||||
for response in &self.method_responses {
|
||||
if response.id == rr.result_of && response.name == rr.name {
|
||||
let path = rr.path.iter();
|
||||
let success = match &response.method {
|
||||
ResponseMethod::Get(response) => match response {
|
||||
GetResponseMethod::Email(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::Mailbox(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::Thread(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::Identity(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::EmailSubmission(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::PushSubscription(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::Sieve(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::VacationResponse(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::Principal(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::Quota(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::Blob(response) => response.eval_jptr(path, &mut results),
|
||||
GetResponseMethod::AddressBook(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::ContactCard(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::FileNode(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::Calendar(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::CalendarEvent(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::CalendarEventNotification(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::ParticipantIdentity(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::ShareNotification(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::PrincipalAvailability(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
GetResponseMethod::Registry(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
},
|
||||
ResponseMethod::Changes(response) => match response {
|
||||
ChangesResponseMethod::Email(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
ChangesResponseMethod::Mailbox(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
ChangesResponseMethod::Thread(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
ChangesResponseMethod::Identity(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
ChangesResponseMethod::EmailSubmission(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
ChangesResponseMethod::Quota(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
ChangesResponseMethod::AddressBook(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
ChangesResponseMethod::ContactCard(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
ChangesResponseMethod::FileNode(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
ChangesResponseMethod::Calendar(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
ChangesResponseMethod::CalendarEvent(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
ChangesResponseMethod::CalendarEventNotification(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
ChangesResponseMethod::ShareNotification(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
},
|
||||
ResponseMethod::Query(response) => response.eval_jptr(path, &mut results),
|
||||
ResponseMethod::QueryChanges(response) => {
|
||||
response.eval_jptr(path, &mut results)
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if success {
|
||||
return Ok(results);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(trc::JmapEvent::InvalidResultReference
|
||||
.into_err()
|
||||
.details(format_compact!(
|
||||
"Result reference to {}#{} not found.",
|
||||
rr.result_of,
|
||||
rr.name
|
||||
)))
|
||||
}
|
||||
|
||||
pub(crate) fn eval_id_reference(&self, ir: &str) -> trc::Result<Id> {
|
||||
if let Some(AnyId::Id(id)) = self.created_ids.get(ir) {
|
||||
Ok(*id)
|
||||
} else {
|
||||
Err(trc::JmapEvent::InvalidResultReference
|
||||
.into_err()
|
||||
.details(format_compact!("Id reference {ir:?} not found.")))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn eval_blob_id_reference(&self, ir: &str) -> trc::Result<BlobId> {
|
||||
if let Some(AnyId::BlobId(id)) = self.created_ids.get(ir) {
|
||||
Ok(id.clone())
|
||||
} else {
|
||||
Err(trc::JmapEvent::InvalidResultReference
|
||||
.into_err()
|
||||
.details(format_compact!("blobId reference {ir:?} not found.")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait EvalObjectReferences {
|
||||
fn eval_object_references(
|
||||
&mut self,
|
||||
response: &Response<'_>,
|
||||
graph: &mut Graph<'_>,
|
||||
depth: usize,
|
||||
max_depth: usize,
|
||||
eval_strings: bool,
|
||||
) -> trc::Result<()>;
|
||||
}
|
||||
|
||||
impl<'x, P, E> EvalObjectReferences for Value<'x, P, E>
|
||||
where
|
||||
P: Property + JmapObjectId,
|
||||
E: Element<Property = P> + JmapObjectId,
|
||||
{
|
||||
fn eval_object_references(
|
||||
&mut self,
|
||||
response: &Response<'_>,
|
||||
graph: &mut Graph<'_>,
|
||||
depth: usize,
|
||||
max_depth: usize,
|
||||
eval_strings: bool,
|
||||
) -> trc::Result<()> {
|
||||
match self {
|
||||
Value::Element(element) => {
|
||||
if let Some(id_ref) = element.as_id_ref() {
|
||||
if let Some(id) = response.created_ids.get(id_ref) {
|
||||
if !element.try_set_id(id.clone()) {
|
||||
return Err(trc::JmapEvent::InvalidResultReference
|
||||
.into_err()
|
||||
.details("Id reference points to invalid type."));
|
||||
}
|
||||
} else if let Graph::Some { child_id, graph } = graph {
|
||||
graph
|
||||
.entry(child_id.to_string())
|
||||
.or_insert_with(Vec::new)
|
||||
.push(id_ref.to_string());
|
||||
} else {
|
||||
return Err(trc::JmapEvent::InvalidResultReference
|
||||
.into_err()
|
||||
.details(format_compact!("Id reference {id_ref:?} not found.")));
|
||||
}
|
||||
}
|
||||
}
|
||||
Value::Array(items) if depth < max_depth => {
|
||||
// Resolve references in arrays (e.g. emailIds: [#idRef1, #idRef2])
|
||||
for item in items {
|
||||
item.eval_object_references(
|
||||
response,
|
||||
graph,
|
||||
depth + 1,
|
||||
max_depth,
|
||||
eval_strings,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
Value::Object(items) if depth < max_depth => {
|
||||
// Resolve references in JMAP sets (e.g. mailboxIds: { "#idRef1": true, "#idRef2": true })
|
||||
for (key, value) in items.as_mut_vec() {
|
||||
if let Key::Property(property) = key
|
||||
&& let Some(id_ref) = property.as_id_ref()
|
||||
{
|
||||
if let Some(id) = response.created_ids.get(id_ref) {
|
||||
if !property.try_set_id(id.clone()) {
|
||||
return Err(trc::JmapEvent::InvalidResultReference
|
||||
.into_err()
|
||||
.details("Id reference points to invalid type."));
|
||||
}
|
||||
} else {
|
||||
return Err(trc::JmapEvent::InvalidResultReference
|
||||
.into_err()
|
||||
.details(format_compact!("Id reference {id_ref:?} not found.")));
|
||||
}
|
||||
} else if eval_strings
|
||||
&& let Some(id) = key
|
||||
.as_string_key()
|
||||
.and_then(|k| k.strip_prefix('#'))
|
||||
.and_then(|id_ref| response.created_ids.get(id_ref))
|
||||
{
|
||||
*key = Key::Owned(match id {
|
||||
AnyId::Id(id) => id.to_string(),
|
||||
AnyId::BlobId(id) => id.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
if matches!(
|
||||
value,
|
||||
Value::Element(_) | Value::Array(_) | Value::Object(_)
|
||||
) {
|
||||
value.eval_object_references(
|
||||
response,
|
||||
graph,
|
||||
depth + 1,
|
||||
max_depth,
|
||||
eval_strings,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user