1import ../make-test-python.nix ({pkgs, ...}:
2let
3 test-certificates = pkgs.runCommandLocal "test-certificates" { } ''
4 mkdir -p $out
5 echo insecure-root-password > $out/root-password-file
6 echo insecure-intermediate-password > $out/intermediate-password-file
7 ${pkgs.step-cli}/bin/step certificate create "Example Root CA" $out/root_ca.crt $out/root_ca.key --password-file=$out/root-password-file --profile root-ca
8 ${pkgs.step-cli}/bin/step certificate create "Example Intermediate CA 1" $out/intermediate_ca.crt $out/intermediate_ca.key --password-file=$out/intermediate-password-file --ca-password-file=$out/root-password-file --profile intermediate-ca --ca $out/root_ca.crt --ca-key $out/root_ca.key
9 '';
10
11 hosts = ''
12 192.168.2.10 ca.local
13 192.168.2.11 mastodon.local
14 '';
15
16in
17{
18 name = "mastodon";
19 meta.maintainers = with pkgs.lib.maintainers; [ erictapen izorkin turion ];
20
21 nodes = {
22 ca = { pkgs, ... }: {
23 networking = {
24 interfaces.eth1 = {
25 ipv4.addresses = [
26 { address = "192.168.2.10"; prefixLength = 24; }
27 ];
28 };
29 extraHosts = hosts;
30 };
31 services.step-ca = {
32 enable = true;
33 address = "0.0.0.0";
34 port = 8443;
35 openFirewall = true;
36 intermediatePasswordFile = "${test-certificates}/intermediate-password-file";
37 settings = {
38 dnsNames = [ "ca.local" ];
39 root = "${test-certificates}/root_ca.crt";
40 crt = "${test-certificates}/intermediate_ca.crt";
41 key = "${test-certificates}/intermediate_ca.key";
42 db = {
43 type = "badger";
44 dataSource = "/var/lib/step-ca/db";
45 };
46 authority = {
47 provisioners = [
48 {
49 type = "ACME";
50 name = "acme";
51 }
52 ];
53 };
54 };
55 };
56 };
57
58 server = { pkgs, ... }: {
59
60 virtualisation.memorySize = 2048;
61
62 networking = {
63 interfaces.eth1 = {
64 ipv4.addresses = [
65 { address = "192.168.2.11"; prefixLength = 24; }
66 ];
67 };
68 extraHosts = hosts;
69 firewall.allowedTCPPorts = [ 80 443 ];
70 };
71
72 security = {
73 acme = {
74 acceptTerms = true;
75 defaults.server = "https://ca.local:8443/acme/acme/directory";
76 defaults.email = "mastodon@mastodon.local";
77 };
78 pki.certificateFiles = [ "${test-certificates}/root_ca.crt" ];
79 };
80
81 services.redis.servers.mastodon = {
82 enable = true;
83 bind = "127.0.0.1";
84 port = 31637;
85 };
86
87 services.mastodon = {
88 enable = true;
89 configureNginx = true;
90 localDomain = "mastodon.local";
91 enableUnixSocket = false;
92 redis = {
93 createLocally = true;
94 host = "127.0.0.1";
95 port = 31637;
96 };
97 database = {
98 createLocally = true;
99 host = "/run/postgresql";
100 port = 5432;
101 };
102 smtp = {
103 createLocally = false;
104 fromAddress = "mastodon@mastodon.local";
105 };
106 extraConfig = {
107 EMAIL_DOMAIN_ALLOWLIST = "example.com";
108 };
109 };
110 };
111
112 client = { pkgs, ... }: {
113 environment.systemPackages = [ pkgs.jq ];
114 networking = {
115 interfaces.eth1 = {
116 ipv4.addresses = [
117 { address = "192.168.2.12"; prefixLength = 24; }
118 ];
119 };
120 extraHosts = hosts;
121 };
122
123 security = {
124 pki.certificateFiles = [ "${test-certificates}/root_ca.crt" ];
125 };
126 };
127 };
128
129 testScript = ''
130 start_all()
131
132 ca.wait_for_unit("step-ca.service")
133 ca.wait_for_open_port(8443)
134
135 # Check that mastodon-media-auto-remove is scheduled
136 server.succeed("systemctl status mastodon-media-auto-remove.timer")
137
138 server.wait_for_unit("nginx.service")
139 server.wait_for_unit("redis-mastodon.service")
140 server.wait_for_unit("postgresql.service")
141 server.wait_for_unit("mastodon-sidekiq.service")
142 server.wait_for_unit("mastodon-streaming.service")
143 server.wait_for_unit("mastodon-web.service")
144 server.wait_for_open_port(55000)
145 server.wait_for_open_port(55001)
146
147 # Check Mastodon version from remote client
148 client.succeed("curl --fail https://mastodon.local/api/v1/instance | jq -r '.version' | grep '${pkgs.mastodon.version}'")
149
150 # Check using admin CLI
151 # Check Mastodon version
152 server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl version' | grep '${pkgs.mastodon.version}'")
153
154 # Manage accounts
155 server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl email_domain_blocks add example.com'")
156 server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl email_domain_blocks list' | grep 'example.com'")
157 server.fail("su - mastodon -s /bin/sh -c 'mastodon-env tootctl email_domain_blocks list' | grep 'mastodon.local'")
158 server.fail("su - mastodon -s /bin/sh -c 'mastodon-env tootctl accounts create alice --email=alice@example.com'")
159 server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl email_domain_blocks remove example.com'")
160 server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl accounts create bob --email=bob@example.com'")
161 server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl accounts approve bob'")
162 server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl accounts delete bob'")
163
164 # Manage IP access
165 server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl ip_blocks add 192.168.0.0/16 --severity=no_access'")
166 server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl ip_blocks export' | grep '192.168.0.0/16'")
167 server.fail("su - mastodon -s /bin/sh -c 'mastodon-env tootctl p_blocks export' | grep '172.16.0.0/16'")
168 client.fail("curl --fail https://mastodon.local/about")
169 server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl ip_blocks remove 192.168.0.0/16'")
170 client.succeed("curl --fail https://mastodon.local/about")
171
172 ca.shutdown()
173 server.shutdown()
174 client.shutdown()
175 '';
176})