diff --git a/.ci/integration/gnupg-git/default.yml b/.ci/integration/gnupg-git/default.yml index 1650f4f8..38f6e416 100644 --- a/.ci/integration/gnupg-git/default.yml +++ b/.ci/integration/gnupg-git/default.yml @@ -151,6 +151,16 @@ when: - ansible_os_family == "Alpine" + # disable gnupg doc build on Ubuntu-Rolling because it won't build + # ( See https://travis-ci.org/sobolevn/git-secret/jobs/439870332 ) + - name: Disable making docs on Ubuntu-Rolling + lineinfile: + path: "{{ gpg_src_path }}/Makefile" + regexp: '^doc = doc$' + line: 'doc = ' + when: + - ansible_distribution == "Ubuntu" + - name: Compile gnupg src command: bash -lc "cd {{ gpg_src_path }} && make" changed_when: False diff --git a/Makefile b/Makefile index 1394034f..50eee9c8 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ PREFIX?="/usr" # Building: # -git-secret: src/version.sh src/_utils/* src/commands/* src/main.sh +git-secret: src/version.sh src/_utils/*.sh src/commands/*.sh src/main.sh @cat $^ > "$@"; \ chmod +x git-secret; sync diff --git a/man/man1/git-secret-hide.1 b/man/man1/git-secret-hide.1 index 08d9aa44..7fe49eb6 100644 --- a/man/man1/git-secret-hide.1 +++ b/man/man1/git-secret-hide.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "GIT\-SECRET\-HIDE" "1" "August 2018" "sobolevn" "git-secret" +.TH "GIT\-SECRET\-HIDE" "1" "September 2018" "sobolevn" "git-secret" . .SH "NAME" \fBgit\-secret\-hide\fR \- encrypts all added files with the inner keyring\. @@ -10,15 +10,27 @@ . .nf -git secret hide [\-c] [\-P] [\-v] [\-d] [\-m] +git secret hide [\-c] [\-F] [\-P] [\-v] [\-d] [\-m] . .fi . .SH "DESCRIPTION" -\fBgit\-secret\-hide\fR creates an encrypted version (typically called filename\.txt\.secret) for each file added by \fBgit\-secret\-add\fR command\. Now anyone enabled via \'git secret tell\' can can decrypt these files\. Under the hood, \fBgit\-secret\fR uses the keyring in \.gitsecret/keys and their secret key to decrypt the files\. +\fBgit\-secret\-hide\fR creates an encrypted version (typically called \fBfilename\.txt\.secret\fR) of each file added by \fBgit\-secret\-add\fR command\. Now anyone enabled via \'git secret tell\' can can decrypt these files\. Under the hood, \fBgit\-secret\fR uses the keyring in \fB\.gitsecret/keys\fR and user\'s secret keys to decrypt the files\. . .P -It is possible to modify the names of the encrypted files by setting \fBSECRETS_EXTENSION\fR variable\. +It is recommended to encrypt (or re\-encrypt) all the files in a git\-secret repo each time \fBgit secret hide\fR is run\. +. +.P +Otherwise the keychain (the one stored in \fB\.gitsecret/keys/*\.gpg\fR), may have changed since the last time the files were encrypted, and it\'s possible to create a state where the users in the output of \fBgit secret whoknows\fR may not be able to decrypt the some files in the repo, or may be able decrypt files they\'re not supposed to be able to\. +. +.P +In other words, unless you re\-encrypt all the files in a repo each time you \'hide\' any, it\'s possible to make it so some files can no longer be decrypted by users who should be (and would appear) able to decrypt them, and vice\-versa\. +. +.P +If you know what you are doing and wish to encrypt or re\-encrypt only a subset of the files even after reading the above paragraphs, you can use the \-F option to force \fBgit secret hide\fR to skip any hidden files where the unencrypted versions aren\'t present\. +. +.P +Also, it is possible to modify the names of the encrypted files by setting \fBSECRETS_EXTENSION\fR variable\. . .P (See git\-secret(7) \fIhttp://git\-secret\.io/git\-secret\fR for information about renaming the \.gitsecret folder using the SECRETS_DIR environment variable\. @@ -29,6 +41,7 @@ It is possible to modify the names of the encrypted files by setting \fBSECRETS_ \-v \- verbose, shows extra information\. \-c \- deletes encrypted files before creating new ones\. +\-F \- forces hide to continue if a file to encrypt is missing\. \-P \- preserve permissions of unencrypted file in encrypted file\. \-d \- deletes unencrypted files after encryption\. \-m \- encrypt files only when modified\. diff --git a/man/man1/git-secret-hide.1.ronn b/man/man1/git-secret-hide.1.ronn index 2eab9bea..f3c4bec2 100644 --- a/man/man1/git-secret-hide.1.ronn +++ b/man/man1/git-secret-hide.1.ronn @@ -3,16 +3,33 @@ git-secret-hide - encrypts all added files with the inner keyring. ## SYNOPSIS - git secret hide [-c] [-P] [-v] [-d] [-m] + git secret hide [-c] [-F] [-P] [-v] [-d] [-m] ## DESCRIPTION -`git-secret-hide` creates an encrypted version (typically called filename.txt.secret) -for each file added by `git-secret-add` command. +`git-secret-hide` creates an encrypted version (typically called `filename.txt.secret`) +of each file added by `git-secret-add` command. Now anyone enabled via 'git secret tell' can can decrypt these files. Under the hood, -`git-secret` uses the keyring in .gitsecret/keys and their secret key to decrypt the files. +`git-secret` uses the keyring in `.gitsecret/keys` and user's secret keys to decrypt the files. -It is possible to modify the names of the encrypted files by setting `SECRETS_EXTENSION` variable. +It is recommended to encrypt (or re-encrypt) all the files in a git-secret repo each +time `git secret hide` is run. + +Otherwise the keychain (the one stored in `.gitsecret/keys/*.gpg`), +may have changed since the last time the files were encrypted, and it's possible +to create a state where the users in the output of `git secret whoknows` +may not be able to decrypt the some files in the repo, or may be able decrypt files +they're not supposed to be able to. + +In other words, unless you re-encrypt all the files in a repo each time you 'hide' any, +it's possible to make it so some files can no longer be decrypted by users who should be +(and would appear) able to decrypt them, and vice-versa. + +If you know what you are doing and wish to encrypt or re-encrypt only a subset of the files +even after reading the above paragraphs, you can use the -F option to force `git secret hide` +to skip any hidden files where the unencrypted versions aren't present. + +Also, it is possible to modify the names of the encrypted files by setting `SECRETS_EXTENSION` variable. (See [git-secret(7)](http://git-secret.io/git-secret) for information about renaming the .gitsecret folder using the SECRETS_DIR environment variable. @@ -22,6 +39,7 @@ folder using the SECRETS_DIR environment variable. -v - verbose, shows extra information. -c - deletes encrypted files before creating new ones. + -F - forces hide to continue if a file to encrypt is missing. -P - preserve permissions of unencrypted file in encrypted file. -d - deletes unencrypted files after encryption. -m - encrypt files only when modified. diff --git a/man/man1/git-secret-reveal.1 b/man/man1/git-secret-reveal.1 index 07a1a015..c6d17df1 100644 --- a/man/man1/git-secret-reveal.1 +++ b/man/man1/git-secret-reveal.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "GIT\-SECRET\-REVEAL" "1" "August 2018" "sobolevn" "git-secret" +.TH "GIT\-SECRET\-REVEAL" "1" "September 2018" "sobolevn" "git-secret" . .SH "NAME" \fBgit\-secret\-reveal\fR \- decrypts all added files\. @@ -10,12 +10,12 @@ . .nf -git secret reveal [\-f] [\-P] [\-d dir] [\-p password] +git secret reveal [\-f] [\-F] [\-P] [\-d dir] [\-p password] [pathspec]\.\.\. . .fi . .SH "DESCRIPTION" -\fBgit\-secret\-reveal\fR \- decrypts all the files in \fB\.gitsecret/paths/mapping\.cfg\fR\. You will need to have imported the paired secret\-key with one of the public\-keys which were used in the encryption\. Under the hood, this uses the \fBgpg \-\-decrypt\fR command\. +\fBgit\-secret\-reveal\fR \- decrypts all the files in \fB\.gitsecret/paths/mapping\.cfg\fR, or the passed \fBpathspec\fRs\. You will need to have imported the paired secret\-key with one of the public\-keys which were used in the encryption\. Under the hood, this uses the \fBgpg \-\-decrypt\fR command\. . .P (See git\-secret(7) \fIhttp://git\-secret\.io/git\-secret\fR for information about renaming the \.gitsecret folder using the SECRETS_DIR environment variable\. @@ -24,7 +24,8 @@ git secret reveal [\-f] [\-P] [\-d dir] [\-p password] . .nf -\-f \- forces to overwrite existing files without prompt\. +\-f \- forces gpg to overwrite existing files without prompt\. +\-F \- forces reveal to continue even if a file fails to decrypt\. \-d \- specifies `\-\-homedir` option for the `gpg`, basically use this option if you store your keys in a custom location\. \-p \- specifies password for noinput mode, adds `\-\-passphrase` option for `gpg`\. \-P \- preserve permissions of encrypted file in unencrypted file\. diff --git a/man/man1/git-secret-reveal.1.ronn b/man/man1/git-secret-reveal.1.ronn index 81e08ac9..12c10f20 100644 --- a/man/man1/git-secret-reveal.1.ronn +++ b/man/man1/git-secret-reveal.1.ronn @@ -3,11 +3,12 @@ git-secret-reveal - decrypts all added files. ## SYNOPSIS - git secret reveal [-f] [-P] [-d dir] [-p password] + git secret reveal [-f] [-F] [-P] [-d dir] [-p password] [pathspec]... ## DESCRIPTION -`git-secret-reveal` - decrypts all the files in `.gitsecret/paths/mapping.cfg`. +`git-secret-reveal` - decrypts all the files in `.gitsecret/paths/mapping.cfg`, +or the passed `pathspec`s. You will need to have imported the paired secret-key with one of the public-keys which were used in the encryption. Under the hood, this uses the `gpg --decrypt` command. @@ -18,7 +19,8 @@ folder using the SECRETS_DIR environment variable. ## OPTIONS - -f - forces to overwrite existing files without prompt. + -f - forces gpg to overwrite existing files without prompt. + -F - forces reveal to continue even if a file fails to decrypt. -d - specifies `--homedir` option for the `gpg`, basically use this option if you store your keys in a custom location. -p - specifies password for noinput mode, adds `--passphrase` option for `gpg`. -P - preserve permissions of encrypted file in unencrypted file. diff --git a/man/man1/git-secret-tell.1 b/man/man1/git-secret-tell.1 index 4771bd88..e65a4bda 100644 --- a/man/man1/git-secret-tell.1 +++ b/man/man1/git-secret-tell.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "GIT\-SECRET\-TELL" "1" "July 2018" "sobolevn" "git-secret" +.TH "GIT\-SECRET\-TELL" "1" "August 2018" "sobolevn" "git-secret" . .SH "NAME" \fBgit\-secret\-tell\fR \- adds a person, who can access private data\. diff --git a/man/man1/git-secret-usage.1 b/man/man1/git-secret-usage.1 index 204b296f..efc8445a 100644 --- a/man/man1/git-secret-usage.1 +++ b/man/man1/git-secret-usage.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "GIT\-SECRET\-USAGE" "1" "June 2018" "sobolevn" "git-secret" +.TH "GIT\-SECRET\-USAGE" "1" "August 2018" "sobolevn" "git-secret" . .SH "NAME" \fBgit\-secret\-usage\fR \- prints all the available commands\. diff --git a/man/man1/git-secret-whoknows.1 b/man/man1/git-secret-whoknows.1 index e39932d6..1b415c91 100644 --- a/man/man1/git-secret-whoknows.1 +++ b/man/man1/git-secret-whoknows.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "GIT\-SECRET\-WHOKNOWS" "1" "June 2018" "sobolevn" "git-secret" +.TH "GIT\-SECRET\-WHOKNOWS" "1" "August 2018" "sobolevn" "git-secret" . .SH "NAME" \fBgit\-secret\-whoknows\fR \- prints email\-labels for each key in the keyring\. diff --git a/src/_utils/_git_secret_tools.sh b/src/_utils/_git_secret_tools.sh index a2646764..4e086c4a 100644 --- a/src/_utils/_git_secret_tools.sh +++ b/src/_utils/_git_secret_tools.sh @@ -184,6 +184,7 @@ function _delete_line { # this sets the global variable 'filename' +# currently this function is only used by 'hide' function _temporary_file { # This function creates temporary file # which will be removed on system exit. @@ -430,9 +431,34 @@ function _get_secrets_dir_paths_mapping { function _abort { local message="$1" # required + local exit_code=${2:-"1"} # defaults to 1 >&2 echo "git-secret: abort: $message" - exit 1 + exit "$exit_code" +} + +# _warn() sends warnings to stdout so user sees them +function _warn { + local message="$1" # required + + >&2 echo "git-secret: warning: $message" +} + +# _warn_or_abort "$error_message" "$exit_code" "$error_ok" +function _warn_or_abort { + local message="$1" # required + local exit_code=${2:-"1"} # defaults to 1 + local error_ok=${3:-0} # can be 0 or 1 + + if [[ "$error_ok" -eq "0" ]]; then + if [[ "$exit_code" -eq "0" ]]; then + # if caller sends an exit_code of 0, we change it to 1 before aborting. + exit_code=1 + fi + _abort "$message" "$exit_code" + else + _warn "$message" "$exit_code" + fi } function _find_and_clean { @@ -643,6 +669,7 @@ function _decrypt { local force=${3:-0} # can be 0 or 1 local homedir=${4:-""} local passphrase=${5:-""} + local error_ok=${6:-0} # can be 0 or 1 local encrypted_filename encrypted_filename=$(_get_encrypted_filename "$filename") @@ -665,6 +692,7 @@ function _decrypt { args+=( "--pinentry-mode" "loopback" ) fi + #echo "# gpg passphrase: $passphrase" >&3 local exit_code if [[ -n "$passphrase" ]]; then echo "$passphrase" | $SECRETS_GPG_COMMAND "${args[@]}" --quiet --batch --yes --no-tty --passphrase-fd 0 \ @@ -674,8 +702,16 @@ function _decrypt { $SECRETS_GPG_COMMAND "${args[@]}" "--quiet" "$encrypted_filename" exit_code=$? fi - if [[ "$exit_code" -ne 0 ]]; then - _abort "problem decrypting file with gpg: exit code $exit_code: $filename" + # note that according to https://github.com/sobolevn/git-secret/issues/238 , + # it's possible for gpg to return a 0 exit code but not have decrypted the file + #echo "# gpg exit code: $exit_code, error_ok: $error_ok" >&3 + if [[ "$exit_code" -ne "0" ]]; then + local msg="problem decrypting file with gpg: exit code $exit_code: $filename" + if [[ "$error_ok" -eq "0" ]]; then + _abort "$msg" "$exit_code" + else + _warn "$msg" + fi fi } diff --git a/src/commands/git_secret_hide.sh b/src/commands/git_secret_hide.sh index 8600dc7e..80dff4bf 100644 --- a/src/commands/git_secret_hide.sh +++ b/src/commands/git_secret_hide.sh @@ -84,13 +84,16 @@ function hide { local delete=0 local fsdb_update_hash=0 # add checksum hashes to fsdb local verbose='' + local force_continue=0 OPTIND=1 - while getopts 'cPdmvh' opt; do + while getopts 'cFPdmvh' opt; do case "$opt" in c) clean=1;; + F) force_continue=1;; + P) preserve=1;; d) delete=1;; @@ -119,6 +122,8 @@ function hide { local path_mappings path_mappings=$(_get_secrets_dir_paths_mapping) + local num_mappings + num_mappings=$(gawk 'END{print NR}' "$path_mappings") # make sure all the unencrypted files needed are present local to_hide=() @@ -148,42 +153,44 @@ function hide { # Checking that file is valid: if [[ ! -f "$input_path" ]]; then - _abort "file not found: $input_path" - fi - - file_hash=$(_get_file_hash "$input_path") - - # encrypt file only if required - if [[ "$fsdb_file_hash" != "$file_hash" ]]; then - # we depend on $recipients being split on whitespace - # shellcheck disable=SC2086 - $SECRETS_GPG_COMMAND --homedir "$secrets_dir_keys" "--no-permission-warning" --use-agent --yes --trust-model=always --encrypt \ - $recipients -o "$output_path" "$input_path" > /dev/null 2>&1 - local exit_code=$? - if [[ "$exit_code" -ne 0 ]]; then - _abort "problem encrypting file with gpg: exit code $exit_code: $filename" + # this catches the case where some decrypted files don't exist + _warn_or_abort "file not found: $input_path" "1" "$force_continue" + else + file_hash=$(_get_file_hash "$input_path") + + # encrypt file only if required + if [[ "$fsdb_file_hash" != "$file_hash" ]]; then + # we depend on $recipients being split on whitespace + # shellcheck disable=SC2086 + $SECRETS_GPG_COMMAND --homedir "$secrets_dir_keys" "--no-permission-warning" --use-agent --yes --trust-model=always --encrypt \ + $recipients -o "$output_path" "$input_path" > /dev/null 2>&1 + local exit_code=$? + if [[ "$exit_code" -ne 0 ]] || [[ ! -f "$output_path" ]]; then + # if gpg can't encrypt a file we asked it to, that's an error unless in force_continue mode. + _warn_or_abort "problem encrypting file with gpg: exit code $exit_code: $filename" "$exit_code" "$force_continue" + fi + + if [[ "$preserve" == 1 ]] && [[ -f "$output_path" ]]; then + local perms + perms=$($SECRETS_OCTAL_PERMS_COMMAND "$input_path") + chmod "$perms" "$output_path" + fi + + + # If -m option was provided, it will update unencrypted file hash + local key="$filename" + local hash="$file_hash" + # Update file hash if required in fsdb + [[ "$fsdb_update_hash" -gt 0 ]] && \ + _optional_fsdb_update_hash "$key" "$hash" + counter=$((counter+1)) fi - - if [[ "$preserve" == 1 ]]; then - local perms - perms=$($SECRETS_OCTAL_PERMS_COMMAND "$input_path") - chmod "$perms" "$output_path" - fi - - - # If -m option was provided, it will update unencrypted file hash - local key="$filename" - local hash="$file_hash" - # Update file hash if required in fsdb - [[ "$fsdb_update_hash" -gt 0 ]] && \ - _optional_fsdb_update_hash "$key" "$hash" fi - counter=$((counter+1)) done # If -d option was provided, it would delete the source files # after we have already hidden them. _optional_delete "$delete" "$verbose" - echo "done. all $counter files are hidden." + echo "done. $counter of $num_mappings files are hidden." } diff --git a/src/commands/git_secret_reveal.sh b/src/commands/git_secret_reveal.sh index cf9fa328..61301ce9 100644 --- a/src/commands/git_secret_reveal.sh +++ b/src/commands/git_secret_reveal.sh @@ -4,17 +4,20 @@ function reveal { local homedir='' local passphrase='' - local force=0 + local force=0 # this means 'clobber without warning' + local force_continue=0 # this means 'continue if we have decryption errors' local preserve=0 OPTIND=1 - while getopts 'hfPd:p:' opt; do + while getopts 'hfFPd:p:' opt; do case "$opt" in h) _show_manual_for 'reveal';; f) force=1;; + F) force_continue=1;; + P) preserve=1;; p) passphrase=$OPTARG;; @@ -36,29 +39,37 @@ function reveal { path_mappings=$(_get_secrets_dir_paths_mapping) local counter=0 - while read -r line; do + local to_show=( "$@" ) + + if [ ${#to_show[@]} -eq 0 ]; then + while read -r record; do + to_show+=("$record") # add record to array + done < "$path_mappings" + fi + + for line in "${to_show[@]}"; do local filename local path filename=$(_get_record_filename "$line") path=$(_append_root_path "$filename") - # The parameters are: filename, write-to-file, force, homedir, passphrase - _decrypt "$path" "1" "$force" "$homedir" "$passphrase" + # The parameters are: filename, write-to-file, force, homedir, passphrase, error_ok + _decrypt "$path" "1" "$force" "$homedir" "$passphrase" "$force_continue" if [[ ! -f "$path" ]]; then - _abort "cannot find decrypted version of file: $filename" - fi - - if [[ "$preserve" == 1 ]]; then + _warn_or_abort "cannot find decrypted version of file: $filename" "2" "$force_continue" + else + counter=$((counter+1)) local secret_file secret_file=$(_get_encrypted_filename "$path") - local perms - perms=$($SECRETS_OCTAL_PERMS_COMMAND "$secret_file") - chmod "$perms" "$path" + if [[ "$preserve" == 1 ]] && [[ -f "$secret_file" ]]; then + local perms + perms=$($SECRETS_OCTAL_PERMS_COMMAND "$secret_file") + chmod "$perms" "$path" + fi fi - - counter=$((counter+1)) + done < "$path_mappings" - echo "done. all $counter files are revealed." + echo "done. $counter of ${#to_show[@]} files are revealed." } diff --git a/src/main.sh b/src/main.sh index fd49647a..da86efb9 100755 --- a/src/main.sh +++ b/src/main.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -set -e +# we don't use set -e, it messes up hide -F and reveal -F error handling function _check_setup { # Checking git and secret-plugin setup: diff --git a/tests/test_hide.bats b/tests/test_hide.bats index 11da2fe4..77ba34d2 100644 --- a/tests/test_hide.bats +++ b/tests/test_hide.bats @@ -28,9 +28,11 @@ function teardown { @test "run 'hide' normally" { run git secret hide + echo "# run hide normally: output: $output" >&3 + # Command must execute normally: [ "$status" -eq 0 ] - [ "$output" = "done. all 1 files are hidden." ] + [ "$output" = "done. 1 of 1 files are hidden." ] # New files should be created: local encrypted_file=$(_get_encrypted_filename "$FILE_TO_HIDE") @@ -44,9 +46,11 @@ function teardown { run git secret hide -P + echo "# run hide with -P: output: $output" >&3 + # Command must execute normally: [ "$status" -eq 0 ] - [ "$output" = "done. all 1 files are hidden." ] + [ "$output" = "done. 1 of 1 files are hidden." ] # New files should be created: local encrypted_file=$(_get_encrypted_filename "$FILE_TO_HIDE") @@ -99,7 +103,7 @@ function teardown { # Now it should return an error because one file can't be found run git secret hide [ "$status" -ne 0 ] - [ "$output" != "done. all 2 files are hidden." ] + [ "$output" != "done. 2 of 2 files are hidden." ] } @@ -111,8 +115,9 @@ function teardown { # Now it should hide 2 files: run git secret hide + echo "# run hide with multiple files: output: $output" >&3 [ "$status" -eq 0 ] - [ "$output" = "done. all 2 files are hidden." ] + [ "$output" = "done. 2 of 2 files are hidden." ] # Cleaning up: rm "$second_file" @@ -126,7 +131,7 @@ function teardown { [ "$status" -eq 0 ] # git secret hide -m, use temp file so cleaning should take place [[ "${#lines[@]}" -eq 2 ]] - [ "${lines[0]}" = "done. all 1 files are hidden." ] + [ "${lines[0]}" = "done. 1 of 1 files are hidden." ] [ "${lines[1]}" = "cleaning up..." ] # New files should be created: @@ -140,12 +145,13 @@ function teardown { path_mappings=$(_get_secrets_dir_paths_mapping) run git secret hide -m + echo "# run hide with -m twice: output: $output" >&3 # Command must execute normally: [ "$status" -eq 0 ] # git secret hide -m, uses a temp file so cleaning should take place [[ "${#lines[@]}" -eq 2 ]] - [ "${lines[0]}" = "done. all 1 files are hidden." ] + [ "${lines[0]}" = "done. 1 of 1 files are hidden." ] [ "${lines[1]}" = "cleaning up..." ] # back path mappings cp "${path_mappings}" "${path_mappings}.bak" @@ -154,7 +160,9 @@ function teardown { # compare [ "$status" -eq 0 ] [[ "${#lines[@]}" -eq 1 ]] - [ "$output" = "done. all 1 files are hidden." ] + + # output says 0 of 1 files are hidden because checksum didn't change and we didn't need to hide it again. + [ "$output" = "done. 0 of 1 files are hidden." ] # no changes should occur to path_mappings files cmp -s "${path_mappings}" "${path_mappings}.bak" @@ -239,5 +247,5 @@ function teardown { run git secret hide [ "$status" -eq 0 ] - [ "$output" = "done. all 1 files are hidden." ] + [ "$output" = "done. 1 of 1 files are hidden." ] } diff --git a/tests/test_hide_continue.bats b/tests/test_hide_continue.bats new file mode 100644 index 00000000..496fb3f9 --- /dev/null +++ b/tests/test_hide_continue.bats @@ -0,0 +1,50 @@ +#!/usr/bin/env bats + +load _test_base + +FILE_TO_HIDE="$TEST_DEFAULT_FILENAME" +FILE_TO_HIDE2="$TEST_SECOND_FILENAME" +FILE_CONTENTS="hidden content юникод" + + +function setup { + install_fixture_key "$TEST_DEFAULT_USER" + + set_state_initial + set_state_git + set_state_secret_init + set_state_secret_tell "$TEST_DEFAULT_USER" + set_state_secret_add "$FILE_TO_HIDE" "$FILE_CONTENTS" + set_state_secret_add "$FILE_TO_HIDE2" "$FILE_CONTENTS" +} + + +function teardown { + rm "$FILE_TO_HIDE" + rm "$FILE_TO_HIDE2" + + uninstall_fixture_key "$TEST_DEFAULT_USER" + unset_current_state +} + +@test "run 'hide -F' with missing input file" { + mv "$FILE_TO_HIDE" "$FILE_TO_HIDE.was" # move the first file out of the way + run git secret hide -F + + #echo "# output of 'git secret hide -F' is: $output" >&3 + + # Command must execute normally: + [ "$status" -eq 0 ] + + # secret file for missing file should not be created: + local encrypted_file=$(_get_encrypted_filename "$FILE_TO_HIDE") + [ ! -f "$encrypted_file" ] + + # this secret file should be created: + local encrypted_file2=$(_get_encrypted_filename "$FILE_TO_HIDE2") + [ -f "$encrypted_file2" ] + + # put back first file so teardown() succeeds + mv "$FILE_TO_HIDE.was" "$FILE_TO_HIDE" +} + diff --git a/tests/test_reveal.bats b/tests/test_reveal.bats index b972f0d2..fe8d7b67 100644 --- a/tests/test_reveal.bats +++ b/tests/test_reveal.bats @@ -93,7 +93,7 @@ function teardown { # Preparations rm "$FILE_TO_HIDE" - local atacker_fingerprint=$(install_fixture_full_key "$TEST_ATTACKER_USER") + local attacker_fingerprint=$(install_fixture_full_key "$TEST_ATTACKER_USER") local password=$(test_user_password "$TEST_ATTACKER_USER") run git secret reveal -d "$TEST_GPG_HOMEDIR" -p "$password" @@ -103,9 +103,30 @@ function teardown { [ ! -f "$FILE_TO_HIDE" ] # Cleaning up: - uninstall_fixture_full_key "$TEST_ATTACKER_USER" "$atacker_fingerprint" + uninstall_fixture_full_key "$TEST_ATTACKER_USER" "$attacker_fingerprint" } +@test "run 'reveal' for attacker with -F (force)" { + # Preparations + rm "$FILE_TO_HIDE" + + local attacker_fingerprint=$(install_fixture_full_key "$TEST_ATTACKER_USER") + local password=$(test_user_password "$TEST_ATTACKER_USER") + + run git secret reveal -F -d "$TEST_GPG_HOMEDIR" -p "$password" + + #echo "# status is $status" >&3 + + # This should return a status code of 1 also. Not sure how to test that we don't die early + [ "$status" -eq 0 ] + [ ! -f "$FILE_TO_HIDE" ] + + + touch "$FILE_TO_HIDE" #create this file so uninstall below works + + # Cleaning up: + uninstall_fixture_full_key "$TEST_ATTACKER_USER" "$attacker_fingerprint" +} @test "run 'reveal' for multiple users (with key deletion)" { # Preparations: