1import ../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;
10
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 broken = true; # times out after spending many hours
36 };
37
38 nodes = {
39 homeserver = { pkgs, ... }: {
40 services.matrix-synapse = {
41 enable = true;
42 settings = {
43 database.name = "sqlite3";
44 tls_certificate_path = "${cert}";
45 tls_private_key_path = "${key}";
46 enable_registration = true;
47 enable_registration_without_verification = true;
48 registration_shared_secret = "supersecret-registration";
49
50 listeners = [ {
51 # The default but tls=false
52 bind_addresses = [
53 "0.0.0.0"
54 ];
55 port = 8448;
56 resources = [ {
57 compress = true;
58 names = [ "client" ];
59 } {
60 compress = false;
61 names = [ "federation" ];
62 } ];
63 tls = false;
64 type = "http";
65 x_forwarded = false;
66 } ];
67 };
68 };
69
70 networking.firewall.allowedTCPPorts = [ 8448 ];
71
72 environment.systemPackages = [
73 (pkgs.writeShellScriptBin "register_mjolnir_user" ''
74 exec ${pkgs.matrix-synapse}/bin/register_new_matrix_user \
75 -u mjolnir \
76 -p mjolnir-password \
77 --admin \
78 --shared-secret supersecret-registration \
79 http://localhost:8448
80 ''
81 )
82 (pkgs.writeShellScriptBin "register_moderator_user" ''
83 exec ${pkgs.matrix-synapse}/bin/register_new_matrix_user \
84 -u moderator \
85 -p moderator-password \
86 --no-admin \
87 --shared-secret supersecret-registration \
88 http://localhost:8448
89 ''
90 )
91 ];
92 };
93
94 mjolnir = { pkgs, ... }: {
95 services.mjolnir = {
96 enable = true;
97 homeserverUrl = "http://homeserver:8448";
98 pantalaimon = {
99 enable = true;
100 username = "mjolnir";
101 passwordFile = pkgs.writeText "password.txt" "mjolnir-password";
102 };
103 managementRoom = "#moderators:homeserver";
104 };
105 };
106
107 client = { pkgs, ... }: {
108 environment.systemPackages = [
109 (pkgs.writers.writePython3Bin "create_management_room_and_invite_mjolnir"
110 { libraries = [ pkgs.python3Packages.matrix-nio ]; } ''
111 import asyncio
112
113 from nio import (
114 AsyncClient,
115 EnableEncryptionBuilder
116 )
117
118
119 async def main() -> None:
120 client = AsyncClient("http://homeserver:8448", "moderator")
121
122 await client.login("moderator-password")
123
124 room = await client.room_create(
125 name="Moderators",
126 alias="moderators",
127 initial_state=[EnableEncryptionBuilder().as_dict()],
128 )
129
130 await client.join(room.room_id)
131 await client.room_invite(room.room_id, "@mjolnir:homeserver")
132
133 asyncio.run(main())
134 ''
135 )
136 ];
137 };
138 };
139
140 testScript = ''
141 with subtest("start homeserver"):
142 homeserver.start()
143
144 homeserver.wait_for_unit("matrix-synapse.service")
145 homeserver.wait_until_succeeds("curl --fail -L http://localhost:8448/")
146
147 with subtest("register users"):
148 # register mjolnir user
149 homeserver.succeed("register_mjolnir_user")
150 # register moderator user
151 homeserver.succeed("register_moderator_user")
152
153 with subtest("start mjolnir"):
154 mjolnir.start()
155
156 # wait for pantalaimon to be ready
157 mjolnir.wait_for_unit("pantalaimon-mjolnir.service")
158 mjolnir.wait_for_unit("mjolnir.service")
159
160 mjolnir.wait_until_succeeds("curl --fail -L http://localhost:8009/")
161
162 with subtest("ensure mjolnir can be invited to the management room"):
163 client.start()
164
165 client.wait_until_succeeds("curl --fail -L http://homeserver:8448/")
166
167 client.succeed("create_management_room_and_invite_mjolnir")
168
169 mjolnir.wait_for_console_text("Startup complete. Now monitoring rooms")
170 '';
171 }
172)