Loading nixos/tests/all-tests.nix +1 −1 Original line number Diff line number Diff line Loading @@ -1013,7 +1013,7 @@ in { vault-agent = handleTest ./vault-agent.nix {}; vault-dev = handleTest ./vault-dev.nix {}; vault-postgresql = handleTest ./vault-postgresql.nix {}; vaultwarden = handleTest ./vaultwarden.nix {}; vaultwarden = discoverTests (import ./vaultwarden.nix); vector = handleTest ./vector {}; vengi-tools = handleTest ./vengi-tools.nix {}; victoriametrics = handleTest ./victoriametrics.nix {}; Loading nixos/tests/vaultwarden.nix +137 −126 Original line number Diff line number Diff line { system ? builtins.currentSystem , config ? { } , pkgs ? import ../.. { inherit system config; } }: # These tests will: # * Set up a vaultwarden server # * Have Firefox use the web vault to create an account, log in, and save a password to the valut # * Have Firefox use the web vault to create an account, log in, and save a password to the vault # * Have the bw cli log in and read that password from the vault # # Note that Firefox must be on the same machine as the server for WebCrypto APIs to be available (or HTTPS must be configured) # # The same tests should work without modification on the official bitwarden server, if we ever package that. with import ../lib/testing-python.nix { inherit system pkgs; }; with pkgs.lib; let backends = [ "sqlite" "mysql" "postgresql" ]; makeVaultwardenTest = name: { backend ? name, withClient ? true, testScript ? null, }: import ./make-test-python.nix ({ lib, pkgs, ...}: let dbPassword = "please_dont_hack"; userEmail = "meow@example.com"; userPassword = "also_super_secret_ZJWpBKZi668QGt"; # Must be complex to avoid interstitial warning on the signup page storedPassword = "seeeecret"; makeVaultwardenTest = backend: makeTest { name = "vaultwarden-${backend}"; meta = { maintainers = with pkgs.lib.maintainers; [ jjjollyjim ]; }; nodes = { server = { pkgs, ... }: let backendConfig = { mysql = { services.mysql = { enable = true; initialScript = pkgs.writeText "mysql-init.sql" '' CREATE DATABASE bitwarden; CREATE USER 'bitwardenuser'@'localhost' IDENTIFIED BY '${dbPassword}'; GRANT ALL ON `bitwarden`.* TO 'bitwardenuser'@'localhost'; FLUSH PRIVILEGES; ''; package = pkgs.mariadb; }; services.vaultwarden.config.databaseUrl = "mysql://bitwardenuser:${dbPassword}@localhost/bitwarden"; systemd.services.vaultwarden.after = [ "mysql.service" ]; }; postgresql = { services.postgresql = { enable = true; initialScript = pkgs.writeText "postgresql-init.sql" '' CREATE USER bitwardenuser WITH PASSWORD '${dbPassword}'; CREATE DATABASE bitwarden WITH OWNER bitwardenuser; ''; }; services.vaultwarden.config.databaseUrl = "postgresql://bitwardenuser:${dbPassword}@localhost/bitwarden"; systemd.services.vaultwarden.after = [ "postgresql.service" ]; }; sqlite = { }; }; in mkMerge [ backendConfig.${backend} { services.vaultwarden = { enable = true; dbBackend = backend; config = { rocketAddress = "0.0.0.0"; rocketPort = 80; }; }; networking.firewall.allowedTCPPorts = [ 80 ]; environment.systemPackages = let testRunner = pkgs.writers.writePython3Bin "test-runner" { testRunner = pkgs.writers.writePython3Bin "test-runner" { libraries = [ pkgs.python3Packages.selenium ]; flakeIgnore = [ "E501" ]; flakeIgnore = [ "E501" ]; } '' from selenium.webdriver.common.by import By Loading Loading @@ -147,19 +79,77 @@ let driver.find_element(By.XPATH, "//button[contains(., 'Save')]").click() ''; in [ pkgs.firefox-unwrapped pkgs.geckodriver testRunner ]; in { inherit name; } ]; meta = { maintainers = with pkgs.lib.maintainers; [ dotlambda SuperSandro2000 ]; }; client = { pkgs, ... }: nodes = { server = { pkgs, ... }: lib.mkMerge [ { mysql = { services.mysql = { enable = true; initialScript = pkgs.writeText "mysql-init.sql" '' CREATE DATABASE bitwarden; CREATE USER 'bitwardenuser'@'localhost' IDENTIFIED BY '${dbPassword}'; GRANT ALL ON `bitwarden`.* TO 'bitwardenuser'@'localhost'; FLUSH PRIVILEGES; ''; package = pkgs.mariadb; }; services.vaultwarden.config.databaseUrl = "mysql://bitwardenuser:${dbPassword}@localhost/bitwarden"; systemd.services.vaultwarden.after = [ "mysql.service" ]; }; postgresql = { services.postgresql = { enable = true; ensureDatabases = [ "vaultwarden" ]; ensureUsers = [{ name = "vaultwarden"; ensureDBOwnership = true; }]; }; services.vaultwarden.config.databaseUrl = "postgresql:///vaultwarden?host=/run/postgresql"; systemd.services.vaultwarden.after = [ "postgresql.service" ]; }; sqlite = { services.vaultwarden.backupDir = "/var/lib/vaultwarden/backups"; environment.systemPackages = [ pkgs.sqlite ]; }; }.${backend} { services.vaultwarden = { enable = true; dbBackend = backend; config = { rocketAddress = "0.0.0.0"; rocketPort = 80; }; }; networking.firewall.allowedTCPPorts = [ 80 ]; environment.systemPackages = [ pkgs.firefox-unwrapped pkgs.geckodriver testRunner ]; } ]; } // lib.optionalAttrs withClient { client = { pkgs, ... }: { environment.systemPackages = [ pkgs.bitwarden-cli ]; }; }; testScript = '' testScript = if testScript != null then testScript else '' start_all() server.wait_for_unit("vaultwarden.service") server.wait_for_open_port(80) Loading @@ -184,15 +174,36 @@ let client.succeed(f"bw --nointeraction --raw --session {key} sync -f") with subtest("get the password with the cli"): password = client.succeed( f"bw --nointeraction --raw --session {key} list items | ${pkgs.jq}/bin/jq -r .[].login.password" password = client.wait_until_succeeds( f"bw --nointeraction --raw --session {key} list items | ${pkgs.jq}/bin/jq -r .[].login.password", timeout=60 ) assert password.strip() == "${storedPassword}" ''; }; }); in builtins.listToAttrs ( map (backend: { name = backend; value = makeVaultwardenTest backend; }) backends ) builtins.mapAttrs (k: v: makeVaultwardenTest k v) { mysql = {}; postgresql = {}; sqlite = {}; sqlite-backup = { backend = "sqlite"; withClient = false; testScript = '' start_all() server.wait_for_unit("vaultwarden.service") server.wait_for_open_port(80) with subtest("Set up vaultwarden"): server.succeed("PYTHONUNBUFFERED=1 test-runner | systemd-cat -t test-runner") with subtest("Run the backup script"): server.start_job("backup-vaultwarden.service") with subtest("Check that backup exists"): server.succeed('[ -d "/var/lib/vaultwarden/backups" ]') server.succeed('[ -f "/var/lib/vaultwarden/backups/db.sqlite3" ]') ''; }; } Loading
nixos/tests/all-tests.nix +1 −1 Original line number Diff line number Diff line Loading @@ -1013,7 +1013,7 @@ in { vault-agent = handleTest ./vault-agent.nix {}; vault-dev = handleTest ./vault-dev.nix {}; vault-postgresql = handleTest ./vault-postgresql.nix {}; vaultwarden = handleTest ./vaultwarden.nix {}; vaultwarden = discoverTests (import ./vaultwarden.nix); vector = handleTest ./vector {}; vengi-tools = handleTest ./vengi-tools.nix {}; victoriametrics = handleTest ./victoriametrics.nix {}; Loading
nixos/tests/vaultwarden.nix +137 −126 Original line number Diff line number Diff line { system ? builtins.currentSystem , config ? { } , pkgs ? import ../.. { inherit system config; } }: # These tests will: # * Set up a vaultwarden server # * Have Firefox use the web vault to create an account, log in, and save a password to the valut # * Have Firefox use the web vault to create an account, log in, and save a password to the vault # * Have the bw cli log in and read that password from the vault # # Note that Firefox must be on the same machine as the server for WebCrypto APIs to be available (or HTTPS must be configured) # # The same tests should work without modification on the official bitwarden server, if we ever package that. with import ../lib/testing-python.nix { inherit system pkgs; }; with pkgs.lib; let backends = [ "sqlite" "mysql" "postgresql" ]; makeVaultwardenTest = name: { backend ? name, withClient ? true, testScript ? null, }: import ./make-test-python.nix ({ lib, pkgs, ...}: let dbPassword = "please_dont_hack"; userEmail = "meow@example.com"; userPassword = "also_super_secret_ZJWpBKZi668QGt"; # Must be complex to avoid interstitial warning on the signup page storedPassword = "seeeecret"; makeVaultwardenTest = backend: makeTest { name = "vaultwarden-${backend}"; meta = { maintainers = with pkgs.lib.maintainers; [ jjjollyjim ]; }; nodes = { server = { pkgs, ... }: let backendConfig = { mysql = { services.mysql = { enable = true; initialScript = pkgs.writeText "mysql-init.sql" '' CREATE DATABASE bitwarden; CREATE USER 'bitwardenuser'@'localhost' IDENTIFIED BY '${dbPassword}'; GRANT ALL ON `bitwarden`.* TO 'bitwardenuser'@'localhost'; FLUSH PRIVILEGES; ''; package = pkgs.mariadb; }; services.vaultwarden.config.databaseUrl = "mysql://bitwardenuser:${dbPassword}@localhost/bitwarden"; systemd.services.vaultwarden.after = [ "mysql.service" ]; }; postgresql = { services.postgresql = { enable = true; initialScript = pkgs.writeText "postgresql-init.sql" '' CREATE USER bitwardenuser WITH PASSWORD '${dbPassword}'; CREATE DATABASE bitwarden WITH OWNER bitwardenuser; ''; }; services.vaultwarden.config.databaseUrl = "postgresql://bitwardenuser:${dbPassword}@localhost/bitwarden"; systemd.services.vaultwarden.after = [ "postgresql.service" ]; }; sqlite = { }; }; in mkMerge [ backendConfig.${backend} { services.vaultwarden = { enable = true; dbBackend = backend; config = { rocketAddress = "0.0.0.0"; rocketPort = 80; }; }; networking.firewall.allowedTCPPorts = [ 80 ]; environment.systemPackages = let testRunner = pkgs.writers.writePython3Bin "test-runner" { testRunner = pkgs.writers.writePython3Bin "test-runner" { libraries = [ pkgs.python3Packages.selenium ]; flakeIgnore = [ "E501" ]; flakeIgnore = [ "E501" ]; } '' from selenium.webdriver.common.by import By Loading Loading @@ -147,19 +79,77 @@ let driver.find_element(By.XPATH, "//button[contains(., 'Save')]").click() ''; in [ pkgs.firefox-unwrapped pkgs.geckodriver testRunner ]; in { inherit name; } ]; meta = { maintainers = with pkgs.lib.maintainers; [ dotlambda SuperSandro2000 ]; }; client = { pkgs, ... }: nodes = { server = { pkgs, ... }: lib.mkMerge [ { mysql = { services.mysql = { enable = true; initialScript = pkgs.writeText "mysql-init.sql" '' CREATE DATABASE bitwarden; CREATE USER 'bitwardenuser'@'localhost' IDENTIFIED BY '${dbPassword}'; GRANT ALL ON `bitwarden`.* TO 'bitwardenuser'@'localhost'; FLUSH PRIVILEGES; ''; package = pkgs.mariadb; }; services.vaultwarden.config.databaseUrl = "mysql://bitwardenuser:${dbPassword}@localhost/bitwarden"; systemd.services.vaultwarden.after = [ "mysql.service" ]; }; postgresql = { services.postgresql = { enable = true; ensureDatabases = [ "vaultwarden" ]; ensureUsers = [{ name = "vaultwarden"; ensureDBOwnership = true; }]; }; services.vaultwarden.config.databaseUrl = "postgresql:///vaultwarden?host=/run/postgresql"; systemd.services.vaultwarden.after = [ "postgresql.service" ]; }; sqlite = { services.vaultwarden.backupDir = "/var/lib/vaultwarden/backups"; environment.systemPackages = [ pkgs.sqlite ]; }; }.${backend} { services.vaultwarden = { enable = true; dbBackend = backend; config = { rocketAddress = "0.0.0.0"; rocketPort = 80; }; }; networking.firewall.allowedTCPPorts = [ 80 ]; environment.systemPackages = [ pkgs.firefox-unwrapped pkgs.geckodriver testRunner ]; } ]; } // lib.optionalAttrs withClient { client = { pkgs, ... }: { environment.systemPackages = [ pkgs.bitwarden-cli ]; }; }; testScript = '' testScript = if testScript != null then testScript else '' start_all() server.wait_for_unit("vaultwarden.service") server.wait_for_open_port(80) Loading @@ -184,15 +174,36 @@ let client.succeed(f"bw --nointeraction --raw --session {key} sync -f") with subtest("get the password with the cli"): password = client.succeed( f"bw --nointeraction --raw --session {key} list items | ${pkgs.jq}/bin/jq -r .[].login.password" password = client.wait_until_succeeds( f"bw --nointeraction --raw --session {key} list items | ${pkgs.jq}/bin/jq -r .[].login.password", timeout=60 ) assert password.strip() == "${storedPassword}" ''; }; }); in builtins.listToAttrs ( map (backend: { name = backend; value = makeVaultwardenTest backend; }) backends ) builtins.mapAttrs (k: v: makeVaultwardenTest k v) { mysql = {}; postgresql = {}; sqlite = {}; sqlite-backup = { backend = "sqlite"; withClient = false; testScript = '' start_all() server.wait_for_unit("vaultwarden.service") server.wait_for_open_port(80) with subtest("Set up vaultwarden"): server.succeed("PYTHONUNBUFFERED=1 test-runner | systemd-cat -t test-runner") with subtest("Run the backup script"): server.start_job("backup-vaultwarden.service") with subtest("Check that backup exists"): server.succeed('[ -d "/var/lib/vaultwarden/backups" ]') server.succeed('[ -f "/var/lib/vaultwarden/backups/db.sqlite3" ]') ''; }; }