Fix MTA: Disabled aliases continue receiving messages
This commit is contained in:
@@ -52,6 +52,8 @@ pub struct EmailAddressRef<'x> {
|
||||
pub enum EmailCache {
|
||||
Account(u32),
|
||||
MailingList(u32),
|
||||
DisabledAccountAddress(u32),
|
||||
DisabledListAddress(u32),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -101,6 +103,7 @@ pub struct RoleCache {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MailingListCache {
|
||||
pub addresses: Box<[EmailAddress]>,
|
||||
pub recipients: Arc<[Box<str>]>,
|
||||
}
|
||||
|
||||
@@ -245,7 +248,11 @@ impl CacheItemWeight for RoleCache {
|
||||
impl CacheItemWeight for MailingListCache {
|
||||
fn weight(&self) -> u64 {
|
||||
std::mem::size_of::<MailingListCache>() as u64
|
||||
//+ self.addresses.iter().map(|s| s.len() as u64).sum::<u64>()
|
||||
+ self
|
||||
.addresses
|
||||
.iter()
|
||||
.map(|s| s.local_part.len() as u64 + std::mem::size_of::<EmailAddress>() as u64)
|
||||
.sum::<u64>()
|
||||
+ self.recipients.iter().map(|s| s.len() as u64).sum::<u64>()
|
||||
}
|
||||
}
|
||||
|
||||
22
crates/common/src/cache/invalidate.rs
vendored
22
crates/common/src/cache/invalidate.rs
vendored
@@ -327,9 +327,14 @@ impl Server {
|
||||
}
|
||||
CacheInvalidation::Account(id) => {
|
||||
cache.accounts.remove(id);
|
||||
cache.emails.inner().retain(
|
||||
|_, v| !matches!(v, EmailCache::Account(account_id) if account_id == id),
|
||||
);
|
||||
cache.emails.inner().retain(|_, v| {
|
||||
!matches!(
|
||||
v,
|
||||
EmailCache::Account(account_id)
|
||||
| EmailCache::DisabledAccountAddress(account_id)
|
||||
if account_id == id
|
||||
)
|
||||
});
|
||||
}
|
||||
CacheInvalidation::DkimSignature(id) => {
|
||||
cache.dkim_signers.remove(id);
|
||||
@@ -342,9 +347,14 @@ impl Server {
|
||||
}
|
||||
CacheInvalidation::List(id) => {
|
||||
cache.lists.remove(id);
|
||||
cache.emails.inner().retain(
|
||||
|_, v| !matches!(v, EmailCache::MailingList(list_id) if list_id == id),
|
||||
);
|
||||
cache.emails.inner().retain(|_, v| {
|
||||
!matches!(
|
||||
v,
|
||||
EmailCache::MailingList(list_id)
|
||||
| EmailCache::DisabledListAddress(list_id)
|
||||
if list_id == id
|
||||
)
|
||||
});
|
||||
}
|
||||
CacheInvalidation::DomainLogo(id) => {
|
||||
self.inner
|
||||
|
||||
78
crates/common/src/cache/principals.rs
vendored
78
crates/common/src/cache/principals.rs
vendored
@@ -230,8 +230,35 @@ impl Server {
|
||||
{
|
||||
let item_id = object.id().document_id();
|
||||
let result = match object.object() {
|
||||
ObjectType::Account => EmailCache::Account(item_id),
|
||||
ObjectType::MailingList => EmailCache::MailingList(item_id),
|
||||
ObjectType::Account => {
|
||||
if self
|
||||
.account(item_id)
|
||||
.await
|
||||
.caused_by(trc::location!())?
|
||||
.addresses
|
||||
.iter()
|
||||
.any(|address| {
|
||||
address.local_part.as_ref() == local_part
|
||||
&& address.domain_id == domain_id
|
||||
})
|
||||
{
|
||||
EmailCache::Account(item_id)
|
||||
} else {
|
||||
EmailCache::DisabledAccountAddress(item_id)
|
||||
}
|
||||
}
|
||||
ObjectType::MailingList => {
|
||||
if let Some(list) = self.try_list(item_id).await?
|
||||
&& !list.addresses.iter().any(|address| {
|
||||
address.local_part.as_ref() == local_part
|
||||
&& address.domain_id == domain_id
|
||||
})
|
||||
{
|
||||
EmailCache::DisabledListAddress(item_id)
|
||||
} else {
|
||||
EmailCache::MailingList(item_id)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(trc::AuthEvent::Error
|
||||
.into_err()
|
||||
@@ -422,10 +449,16 @@ impl Server {
|
||||
domain_id: account.domain_id.document_id(),
|
||||
}]
|
||||
.into_iter()
|
||||
.chain(account.aliases.into_iter().map(|alias| EmailAddress {
|
||||
local_part: alias.name.into(),
|
||||
domain_id: alias.domain_id.document_id(),
|
||||
}))
|
||||
.chain(
|
||||
account
|
||||
.aliases
|
||||
.into_iter()
|
||||
.filter(|alias| alias.enabled)
|
||||
.map(|alias| EmailAddress {
|
||||
local_part: alias.name.into(),
|
||||
domain_id: alias.domain_id.document_id(),
|
||||
}),
|
||||
)
|
||||
.collect(),
|
||||
id_tenant: account.member_tenant_id.map(|id| id.document_id()),
|
||||
id_member_of: account
|
||||
@@ -479,10 +512,16 @@ impl Server {
|
||||
domain_id: account.domain_id.document_id(),
|
||||
}]
|
||||
.into_iter()
|
||||
.chain(account.aliases.into_iter().map(|alias| EmailAddress {
|
||||
local_part: alias.name.into(),
|
||||
domain_id: alias.domain_id.document_id(),
|
||||
}))
|
||||
.chain(
|
||||
account
|
||||
.aliases
|
||||
.into_iter()
|
||||
.filter(|alias| alias.enabled)
|
||||
.map(|alias| EmailAddress {
|
||||
local_part: alias.name.into(),
|
||||
domain_id: alias.domain_id.document_id(),
|
||||
}),
|
||||
)
|
||||
.collect(),
|
||||
id_tenant: account.member_tenant_id.map(|id| id.document_id()),
|
||||
id_member_of: Default::default(),
|
||||
@@ -764,9 +803,22 @@ impl Server {
|
||||
let Some(list) = self.registry().object::<MailingList>(id.into()).await? else {
|
||||
return Ok(None);
|
||||
};
|
||||
let cache = Arc::new(MailingListCache {
|
||||
recipients: list.recipients.into_iter().map(Into::into).collect(),
|
||||
});
|
||||
let cache =
|
||||
Arc::new(MailingListCache {
|
||||
addresses: [EmailAddress {
|
||||
local_part: list.name.into(),
|
||||
domain_id: list.domain_id.document_id(),
|
||||
}]
|
||||
.into_iter()
|
||||
.chain(list.aliases.into_iter().filter(|alias| alias.enabled).map(
|
||||
|alias| EmailAddress {
|
||||
local_part: alias.name.into(),
|
||||
domain_id: alias.domain_id.document_id(),
|
||||
},
|
||||
))
|
||||
.collect(),
|
||||
recipients: list.recipients.into_iter().map(Into::into).collect(),
|
||||
});
|
||||
let _ = guard.insert(cache.clone());
|
||||
Ok(Some(cache))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user