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,330 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::config::smtp::{
|
||||
queue::QueueName,
|
||||
report::AggregateFrequency,
|
||||
resolver::{Policy, Tlsa},
|
||||
};
|
||||
use ahash::RandomState;
|
||||
use mail_auth::{
|
||||
dmarc::Dmarc,
|
||||
mta_sts::TlsRpt,
|
||||
report::{Record, tlsrpt::FailureDetails},
|
||||
};
|
||||
use registry::{schema::prelude::ObjectType, types::id::ObjectId};
|
||||
use std::sync::{
|
||||
Arc,
|
||||
atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
use tokio::sync::{Semaphore, SemaphorePermit, mpsc};
|
||||
use types::type_state::{DataType, StateChange};
|
||||
use utils::map::bitmap::Bitmap;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PushEvent {
|
||||
Subscribe {
|
||||
account_ids: Vec<u32>,
|
||||
types: Bitmap<DataType>,
|
||||
tx: mpsc::Sender<PushNotification>,
|
||||
},
|
||||
Publish {
|
||||
notification: PushNotification,
|
||||
broadcast: bool,
|
||||
},
|
||||
PushServerRegister {
|
||||
activate: Vec<u32>,
|
||||
expired: Vec<u32>,
|
||||
},
|
||||
PushServerUpdate {
|
||||
account_id: u32,
|
||||
broadcast: bool,
|
||||
},
|
||||
Stop,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum PushNotification {
|
||||
StateChange(StateChange),
|
||||
CalendarAlert(CalendarAlert),
|
||||
EmailPush(EmailPush),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EmailPush {
|
||||
pub account_id: u32,
|
||||
pub email_id: u32,
|
||||
pub change_id: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CalendarAlert {
|
||||
pub account_id: u32,
|
||||
pub event_id: u32,
|
||||
pub recurrence_id: Option<i64>,
|
||||
pub uid: String,
|
||||
pub alert_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BroadcastEvent {
|
||||
PushNotification(PushNotification),
|
||||
PushServerUpdate(u32),
|
||||
RegistryChange(RegistryChange),
|
||||
CacheInvalidate(Vec<CacheInvalidation>),
|
||||
CacheInvalidateAll,
|
||||
CacheInvalidateNegative,
|
||||
MtaQueueStatus { is_running: bool },
|
||||
QueueRefresh,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum RegistryChange {
|
||||
Insert(ObjectId),
|
||||
Delete(ObjectId),
|
||||
Reload(ObjectType),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
|
||||
pub enum CacheInvalidation {
|
||||
AccessToken(u32),
|
||||
DavResources(u32),
|
||||
Domain(u32),
|
||||
Account(u32),
|
||||
DkimSignature(u32),
|
||||
Tenant(u32),
|
||||
Role(u32),
|
||||
List(u32),
|
||||
DomainLogo(u32),
|
||||
TenantLogo(u32),
|
||||
EmailNegative {
|
||||
domain_id: u32,
|
||||
local_part_hash: u32,
|
||||
},
|
||||
DomainNegative,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum QueueEvent {
|
||||
Refresh,
|
||||
WorkerDone {
|
||||
queue_id: u64,
|
||||
queue_name: QueueName,
|
||||
status: QueueEventStatus,
|
||||
},
|
||||
Paused(bool),
|
||||
ReloadSettings,
|
||||
Stop,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum QueueEventStatus {
|
||||
Completed,
|
||||
Locked,
|
||||
Deferred,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ReportingEvent {
|
||||
Dmarc(Box<DmarcEvent>),
|
||||
Tls(Box<TlsEvent>),
|
||||
Stop,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DmarcEvent {
|
||||
pub domain: String,
|
||||
pub report_record: Record,
|
||||
pub dmarc_record: Arc<Dmarc>,
|
||||
pub interval: AggregateFrequency,
|
||||
pub span_id: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TlsEvent {
|
||||
pub domain: String,
|
||||
pub policy: PolicyType,
|
||||
pub failure: Option<FailureDetails>,
|
||||
pub tls_record: Arc<TlsRpt>,
|
||||
pub interval: AggregateFrequency,
|
||||
pub span_id: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Hash, PartialEq, Eq)]
|
||||
pub enum PolicyType {
|
||||
Tlsa(Option<Arc<Tlsa>>),
|
||||
Sts(Option<Arc<Policy>>),
|
||||
None,
|
||||
}
|
||||
|
||||
pub struct TrainTaskController {
|
||||
semaphore: Semaphore,
|
||||
stop_flag: AtomicBool,
|
||||
}
|
||||
|
||||
impl Default for TrainTaskController {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
semaphore: Semaphore::new(1),
|
||||
stop_flag: AtomicBool::new(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TrainTaskController {
|
||||
pub fn try_run(&self) -> Option<SemaphorePermit<'_>> {
|
||||
let permit = self.semaphore.try_acquire().ok()?;
|
||||
|
||||
self.stop_flag.store(false, Ordering::SeqCst);
|
||||
|
||||
Some(permit)
|
||||
}
|
||||
|
||||
pub fn is_running(&self) -> bool {
|
||||
self.semaphore.available_permits() == 0
|
||||
}
|
||||
|
||||
pub fn stop(&self) {
|
||||
self.stop_flag.store(true, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
pub fn should_stop(&self) -> bool {
|
||||
self.stop_flag.load(Ordering::SeqCst)
|
||||
}
|
||||
}
|
||||
|
||||
impl BroadcastEvent {
|
||||
pub fn reload(object: ObjectType) -> Self {
|
||||
BroadcastEvent::RegistryChange(RegistryChange::Reload(object))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ToHash {
|
||||
fn to_hash(&self) -> u64;
|
||||
}
|
||||
|
||||
impl ToHash for Dmarc {
|
||||
fn to_hash(&self) -> u64 {
|
||||
RandomState::with_seeds(1, 9, 7, 9).hash_one(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHash for PolicyType {
|
||||
fn to_hash(&self) -> u64 {
|
||||
RandomState::with_seeds(1, 9, 7, 9).hash_one(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DmarcEvent> for ReportingEvent {
|
||||
fn from(value: DmarcEvent) -> Self {
|
||||
ReportingEvent::Dmarc(Box::new(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TlsEvent> for ReportingEvent {
|
||||
fn from(value: TlsEvent) -> Self {
|
||||
ReportingEvent::Tls(Box::new(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Arc<Tlsa>> for PolicyType {
|
||||
fn from(value: Arc<Tlsa>) -> Self {
|
||||
PolicyType::Tlsa(Some(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Arc<Policy>> for PolicyType {
|
||||
fn from(value: Arc<Policy>) -> Self {
|
||||
PolicyType::Sts(Some(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Arc<Tlsa>> for PolicyType {
|
||||
fn from(value: &Arc<Tlsa>) -> Self {
|
||||
PolicyType::Tlsa(Some(value.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Arc<Policy>> for PolicyType {
|
||||
fn from(value: &Arc<Policy>) -> Self {
|
||||
PolicyType::Sts(Some(value.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(&Option<Arc<Policy>>, &Option<Arc<Tlsa>>)> for PolicyType {
|
||||
fn from(value: (&Option<Arc<Policy>>, &Option<Arc<Tlsa>>)) -> Self {
|
||||
match value {
|
||||
(Some(value), _) => PolicyType::Sts(Some(value.clone())),
|
||||
(_, Some(value)) => PolicyType::Tlsa(Some(value.clone())),
|
||||
_ => PolicyType::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PushNotification {
|
||||
pub fn account_id(&self) -> u32 {
|
||||
match self {
|
||||
PushNotification::StateChange(state_change) => state_change.account_id,
|
||||
PushNotification::CalendarAlert(calendar_alert) => calendar_alert.account_id,
|
||||
PushNotification::EmailPush(email_push) => email_push.account_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn filter_types(&self, types: &Bitmap<DataType>) -> Option<PushNotification> {
|
||||
match self {
|
||||
PushNotification::StateChange(state_change) => {
|
||||
let mut filtered_types = state_change.types;
|
||||
filtered_types.intersection(types);
|
||||
if !filtered_types.is_empty() {
|
||||
Some(PushNotification::StateChange(StateChange {
|
||||
account_id: state_change.account_id,
|
||||
change_id: state_change.change_id,
|
||||
types: filtered_types,
|
||||
}))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
PushNotification::CalendarAlert(_) => {
|
||||
if types.contains(DataType::CalendarAlert) {
|
||||
Some(self.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
PushNotification::EmailPush(_) => {
|
||||
if types.contains_any(
|
||||
[
|
||||
DataType::EmailDelivery,
|
||||
DataType::Email,
|
||||
DataType::Mailbox,
|
||||
DataType::Thread,
|
||||
]
|
||||
.into_iter(),
|
||||
) {
|
||||
Some(self.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EmailPush {
|
||||
pub fn to_state_change(&self) -> StateChange {
|
||||
StateChange {
|
||||
account_id: self.account_id,
|
||||
change_id: self.change_id,
|
||||
types: Bitmap::from_iter([
|
||||
DataType::EmailDelivery,
|
||||
DataType::Email,
|
||||
DataType::Mailbox,
|
||||
DataType::Thread,
|
||||
]),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user