···
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
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, ... }:
28
+
send-toot = pkgs.writeScriptBin "send-toot" ''
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
+
export TOOT_LOGIN_CLI_PASSWORD="jamy-password"
36
+
toot login_cli -i "pleroma.nixos.test" -e "jamy@nixos.test"
39
+
# Send a toot then verify it's part of the public timeline
40
+
echo "y" | toot post "hello world Jamy here"
42
+
echo "y" | toot timeline | grep -c "hello world Jamy here"
43
+
echo "Get toot from timeline OK"
46
+
echo "y" | toot upload ${db-seed} | grep -c "https://pleroma.nixos.test/media"
47
+
echo "File upload OK"
49
+
echo "====================================================="
52
+
echo "= We were able to sent a toot + a upload and ="
53
+
echo "= retrieve both of them in the public timeline. ="
54
+
echo "====================================================="
57
+
provision-db = pkgs.writeScriptBin "provision-db" ''
59
+
sudo -u postgres psql -f ${db-seed}
62
+
test-db-passwd = "SccZOvTGM//BMrpoQj68JJkjDkMGb4pHv2cECWiI+XhVe3uGJTLI0vFV/gDlZ5jJ";
64
+
/* For this NixOS test, we *had* to store this secret to the store.
65
+
Keep in mind the store is world-readable, it's the worst place
66
+
possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
68
+
db-seed = pkgs.writeText "provision.psql" ''
69
+
CREATE USER pleroma WITH ENCRYPTED PASSWORD '${test-db-passwd}';
70
+
CREATE DATABASE pleroma OWNER pleroma;
72
+
--Extensions made by ecto.migrate that need superuser access
73
+
CREATE EXTENSION IF NOT EXISTS citext;
74
+
CREATE EXTENSION IF NOT EXISTS pg_trgm;
75
+
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
81
+
config :pleroma, Pleroma.Web.Endpoint,
82
+
url: [host: "pleroma.nixos.test", scheme: "https", port: 443],
83
+
http: [ip: {127, 0, 0, 1}, port: 4000]
85
+
config :pleroma, :instance,
86
+
name: "NixOS test pleroma server",
87
+
email: "pleroma@nixos.test",
88
+
notify_email: "pleroma@nixos.test",
90
+
registrations_open: true
92
+
config :pleroma, :media_proxy,
94
+
redirect_on_failure: true
95
+
#base_url: "https://cache.pleroma.social"
97
+
config :pleroma, Pleroma.Repo,
98
+
adapter: Ecto.Adapters.Postgres,
99
+
username: "pleroma",
100
+
password: "${test-db-passwd}",
101
+
database: "pleroma",
102
+
hostname: "localhost",
106
+
plan_cache_mode: "force_custom_plan"
109
+
config :pleroma, :database, rum_enabled: false
110
+
config :pleroma, :instance, static_dir: "/var/lib/pleroma/static"
111
+
config :pleroma, Pleroma.Uploaders.Local, uploads: "/var/lib/pleroma/uploads"
112
+
config :pleroma, configurable_from_database: false
115
+
/* For this NixOS test, we *had* to store this secret to the store.
116
+
Keep in mind the store is world-readable, it's the worst place
117
+
possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
119
+
In a real-word deployment, you'd handle this either by:
120
+
- manually upload your pleroma secrets to /var/lib/pleroma/secrets.exs
121
+
- use a deployment tool such as morph or NixOps to deploy your secrets.
123
+
pleroma-conf-secret = pkgs.writeText "secrets.exs" ''
126
+
config :joken, default_signer: "PS69/wMW7X6FIQPABt9lwvlZvgrJIncfiAMrK9J5mjVus/7/NJJi1DsDA1OghBE5"
128
+
config :pleroma, Pleroma.Web.Endpoint,
129
+
secret_key_base: "NvfmU7lYaQrmmxt4NACm0AaAfN9t6WxsrX0NCB4awkGHvr1S7jyshlEmrjaPFhhq",
130
+
signing_salt: "3L41+BuJ"
132
+
config :web_push_encryption, :vapid_details,
133
+
subject: "mailto:pleroma@nixos.test",
134
+
public_key: "BKjfNX9-UqAcncaNqERQtF7n9pKrB0-MO-juv6U5E5XQr_Tg5D-f8AlRjduAguDpyAngeDzG8MdrTejMSL4VF30",
135
+
private_key: "k7o9onKMQrgMjMb6l4fsxSaXO0BTNAer5MVSje3q60k"
138
+
/* For this NixOS test, we *had* to store this secret to the store.
139
+
Keep in mind the store is world-readable, it's the worst place
140
+
possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
142
+
In a real-word deployment, you'd handle this either by:
143
+
- manually upload your pleroma secrets to /var/lib/pleroma/secrets.exs
144
+
- use a deployment tool such as morph or NixOps to deploy your secrets.
146
+
provision-secrets = pkgs.writeScriptBin "provision-secrets" ''
148
+
cp "${pleroma-conf-secret}" "/var/lib/pleroma/secrets.exs"
149
+
chown pleroma:pleroma /var/lib/pleroma/secrets.exs
152
+
/* For this NixOS test, we *had* to store this secret to the store.
153
+
Keep in mind the store is world-readable, it's the worst place
154
+
possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
157
+
provision-user = pkgs.writeScriptBin "provision-user" ''
160
+
# Waiting for pleroma to be up.
161
+
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'
162
+
pleroma_ctl user new jamy jamy@nixos.test --password 'jamy-password' --moderator --admin -y
165
+
tls-cert = pkgs.runCommandNoCC "selfSignedCerts" { buildInputs = [ pkgs.openssl ]; } ''
166
+
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -subj '/CN=pleroma.nixos.test'
168
+
cp key.pem cert.pem $out
171
+
/* Toot is preventing users from feeding login_cli a password non
172
+
interactively. While it makes sense most of the times, it's
173
+
preventing us to login in this non-interactive test. This patch
174
+
introduce a TOOT_LOGIN_CLI_PASSWORD env variable allowing us to
175
+
provide a password to toot login_cli
177
+
If https://github.com/ihabunek/toot/pull/180 gets merged at some
178
+
point, feel free to remove this patch. */
179
+
custom-toot = pkgs.toot.overrideAttrs(old:{
180
+
patches = [ (pkgs.fetchpatch {
181
+
url = "https://github.com/NinjaTrappeur/toot/commit/b4a4c30f41c0cb7e336714c2c4af9bc9bfa0c9f2.patch";
182
+
sha256 = "sha256-0xxNwjR/fStLjjUUhwzCCfrghRVts+fc+fvVJqVcaFg=";
187
+
${nodes.pleroma.config.networking.primaryIPAddress} pleroma.nixos.test
188
+
${nodes.client.config.networking.primaryIPAddress} client.nixos.test
193
+
client = { nodes, pkgs, config, ... }: {
194
+
security.pki.certificateFiles = [ "${tls-cert}/cert.pem" ];
195
+
networking.extraHosts = hosts nodes;
196
+
environment.systemPackages = with pkgs; [
201
+
pleroma = { nodes, pkgs, config, ... }: {
202
+
security.pki.certificateFiles = [ "${tls-cert}/cert.pem" ];
203
+
networking.extraHosts = hosts nodes;
204
+
networking.firewall.enable = false;
205
+
environment.systemPackages = with pkgs; [
219
+
package = pkgs.postgresql_12;
223
+
virtualHosts."pleroma.nixos.test" = {
225
+
sslCertificate = "${tls-cert}/cert.pem";
226
+
sslCertificateKey = "${tls-cert}/key.pem";
228
+
proxyPass = "http://127.0.0.1:4000";
230
+
add_header 'Access-Control-Allow-Origin' '*' always;
231
+
add_header 'Access-Control-Allow-Methods' 'POST, PUT, DELETE, GET, PATCH, OPTIONS' always;
232
+
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Idempotency-Key' always;
233
+
add_header 'Access-Control-Expose-Headers' 'Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id' always;
234
+
if ($request_method = OPTIONS) {
237
+
add_header X-XSS-Protection "1; mode=block";
238
+
add_header X-Permitted-Cross-Domain-Policies none;
239
+
add_header X-Frame-Options DENY;
240
+
add_header X-Content-Type-Options nosniff;
241
+
add_header Referrer-Policy same-origin;
242
+
add_header X-Download-Options noopen;
243
+
proxy_http_version 1.1;
244
+
proxy_set_header Upgrade $http_upgrade;
245
+
proxy_set_header Connection "upgrade";
246
+
proxy_set_header Host $host;
247
+
client_max_body_size 16m;
256
+
testScript = { nodes, ... }: ''
257
+
pleroma.wait_for_unit("postgresql.service")
258
+
pleroma.succeed("provision-db")
259
+
pleroma.succeed("provision-secrets")
260
+
pleroma.systemctl("restart pleroma.service")
261
+
pleroma.wait_for_unit("pleroma.service")
262
+
pleroma.succeed("provision-user")
263
+
client.succeed("send-toot")