python312Packages.millheater: 0.11.8 -> 0.12.0
[NixPkgs.git] / nixos / tests / matrix / synapse.nix
blob8c10a575ffbd304fd5eee2979ca1bb18be6816d2
1 import ../make-test-python.nix ({ pkgs, ... } : let
3   ca_key = mailerCerts.ca.key;
4   ca_pem = mailerCerts.ca.cert;
6   bundle = pkgs.runCommand "bundle" {
7     nativeBuildInputs = [ pkgs.minica ];
8   } ''
9     minica -ca-cert ${ca_pem} -ca-key ${ca_key} \
10       -domains localhost
11     install -Dm444 -t $out localhost/{key,cert}.pem
12   '';
14   mailerCerts = import ../common/acme/server/snakeoil-certs.nix;
15   mailerDomain = mailerCerts.domain;
16   registrationSharedSecret = "unsecure123";
17   testUser = "alice";
18   testPassword = "alicealice";
19   testEmail = "alice@example.com";
21   listeners = [ {
22     port = 8448;
23     bind_addresses = [
24       "127.0.0.1"
25       "::1"
26     ];
27     type = "http";
28     tls = true;
29     x_forwarded = false;
30     resources = [ {
31       names = [
32         "client"
33       ];
34       compress = true;
35     } {
36       names = [
37         "federation"
38       ];
39       compress = false;
40     } ];
41   } ];
43 in {
45   name = "matrix-synapse";
46   meta = with pkgs.lib; {
47     maintainers = teams.matrix.members;
48   };
50   nodes = {
51     # Since 0.33.0, matrix-synapse doesn't allow underscores in server names
52     serverpostgres = { pkgs, nodes, config, ... }: let
53       mailserverIP = nodes.mailserver.config.networking.primaryIPAddress;
54     in
55     {
56       services.matrix-synapse = {
57         enable = true;
58         settings = {
59           inherit listeners;
60           database = {
61             name = "psycopg2";
62             args.password = "synapse";
63           };
64           redis = {
65             enabled = true;
66             host = "localhost";
67             port = config.services.redis.servers.matrix-synapse.port;
68           };
69           tls_certificate_path = "${bundle}/cert.pem";
70           tls_private_key_path = "${bundle}/key.pem";
71           registration_shared_secret = registrationSharedSecret;
72           public_baseurl = "https://example.com";
73           email = {
74             smtp_host = mailerDomain;
75             smtp_port = 25;
76             require_transport_security = true;
77             notif_from = "matrix <matrix@${mailerDomain}>";
78             app_name = "Matrix";
79           };
80         };
81       };
82       services.postgresql = {
83         enable = true;
85         # The database name and user are configured by the following options:
86         #   - services.matrix-synapse.database_name
87         #   - services.matrix-synapse.database_user
88         #
89         # The values used here represent the default values of the module.
90         initialScript = pkgs.writeText "synapse-init.sql" ''
91           CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
92           CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
93             TEMPLATE template0
94             LC_COLLATE = "C"
95             LC_CTYPE = "C";
96         '';
97       };
99       services.redis.servers.matrix-synapse = {
100         enable = true;
101         port = 6380;
102       };
104       networking.extraHosts = ''
105         ${mailserverIP} ${mailerDomain}
106       '';
108       security.pki.certificateFiles = [
109         mailerCerts.ca.cert ca_pem
110       ];
112       environment.systemPackages = let
113         sendTestMailStarttls = pkgs.writeScriptBin "send-testmail-starttls" ''
114           #!${pkgs.python3.interpreter}
115           import smtplib
116           import ssl
118           ctx = ssl.create_default_context()
120           with smtplib.SMTP('${mailerDomain}') as smtp:
121             smtp.ehlo()
122             smtp.starttls(context=ctx)
123             smtp.ehlo()
124             smtp.sendmail('matrix@${mailerDomain}', '${testEmail}', 'Subject: Test STARTTLS\n\nTest data.')
125             smtp.quit()
126          '';
128         obtainTokenAndRegisterEmail = let
129           # adding the email through the API is quite complicated as it involves more than one step and some
130           # client-side calculation
131           insertEmailForAlice = pkgs.writeText "alice-email.sql" ''
132             INSERT INTO user_threepids (user_id, medium, address, validated_at, added_at) VALUES ('${testUser}@serverpostgres', 'email', '${testEmail}', '1629149927271', '1629149927270');
133           '';
134         in
135         pkgs.writeScriptBin "obtain-token-and-register-email" ''
136           #!${pkgs.runtimeShell}
137           set -o errexit
138           set -o pipefail
139           set -o nounset
140           su postgres -c "psql -d matrix-synapse -f ${insertEmailForAlice}"
141           curl --fail -XPOST 'https://localhost:8448/_matrix/client/r0/account/password/email/requestToken' -d '{"email":"${testEmail}","client_secret":"foobar","send_attempt":1}' -v
142         '';
143         in [ sendTestMailStarttls pkgs.matrix-synapse obtainTokenAndRegisterEmail ];
144     };
146     # test mail delivery
147     mailserver = args: let
148     in
149     {
150       security.pki.certificateFiles = [
151         mailerCerts.ca.cert
152       ];
154       networking.firewall.enable = false;
156       services.postfix = {
157         enable = true;
158         hostname = "${mailerDomain}";
159         # open relay for subnet
160         networksStyle = "subnet";
161         enableSubmission = true;
162         tlsTrustedAuthorities = "${mailerCerts.ca.cert}";
163         sslCert = "${mailerCerts.${mailerDomain}.cert}";
164         sslKey = "${mailerCerts.${mailerDomain}.key}";
166         # blackhole transport
167         transport = "example.com discard:silently";
169         config = {
170           debug_peer_level = "10";
171           smtpd_relay_restrictions = [
172             "permit_mynetworks" "reject_unauth_destination"
173           ];
175           # disable obsolete protocols, something old versions of twisted are still using
176           smtpd_tls_protocols = "TLSv1.3, TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3";
177           smtp_tls_protocols = "TLSv1.3, TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3";
178           smtpd_tls_mandatory_protocols = "TLSv1.3, TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3";
179           smtp_tls_mandatory_protocols = "TLSv1.3, TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3";
180         };
181       };
182     };
184     serversqlite = args: {
185       services.matrix-synapse = {
186         enable = true;
187         settings = {
188           inherit listeners;
189           database.name = "sqlite3";
190           tls_certificate_path = "${bundle}/cert.pem";
191           tls_private_key_path = "${bundle}/key.pem";
192         };
193       };
194     };
195   };
197   testScript = ''
198     start_all()
199     mailserver.wait_for_unit("postfix.service")
200     serverpostgres.succeed("send-testmail-starttls")
201     serverpostgres.wait_for_unit("matrix-synapse.service")
202     serverpostgres.wait_until_succeeds(
203         "curl --fail -L --cacert ${ca_pem} https://localhost:8448/"
204     )
205     serverpostgres.wait_until_succeeds(
206         "journalctl -u matrix-synapse.service | grep -q 'Connected to redis'"
207     )
208     serverpostgres.require_unit_state("postgresql.service")
209     serverpostgres.succeed("REQUESTS_CA_BUNDLE=${ca_pem} register_new_matrix_user -u ${testUser} -p ${testPassword} -a -k ${registrationSharedSecret} https://localhost:8448/")
210     serverpostgres.succeed("obtain-token-and-register-email")
211     serversqlite.wait_for_unit("matrix-synapse.service")
212     serversqlite.wait_until_succeeds(
213         "curl --fail -L --cacert ${ca_pem} https://localhost:8448/"
214     )
215     serversqlite.succeed("[ -e /var/lib/matrix-synapse/homeserver.db ]")
216   '';