Import upstream v0.16.23, stripped
trivy / Check (pull_request) Waiting to run

Upstream commit: 9d1c75ab68435e4417337f768291e5f947686203
Enterprise-only files removed or emptied: 63
Enterprise-only snippets removed: 118 in 50 files
Dangling module declarations removed: 5
Edits turning enterprise off: 25
Third-party code: 14 files, 0 not in THIRD-PARTY.md
Verification: clean

One snippet more than v0.16.22, in crates/common/src/auth/authentication.rs
(3, was 2).
This commit is contained in:
2026-09-22 16:31:25 -07:00
parent 083474f67a
commit 3a272096c0
82 changed files with 1544 additions and 646 deletions
+61 -4
View File
@@ -8,11 +8,12 @@ use crate::utils::server::{TestServer, TestServerBuilder};
use common::config::smtp::queue::{QueueExpiry, QueueName};
use registry::schema::{
enums::CompressionAlgo,
structs::{DsnReportSettings, Expression, ReportSettings},
structs::{DsnReportSettings, Expression, FileSystemStore, ReportSettings},
};
use smtp::queue::{
Error, ErrorDetails, HostResponse, Message, MessageWrapper, Recipient, Schedule, Status,
UnexpectedResponse, dsn::SendDsn,
Error, ErrorDetails, HostResponse, Message, MessageWrapper, RCPT_DSN_SENT, Recipient, Schedule,
Status, UnexpectedResponse,
dsn::{DsnStatus, SendDsn},
};
use smtp_proto::{RCPT_NOTIFY_DELAY, RCPT_NOTIFY_FAILURE, RCPT_NOTIFY_SUCCESS, Response};
use std::{
@@ -21,7 +22,7 @@ use std::{
path::PathBuf,
time::SystemTime,
};
use store::write::now;
use store::{BlobStore, backend::fs::FsStore, write::now};
use types::blob_hash::BlobHash;
#[tokio::test]
@@ -194,9 +195,65 @@ async fn generate_dsn() {
// Load queue
let queue = local.read_queued_messages().await;
assert_eq!(queue.len(), 4);
// A DSN that cannot be written is retried rather than marked as sent
message.message.recipients = vec![Recipient {
address: "[email protected]".into(),
status: Status::PermanentFailure(ErrorDetails {
entity: "mx.example.org".into(),
details: Error::UnexpectedResponse(UnexpectedResponse {
command: "RCPT TO:<[email protected]>".into(),
response: Response {
code: 550,
esc: [5, 1, 2],
message: "User does not exist".into(),
},
}),
}),
flags,
orcpt: None,
retry: Schedule::now(),
notify: Schedule::now(),
expires: QueueExpiry::Ttl(10),
queue: QueueName::default(),
}];
let blob_store = local.server.blob_store().clone();
local.set_blob_store(unwritable_blob_store(local.tmp_dir()).await);
assert_eq!(
local.server.send_dsn(&mut message).await,
DsnStatus::Deferred
);
assert_eq!(message.message.recipients[0].flags & RCPT_DSN_SENT, 0);
local.assert_no_events();
assert_eq!(local.read_queued_messages().await.len(), 4);
local.set_blob_store(blob_store);
assert_eq!(
local.server.send_dsn(&mut message).await,
DsnStatus::Completed
);
assert_ne!(message.message.recipients[0].flags & RCPT_DSN_SENT, 0);
local.expect_message().await;
assert_eq!(local.read_queued_messages().await.len(), 5);
}
async fn unwritable_blob_store(tmp_dir: &str) -> BlobStore {
let path = format!("{tmp_dir}/unwritable-blob-store");
fs::write(&path, b"").unwrap();
FsStore::open(FileSystemStore { path, depth: 0 })
.await
.unwrap()
}
impl TestServer {
fn set_blob_store(&mut self, blob: BlobStore) {
let mut core = self.server.core.as_ref().clone();
core.storage.blob = blob;
self.server.core = core.into();
}
async fn compare_dsn(&self, message: Message, test: &str) {
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push("resources");
+3 -3
View File
@@ -33,15 +33,15 @@ async fn queue_due() {
let mut message = new_message(0);
message.message.recipients.push(build_rcpt("c", 3, 8, 9));
message.save_changes(&local.server, 0.into()).await;
message.save_changes(&local.server, 0.into(), None).await;
let mut message = new_message(1);
message.message.recipients.push(build_rcpt("b", 2, 6, 7));
message.save_changes(&local.server, 0.into()).await;
message.save_changes(&local.server, 0.into(), None).await;
let mut message = new_message(2);
message.message.recipients.push(build_rcpt("a", 1, 4, 5));
message.save_changes(&local.server, 0.into()).await;
message.save_changes(&local.server, 0.into(), None).await;
for domain in vec!["a", "b", "c"].into_iter() {
let now = now();