python312Packages.dissect-extfs: 3.11 -> 3.12
[NixPkgs.git] / nixos / tests / pleroma.nix
blob8a765c9193291a7015c5169a71b0eb4310c4f38e
1 /*
2   Pleroma E2E VM test.
4   Abstract:
5   =========
6   Using pleroma, postgresql, a local CA cert, a nginx reverse proxy
7   and a toot-based client, we're going to:
9   1. Provision a pleroma service from scratch (pleroma config + postgres db).
10   2. Create a "jamy" admin user.
11   3. Send a toot from this user.
12   4. Send a upload from this user.
13   5. Check the toot is part of the server public timeline
15   Notes:
16   - We need a fully functional TLS setup without having any access to
17     the internet. We do that by issuing a self-signed cert, add this
18     self-cert to the hosts pki trust store and finally spoof the
19     hostnames using /etc/hosts.
20   - For this NixOS test, we *had* to store some DB-related and
21     pleroma-related secrets to the store. Keep in mind the store is
22     world-readable, it's the worst place possible to store *any*
23     secret. **DO NOT DO THIS IN A REAL WORLD DEPLOYMENT**.
26 import ./make-test-python.nix ({ pkgs, ... }:
27   let
28   send-toot = pkgs.writeScriptBin "send-toot" ''
29     set -eux
30     # toot is using the requests library internally. This library
31     # sadly embed its own certificate store instead of relying on the
32     # system one. Overriding this pretty bad default behaviour.
33     export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
35     toot login_cli -i "pleroma.nixos.test" -e "jamy@nixos.test" -p 'jamy-password'
36     echo "Login OK"
38     # Send a toot then verify it's part of the public timeline
39     toot post "hello world Jamy here"
40     echo "Send toot OK"
41     toot timeline -1 | grep -F -q "hello world Jamy here"
42     echo "Get toot from timeline OK"
44     # Test file upload
45     echo "y" | ${pkgs.toot}/bin/toot upload <(dd if=/dev/zero bs=1024 count=1024 status=none) \
46       | grep -F -q "https://pleroma.nixos.test/media"
48     echo "====================================================="
49     echo "=                   SUCCESS                         ="
50     echo "=                                                   ="
51     echo "=    We were able to sent a toot + a upload and     ="
52     echo "=   retrieve both of them in the public timeline.   ="
53     echo "====================================================="
54   '';
56   provision-db = pkgs.writeScriptBin "provision-db" ''
57     set -eux
58     sudo -u postgres psql -f ${db-seed}
59   '';
61   test-db-passwd = "SccZOvTGM//BMrpoQj68JJkjDkMGb4pHv2cECWiI+XhVe3uGJTLI0vFV/gDlZ5jJ";
63   /* For this NixOS test, we *had* to store this secret to the store.
64     Keep in mind the store is world-readable, it's the worst place
65     possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
66     DEPLOYMENT**.*/
67   db-seed = pkgs.writeText "provision.psql" ''
68     CREATE USER pleroma WITH ENCRYPTED PASSWORD '${test-db-passwd}';
69     CREATE DATABASE pleroma OWNER pleroma;
70     \c pleroma;
71     --Extensions made by ecto.migrate that need superuser access
72     CREATE EXTENSION IF NOT EXISTS citext;
73     CREATE EXTENSION IF NOT EXISTS pg_trgm;
74     CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
75   '';
77   pleroma-conf = ''
78     import Config
80     config :pleroma, Pleroma.Web.Endpoint,
81        url: [host: "pleroma.nixos.test", scheme: "https", port: 443],
82        http: [ip: {127, 0, 0, 1}, port: 4000]
84     config :pleroma, :instance,
85       name: "NixOS test pleroma server",
86       email: "pleroma@nixos.test",
87       notify_email: "pleroma@nixos.test",
88       limit: 5000,
89       registrations_open: true
91     config :pleroma, :media_proxy,
92       enabled: false,
93       redirect_on_failure: true
94       #base_url: "https://cache.pleroma.social"
96     config :pleroma, Pleroma.Repo,
97       adapter: Ecto.Adapters.Postgres,
98       username: "pleroma",
99       password: "${test-db-passwd}",
100       database: "pleroma",
101       hostname: "localhost",
102       pool_size: 10,
103       prepare: :named,
104       parameters: [
105         plan_cache_mode: "force_custom_plan"
106       ]
108     config :pleroma, :database, rum_enabled: false
109     config :pleroma, :instance, static_dir: "/var/lib/pleroma/static"
110     config :pleroma, Pleroma.Uploaders.Local, uploads: "/var/lib/pleroma/uploads"
111     config :pleroma, configurable_from_database: false
112   '';
114   /* For this NixOS test, we *had* to store this secret to the store.
115     Keep in mind the store is world-readable, it's the worst place
116     possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
117     DEPLOYMENT**.
118     In a real-word deployment, you'd handle this either by:
119     - manually upload your pleroma secrets to /var/lib/pleroma/secrets.exs
120     - use a deployment tool such as morph or NixOps to deploy your secrets.
121   */
122   pleroma-conf-secret = pkgs.writeText "secrets.exs" ''
123     import Config
125     config :joken, default_signer: "PS69/wMW7X6FIQPABt9lwvlZvgrJIncfiAMrK9J5mjVus/7/NJJi1DsDA1OghBE5"
127     config :pleroma, Pleroma.Web.Endpoint,
128        secret_key_base: "NvfmU7lYaQrmmxt4NACm0AaAfN9t6WxsrX0NCB4awkGHvr1S7jyshlEmrjaPFhhq",
129        signing_salt: "3L41+BuJ"
131     config :web_push_encryption, :vapid_details,
132       subject: "mailto:pleroma@nixos.test",
133       public_key: "BKjfNX9-UqAcncaNqERQtF7n9pKrB0-MO-juv6U5E5XQr_Tg5D-f8AlRjduAguDpyAngeDzG8MdrTejMSL4VF30",
134       private_key: "k7o9onKMQrgMjMb6l4fsxSaXO0BTNAer5MVSje3q60k"
135   '';
137   /* For this NixOS test, we *had* to store this secret to the store.
138     Keep in mind the store is world-readable, it's the worst place
139     possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
140     DEPLOYMENT**.
141     In a real-word deployment, you'd handle this either by:
142     - manually upload your pleroma secrets to /var/lib/pleroma/secrets.exs
143     - use a deployment tool such as morph or NixOps to deploy your secrets.
144     */
145   provision-secrets = pkgs.writeScriptBin "provision-secrets" ''
146     set -eux
147     cp "${pleroma-conf-secret}" "/var/lib/pleroma/secrets.exs"
148     chown pleroma:pleroma /var/lib/pleroma/secrets.exs
149   '';
151   /* For this NixOS test, we *had* to store this secret to the store.
152     Keep in mind the store is world-readable, it's the worst place
153     possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
154     DEPLOYMENT**.
155   */
156   provision-user = pkgs.writeScriptBin "provision-user" ''
157     set -eux
159     # Waiting for pleroma to be up.
160     timeout 5m bash -c 'while [[ "$(curl -s -o /dev/null -w '%{http_code}' https://pleroma.nixos.test/api/v1/instance)" != "200" ]]; do sleep 2; done'
161     # Toremove the RELEASE_COOKIE bit when https://github.com/NixOS/nixpkgs/issues/166229 gets fixed.
162     RELEASE_COOKIE="/var/lib/pleroma/.cookie" \
163       pleroma_ctl user new jamy jamy@nixos.test --password 'jamy-password' --moderator --admin -y
164   '';
166   tls-cert = pkgs.runCommand "selfSignedCerts" { buildInputs = [ pkgs.openssl ]; } ''
167     mkdir -p $out
168     openssl req -x509 \
169       -subj '/CN=pleroma.nixos.test/' -days 49710 \
170       -addext 'subjectAltName = DNS:pleroma.nixos.test' \
171       -keyout "$out/key.pem" -newkey ed25519 \
172       -out "$out/cert.pem" -noenc
173   '';
175   hosts = nodes: ''
176     ${nodes.pleroma.networking.primaryIPAddress} pleroma.nixos.test
177     ${nodes.client.networking.primaryIPAddress} client.nixos.test
178   '';
179   in {
180   name = "pleroma";
181   nodes = {
182     client = { nodes, pkgs, config, ... }: {
183       security.pki.certificateFiles = [ "${tls-cert}/cert.pem" ];
184       networking.extraHosts = hosts nodes;
185       environment.systemPackages = [
186         pkgs.toot
187         send-toot
188       ];
189     };
190     pleroma = { nodes, pkgs, config, ... }: {
191       security.pki.certificateFiles = [ "${tls-cert}/cert.pem" ];
192       networking.extraHosts = hosts nodes;
193       networking.firewall.enable = false;
194       environment.systemPackages = [
195         provision-db
196         provision-secrets
197         provision-user
198       ];
199       services = {
200         pleroma = {
201           enable = true;
202           configs = [
203             pleroma-conf
204           ];
205         };
206         postgresql = {
207           enable = true;
208           package = pkgs.postgresql_13;
209         };
210         nginx = {
211           enable = true;
212           virtualHosts."pleroma.nixos.test" = {
213             addSSL = true;
214             sslCertificate = "${tls-cert}/cert.pem";
215             sslCertificateKey = "${tls-cert}/key.pem";
216             locations."/" = {
217               proxyPass = "http://127.0.0.1:4000";
218               extraConfig = ''
219                 add_header 'Access-Control-Allow-Origin' '*' always;
220                 add_header 'Access-Control-Allow-Methods' 'POST, PUT, DELETE, GET, PATCH, OPTIONS' always;
221                 add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Idempotency-Key' always;
222                 add_header 'Access-Control-Expose-Headers' 'Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id' always;
223                 if ($request_method = OPTIONS) {
224                     return 204;
225                 }
226                 add_header X-XSS-Protection "1; mode=block";
227                 add_header X-Permitted-Cross-Domain-Policies none;
228                 add_header X-Frame-Options DENY;
229                 add_header X-Content-Type-Options nosniff;
230                 add_header Referrer-Policy same-origin;
231                 add_header X-Download-Options noopen;
232                 proxy_http_version 1.1;
233                 proxy_set_header Upgrade $http_upgrade;
234                 proxy_set_header Connection "upgrade";
235                 proxy_set_header Host $host;
236                 client_max_body_size 16m;
237               '';
238             };
239           };
240         };
241       };
242     };
243   };
245   testScript = { nodes, ... }: ''
246     pleroma.wait_for_unit("postgresql.service")
247     pleroma.wait_until_succeeds("ls /var/lib/pleroma")
248     pleroma.succeed("provision-db")
249     pleroma.wait_for_file("/var/lib/pleroma")
250     pleroma.succeed("provision-secrets")
251     pleroma.systemctl("restart pleroma.service")
252     pleroma.wait_for_unit("pleroma.service")
253     pleroma.succeed("provision-user")
254     client.succeed("send-toot")
255   '';
257   meta.timeout = 600;