Key/value store access from Sieve scripts

This commit is contained in:
mdecimus
2023-12-12 15:28:21 +01:00
parent 78f932990d
commit 4301ec16d0
46 changed files with 1087 additions and 592 deletions

View File

@@ -46,25 +46,6 @@ duplicate-expiry = "7d"
type = "sqlite"
path = "%PATH%/test_antispam.db"
[store."spamdb".pool]
max-connections = 10
min-connections = 0
idle-timeout = "5m"
[store."spamdb".query]
token-insert = "INSERT INTO bayes_tokens (h1, h2, ws, wh) VALUES (?, ?, ?, ?)
ON CONFLICT(h1, h2)
DO UPDATE SET ws = ws + excluded.ws, wh = wh + excluded.wh"
token-lookup = "SELECT ws, wh FROM bayes_tokens WHERE h1 = ? AND h2 = ?"
id-insert = "INSERT INTO seen_ids (id, ttl) VALUES (?, datetime('now', ? || ' seconds'))"
id-lookup = "SELECT 1 FROM seen_ids WHERE id = ? AND ttl > CURRENT_TIMESTAMP"
id-cleanup = "DELETE FROM seen_ids WHERE ttl < CURRENT_TIMESTAMP"
reputation-insert = "INSERT INTO reputation (token, score, count, ttl) VALUES (?, ?, 1, datetime('now', '30 days'))
ON CONFLICT(token)
DO UPDATE SET score = (count + 1) * (excluded.score + 0.98 * score) / (0.98 * count + 1), count = count + 1, ttl = excluded.ttl"
reputation-lookup = "SELECT score, count FROM reputation WHERE token = ?"
reputation-cleanup = "DELETE FROM reputation WHERE ttl < CURRENT_TIMESTAMP"
[store."default"]
type = "memory"
@@ -130,26 +111,6 @@ public-suffix = "file://%LIST_PATH%/public-suffix.dat"
[sieve.trusted.scripts]
"#;
const CREATE_TABLES: &[&str; 3] = &[
"CREATE TABLE IF NOT EXISTS bayes_tokens (
h1 INTEGER NOT NULL,
h2 INTEGER NOT NULL,
ws INTEGER,
wh INTEGER,
PRIMARY KEY (h1, h2)
)",
"CREATE TABLE IF NOT EXISTS seen_ids (
id STRING NOT NULL PRIMARY KEY,
ttl DATETIME NOT NULL
)",
"CREATE TABLE IF NOT EXISTS reputation (
token STRING NOT NULL PRIMARY KEY,
score FLOAT NOT NULL DEFAULT '0',
count INT(11) NOT NULL DEFAULT '0',
ttl DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
)",
];
#[tokio::test(flavor = "multi_thread")]
async fn antispam() {
/*tracing::subscriber::set_global_default(
@@ -259,12 +220,6 @@ async fn antispam() {
let config = &mut core.session.config;
config.rcpt.relay = IfBlock::new(true);
// Create tables
let sdb = ctx.stores.lookup_stores.get("spamdb").unwrap();
for query in CREATE_TABLES {
sdb.query::<usize>(query, vec![]).await.expect(query);
}
// Add mock DNS entries
for (domain, ip) in [
("bank.com", "127.0.0.1"),

View File

@@ -48,7 +48,7 @@ use smtp::{
},
core::{
throttle::ThrottleKeyHasherBuilder, QueueCore, ReportCore, Resolvers, SessionCore,
SieveConfig, SieveCore, TlsConnectors, SMTP,
SieveCore, TlsConnectors, SMTP,
},
outbound::dane::DnssecResolver,
};
@@ -434,14 +434,12 @@ impl TestConfig for SieveCore {
runtime: Runtime::new_with_context(SieveContext::default()),
scripts: AHashMap::new(),
lookup: AHashMap::new(),
config: SieveConfig {
from_addr: "MAILER-DAEMON@example.org".to_string(),
from_name: "Mailer Daemon".to_string(),
return_path: "".to_string(),
sign: vec![],
directories: Default::default(),
lookup_stores: Default::default(),
},
from_addr: "MAILER-DAEMON@example.org".to_string(),
from_name: "Mailer Daemon".to_string(),
return_path: "".to_string(),
sign: vec![],
directories: Default::default(),
lookup_stores: Default::default(),
}
}
}

View File

@@ -111,7 +111,7 @@ pub async fn blob_tests() {
);
// Purge expired blobs
store.blob_hash_purge(blob_store.clone()).await.unwrap();
store.purge_blobs(blob_store.clone()).await.unwrap();
// Blob hash should no longer exist
assert!(!store.blob_hash_exists(&hash).await.unwrap());
@@ -192,7 +192,7 @@ pub async fn blob_tests() {
);
// Purge expired blobs and make sure nothing else is deleted
store.blob_hash_purge(blob_store.clone()).await.unwrap();
store.purge_blobs(blob_store.clone()).await.unwrap();
for (pos, (blob, blob_class)) in [
(b"abc", BlobClass::Reserved { account_id: 0 }),
(
@@ -266,7 +266,7 @@ pub async fn blob_tests() {
.unwrap();
// Purge and make sure blob is deleted
store.blob_hash_purge(blob_store.clone()).await.unwrap();
store.purge_blobs(blob_store.clone()).await.unwrap();
for (pos, (blob, blob_class)) in [
(
b"789",
@@ -314,7 +314,7 @@ pub async fn blob_tests() {
// Unlink all blobs from accountId 1 and purge
store.blob_hash_unlink_account(1).await.unwrap();
store.blob_hash_purge(blob_store.clone()).await.unwrap();
store.purge_blobs(blob_store.clone()).await.unwrap();
// Make sure only accountId 0's blobs are left
for (pos, (blob, blob_class)) in [