#!/bin/bash # Tests for where szecret finds the global store and its public key this_dir="$(cd "$(dirname "$0")" && pwd)" source "${this_dir}/common.sh" # A copy of the scripts with no store beside them, so the tests do not depend # on whether this checkout still carries one. make_code_dir() { local dir="$1" mkdir -p "${dir}" cp "${SECRETS_DIR}"/*.sh "${dir}/" } # Runs szecret from a code dir with only XDG_DATA_HOME to go on. szecret_at() { local code_dir="$1" shift env -u SZECRET_STORE -u SZECRET_PUBLIC_KEY -u SZECRET_PRIVATE_KEY -u SZECRET_PRIVATE_KEY_DIR \ XDG_DATA_HOME="${TEST_DIR}/xdg" \ "${code_dir}/main.sh" "$@" } # Makes a keypair: the public key goes to $1, the private key into the private # key directory, named after its public key. make_key() { local pub_file="$1" local key_dir="${TEST_DIR}/xdg/szecret" mkdir -p "${key_dir}" "$(dirname "${pub_file}")" age-keygen -o "${TEST_DIR}/new-key" 2>/dev/null age-keygen -y "${TEST_DIR}/new-key" > "${pub_file}" mv "${TEST_DIR}/new-key" "${key_dir}/$(cat "${pub_file}")" } reset_xdg() { rm -rf "${TEST_DIR}/xdg" } test_no_store_fails() { reset_xdg local code="${TEST_DIR}/code-bare" make_code_dir "${code}" local err err="$(szecret_at "${code}" list 2>&1 >/dev/null)" && fail "list should fail without a store" assert_contains "${err}" "no szecret store" "error message" pass "no store: commands fail with instructions" } test_no_store_ready_is_quiet() { reset_xdg local code="${TEST_DIR}/code-bare" make_code_dir "${code}" local err err="$(szecret_at "${code}" ready 2>&1)" && fail "ready should fail without a store" assert_equals "" "${err}" "ready output" pass "no store: ready fails silently" } test_data_dir_store() { reset_xdg local code="${TEST_DIR}/code-bare" make_code_dir "${code}" # The store and public key live elsewhere and are linked in, as on a host. local elsewhere="${TEST_DIR}/checkout/szecret" mkdir -p "${elsewhere}/store" make_key "${elsewhere}/id.pub" ln -s "${elsewhere}/store" "${TEST_DIR}/xdg/szecret/store" ln -s "${elsewhere}/id.pub" "${TEST_DIR}/xdg/szecret/id.pub" echo "linked-value" | szecret_at "${code}" put "linked-secret" assert_file_exists "${elsewhere}/store/linked-secret.age" "secret written through the link" assert_equals "linked-value" "$(szecret_at "${code}" get "linked-secret")" "round trip" pass "store and id.pub are found in the data dir" } test_data_dir_wins_over_a_stray_store() { reset_xdg local code="${TEST_DIR}/code-stray" make_code_dir "${code}" mkdir -p "${code}/store" make_key "${code}/.id.pub" mkdir -p "${TEST_DIR}/xdg/szecret/store" make_key "${TEST_DIR}/xdg/szecret/id.pub" echo "v" | szecret_at "${code}" put "where" assert_file_exists "${TEST_DIR}/xdg/szecret/store/where.age" "secret in data dir store" if [[ -e "${code}/store/where.age" ]]; then fail "secret was written to the store beside the scripts" fi pass "data dir is used even with a store beside the scripts" } test_env_beats_data_dir() { reset_xdg mkdir -p "${TEST_DIR}/xdg/szecret/store" make_key "${TEST_DIR}/xdg/szecret/id.pub" # The common.sh setup exported SZECRET_STORE and friends; use them as-is. echo "v" | XDG_DATA_HOME="${TEST_DIR}/xdg" szecret put "env-wins" assert_file_exists "${SZECRET_STORE}/env-wins.age" "secret in SZECRET_STORE" if [[ -e "${TEST_DIR}/xdg/szecret/store/env-wins.age" ]]; then fail "secret was written to the data dir store" fi pass "SZECRET_STORE takes precedence over the data dir" } run_tests() { test_no_store_fails test_no_store_ready_is_quiet test_data_dir_store test_data_dir_wins_over_a_stray_store test_env_beats_data_dir } [[ "${BASH_SOURCE[0]}" == "${0}" ]] && run_tests