1#!/usr/bin/env bash
2
3# This file is following a name convention defined in:
4# https://github.com/bats-core/bats-core
5
6# shellcheck disable=1090
7source "$SECRET_PROJECT_ROOT/src/version.sh"
8# shellcheck disable=1090
9source "$SECRET_PROJECT_ROOT/src/_utils/_git_secret_tools.sh"
10
11# Constants:
12FIXTURES_DIR="$BATS_TEST_DIRNAME/fixtures"
13
14TEST_GPG_HOMEDIR="$BATS_TMPDIR"
15
16AWK_GPG_GET_FP='
17BEGIN { OFS=":"; FS=":"; }
18{
19  if ( $1 == "fpr" )
20  {
21    print $10
22    exit
23  }
24}
25'
26
27# GPG-based stuff:
28: "${SECRETS_GPG_COMMAND:="gpg"}"
29
30# This command is used with absolute homedir set and disabled warnings:
31GPGTEST="$SECRETS_GPG_COMMAND --homedir=$TEST_GPG_HOMEDIR --no-permission-warning --batch"
32
33
34# Personal data:
35
36# these two are 'normal' keys
37TEST_DEFAULT_USER="user1@gitsecret.io"
38TEST_SECOND_USER="user2@gitsecret.io"
39
40# TEST_NONAME_USER (user3) created with '--quick-key-generate' and has only an email, no username.
41TEST_NONAME_USER="user3@gitsecret.io"
42
43# TEST_EXPIRED_USER (user4) has expired
44TEST_EXPIRED_USER="user4@gitsecret.io"    # this key expires 2018-09-24
45
46TEST_ATTACKER_USER="attacker1@gitsecret.io"
47
48#TEST_DEFAULT_FILENAME="file_one"  # no spaces
49#TEST_SECOND_FILENAME="file_two"  # no spaces
50#TEST_THIRD_FILENAME="file_three"  # no spaces
51
52TEST_DEFAULT_FILENAME="space file" # has spaces
53TEST_SECOND_FILENAME="space file two" # has spaces
54TEST_THIRD_FILENAME="space file three"  # has spaces
55
56
57function test_user_password {
58  # Password for 'user3@gitsecret.io' is 'user3pass'
59  # As it was set on key creation.
60  echo "$1" | sed -e 's/@.*/pass/'
61}
62
63
64
65# GPG:
66
67function stop_gpg_agent {
68  local username=$(id -u -n)
69  ps -wx -U "$username" | gawk \
70    '/gpg-agent --homedir/ { if ( $0 !~ "awk" ) { system("kill -9 "$1) } }' \
71    > /dev/null 2>&1
72}
73
74
75function get_gpgtest_prefix {
76  if [[ $GPG_VER_21 -eq 1  ]]; then
77    echo "echo \"$(test_user_password $1)\" | "
78  else
79    echo ""
80  fi
81}
82
83
84function get_gpg_fingerprint_by_email {
85  local email="$1"
86  local fingerprint
87
88  fingerprint=$($GPGTEST --with-fingerprint \
89                         --with-colon \
90                         --list-secret-key $email | gawk "$AWK_GPG_GET_FP")
91  echo "$fingerprint"
92}
93
94
95function install_fixture_key {
96  local public_key="$BATS_TMPDIR/public-${1}.key"
97
98  \cp "$FIXTURES_DIR/gpg/${1}/public.key" "$public_key"
99  $GPGTEST --import "$public_key" > /dev/null 2>&1
100  rm -f "$public_key"
101}
102
103
104function install_fixture_full_key {
105  local private_key="$BATS_TMPDIR/private-${1}.key"
106  local gpgtest_prefix="$(get_gpgtest_prefix $1)"
107  local gpgtest_import="$gpgtest_prefix $GPGTEST"
108  local email
109  local fp
110  local fingerprint
111
112  email="$1"
113
114  \cp "$FIXTURES_DIR/gpg/${1}/private.key" "$private_key"
115
116  bash -c "$gpgtest_import --allow-secret-key-import \
117    --import \"$private_key\"" > /dev/null 2>&1
118
119  # since 0.1.2 fingerprint is returned:
120  fingerprint=$(get_gpg_fingerprint_by_email $email)
121
122  install_fixture_key "$1"
123
124  rm -f "$private_key"
125  # return fingerprint to delete it later:
126  echo "$fingerprint"
127}
128
129
130function uninstall_fixture_key {
131  local email
132
133  email="$1"
134  $GPGTEST --yes --delete-key "$email" > /dev/null 2>&1
135}
136
137
138function uninstall_fixture_full_key {
139  local email
140  email="$1"
141
142  local fingerprint="$2"
143  if [[ -z "$fingerprint" ]]; then
144    # see issue_12, fingerprint on `gpg2` has different format:
145    fingerprint=$(get_gpg_fingerprint_by_email "$email")
146  fi
147
148  $GPGTEST --yes \
149    --delete-secret-keys "$fingerprint" > /dev/null 2>&1
150
151  uninstall_fixture_key "$1"
152}
153
154
155# Git:
156
157function git_set_config_email {
158  git config --local user.email "$1"
159}
160
161
162function git_commit {
163  git_set_config_email "$1"
164
165  local user_name
166  local commit_gpgsign
167
168  user_name=$(git config user.name)
169
170  commit_gpgsign=$(git config commit.gpgsign)
171
172  git config --local user.name "$TEST_DEFAULT_USER"
173  git config --local commit.gpgsign false
174
175  git add --all
176  git commit -m "$2"
177
178  git config --local user.name "$user_name"
179  git config --local commit.gpgsign "$commit_gpgsign"
180}
181
182
183function remove_git_repository {
184  rm -rf ".git"
185}
186
187
188# Git Secret:
189
190function set_state_initial {
191  cd "$BATS_TMPDIR" || exit 1
192  rm -rf "${BATS_TMPDIR:?}/*"
193}
194
195
196function set_state_git {
197  git init > /dev/null 2>&1
198}
199
200
201function set_state_secret_init {
202  git secret init > /dev/null 2>&1
203}
204
205
206function set_state_secret_tell {
207  local email
208
209  email="$1"
210  git secret tell -d "$TEST_GPG_HOMEDIR" "$email" > /dev/null 2>&1
211}
212
213
214function set_state_secret_add {
215  local filename="$1"
216  local content="$2"
217  echo "$content" > "$filename"      # we add a newline
218  echo "$filename" >> ".gitignore"
219
220  git secret add "$filename" > /dev/null 2>&1
221}
222
223function set_state_secret_add_without_newline {
224  local filename="$1"
225  local content="$2"
226  echo -n "$content" > "$filename"      # we do not add a newline
227  echo "$filename" >> ".gitignore"
228
229  git secret add "$filename" > /dev/null 2>&1
230}
231
232
233function set_state_secret_hide {
234  git secret hide > /dev/null 2>&1
235}
236
237
238function unset_current_state {
239  # states order:
240  # initial, git, secret_init, secret_tell, secret_add, secret_hide
241
242  # unsets `secret_hide`
243  # removes .secret files:
244  git secret clean > /dev/null 2>&1
245
246  # unsets `secret_add`, `secret_tell` and `secret_init` by removing $_SECRETS_DIR
247  local secrets_dir
248  secrets_dir=$(_get_secrets_dir)
249
250  rm -rf "$secrets_dir"
251  rm -rf ".gitignore"
252
253  # unsets `git` state
254  remove_git_repository
255
256  # stop gpg-agent
257  stop_gpg_agent
258
259  # removes gpg homedir:
260  find "$TEST_GPG_HOMEDIR" \
261    -regex ".*\/random_seed\|.*\.gpg\|.*\.kbx.?\|.*private-keys.*\|.*test_sub_dir\|.*S.gpg-agent\|.*file_to_hide.*" \
262    -exec rm -rf {} +
263
264  # return to the base dir:
265  cd "$SECRET_PROJECT_ROOT" || exit 1
266}
267