about summary refs log tree commit diff
path: root/nixos/tests/stalwart-mail.nix
blob: 581090cd70f4858903d2c9d74928296b073413b1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# Rudimentary test checking that the Stalwart email server can:
# - receive some message through SMTP submission, then
# - serve this message through IMAP.

let
  certs = import ./common/acme/server/snakeoil-certs.nix;
  domain = certs.domain;

in import ./make-test-python.nix ({ lib, ... }: {
  name = "stalwart-mail";

  nodes.main = { pkgs, ... }: {
    security.pki.certificateFiles = [ certs.ca.cert ];

    services.stalwart-mail = {
      enable = true;
      settings = {
        server.hostname = domain;

        certificate."snakeoil" = {
          cert = "file://${certs.${domain}.cert}";
          private-key = "file://${certs.${domain}.key}";
        };

        server.tls = {
          certificate = "snakeoil";
          enable = true;
          implicit = false;
        };

        server.listener = {
          "smtp-submission" = {
            bind = [ "[::]:587" ];
            protocol = "smtp";
          };

          "imap" = {
            bind = [ "[::]:143" ];
            protocol = "imap";
          };
        };

        resolver.public-suffix = [ ];  # do not fetch from web in sandbox

        session.auth.mechanisms = "[plain]";
        session.auth.directory = "'in-memory'";
        storage.directory = "in-memory";

        session.rcpt.directory = "'in-memory'";
        queue.outbound.next-hop = "'local'";

        directory."in-memory" = {
          type = "memory";
          principals = [
            {
              type = "individual";
              name = "alice";
              secret = "foobar";
              email = [ "alice@${domain}" ];
            }
            {
              type = "individual";
              name = "bob";
              secret = "foobar";
              email = [ "bob@${domain}" ];
            }
          ];
        };
      };
    };

    environment.systemPackages = [
      (pkgs.writers.writePython3Bin "test-smtp-submission" { } ''
        from smtplib import SMTP

        with SMTP('localhost', 587) as smtp:
            smtp.starttls()
            smtp.login('alice', 'foobar')
            smtp.sendmail(
                'alice@${domain}',
                'bob@${domain}',
                """
                    From: alice@${domain}
                    To: bob@${domain}
                    Subject: Some test message

                    This is a test message.
                """.strip()
            )
      '')

      (pkgs.writers.writePython3Bin "test-imap-read" { } ''
        from imaplib import IMAP4

        with IMAP4('localhost') as imap:
            imap.starttls()
            status, [caps] = imap.login('bob', 'foobar')
            assert status == 'OK'
            imap.select()
            status, [ref] = imap.search(None, 'ALL')
            assert status == 'OK'
            [msgId] = ref.split()
            status, msg = imap.fetch(msgId, 'BODY[TEXT]')
            assert status == 'OK'
            assert msg[0][1].strip() == b'This is a test message.'
      '')
    ];
  };

  testScript = /* python */ ''
    main.wait_for_unit("stalwart-mail.service")
    main.wait_for_open_port(587)
    main.wait_for_open_port(143)

    main.succeed("test-smtp-submission")
    main.succeed("test-imap-read")
  '';

  meta = {
    maintainers = with lib.maintainers; [ happysalada pacien ];
  };
})