nixpkgs/nixos/tests/rspamd-trainer.nix

155 lines
4.8 KiB
Nix

import ./make-test-python.nix ({ pkgs, ... }:
let
certs = import ./common/acme/server/snakeoil-certs.nix;
domain = certs.domain;
in {
name = "rspamd-trainer";
meta = with pkgs.lib.maintainers; { maintainers = [ onny ]; };
nodes = {
machine = { options, config, ... }: {
security.pki.certificateFiles = [
certs.ca.cert
];
networking.extraHosts = ''
127.0.0.1 ${domain}
'';
services.rspamd-trainer = {
enable = true;
settings = {
HOST = domain;
USERNAME = "spam@${domain}";
INBOXPREFIX = "INBOX/";
};
secrets = [
# Do not use this in production. This will make passwords
# world-readable in the Nix store
"${pkgs.writeText "secrets" ''
PASSWORD = test123
''}"
];
};
services.maddy = {
enable = true;
hostname = domain;
primaryDomain = domain;
ensureAccounts = [ "spam@${domain}" ];
ensureCredentials = {
# Do not use this in production. This will make passwords world-readable
# in the Nix store
"spam@${domain}".passwordFile = "${pkgs.writeText "postmaster" "test123"}";
};
tls = {
loader = "file";
certificates = [{
certPath = "${certs.${domain}.cert}";
keyPath = "${certs.${domain}.key}";
}];
};
config = builtins.replaceStrings [
"imap tcp://0.0.0.0:143"
"submission tcp://0.0.0.0:587"
] [
"imap tls://0.0.0.0:993 tcp://0.0.0.0:143"
"submission tls://0.0.0.0:465 tcp://0.0.0.0:587"
] options.services.maddy.config.default;
};
services.rspamd = {
enable = true;
locals = {
"redis.conf".text = ''
servers = "${config.services.redis.servers.rspamd.unixSocket}";
'';
"classifier-bayes.conf".text = ''
backend = "redis";
autolearn = true;
'';
};
};
services.redis.servers.rspamd = {
enable = true;
port = 0;
unixSocket = "/run/redis-rspamd/redis.sock";
user = config.services.rspamd.user;
};
environment.systemPackages = [
(pkgs.writers.writePython3Bin "send-testmail" { } ''
import smtplib
import ssl
from email.mime.text import MIMEText
context = ssl.create_default_context()
msg = MIMEText("Hello World")
msg['Subject'] = 'Test'
msg['From'] = "spam@${domain}"
msg['To'] = "spam@${domain}"
with smtplib.SMTP_SSL(host='${domain}', port=465, context=context) as smtp:
smtp.login('spam@${domain}', 'test123')
smtp.sendmail(
'spam@${domain}', 'spam@${domain}', msg.as_string()
)
'')
(pkgs.writers.writePython3Bin "create-mail-dirs" { } ''
import imaplib
with imaplib.IMAP4_SSL('${domain}') as imap:
imap.login('spam@${domain}', 'test123')
imap.create("\"INBOX/report_spam\"")
imap.create("\"INBOX/report_ham\"")
imap.create("\"INBOX/report_spam_reply\"")
imap.select("INBOX")
imap.copy("1", "\"INBOX/report_ham\"")
imap.logout()
'')
(pkgs.writers.writePython3Bin "test-imap" { } ''
import imaplib
with imaplib.IMAP4_SSL('${domain}') as imap:
imap.login('spam@${domain}', 'test123')
imap.select("INBOX/learned_ham")
status, refs = imap.search(None, 'ALL')
assert status == 'OK'
assert len(refs) == 1
status, msg = imap.fetch(refs[0], 'BODY[TEXT]')
assert status == 'OK'
assert msg[0][1].strip() == b"Hello World"
imap.logout()
'')
];
};
};
testScript = { nodes }: ''
start_all()
machine.wait_for_unit("maddy.service")
machine.wait_for_open_port(143)
machine.wait_for_open_port(993)
machine.wait_for_open_port(587)
machine.wait_for_open_port(465)
# Send test mail to spam@domain
machine.succeed("send-testmail")
# Create mail directories required for rspamd-trainer and copy mail from
# INBOX into INBOX/report_ham
machine.succeed("create-mail-dirs")
# Start rspamd-trainer. It should read mail from INBOX/report_ham
machine.wait_for_unit("rspamd.service")
machine.wait_for_unit("redis-rspamd.service")
machine.wait_for_file("/run/rspamd/rspamd.sock")
machine.succeed("systemctl start rspamd-trainer.service")
# Check if mail got processed by rspamd-trainer successfully and check for
# it in INBOX/learned_ham
machine.succeed("test-imap")
'';
})