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).
140 lines
4.5 KiB
Rust
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
|
|
);
|
|
}
|
|
}
|