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