Files
inbuxa-server/tests/src/smtp/lookup/expressions.rs
T
jcoffey-dev 3a272096c0
trivy / Check (pull_request) Waiting to run
Import upstream v0.16.23, stripped
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).
2026-09-22 16:31:25 -07:00

140 lines
4.5 KiB
Rust

/*
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use crate::utils::{dns::DnsCache, server::TestServerBuilder};
use common::expr::{tokenizer::TokenMap, *};
use mail_auth::{DnssecStatus, MX};
use registry::schema::{
enums::ExpressionVariable,
prelude::{ObjectType, Property},
structs::{LookupStore, SqliteStore, StoreLookup},
};
use smtp::queue::RecipientDomain;
use std::time::{Duration, Instant};
const TESTS: &[(&str, &str)] = &[
("dns_query(rcpt_domain, 'mx')[0]", "mx.foobar.org"),
(
"key_get('sql', 'hello') + '-' + key_exists('sql', 'hello') + '-' + key_set('sql', 'hello', 'world') + '-' + key_get('sql', 'hello') + '-' + key_exists('sql', 'hello')",
"-0-1-world-1",
),
(
"counter_get('sql', 'county') + '-' + counter_incr('sql', 'county', 1) + '-' + counter_incr('sql', 'county', 1) + '-' + counter_get('sql', 'county')",
"0-1-2-2",
),
(
"sql_query('sql', 'SELECT description FROM domains WHERE name = ?', 'foobar.org')",
"Main domain",
),
(
"is_local_domain('foobar.org') + '-' + is_local_domain('unknown.org') + '-' + is_local_address('[email protected]') + '-' + is_local_address('[email protected]')",
"1-0-1-0",
),
(
"is_local_domain('FooBar.org') + '-' + is_local_address('[email protected]') + '-' + is_local_address('[email protected]')",
"1-1-1",
),
(
"bit_and(254, 16) + '-' + bit_and(254, 1) + '-' + bit_and(80, 64) + '-' + bit_and(255, 128)",
"16-0-64-128",
),
];
#[tokio::test]
async fn expressions() {
let mut test = TestServerBuilder::new("smtp_lookup_test")
.await
.with_http_listener(19017)
.await
.disable_services()
.capture_queue()
.build()
.await;
// Create test data
let admin = test.account("admin");
for (name, secret, description, aliases) in [
("[email protected]", "12345 + extra safety", "John Doe", &[]),
("[email protected]", "abcde + extra safety", "Jane Smith", &[]),
] {
admin
.create_user_account(name, secret, description, aliases, vec![])
.await;
}
admin
.registry_create_object(StoreLookup {
namespace: "sql".into(),
store: LookupStore::Sqlite(SqliteStore {
path: format!("{}/smtp_sql.db", test.tmp_dir()),
pool_max_connections: 10,
pool_workers: None,
}),
})
.await;
admin.reload_lookup_stores().await;
test.reload_core();
test.server.mx_add(
"test.org",
vec![MX {
exchanges: vec!["mx.foobar.org".into()].into_boxed_slice(),
preference: 10,
}],
DnssecStatus::Secure,
Instant::now() + Duration::from_secs(10),
);
let sql = test
.server
.get_lookup_store("sql")
.unwrap()
.into_store()
.unwrap();
sql.create_tables().await.unwrap();
for query in [
"CREATE TABLE domains (name TEXT PRIMARY KEY, description TEXT);",
"INSERT INTO domains (name, description) VALUES ('foobar.org', 'Main domain');",
"INSERT INTO domains (name, description) VALUES ('foobar.net', 'Secondary domain');",
"CREATE TABLE allowed_ips (addr TEXT PRIMARY KEY);",
"INSERT INTO allowed_ips (addr) VALUES ('10.0.0.50');",
] {
sql.sql_query::<usize>(query, Vec::new()).await.unwrap();
}
// Test expression functions
let token_map = TokenMap::default().with_variables(&[
ExpressionVariable::Rcpt,
ExpressionVariable::RcptDomain,
ExpressionVariable::Sender,
ExpressionVariable::SenderDomain,
ExpressionVariable::Mx,
ExpressionVariable::HeloDomain,
ExpressionVariable::AuthenticatedAs,
ExpressionVariable::Listener,
ExpressionVariable::RemoteIp,
ExpressionVariable::LocalIp,
ExpressionVariable::Priority,
]);
for (expr, expected) in TESTS {
let e = Expression::parse(&token_map, expr);
assert_eq!(
test.server
.eval_expr::<String, _>(
&e,
&RecipientDomain::new("test.org"),
ObjectType::Account.singleton(),
Property::AccountName,
0
)
.await
.unwrap(),
*expected,
"failed for '{}'",
expr
);
}
}