1import ./make-test-python.nix (
2 { pkgs, ... }:
3 let
4 certs = import ./common/acme/server/snakeoil-certs.nix;
5 domain = certs.domain;
6 in
7 {
8 name = "rspamd-trainer";
9 meta = with pkgs.lib.maintainers; {
10 maintainers = [ onny ];
11 };
12
13 nodes = {
14 machine =
15 { options, config, ... }:
16 {
17
18 security.pki.certificateFiles = [
19 certs.ca.cert
20 ];
21
22 networking.extraHosts = ''
23 127.0.0.1 ${domain}
24 '';
25
26 services.rspamd-trainer = {
27 enable = true;
28 settings = {
29 HOST = domain;
30 USERNAME = "spam@${domain}";
31 INBOXPREFIX = "INBOX/";
32 };
33 secrets = [
34 # Do not use this in production. This will make passwords
35 # world-readable in the Nix store
36 "${pkgs.writeText "secrets" ''
37 PASSWORD = test123
38 ''}"
39 ];
40 };
41
42 services.maddy = {
43 enable = true;
44 hostname = domain;
45 primaryDomain = domain;
46 ensureAccounts = [ "spam@${domain}" ];
47 ensureCredentials = {
48 # Do not use this in production. This will make passwords world-readable
49 # in the Nix store
50 "spam@${domain}".passwordFile = "${pkgs.writeText "postmaster" "test123"}";
51 };
52 tls = {
53 loader = "file";
54 certificates = [
55 {
56 certPath = "${certs.${domain}.cert}";
57 keyPath = "${certs.${domain}.key}";
58 }
59 ];
60 };
61 config =
62 builtins.replaceStrings
63 [
64 "imap tcp://0.0.0.0:143"
65 "submission tcp://0.0.0.0:587"
66 ]
67 [
68 "imap tls://0.0.0.0:993 tcp://0.0.0.0:143"
69 "submission tls://0.0.0.0:465 tcp://0.0.0.0:587"
70 ]
71 options.services.maddy.config.default;
72 };
73
74 services.rspamd = {
75 enable = true;
76 locals = {
77 "redis.conf".text = ''
78 servers = "${config.services.redis.servers.rspamd.unixSocket}";
79 '';
80 "classifier-bayes.conf".text = ''
81 backend = "redis";
82 autolearn = true;
83 '';
84 };
85 };
86
87 services.redis.servers.rspamd = {
88 enable = true;
89 port = 0;
90 unixSocket = "/run/redis-rspamd/redis.sock";
91 user = config.services.rspamd.user;
92 };
93
94 environment.systemPackages = [
95 (pkgs.writers.writePython3Bin "send-testmail" { } ''
96 import smtplib
97 import ssl
98 from email.mime.text import MIMEText
99 context = ssl.create_default_context()
100 msg = MIMEText("Hello World")
101 msg['Subject'] = 'Test'
102 msg['From'] = "spam@${domain}"
103 msg['To'] = "spam@${domain}"
104 with smtplib.SMTP_SSL(host='${domain}', port=465, context=context) as smtp:
105 smtp.login('spam@${domain}', 'test123')
106 smtp.sendmail(
107 'spam@${domain}', 'spam@${domain}', msg.as_string()
108 )
109 '')
110 (pkgs.writers.writePython3Bin "create-mail-dirs" { } ''
111 import imaplib
112 with imaplib.IMAP4_SSL('${domain}') as imap:
113 imap.login('spam@${domain}', 'test123')
114 imap.create("\"INBOX/report_spam\"")
115 imap.create("\"INBOX/report_ham\"")
116 imap.create("\"INBOX/report_spam_reply\"")
117 imap.select("INBOX")
118 imap.copy("1", "\"INBOX/report_ham\"")
119 imap.logout()
120 '')
121 (pkgs.writers.writePython3Bin "test-imap" { } ''
122 import imaplib
123 with imaplib.IMAP4_SSL('${domain}') as imap:
124 imap.login('spam@${domain}', 'test123')
125 imap.select("INBOX/learned_ham")
126 status, refs = imap.search(None, 'ALL')
127 assert status == 'OK'
128 assert len(refs) == 1
129 status, msg = imap.fetch(refs[0], 'BODY[TEXT]')
130 assert status == 'OK'
131 assert msg[0][1].strip() == b"Hello World"
132 imap.logout()
133 '')
134 ];
135
136 };
137
138 };
139
140 testScript =
141 { nodes }:
142 ''
143 start_all()
144 machine.wait_for_unit("maddy.service")
145 machine.wait_for_open_port(143)
146 machine.wait_for_open_port(993)
147 machine.wait_for_open_port(587)
148 machine.wait_for_open_port(465)
149
150 # Send test mail to spam@domain
151 machine.succeed("send-testmail")
152
153 # Create mail directories required for rspamd-trainer and copy mail from
154 # INBOX into INBOX/report_ham
155 machine.succeed("create-mail-dirs")
156
157 # Start rspamd-trainer. It should read mail from INBOX/report_ham
158 machine.wait_for_unit("rspamd.service")
159 machine.wait_for_unit("redis-rspamd.service")
160 machine.wait_for_file("/run/rspamd/rspamd.sock")
161 machine.succeed("systemctl start rspamd-trainer.service")
162
163 # Check if mail got processed by rspamd-trainer successfully and check for
164 # it in INBOX/learned_ham
165 machine.succeed("test-imap")
166 '';
167 }
168)