python310Packages.pydeconz: 104 -> 105
[NixPkgs.git] / nixos / tests / parsedmarc / default.nix
blob50b977723e9c777ecc9e2ba39896a42d75e9d31c
1 # This tests parsedmarc by sending a report to its monitored email
2 # address and reading the results out of Elasticsearch.
4 { pkgs, ... }@args:
5 let
6   inherit (import ../../lib/testing-python.nix args) makeTest;
7   inherit (pkgs) lib;
9   dmarcTestReport = builtins.fetchurl {
10     name = "dmarc-test-report";
11     url = "https://github.com/domainaware/parsedmarc/raw/f45ab94e0608088e0433557608d9f4e9517d3afe/samples/aggregate/estadocuenta1.infonacot.gob.mx!example.com!1536853302!1536939702!2940.xml.zip";
12     sha256 = "0dq64cj49711kbja27pjl2hy0d3azrjxg91kqrh40x46fkn1dwkx";
13   };
15   sendEmail = address:
16     pkgs.writeScriptBin "send-email" ''
17       #!${pkgs.python3.interpreter}
18       import smtplib
19       from email import encoders
20       from email.mime.base import MIMEBase
21       from email.mime.multipart import MIMEMultipart
22       from email.mime.text import MIMEText
24       sender_email = "dmarc_tester@fake.domain"
25       receiver_email = "${address}"
27       message = MIMEMultipart()
28       message["From"] = sender_email
29       message["To"] = receiver_email
30       message["Subject"] = "DMARC test"
32       message.attach(MIMEText("Testing parsedmarc", "plain"))
34       attachment = MIMEBase("application", "zip")
36       with open("${dmarcTestReport}", "rb") as report:
37           attachment.set_payload(report.read())
39       encoders.encode_base64(attachment)
41       attachment.add_header(
42           "Content-Disposition",
43           "attachment; filename= estadocuenta1.infonacot.gob.mx!example.com!1536853302!1536939702!2940.xml.zip",
44       )
46       message.attach(attachment)
47       text = message.as_string()
49       with smtplib.SMTP('localhost') as server:
50           server.sendmail(sender_email, receiver_email, text)
51           server.quit()
52     '';
55   localMail = makeTest
56     {
57       name = "parsedmarc-local-mail";
58       meta = with lib.maintainers; {
59         maintainers = [ talyz ];
60       };
62       nodes.parsedmarc =
63         { nodes, ... }:
64         {
65           virtualisation.memorySize = 2048;
67           services.postfix = {
68             enableSubmission = true;
69             enableSubmissions = true;
70             submissionsOptions = {
71               smtpd_sasl_auth_enable = "yes";
72               smtpd_client_restrictions = "permit";
73             };
74           };
76           services.parsedmarc = {
77             enable = true;
78             provision = {
79               geoIp = false;
80               localMail = {
81                 enable = true;
82                 hostname = "localhost";
83               };
84             };
85           };
87           services.elasticsearch.package = pkgs.elasticsearch-oss;
89           environment.systemPackages = [
90             (sendEmail "dmarc@localhost")
91             pkgs.jq
92           ];
93         };
95       testScript = { nodes }:
96         let
97           esPort = toString nodes.parsedmarc.config.services.elasticsearch.port;
98           valueObject = lib.optionalString (lib.versionAtLeast nodes.parsedmarc.config.services.elasticsearch.package.version "7") ".value";
99         in ''
100           parsedmarc.start()
101           parsedmarc.wait_for_unit("postfix.service")
102           parsedmarc.wait_for_unit("dovecot2.service")
103           parsedmarc.wait_for_unit("parsedmarc.service")
104           parsedmarc.wait_until_succeeds(
105               "curl -sS -f http://localhost:${esPort}"
106           )
108           parsedmarc.fail(
109               "curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940"
110               + " | tee /dev/console"
111               + " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'"
112           )
113           parsedmarc.succeed("send-email")
114           parsedmarc.wait_until_succeeds(
115               "curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940"
116               + " | tee /dev/console"
117               + " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'"
118           )
119         '';
120     };
122   externalMail =
123     let
124       certs = import ../common/acme/server/snakeoil-certs.nix;
125       mailDomain = certs.domain;
126       parsedmarcDomain = "parsedmarc.fake.domain";
127     in
128       makeTest {
129         name = "parsedmarc-external-mail";
130         meta = with lib.maintainers; {
131           maintainers = [ talyz ];
132         };
134         nodes = {
135           parsedmarc =
136             { nodes, ... }:
137             {
138               virtualisation.memorySize = 2048;
140               security.pki.certificateFiles = [
141                 certs.ca.cert
142               ];
144               networking.extraHosts = ''
145                 127.0.0.1 ${parsedmarcDomain}
146                 ${nodes.mail.config.networking.primaryIPAddress} ${mailDomain}
147               '';
149               services.parsedmarc = {
150                 enable = true;
151                 provision.geoIp = false;
152                 settings.imap = {
153                   host = mailDomain;
154                   port = 993;
155                   ssl = true;
156                   user = "alice";
157                   password = "${pkgs.writeText "imap-password" "foobar"}";
158                   watch = true;
159                 };
160               };
162               services.elasticsearch.package = pkgs.elasticsearch-oss;
164               environment.systemPackages = [
165                 pkgs.jq
166               ];
167             };
169           mail =
170             { nodes, ... }:
171             {
172               imports = [ ../common/user-account.nix ];
174               networking.extraHosts = ''
175                 127.0.0.1 ${mailDomain}
176                 ${nodes.parsedmarc.config.networking.primaryIPAddress} ${parsedmarcDomain}
177               '';
179               services.dovecot2 = {
180                 enable = true;
181                 protocols = [ "imap" ];
182                 sslCACert = "${certs.ca.cert}";
183                 sslServerCert = "${certs.${mailDomain}.cert}";
184                 sslServerKey = "${certs.${mailDomain}.key}";
185               };
187               services.postfix = {
188                 enable = true;
189                 origin = mailDomain;
190                 config = {
191                   myhostname = mailDomain;
192                   mydestination = mailDomain;
193                 };
194                 enableSubmission = true;
195                 enableSubmissions = true;
196                 submissionsOptions = {
197                   smtpd_sasl_auth_enable = "yes";
198                   smtpd_client_restrictions = "permit";
199                 };
200               };
201               environment.systemPackages = [ (sendEmail "alice@${mailDomain}") ];
203               networking.firewall.allowedTCPPorts = [ 993 ];
204             };
205         };
207         testScript = { nodes }:
208           let
209             esPort = toString nodes.parsedmarc.config.services.elasticsearch.port;
210             valueObject = lib.optionalString (lib.versionAtLeast nodes.parsedmarc.config.services.elasticsearch.package.version "7") ".value";
211           in ''
212             mail.start()
213             mail.wait_for_unit("postfix.service")
214             mail.wait_for_unit("dovecot2.service")
216             parsedmarc.start()
217             parsedmarc.wait_for_unit("parsedmarc.service")
218             parsedmarc.wait_until_succeeds(
219                 "curl -sS -f http://localhost:${esPort}"
220             )
222             parsedmarc.fail(
223                 "curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940"
224                 + " | tee /dev/console"
225                 + " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'"
226             )
227             mail.succeed("send-email")
228             parsedmarc.wait_until_succeeds(
229                 "curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940"
230                 + " | tee /dev/console"
231                 + " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'"
232             )
233           '';
234       };