python312Packages.millheater: 0.11.8 -> 0.12.0
[NixPkgs.git] / nixos / tests / matrix / mjolnir.nix
blob265b13821ebd836223bbf32012e7f291afbfe02b
1 import ../make-test-python.nix (
2   { pkgs, ... }:
3   let
4     # Set up SSL certs for Synapse to be happy.
5     runWithOpenSSL = file: cmd: pkgs.runCommand file
6       {
7         buildInputs = [ pkgs.openssl ];
8       }
9       cmd;
11     ca_key = runWithOpenSSL "ca-key.pem" "openssl genrsa -out $out 2048";
12     ca_pem = runWithOpenSSL "ca.pem" ''
13       openssl req \
14         -x509 -new -nodes -key ${ca_key} \
15         -days 10000 -out $out -subj "/CN=snakeoil-ca"
16     '';
17     key = runWithOpenSSL "matrix_key.pem" "openssl genrsa -out $out 2048";
18     csr = runWithOpenSSL "matrix.csr" ''
19       openssl req \
20          -new -key ${key} \
21          -out $out -subj "/CN=localhost" \
22     '';
23     cert = runWithOpenSSL "matrix_cert.pem" ''
24       openssl x509 \
25         -req -in ${csr} \
26         -CA ${ca_pem} -CAkey ${ca_key} \
27         -CAcreateserial -out $out \
28         -days 365
29     '';
30   in
31   {
32     name = "mjolnir";
33     meta = with pkgs.lib; {
34       maintainers = teams.matrix.members;
35     };
37     nodes = {
38       homeserver = { pkgs, ... }: {
39         services.matrix-synapse = {
40           enable = true;
41           settings = {
42             database.name = "sqlite3";
43             tls_certificate_path = "${cert}";
44             tls_private_key_path = "${key}";
45             enable_registration = true;
46             enable_registration_without_verification = true;
47             registration_shared_secret = "supersecret-registration";
49             listeners = [ {
50               # The default but tls=false
51               bind_addresses = [
52                 "0.0.0.0"
53               ];
54               port = 8448;
55               resources = [ {
56                 compress = true;
57                 names = [ "client" ];
58               } {
59                 compress = false;
60                 names = [ "federation" ];
61               } ];
62               tls = false;
63               type = "http";
64               x_forwarded = false;
65             } ];
66           };
67         };
69         networking.firewall.allowedTCPPorts = [ 8448 ];
71         environment.systemPackages = [
72           (pkgs.writeShellScriptBin "register_mjolnir_user" ''
73             exec ${pkgs.matrix-synapse}/bin/register_new_matrix_user \
74               -u mjolnir \
75               -p mjolnir-password \
76               --admin \
77               --shared-secret supersecret-registration \
78               http://localhost:8448
79           ''
80           )
81           (pkgs.writeShellScriptBin "register_moderator_user" ''
82             exec ${pkgs.matrix-synapse}/bin/register_new_matrix_user \
83               -u moderator \
84               -p moderator-password \
85               --no-admin \
86               --shared-secret supersecret-registration \
87               http://localhost:8448
88           ''
89           )
90         ];
91       };
93       mjolnir = { pkgs, ... }: {
94         services.mjolnir = {
95           enable = true;
96           homeserverUrl = "http://homeserver:8448";
97           pantalaimon = {
98             enable = true;
99             username = "mjolnir";
100             passwordFile = pkgs.writeText "password.txt" "mjolnir-password";
101             # otherwise mjolnir tries to connect to ::1, which is not listened by pantalaimon
102             options.listenAddress = "127.0.0.1";
103           };
104           managementRoom = "#moderators:homeserver";
105         };
106       };
108       client = { pkgs, ... }: {
109         environment.systemPackages = [
110           (pkgs.writers.writePython3Bin "create_management_room_and_invite_mjolnir"
111             { libraries = with pkgs.python3Packages; [
112                 (matrix-nio.override { withOlm = true; })
113               ];
114             } ''
115             import asyncio
117             from nio import (
118                 AsyncClient,
119                 EnableEncryptionBuilder
120             )
123             async def main() -> None:
124                 client = AsyncClient("http://homeserver:8448", "moderator")
126                 await client.login("moderator-password")
128                 room = await client.room_create(
129                     name="Moderators",
130                     alias="moderators",
131                     initial_state=[EnableEncryptionBuilder().as_dict()],
132                 )
134                 await client.join(room.room_id)
135                 await client.room_invite(room.room_id, "@mjolnir:homeserver")
137             asyncio.run(main())
138           ''
139           )
140         ];
141       };
142     };
144     testScript = ''
145       with subtest("start homeserver"):
146         homeserver.start()
148         homeserver.wait_for_unit("matrix-synapse.service")
149         homeserver.wait_until_succeeds("curl --fail -L http://localhost:8448/")
151       with subtest("register users"):
152         # register mjolnir user
153         homeserver.succeed("register_mjolnir_user")
154         # register moderator user
155         homeserver.succeed("register_moderator_user")
157       with subtest("start mjolnir"):
158         mjolnir.start()
160         # wait for pantalaimon to be ready
161         mjolnir.wait_for_unit("pantalaimon-mjolnir.service")
162         mjolnir.wait_for_unit("mjolnir.service")
164         mjolnir.wait_until_succeeds("curl --fail -L http://localhost:8009/")
166       with subtest("ensure mjolnir can be invited to the management room"):
167         client.start()
169         client.wait_until_succeeds("curl --fail -L http://homeserver:8448/")
171         client.succeed("create_management_room_and_invite_mjolnir")
173         mjolnir.wait_for_console_text("Startup complete. Now monitoring rooms")
174     '';
175   }