JMAP Registry API implementation - part 7
This commit is contained in:
120
crates/registry/src/utils/archived_item.rs
Normal file
120
crates/registry/src/utils/archived_item.rs
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <hello@stalw.art>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::schema::prelude::{ArchivedItem, UTCDateTime};
|
||||
use types::{blob::BlobId, id::Id};
|
||||
|
||||
impl ArchivedItem {
|
||||
pub fn account_id(&self) -> Id {
|
||||
match self {
|
||||
ArchivedItem::Email(i) => i.account_id,
|
||||
ArchivedItem::FileNode(i) => i.account_id,
|
||||
ArchivedItem::CalendarEvent(i) => i.account_id,
|
||||
ArchivedItem::ContactCard(i) => i.account_id,
|
||||
ArchivedItem::SieveScript(i) => i.account_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn blob_id(&self) -> &BlobId {
|
||||
match self {
|
||||
ArchivedItem::Email(i) => &i.blob_id,
|
||||
ArchivedItem::FileNode(i) => &i.blob_id,
|
||||
ArchivedItem::CalendarEvent(i) => &i.blob_id,
|
||||
ArchivedItem::ContactCard(i) => &i.blob_id,
|
||||
ArchivedItem::SieveScript(i) => &i.blob_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn archived_until(&self) -> UTCDateTime {
|
||||
match self {
|
||||
ArchivedItem::Email(i) => i.archived_until,
|
||||
ArchivedItem::FileNode(i) => i.archived_until,
|
||||
ArchivedItem::CalendarEvent(i) => i.archived_until,
|
||||
ArchivedItem::ContactCard(i) => i.archived_until,
|
||||
ArchivedItem::SieveScript(i) => i.archived_until,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn created_at(&self) -> UTCDateTime {
|
||||
match self {
|
||||
ArchivedItem::Email(i) => i.received_at,
|
||||
ArchivedItem::FileNode(i) => i.created_at,
|
||||
ArchivedItem::CalendarEvent(i) => i.created_at,
|
||||
ArchivedItem::ContactCard(i) => i.created_at,
|
||||
ArchivedItem::SieveScript(i) => i.created_at,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_account_id(&mut self, value: Id) {
|
||||
match self {
|
||||
ArchivedItem::Email(i) => i.account_id = value,
|
||||
ArchivedItem::FileNode(i) => i.account_id = value,
|
||||
ArchivedItem::CalendarEvent(i) => i.account_id = value,
|
||||
ArchivedItem::ContactCard(i) => i.account_id = value,
|
||||
ArchivedItem::SieveScript(i) => i.account_id = value,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_blob_id(&mut self, value: BlobId) {
|
||||
match self {
|
||||
ArchivedItem::Email(i) => i.blob_id = value,
|
||||
ArchivedItem::FileNode(i) => i.blob_id = value,
|
||||
ArchivedItem::CalendarEvent(i) => i.blob_id = value,
|
||||
ArchivedItem::ContactCard(i) => i.blob_id = value,
|
||||
ArchivedItem::SieveScript(i) => i.blob_id = value,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_archived_until(&mut self, value: UTCDateTime) {
|
||||
match self {
|
||||
ArchivedItem::Email(i) => i.archived_until = value,
|
||||
ArchivedItem::FileNode(i) => i.archived_until = value,
|
||||
ArchivedItem::CalendarEvent(i) => i.archived_until = value,
|
||||
ArchivedItem::ContactCard(i) => i.archived_until = value,
|
||||
ArchivedItem::SieveScript(i) => i.archived_until = value,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn account_id_mut(&mut self) -> &mut Id {
|
||||
match self {
|
||||
ArchivedItem::Email(i) => &mut i.account_id,
|
||||
ArchivedItem::FileNode(i) => &mut i.account_id,
|
||||
ArchivedItem::CalendarEvent(i) => &mut i.account_id,
|
||||
ArchivedItem::ContactCard(i) => &mut i.account_id,
|
||||
ArchivedItem::SieveScript(i) => &mut i.account_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn blob_id_mut(&mut self) -> &mut BlobId {
|
||||
match self {
|
||||
ArchivedItem::Email(i) => &mut i.blob_id,
|
||||
ArchivedItem::FileNode(i) => &mut i.blob_id,
|
||||
ArchivedItem::CalendarEvent(i) => &mut i.blob_id,
|
||||
ArchivedItem::ContactCard(i) => &mut i.blob_id,
|
||||
ArchivedItem::SieveScript(i) => &mut i.blob_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn archived_until_mut(&mut self) -> &mut UTCDateTime {
|
||||
match self {
|
||||
ArchivedItem::Email(i) => &mut i.archived_until,
|
||||
ArchivedItem::FileNode(i) => &mut i.archived_until,
|
||||
ArchivedItem::CalendarEvent(i) => &mut i.archived_until,
|
||||
ArchivedItem::ContactCard(i) => &mut i.archived_until,
|
||||
ArchivedItem::SieveScript(i) => &mut i.archived_until,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_blob_id(self) -> BlobId {
|
||||
match self {
|
||||
ArchivedItem::Email(i) => i.blob_id,
|
||||
ArchivedItem::FileNode(i) => i.blob_id,
|
||||
ArchivedItem::CalendarEvent(i) => i.blob_id,
|
||||
ArchivedItem::ContactCard(i) => i.blob_id,
|
||||
ArchivedItem::SieveScript(i) => i.blob_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ use crate::schema::prelude::Roles;
|
||||
use types::id::Id;
|
||||
|
||||
pub mod account;
|
||||
pub mod archived_item;
|
||||
pub mod cron;
|
||||
pub mod http;
|
||||
pub mod report;
|
||||
|
||||
@@ -5,160 +5,11 @@
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
schema::{
|
||||
enums,
|
||||
prelude::{Property, UTCDateTime},
|
||||
structs,
|
||||
},
|
||||
types::{index::IndexBuilder, ipaddr::IpAddr},
|
||||
schema::{enums, prelude::UTCDateTime, structs},
|
||||
types::ipaddr::IpAddr,
|
||||
};
|
||||
use mail_auth::report::{tlsrpt::*, *};
|
||||
use std::borrow::Cow;
|
||||
use types::id::Id;
|
||||
|
||||
pub trait ReportIndex {
|
||||
fn text(&self) -> impl Iterator<Item = &str>;
|
||||
|
||||
fn tenant_id(&self) -> Option<Id>;
|
||||
|
||||
fn expires_at(&self) -> u64;
|
||||
|
||||
fn domains(&self) -> impl Iterator<Item = &str>;
|
||||
|
||||
fn build_search_index<'x>(&'x self, index: &mut IndexBuilder<'x>) {
|
||||
for text in self.text() {
|
||||
index.text(Property::Domain, text);
|
||||
}
|
||||
|
||||
if let Some(tenant_id) = self.tenant_id() {
|
||||
index.search(Property::MemberTenantId, tenant_id.id());
|
||||
}
|
||||
|
||||
index.search(Property::ExpiresAt, self.expires_at());
|
||||
}
|
||||
}
|
||||
|
||||
impl ReportIndex for structs::ArfExternalReport {
|
||||
fn domains(&self) -> impl Iterator<Item = &str> {
|
||||
let report = &self.report;
|
||||
|
||||
report
|
||||
.reported_domains
|
||||
.iter()
|
||||
.filter_map(|s| non_empty(s))
|
||||
.chain(
|
||||
[report.dkim_domain.as_deref()]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter_map(non_empty),
|
||||
)
|
||||
}
|
||||
|
||||
fn text(&self) -> impl Iterator<Item = &str> {
|
||||
let report = &self.report;
|
||||
|
||||
report
|
||||
.reported_domains
|
||||
.iter()
|
||||
.filter_map(|s| non_empty(s))
|
||||
.chain(
|
||||
[
|
||||
report.dkim_domain.as_deref(),
|
||||
report.reporting_mta.as_deref(),
|
||||
report.original_mail_from.as_deref(),
|
||||
report.original_rcpt_to.as_deref(),
|
||||
]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter_map(non_empty),
|
||||
)
|
||||
.chain(non_empty(&self.from))
|
||||
}
|
||||
|
||||
fn tenant_id(&self) -> Option<Id> {
|
||||
self.member_tenant_id
|
||||
}
|
||||
|
||||
fn expires_at(&self) -> u64 {
|
||||
self.expires_at.timestamp() as u64
|
||||
}
|
||||
}
|
||||
|
||||
impl ReportIndex for structs::DmarcExternalReport {
|
||||
fn domains(&self) -> impl Iterator<Item = &str> {
|
||||
let report = &self.report;
|
||||
|
||||
non_empty(&report.policy_domain)
|
||||
.into_iter()
|
||||
.filter_map(non_empty)
|
||||
}
|
||||
|
||||
fn text(&self) -> impl Iterator<Item = &str> {
|
||||
let report = &self.report;
|
||||
|
||||
non_empty(&report.email)
|
||||
.into_iter()
|
||||
.filter_map(non_empty)
|
||||
.chain(non_empty(&report.policy_domain))
|
||||
.chain(report.records.iter().flat_map(|r| {
|
||||
r.envelope_to
|
||||
.as_deref()
|
||||
.into_iter()
|
||||
.filter_map(non_empty)
|
||||
.chain(non_empty(&r.envelope_from))
|
||||
.chain(non_empty(&r.header_from))
|
||||
.chain(r.dkim_results.iter().filter_map(|d| non_empty(&d.domain)))
|
||||
.chain(r.spf_results.iter().filter_map(|s| non_empty(&s.domain)))
|
||||
}))
|
||||
.chain(non_empty(&self.from))
|
||||
}
|
||||
|
||||
fn tenant_id(&self) -> Option<Id> {
|
||||
self.member_tenant_id
|
||||
}
|
||||
|
||||
fn expires_at(&self) -> u64 {
|
||||
self.expires_at.timestamp() as u64
|
||||
}
|
||||
}
|
||||
|
||||
impl ReportIndex for structs::TlsExternalReport {
|
||||
fn domains(&self) -> impl Iterator<Item = &str> {
|
||||
let report = &self.report;
|
||||
|
||||
report
|
||||
.policies
|
||||
.iter()
|
||||
.flat_map(|p| non_empty(&p.policy_domain).into_iter())
|
||||
}
|
||||
|
||||
fn text(&self) -> impl Iterator<Item = &str> {
|
||||
let report = &self.report;
|
||||
|
||||
report
|
||||
.policies
|
||||
.iter()
|
||||
.flat_map(|p| {
|
||||
non_empty(&p.policy_domain)
|
||||
.into_iter()
|
||||
.chain(p.mx_hosts.iter().filter_map(|s| non_empty(s)))
|
||||
.chain(p.failure_details.iter().flat_map(|fd| {
|
||||
non_empty_opt(&fd.receiving_mx_hostname)
|
||||
.into_iter()
|
||||
.chain(non_empty_opt(&fd.receiving_mx_helo))
|
||||
}))
|
||||
})
|
||||
.chain(non_empty(&self.from))
|
||||
}
|
||||
|
||||
fn tenant_id(&self) -> Option<Id> {
|
||||
self.member_tenant_id
|
||||
}
|
||||
|
||||
fn expires_at(&self) -> u64 {
|
||||
self.expires_at.timestamp() as u64
|
||||
}
|
||||
}
|
||||
|
||||
impl From<enums::DmarcAlignment> for Alignment {
|
||||
fn from(value: enums::DmarcAlignment) -> Self {
|
||||
@@ -938,13 +789,3 @@ fn fo_to_failure_reporting_options(fo: &Option<String>) -> Vec<enums::FailureRep
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn non_empty(s: &str) -> Option<&str> {
|
||||
if s.is_empty() { None } else { Some(s) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn non_empty_opt(s: &Option<String>) -> Option<&str> {
|
||||
s.as_deref().filter(|s| !s.is_empty())
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ impl Task {
|
||||
Task::MergeThreads(task) => task.status = status,
|
||||
Task::DmarcReport(task) => task.status = status,
|
||||
Task::TlsReport(task) => task.status = status,
|
||||
Task::RestoreArchivedItem(task) => task.status = status,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +33,7 @@ impl Task {
|
||||
Task::MergeThreads(task) => &task.status,
|
||||
Task::DmarcReport(task) => &task.status,
|
||||
Task::TlsReport(task) => &task.status,
|
||||
Task::RestoreArchivedItem(task) => &task.status,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user