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