{ pkgs }: let ourpkgs = pkgs.callPackage ../pkgs { }; sshPrivateKeyFile = ./probeuser_ed25519; sshPublicKeyFile = ./probeuser_ed25519.pub; sshUsers = { root = [(builtins.readFile sshPublicKeyFile)]; probeuser = [(builtins.readFile sshPublicKeyFile)]; }; # This is a test double of the Stripe API server. It is extremely simple. # It barely knows how to respond to exactly the API endpoints we use, # exactly how we use them. stripe-api-double = ./stripe-api-double.py; # The root URL of the Ristretto-flavored PrivacyPass issuer API. issuerURL = "http://issuer/"; voucher = "xyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxy"; # The issuer's signing key. Notionally, this is a secret key. This is only # the value for this system test though so I don't care if it leaks to the # world at large. ristrettoSigningKeyPath = let key = "wumQAfSsJlQKDDSaFN/PZ3EbgBit8roVgfzllfCK2gQ="; basename = "signing-key.private"; in pkgs.writeText basename key; ristrettoPublicKey = "xoNHEqAi+kC5EWfqN+kuDINhjQTwGrSQyshHvGFpoys="; stripeSecretKeyPath = let # Ugh. key = "sk_test_blubblub"; basename = "stripe.secret"; in pkgs.writeText basename key; # Here are the preconstructed secrets which we can assign to the introducer. # This is a lot easier than having the introducer generate them and then # discovering and configuring the other nodes with them. pemFile = ./node.pem; tubID = "rr7y46ixsg6qmck4jkkc7hke6xe4sv5f"; swissnum = "2k6p3wrabat5jrj7otcih4cjdema4q3m"; introducerPort = 35151; location = "tcp:introducer:${toString introducerPort}"; introducerFURL = "pb://${tubID}@${location}/${swissnum}"; introducerFURLFile = pkgs.writeTextFile { name = "introducer.furl"; text = introducerFURL; }; networkConfig = { # Just need to disable the firewall so all the traffic flows freely. We # could do other network configuration here too, if we wanted. Initially # I thought we might need to statically asssign IPs but we can just use # the node names, "introducer", etc, instead. networking.firewall.enable = false; networking.dhcpcd.enable = false; }; in { # https://nixos.org/nixos/manual/index.html#sec-nixos-tests # https://nixos.mayflower.consulting/blog/2019/07/11/leveraging-nixos-tests-in-your-project/ nodes = rec { # Get a machine where we can run a Tahoe-LAFS client node. client = { config, pkgs, ourpkgs, ... }: { imports = [ ../modules/packages.nix ]; environment.systemPackages = [ pkgs.daemonize # A Tahoe-LAFS configuration capable of using the right storage # plugin. ourpkgs.privatestorage # Support for the tests we'll run. (pkgs.python3.withPackages (ps: [ ps.requests ps.hyperlink ])) ]; } // networkConfig; # Get another machine where we can run a Tahoe-LAFS introducer node. It has the same configuration as the client. introducer = client; # Configure a single machine as a PrivateStorage storage node. storage = { config, pkgs, ... }: { imports = [ ../modules/packages.nix ../modules/private-storage.nix ../modules/ssh.nix ]; services.private-storage = { enable = true; publicAddress = "storage"; introducerFURL = introducerFURL; issuerRootURL = issuerURL; inherit ristrettoSigningKeyPath; inherit sshUsers; }; } // networkConfig; # Operate an issuer as well. issuer = { config, pkgs, ... }: { imports = [ ../modules/packages.nix ../modules/issuer.nix ../modules/ssh.nix ]; services.private-storage.sshUsers = sshUsers; services.private-storage-issuer = { enable = true; domains = ["issuer"]; tls = false; issuer = "Ristretto"; inherit ristrettoSigningKeyPath; letsEncryptAdminEmail = "user@example.invalid"; allowedChargeOrigins = [ "http://unused.invalid" ]; inherit stripeSecretKeyPath; stripeEndpointDomain = "api_stripe_com"; stripeEndpointScheme = "HTTP"; stripeEndpointPort = 80; }; } // networkConfig; # Also run a fake Stripe API endpoint server. Nodes in these tests run on # a network without outside access so we can't easily use the real Stripe # API endpoint and with this one we have greater control over the # behavior, anyway, without all of the unintentional transient network # errors that come from the public internet. These tests *aren't* meant # to prove PaymentServer correctly interacts with the real Stripe API # server so this is an unverified fake. The PaymentServer test suite # needs to take care of any actual Stripe API integration testing. "api_stripe_com" = { config, pkgs, ... }: let python = pkgs.python3.withPackages (ps: [ ps.twisted ]); in networkConfig // { environment.systemPackages = [ python pkgs.curl ]; systemd.services."api.stripe.com" = { enable = true; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; script = "${python}/bin/python ${stripe-api-double} tcp:80"; }; }; }; # Test the machines with a Python program. testScript = ourpkgs.lib.testing.makeTestScript { testpath = ./test_privatestorage.py; kwargs = { inherit sshPrivateKeyFile pemFile introducerPort introducerFURL issuerURL ristrettoPublicKey voucher; # Supply some helper programs to help the tests stay a bit higher level. run_introducer = ./run-introducer.py; run_client = ./run-client.py; get_passes = ./get-passes.py; exercise_storage = ./exercise-storage.py; }; }; }