From a359d95c7389e42fcbdbfa7a35b8fb9feae08c34 Mon Sep 17 00:00:00 2001 From: Jamie McClymont Date: Sun, 16 Aug 2020 14:21:53 +1200 Subject: [PATCH 1/2] maintainers: add JJJollyjim --- maintainers/maintainer-list.nix | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index cc2aa5a7efc3..9a6fa5e6f39d 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -3835,6 +3835,12 @@ githubId = 51518420; name = "jitwit"; }; + jjjollyjim = { + email = "jamie@kwiius.com"; + github = "JJJollyjim"; + githubId = 691552; + name = "Jamie McClymont"; + }; jk = { email = "hello+nixpkgs@j-k.io"; github = "06kellyjac"; From f5f2d89fb7996c989cec0d7de63b1129aa32a14a Mon Sep 17 00:00:00 2001 From: Jamie McClymont Date: Sat, 6 Jun 2020 22:55:50 +1200 Subject: [PATCH 2/2] nixos/bitwarden_rs: add test --- nixos/tests/all-tests.nix | 1 + nixos/tests/bitwarden.nix | 188 +++++++++++++++++++ pkgs/tools/security/bitwarden_rs/default.nix | 4 +- pkgs/tools/security/bitwarden_rs/vault.nix | 4 +- 4 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 nixos/tests/bitwarden.nix diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index a4a62d85a592..0ce5f89b27c7 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -34,6 +34,7 @@ in bind = handleTest ./bind.nix {}; bitcoind = handleTest ./bitcoind.nix {}; bittorrent = handleTest ./bittorrent.nix {}; + bitwarden = handleTest ./bitwarden.nix {}; blockbook-frontend = handleTest ./blockbook-frontend.nix {}; buildkite-agents = handleTest ./buildkite-agents.nix {}; boot = handleTestOn ["x86_64-linux"] ./boot.nix {}; # syslinux is unsupported on aarch64 diff --git a/nixos/tests/bitwarden.nix b/nixos/tests/bitwarden.nix new file mode 100644 index 000000000000..a47c77cec213 --- /dev/null +++ b/nixos/tests/bitwarden.nix @@ -0,0 +1,188 @@ +{ system ? builtins.currentSystem +, config ? { } +, pkgs ? import ../.. { inherit system config; } +}: + +# These tests will: +# * Set up a bitwarden-rs server +# * Have Firefox use the web vault to create an account, log in, and save a password to the valut +# * 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" ]; + + 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"; + + makeBitwardenTest = backend: makeTest { + name = "bitwarden_rs-${backend}"; + meta = { + maintainers = with pkgs.stdenv.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.mysql; + }; + + services.bitwarden_rs.config.databaseUrl = "mysql://bitwardenuser:${dbPassword}@localhost/bitwarden"; + + systemd.services.bitwarden_rs.after = [ "mysql.service" ]; + }; + + postgresql = { + services.postgresql = { + enable = true; + initialScript = pkgs.writeText "postgresql-init.sql" '' + CREATE DATABASE bitwarden; + CREATE USER bitwardenuser WITH PASSWORD '${dbPassword}'; + GRANT ALL PRIVILEGES ON DATABASE bitwarden TO bitwardenuser; + ''; + }; + + services.bitwarden_rs.config.databaseUrl = "postgresql://bitwardenuser:${dbPassword}@localhost/bitwarden"; + + systemd.services.bitwarden_rs.after = [ "postgresql.service" ]; + }; + + sqlite = { }; + }; + in + mkMerge [ + backendConfig.${backend} + { + services.bitwarden_rs = { + enable = true; + dbBackend = backend; + config.rocketPort = 80; + }; + + networking.firewall.allowedTCPPorts = [ 80 ]; + + environment.systemPackages = + let + testRunner = pkgs.writers.writePython3Bin "test-runner" + { + libraries = [ pkgs.python3Packages.selenium ]; + } '' + from selenium.webdriver import Firefox + from selenium.webdriver.firefox.options import Options + from selenium.webdriver.support.ui import WebDriverWait + from selenium.webdriver.support import expected_conditions as EC + + options = Options() + options.add_argument('--headless') + driver = Firefox(options=options) + + driver.implicitly_wait(20) + driver.get('http://localhost/#/register') + + wait = WebDriverWait(driver, 10) + + wait.until(EC.title_contains("Create Account")) + + driver.find_element_by_css_selector('input#email').send_keys( + '${userEmail}' + ) + driver.find_element_by_css_selector('input#name').send_keys( + 'A Cat' + ) + driver.find_element_by_css_selector('input#masterPassword').send_keys( + '${userPassword}' + ) + driver.find_element_by_css_selector('input#masterPasswordRetype').send_keys( + '${userPassword}' + ) + + driver.find_element_by_xpath("//button[contains(., 'Submit')]").click() + + wait.until_not(EC.title_contains("Create Account")) + + driver.find_element_by_css_selector('input#masterPassword').send_keys( + '${userPassword}' + ) + driver.find_element_by_xpath("//button[contains(., 'Log In')]").click() + + wait.until(EC.title_contains("My Vault")) + + driver.find_element_by_xpath("//button[contains(., 'Add Item')]").click() + + driver.find_element_by_css_selector('input#name').send_keys( + 'secrets' + ) + driver.find_element_by_css_selector('input#loginPassword').send_keys( + '${storedPassword}' + ) + + driver.find_element_by_xpath("//button[contains(., 'Save')]").click() + ''; + in + [ pkgs.firefox-unwrapped pkgs.geckodriver testRunner ]; + + virtualisation.memorySize = 768; + } + ]; + + client = { pkgs, ... }: + { + environment.systemPackages = [ pkgs.bitwarden-cli ]; + }; + }; + + testScript = '' + start_all() + server.wait_for_unit("bitwarden_rs.service") + server.wait_for_open_port(80) + + with subtest("configure the cli"): + client.succeed("bw --nointeraction config server http://server") + + with subtest("can't login to nonexistant account"): + client.fail( + "bw --nointeraction --raw login ${userEmail} ${userPassword}" + ) + + with subtest("use the web interface to sign up, log in, and save a password"): + server.succeed("PYTHONUNBUFFERED=1 test-runner | systemd-cat -t test-runner") + + with subtest("log in with the cli"): + key = client.succeed( + "bw --nointeraction --raw login ${userEmail} ${userPassword}" + ).strip() + + with subtest("sync with the cli"): + 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" + ) + assert password.strip() == "${storedPassword}" + ''; + }; +in +builtins.listToAttrs ( + map + (backend: { name = backend; value = makeBitwardenTest backend; }) + backends +) diff --git a/pkgs/tools/security/bitwarden_rs/default.nix b/pkgs/tools/security/bitwarden_rs/default.nix index ebf65b07234a..c2bb83241861 100644 --- a/pkgs/tools/security/bitwarden_rs/default.nix +++ b/pkgs/tools/security/bitwarden_rs/default.nix @@ -1,4 +1,4 @@ -{ stdenv, rustPlatform, fetchFromGitHub +{ stdenv, rustPlatform, fetchFromGitHub, nixosTests , pkgconfig, openssl , Security, CoreServices , dbBackend ? "sqlite", libmysqlclient, postgresql }: @@ -35,6 +35,8 @@ in rustPlatform.buildRustPackage rec { runHook postCheck ''; + passthru.tests = nixosTests.bitwarden; + meta = with stdenv.lib; { description = "Unofficial Bitwarden compatible server written in Rust"; homepage = "https://github.com/dani-garcia/bitwarden_rs"; diff --git a/pkgs/tools/security/bitwarden_rs/vault.nix b/pkgs/tools/security/bitwarden_rs/vault.nix index 7c71506c8881..2ac50912c056 100644 --- a/pkgs/tools/security/bitwarden_rs/vault.nix +++ b/pkgs/tools/security/bitwarden_rs/vault.nix @@ -1,4 +1,4 @@ -{ stdenv, fetchurl }: +{ stdenv, fetchurl, nixosTests }: stdenv.mkDerivation rec { pname = "bitwarden_rs-vault"; @@ -16,6 +16,8 @@ stdenv.mkDerivation rec { mv web-vault vault ''; + passthru.tests = nixosTests.bitwarden; + meta = with stdenv.lib; { description = "Integrates the web vault into bitwarden_rs"; homepage = "https://github.com/dani-garcia/bw_web_builds";